diff options
188 files changed, 35957 insertions, 20981 deletions
diff --git a/classes/opie.bbclass b/classes/opie.bbclass index c00f7e19a9..47f364a644 100644 --- a/classes/opie.bbclass +++ b/classes/opie.bbclass @@ -23,7 +23,8 @@ OPIE_CVS_PV = "1.2.1+cvs-${SRCDATE}" DEPENDS_prepend = "${@["libopie2 ", ""][(bb.data.getVar('PN', d, 1) == 'libopie2')]}" # to be consistent, put all targets into workdir -EXTRA_QMAKEVARS_POST_append = " DESTDIR=${S}" +# NOTE: leave one space at the end, other files are expecting that +EXTRA_QMAKEVARS_POST += "DESTDIR=${S} " # Opie standard TAG value TAG = "${@'v' + bb.data.getVar('PV',d,1).replace('.', '_')}" diff --git a/classes/palmtop.bbclass b/classes/palmtop.bbclass index 523c3d71bb..7c65271b91 100644 --- a/classes/palmtop.bbclass +++ b/classes/palmtop.bbclass @@ -1,10 +1,17 @@ -# basically a placeholder for something more fancy -# for now, just declare some things +# this build class sets up qmake variables to +# * build using the Qt Windowing System (QWS) +# * use qt +# * link against supc++ instead of stdc++ +# * use threads, if requested via PALMTOP_USE_MULTITHREADED_QT = "yes" +# inherit this class to build programs against libqpe +# inherit opie if you want to build programs against libopie2 +# don't override EXTRA_QMAKEVARS_POST, if you use inherit this class inherit qmake -EXTRA_QMAKEVARS_POST_append = " DEFINES+=QWS LIBS+=-lqpe CONFIG+=qt LIBS-=-lstdc++ LIBS+=-lsupc++" - -DEPENDS_prepend = "virtual/libqpe uicmoc-native " +EXTRA_QMAKEVARS_POST += "DEFINES+=QWS CONFIG+=qt LIBS-=-lstdc++ LIBS+=-lsupc++" +EXTRA_QMAKEVARS_POST += '${@base_conditional("PALMTOP_USE_MULTITHREADED_QT", "yes", "CONFIG+=thread", "CONFIG-=thread",d)}' +EXTRA_QMAKEVARS_POST += "${@["LIBS+=-lqpe ", ""][(bb.data.getVar('PN', d, 1) == 'libqpe-opie')]}" +DEPENDS_prepend = "${@["virtual/libqpe1 uicmoc-native ", ""][(bb.data.getVar('PN', d, 1) == 'libqpe-opie')]}" FILES_${PN} = "${palmtopdir}" diff --git a/classes/qmake.bbclass b/classes/qmake.bbclass index 3a06b1af9f..4f2fceff35 100644 --- a/classes/qmake.bbclass +++ b/classes/qmake.bbclass @@ -49,7 +49,7 @@ qmake_do_configure() { #oenote "Calling '${OE_QMAKE_QMAKE} -makefile -spec ${QMAKESPEC} -o Makefile $QMAKE_VARSUBST_PRE $AFTER $PROFILES $QMAKE_VARSUBST_POST'" unset QMAKESPEC || true - ${OE_QMAKE_QMAKE} -makefile -spec ${QMAKESPEC} -o Makefile $QMAKE_VARSUBST_PRE $AFTER $PROFILES $QMAKE_VARSUBST_POST || die "Error calling qmake on $PROFILES" + ${OE_QMAKE_QMAKE} -makefile -spec ${QMAKESPEC} -o Makefile $QMAKE_VARSUBST_PRE $AFTER $PROFILES $QMAKE_VARSUBST_POST || die "Error calling ${OE_QMAKE_QMAKE} on $PROFILES" } EXPORT_FUNCTIONS do_configure diff --git a/classes/sanity.bbclass b/classes/sanity.bbclass index f03564c607..6af44ee191 100644 --- a/classes/sanity.bbclass +++ b/classes/sanity.bbclass @@ -78,7 +78,7 @@ def check_sanity(e): raise_sanity_error('Please install the patch utility, preferable GNU patch.') if not check_app_exists('diffstat', e.data): - raise_sanity_error('Please install the diffstat utilits') + raise_sanity_error('Please install the diffstat utility') if not check_app_exists('texi2html', e.data): raise_sanity_error('Please install the texi2html binary') diff --git a/classes/sdl.bbclass b/classes/sdl.bbclass index 541812ed93..c0b21427a4 100644 --- a/classes/sdl.bbclass +++ b/classes/sdl.bbclass @@ -1,27 +1,44 @@ -FILES_${PN} += '${libdir}/perl5' +# +# (C) Michael 'Mickey' Lauer <mickey@Vanille.de> +# -sdl_do_configure () { - if [ -x ${S}/configure ] ; then - cfgcmd="${S}/configure \ - -GL -GLU" - oenote "Running $cfgcmd..." - $cfgcmd || oefatal "oe_runconf failed" - if [ "${BUILD_SYS}" != "${HOST_SYS}" ]; then - . ${STAGING_DIR}/${TARGET_SYS}/perl/config.sh - sed -e "s:\(SITELIBEXP = \).*:\1${sitelibexp}:; s:\(SITEARCHEXP = \).*:\1${sitearchexp}:; s:\(INSTALLVENDORLIB = \).*:\1${D}${libdir}/perl5:; s:\(INSTALLVENDORARCH = \).*:\1${D}${libdir}/perl5:" < Makefile > Makefile.new - mv Makefile.new Makefile - fi - else - oefatal "no configure script found" - fi -} +DEPENDS += "virtual/libsdl libsdl-mixer libsdl-image" -sdl_do_compile () { - oe_runmake PASTHRU_INC="${CFLAGS}" -} +APPDESKTOP ?= "${PN}.desktop" +APPNAME ?= "${PN}" +APPIMAGE ?= "${PN}.png" + +sdl_do_sdl_install() { + install -d ${D}${palmtopdir}/bin + install -d ${D}${palmtopdir}/pics + install -d ${D}${palmtopdir}/apps/Games + ln -sf ${bindir}/${APPNAME} ${D}${palmtopdir}/bin/${APPNAME} + install -m 0644 ${APPIMAGE} ${D}${palmtopdir}/pics/${PN}.png -sdl_do_install () { - oe_runmake install_vendor + if [ -e "${APPDESKTOP}" ] + then + echo ${APPDESKTOP} present, installing to palmtopdir... + install -m 0644 ${APPDESKTOP} ${D}${palmtopdir}/apps/Games/${PN}.desktop + else + echo ${APPDESKTOP} not present, creating one on-the-fly... + cat >${D}${palmtopdir}/apps/Games/${PN}.desktop <<EOF +[Desktop Entry] +Note=Auto Generated... this may be not what you want +Comment=${DESCRIPTION} +Exec=${APPNAME} +Icon=${APPIMAGE} +Type=Application +Name=${PN} +EOF + fi } -EXPORT_FUNCTIONS do_configure do_compile do_install +EXPORT_FUNCTIONS do_sdl_install +addtask sdl_install after do_compile before do_populate_staging + +SECTION = "x11/games" +SECTION_${PN}-opie = "opie/games" + +PACKAGES += "${PN}-opie" +RDEPENDS_${PN}-opie += "${PN}" +FILES_${PN}-opie = "${palmtopdir}" diff --git a/conf/distro/angstrom-2006.9.conf b/conf/distro/angstrom-2006.9.conf index 2fc1e31c72..531ad6818c 100644 --- a/conf/distro/angstrom-2006.9.conf +++ b/conf/distro/angstrom-2006.9.conf @@ -3,7 +3,6 @@ DISTRO_VERSION = "test-${DATE}" include conf/distro/angstrom.conf - DISTRO_TYPE = "debug" #DISTRO_TYPE = "release" #!!!!! DON'T FORGET TO ENABLE ZAPROOTPASSWD !!!!! @@ -15,27 +14,32 @@ FEED_URIS += " \ # ${MACHINE}##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/${MACHINE} \ # updates##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/updates" -#CVSDATE = 20050331 +SRCDATE = "20060424" # Opie +QTE_VERSION = "2.3.10" +OPIE_VERSION = "1.2.2" include conf/distro/preferred-opie-versions.inc # GPE include conf/distro/preferred-gpe-versions-2.8.inc +#zap extra stuff taking place in $MACHINE.conf +GPE_EXTRA_INSTALL = "" + # E include conf/distro/preferred-e-versions.inc -PREFERRED_PROVIDERS += " virtual/libqpe:libqpe-opie" -PREFERRED_VERSION_qte = "2.3.10" - - PREFERRED_PROVIDERS += "virtual/xserver:xserver-kdrive" PREFERRED_PROVIDERS += "virtual/gconf:gconf-dbus" PREFERRED_PROVIDER_libx11 = "diet-x11" +#Make sure we use 2.6 on machines with a 2.4/2.6 selector +KERNEL = "kernel26" +ZKERNEL_VERSION = "2.6" + PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial" PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc:gcc-cross" PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}g++:gcc-cross" diff --git a/conf/distro/debianslug.conf b/conf/distro/debianslug.conf index 1063356217..32dd55d978 100644 --- a/conf/distro/debianslug.conf +++ b/conf/distro/debianslug.conf @@ -30,7 +30,7 @@ DEBIANSLUG_EXTRA_BBFILES ?= "" # not absolutely required for boot. # NOTE: only jffs2 support is an absolute requirement of boot, even # the ext2/ext3 support is optional! -DEBIANSLUG_EXT2_PROGS = "e2fsprogs-mke2fs e2fsprogs-fsck e2fsprogs-e2fsck" +DEBIANSLUG_EXT2_PROGS = "e2fsprogs-mke2fs e2fsprogs-fsck e2fsprogs-e2fsck e2fsprogs-badblocks" DEBIANSLUG_REISER_PROGS = "reiserfsprogs" # The standard firmware contents and additional packages built as requirements diff --git a/conf/distro/familiar-unstable.conf b/conf/distro/familiar-unstable.conf index ab367378af..8b40c5811a 100644 --- a/conf/distro/familiar-unstable.conf +++ b/conf/distro/familiar-unstable.conf @@ -5,7 +5,6 @@ DISTRO_VERSION = "unstable-${DATE}" include conf/distro/familiar.conf - DISTRO_TYPE = "debug" #DISTRO_TYPE = "release" #!!!!! DON'T FORGET TO ENABLE ZAPROOTPASSWD !!!!! @@ -39,7 +38,6 @@ PREFERRED_VERSION_orinoco-modules_h2200 ?= "0.15" PREFERRED_VERSION_orinoco-modules_ipaq-pxa270 ?= "0.15" - # The CSL compiler is unusable because # 1) certain programs stop to compile # 2) more programs segfault @@ -57,9 +55,6 @@ PREFERRED_VERSION_binutils ?= "2.15.94.0.1" # Opie # -PREFERRED_PROVIDERS += " virtual/libqpe:libqpe-opie" -PREFERRED_VERSION_qte = "2.3.10" - #OPIE_VERSION = "1.2.1" #include conf/distro/preferred-opie-versions.inc diff --git a/conf/distro/jlime-shrek.conf b/conf/distro/jlime-shrek.conf index c3f88c5511..943da6b9db 100644 --- a/conf/distro/jlime-shrek.conf +++ b/conf/distro/jlime-shrek.conf @@ -29,7 +29,6 @@ PREFERRED_VERSION_linux-libc-headers = "2.6.7.0" PREFERRED_VERSION_glib-2.0-native = "2.6.2" PREFERRED_VERSION_glib-2.0 = "2.6.2" PREFERRED_VERSION_dpkg = "1.10.23" -PREFERRED_VERSION_qte = "2.3.10" PREFERRED_VERSION_xserver-kdrive = "20050207" INHERIT += "package_tar package_ipk" diff --git a/conf/distro/openslug.conf b/conf/distro/openslug.conf index 09f3691b65..9c9ce228b4 100644 --- a/conf/distro/openslug.conf +++ b/conf/distro/openslug.conf @@ -30,7 +30,7 @@ OPENSLUG_EXTRA_BBFILES ?= "" # not absolutely required for boot. # NOTE: only jffs2 support is an absolute requirement of boot, even # the ext2/ext3 support is optional! -OPENSLUG_EXT2_PROGS = "e2fsprogs-mke2fs e2fsprogs-fsck e2fsprogs-e2fsck" +OPENSLUG_EXT2_PROGS = "e2fsprogs-mke2fs e2fsprogs-fsck e2fsprogs-e2fsck e2fsprogs-badblocks" OPENSLUG_REISER_PROGS = "reiserfsprogs" # The standard firmware contents and additional packages built as requirements diff --git a/conf/distro/openzaurus-unstable.conf b/conf/distro/openzaurus-unstable.conf index 1143f1d940..cc87380494 100644 --- a/conf/distro/openzaurus-unstable.conf +++ b/conf/distro/openzaurus-unstable.conf @@ -21,26 +21,20 @@ DISTRO_TYPE = "debug" # ASSUME_PROVIDED += "virtual/arm-linux-gcc-2.95" +PREFERRED_PROVIDER_hostap-conf = "hostap-conf" KERNEL_CONSOLE = "ttyS0" #DEBUG_OPTIMIZATION = "-O -g3" #DEBUG_BUILD = "1" #INHIBIT_PACKAGE_STRIP = "1" -PREFERRED_VERSION_gcc-cross ?= "3.4.4" -PREFERRED_VERSION_gcc-cross-initial ?= "3.4.4" - -PREFERRED_VERSION_hostap-modules ?= "0.3.9" - -#fix some iconv issues, needs to be adjusted when doing uclibc builds +# fix some iconv issues, needs to be adjusted when doing uclibc builds PREFERRED_PROVIDER_virtual/libiconv = "glibc" PREFERRED_PROVIDER_virtual/libintl = "glibc" - # # Base # -PREFERRED_VERSION_binutils-cross ?= "2.15.94.0.1" PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial" PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc:gcc-cross" PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross" @@ -48,10 +42,11 @@ PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross" # # Opie # -PREFERRED_PROVIDERS += " virtual/libqpe:libqpe-opie" - -#OPIE_VERSION = "1.2.1" -#include conf/distro/preferred-opie-versions.inc +QTE_VERSION = "2.3.10" +OPIE_VERSION = "1.2.2" +PALMTOP_USE_MULTITHREADED_QT = "no" +#PALMTOP_USE_MULTITHREADED_QT = "yes" +include conf/distro/preferred-opie-versions.inc # # GPE diff --git a/conf/distro/preferred-opie-versions.inc b/conf/distro/preferred-opie-versions.inc index d9f65b3831..5811856e55 100644 --- a/conf/distro/preferred-opie-versions.inc +++ b/conf/distro/preferred-opie-versions.inc @@ -1,14 +1,19 @@ # -# A list of applications. +# Opie libraries # - - +PREFERRED_PROVIDER_virtual/libqte2 = '${@base_conditional("PALMTOP_USE_MULTITHREADED_QT", "yes", "qte-mt", "qte", d)}' +PREFERRED_PROVIDER_virtual/libqpe1 = "libqpe-opie" +PREFERRED_VERSION_qte-mt = "${QTE_VERSION}" +PREFERRED_VERSION_qte = "${QTE_VERSION}" PREFERRED_VERSION_libopie2 = "${OPIE_VERSION}" PREFERRED_VERSION_libopieobex0 = "${OPIE_VERSION}" PREFERRED_VERSION_libopietooth1 = "${OPIE_VERSION}" PREFERRED_VERSION_libqpe-opie = "${OPIE_VERSION}" PREFERRED_VERSION_libqtaux2 = "${OPIE_VERSION}" PREFERRED_VERSION_libmailwrapper = "${OPIE_VERSION}" +# +# Opie applications +# PREFERRED_VERSION_opie-aboutapplet = "${OPIE_VERSION}" PREFERRED_VERSION_opie-addressbook = "${OPIE_VERSION}" PREFERRED_VERSION_opie-advancedfm = "${OPIE_VERSION}" @@ -191,4 +196,4 @@ PREFERRED_VERSION_opie-zkbapplet = "${OPIE_VERSION}" PREFERRED_VERSION_opie-zlines = "${OPIE_VERSION}" PREFERRED_VERSION_opie-zsafe = "${OPIE_VERSION}" PREFERRED_VERSION_opie-zsame = "${OPIE_VERSION}" -PREFERRED_VERSION_konqueror-embedded = "20030705" +PREFERRED_VERSION_konqueror-embedded = "20060404" diff --git a/conf/documentation.conf b/conf/documentation.conf index 57ca4fe237..d85ccdb0db 100644 --- a/conf/documentation.conf +++ b/conf/documentation.conf @@ -91,3 +91,8 @@ GROUP_locale[doc] = "Locale generation of the GNU libc implementation" ENABLE_BINARY_LOCALE_GENERATION[doc] = "Enable the use of qemu to generate locale information during build time on the host instead of runtime on the target. If you have trouble with qemu-native you should make this an empty var. @group locale" PCMCIA_MANAGER[doc] = "Specify which package(s) to install to handle PCMCIA slots (usually pcmcia-cs or pcmciautils)." + +SYSVINIT_ENABLED_GETTYS[doc] = "Specify which VTs should be running a getty, the default is 1" + +# palmtop build class +PALMTOP_USE_MULTITHREADED_QT[doc] = "Set to yes, if you want to build qt apps with CONFIG+=thread" diff --git a/conf/machine/include/zaurus-clamshell.conf b/conf/machine/include/zaurus-clamshell.conf index 2a174288b1..1e3d3d7779 100644 --- a/conf/machine/include/zaurus-clamshell.conf +++ b/conf/machine/include/zaurus-clamshell.conf @@ -11,6 +11,11 @@ IMAGE_CMD_jffs2 = "mkfs.jffs2 --root=${IMAGE_ROOTFS} --faketime \ cat ${STAGING_LIBDIR}/sharp-flash-header/header-c700.bin \ ${T}/${IMAGE_NAME}.rootfs.jffs2 > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.img" +# add a summary to the jffs2 file to make it mount a lot faster +#EXTRA_IMAGECMD_jffs2 += "&& sumtool -i ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.img \ +# -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs-summary.img \ +# --eraseblock=0x4000" + GUI_MACHINE_CLASS = "bigscreen" GPE_EXTRA_INSTALL += "gaim sylpheed" diff --git a/packages/abuse/abuse-qpe_0.7.0.bb b/packages/abuse/abuse-qpe_0.7.0.bb deleted file mode 100644 index 0b588b3c07..0000000000 --- a/packages/abuse/abuse-qpe_0.7.0.bb +++ /dev/null @@ -1,19 +0,0 @@ -SECTION = "opie/games" - -include abuse_${PV}.bb - -DEPENDS += "virtual/libqpe" - -EXTRA_CXXFLAGS_append = " -Dmain=SDL_main" -EXTRA_CFLAGS_append = " -Dmain=SDL_main" -EXTRA_LFLAGS_append = "-lqpe" - -do_install() { - install -d ${D}${palmtopdir}/bin \ - ${D}${palmtopdir}/pics \ - ${D}${palmtopdir}/apps/Games \ - ${D}${palmtopdir}/share/aliens - install -D -m 0755 aliens ${D}${palmtopdir}/bin/aliens - install -D -m 0644 aliens.png ${D}${palmtopdir}/pics/aliens.png - install -D -m 0644 aliens.desktop ${D}${palmtopdir}/Games/aliens.desktop -} diff --git a/packages/abuse/abuse_0.7.0.bb b/packages/abuse/abuse_0.7.0.bb index 38124296fa..17280718b8 100644 --- a/packages/abuse/abuse_0.7.0.bb +++ b/packages/abuse/abuse_0.7.0.bb @@ -1,13 +1,11 @@ -DESCRIPTION = "Abuse-SDL is a port of Abuse by Crack Dot Com to Linux using the Simple DirectMedia Layer library." -PRIORITY = "optional" -MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" +DESCRIPTION = "Abuse-SDL is a port of Abuse by Crack Dot Com to Linux - SDL edition." SECTION = "games" LICENSE = "GPL" -DEPENDS = "virtual/libsdl libsdl-mixer libsdl-image" - -FILES_${PN} += "${datadir}/games" +APPNAME = "abuse.sdl" SRC_URI = "http://www.labyrinth.net.au/~trandor/abuse/files/abuse_sdl-${PV}.tar.bz2" S = "${WORKDIR}/abuse_sdl-${PV}" -inherit autotools +inherit autotools sdl + +FILES_${PN} += "${datadir}/games" diff --git a/packages/aliens/aliens_1.0.0.bb b/packages/aliens/aliens_1.0.0.bb index 829aa2ba77..3b8399aac5 100644 --- a/packages/aliens/aliens_1.0.0.bb +++ b/packages/aliens/aliens_1.0.0.bb @@ -3,24 +3,20 @@ SECTION = "opie/games" PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" LICENSE = "GPL" -DEPENDS = "virtual/libqpe" -PR = "r3" +APPNAME = "aliens.sdl" +APPTYPE = "binary" +PR = "r4" SRC_URI = "ftp://ftp.billsgames.com/unix/agenda/aliens/src/aliens_V${PV}.tar.gz" S = "${WORKDIR}/aliens_V${PV}" -inherit palmtop +inherit opie do_compile_prepend() { cd images && make && cd .. } do_install() { - install -d ${D}${palmtopdir}/bin \ - ${D}${palmtopdir}/pics \ - ${D}${palmtopdir}/apps/Games \ - ${D}${palmtopdir}/share/aliens - install -D -m 0755 aliens ${D}${palmtopdir}/bin/aliens - install -D -m 0644 aliens.png ${D}${palmtopdir}/pics/aliens.png - install -D -m 0644 aliens.desktop ${D}${palmtopdir}/apps/Games/aliens.desktop + install -d ${D}${palmtopdir}/pics + install -m 0644 aliens.png ${D}${palmtopdir}/pics/aliens.png } diff --git a/packages/altboot/altboot_0.0.0.bb b/packages/altboot/altboot_0.0.0.bb index 6e4cea25c3..3bda946415 100644 --- a/packages/altboot/altboot_0.0.0.bb +++ b/packages/altboot/altboot_0.0.0.bb @@ -6,8 +6,12 @@ MAINTAINER = "Matthias 'CoreDump' Hentges <oe@hentges.net>" LICENSE = "GPL" IGNORE_STRIP_ERRORS = "1" -PR = "r40" +RRECOMMENDS = "e2fsprogs-e2fsck dosfstools" +RRECOMMENDS_append_akita = " kexec-tools" +RRECOMMENDS_append_spitz = " kexec-tools" +RRECOMMENDS_append_c7x0 = " kexec-tools" +PR = "r41" SRC_URI = "file://altboot-menu \ file://altboot.rc \ diff --git a/packages/altboot/altboot_1.0.6.bb b/packages/altboot/altboot_1.0.6.bb index c13b346fc3..5f76d1b516 100644 --- a/packages/altboot/altboot_1.0.6.bb +++ b/packages/altboot/altboot_1.0.6.bb @@ -12,7 +12,14 @@ HOMEPAGE = "http://www.hentges.net/misc/openzaurus/index.shtml" ###################################################################################### -PR = "r0" +RRECOMMENDS = "e2fsprogs-e2fsck dosfstools" +RRECOMMENDS_append_akita = " kexec-tools" +RRECOMMENDS_append_spitz = " kexec-tools" +RRECOMMENDS_append_c7x0 = " kexec-tools" + +###################################################################################### + +PR = "r1" ###################################################################################### diff --git a/packages/altboot/altboot_1.0.7-rc1.bb b/packages/altboot/altboot_1.0.7-rc2.bb index c13b346fc3..18ba022a71 100644 --- a/packages/altboot/altboot_1.0.7-rc1.bb +++ b/packages/altboot/altboot_1.0.7-rc2.bb @@ -12,6 +12,13 @@ HOMEPAGE = "http://www.hentges.net/misc/openzaurus/index.shtml" ###################################################################################### +RRECOMMENDS = "e2fsprogs-e2fsck dosfstools" +RRECOMMENDS_append_akita = " kexec-tools" +RRECOMMENDS_append_spitz = " kexec-tools" +RRECOMMENDS_append_c7x0 = " kexec-tools" + +###################################################################################### + PR = "r0" ###################################################################################### diff --git a/packages/altboot/files/akita/altboot-2.6.cfg b/packages/altboot/files/akita/altboot-2.6.cfg index 2254a35552..c763f8b953 100644 --- a/packages/altboot/files/akita/altboot-2.6.cfg +++ b/packages/altboot/files/akita/altboot-2.6.cfg @@ -14,8 +14,8 @@ ENABLE_IMAGECONF="yes" SD_DEVICE="/dev/mmcblk0p1" SD_KERNEL_MODULE="" -USB_HOST_AVAILABLE="no" -USB_STORAGE_MODULES="usb_ohci_pxa27x usb-storage" +USB_HOST_AVAILABLE="yes" +USB_STORAGE_MODULES="ohci_hcd usb_storage sd_mod" USB_STORAGE_PARTITION="/dev/sda1" USB_STORAGE_WAIT="4" diff --git a/packages/altboot/files/altboot-menu/15-bootSD b/packages/altboot/files/altboot-menu/15-bootSD index 7123491000..0476a5ce0f 100644 --- a/packages/altboot/files/altboot-menu/15-bootSD +++ b/packages/altboot/files/altboot-menu/15-bootSD @@ -7,11 +7,6 @@ M_TITLE="Boot SD card" -die() { - echo "ERROR: $1" >/dev/tty0 - exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 -} - # This function is activated by init.altboot by calling this script with the "run" option run_module() { diff --git a/packages/altboot/files/altboot-menu/20-bootCF b/packages/altboot/files/altboot-menu/20-bootCF index 3a3f4fbafe..36d6b8245f 100644 --- a/packages/altboot/files/altboot-menu/20-bootCF +++ b/packages/altboot/files/altboot-menu/20-bootCF @@ -7,11 +7,6 @@ M_TITLE="Boot CF card" -die() { - echo "ERROR: $1" >/dev/tty0 - exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 -} - # This function is activated by init.altboot by calling this script with the "run" option run_module() { diff --git a/packages/altboot/files/altboot-menu/99-ownScripts-example b/packages/altboot/files/altboot-menu/99-ownScripts-example index b1b444f2d1..7566416b87 100644 --- a/packages/altboot/files/altboot-menu/99-ownScripts-example +++ b/packages/altboot/files/altboot-menu/99-ownScripts-example @@ -20,14 +20,6 @@ exit 0 # The "title" parameter is implemented at the end of this script so it will never be reached # and the script will simply be ignored by altboot. - -# The die() function aborts the boot if something goes wrong and sets STDIN / STDERR / STDOUT -# correctly. -die() { - echo "ERROR: $1" >/dev/tty0 - exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 -} - # This function is activated by init.altboot by calling this script with the "run" option run_module() { diff --git a/packages/altboot/files/altboot-menu/Advanced/30-bootUSB-Stick b/packages/altboot/files/altboot-menu/Advanced/30-bootUSB-Stick index 3cf8c506b0..b573e7a10c 100644 --- a/packages/altboot/files/altboot-menu/Advanced/30-bootUSB-Stick +++ b/packages/altboot/files/altboot-menu/Advanced/30-bootUSB-Stick @@ -8,12 +8,7 @@ M_TITLE="Boot USB Storage" test "$USB_HOST_AVAILABLE" = "yes" || exit 0 - -die() { - echo "ERROR: $1" >/dev/tty0 - exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 -} - + # This function is activated by init.altboot by calling this script with the "run" option run_module() { diff --git a/packages/altboot/files/altboot-menu/Advanced/40-bootNFS b/packages/altboot/files/altboot-menu/Advanced/40-bootNFS index 352b29ed07..9a36b8ed01 100644 --- a/packages/altboot/files/altboot-menu/Advanced/40-bootNFS +++ b/packages/altboot/files/altboot-menu/Advanced/40-bootNFS @@ -9,11 +9,6 @@ M_TITLE="Boot from NFS" -die() { - echo -e "ERROR: $1" >/dev/tty0 - exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 -} - # This function is activated by init.altboot by calling this script with the "run" option run_module() { @@ -24,9 +19,7 @@ run_module() { nfs_host="`cat /etc/fstab | grep -v ^# | grep nfs | awk '{print $1}'|sed -n "s/\(.*\)\:\(.*\)/\1/p" `" nfs_mounts="`cat /etc/fstab | grep -v ^# | grep nfs | awk '{print $1}'`" - nfs_mountpoints="`cat /etc/fstab | grep -v ^# | grep nfs | awk '{print $2}'`" - - WLAN_NIC="`iwconfig 2>/dev/null | grep ESSID | awk '{print $1}'`" + nfs_mountpoints="`cat /etc/fstab | grep -v ^# | grep nfs | awk '{print $2}'`" start_networking "$nfs_host" diff --git a/packages/altboot/files/altboot-menu/Advanced/70-install-tgz b/packages/altboot/files/altboot-menu/Advanced/70-install-tgz index 2ee92cd27e..cb8b2722d5 100644 --- a/packages/altboot/files/altboot-menu/Advanced/70-install-tgz +++ b/packages/altboot/files/altboot-menu/Advanced/70-install-tgz @@ -2,11 +2,6 @@ M_TITLE="Install RootFS from tar.gz" -# die() { -# echo "ERROR: $1" >/dev/tty0 -# exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 -# } - run_module(){ test -e /etc/altboot.func && . /etc/altboot.func || die "ERROR: /etc/altboot.func not found. Check your installation!" diff --git a/packages/altboot/files/altboot-menu/Advanced/70-setKernel b/packages/altboot/files/altboot-menu/Advanced/70-setKernel index a2c1efa81b..6192232a73 100644 --- a/packages/altboot/files/altboot-menu/Advanced/70-setKernel +++ b/packages/altboot/files/altboot-menu/Advanced/70-setKernel @@ -40,11 +40,13 @@ run_module() { get_pref "kexec_klist" "$junk" KEXEC_SELECTED_KERNEL && break - done - - echo "Using [$KEXEC_SELECTED_KERNEL]" + done + else + KEXEC_SELECTED_KERNEL="`ls -1 $KEXEC_KERNEL_DIR/zImage* | grep -v "kexec.cfg" `" fi + echo -e "\nUsing [$KEXEC_SELECTED_KERNEL]" + if ! test -e "$KEXEC_SELECTED_KERNEL.kexec.cfg" then echo -e "\nWARNING: This kernel has not been configured." diff --git a/packages/altboot/files/altboot-menu/Advanced/80-configure-kexec b/packages/altboot/files/altboot-menu/Advanced/80-configure-kexec index 27b6a871a6..e294df683f 100644 --- a/packages/altboot/files/altboot-menu/Advanced/80-configure-kexec +++ b/packages/altboot/files/altboot-menu/Advanced/80-configure-kexec @@ -38,11 +38,13 @@ run_module() { get_pref "kexec_klist" "$junk" KEXEC_KERNEL && break - done - - echo "Using [$KEXEC_KERNEL]" + done + else + KEXEC_KERNEL="`ls -1 $KEXEC_KERNEL_DIR/zImage* | grep -v "kexec.cfg" `" fi + echo -e "\nUsing [$KEXEC_KERNEL]" + configure_rootdev configure_roottype configure_verbose diff --git a/packages/altboot/files/altboot-menu/Advanced/80-copyrootfs b/packages/altboot/files/altboot-menu/Advanced/80-copyrootfs index 13f98a0d41..af6bd38c1d 100644 --- a/packages/altboot/files/altboot-menu/Advanced/80-copyrootfs +++ b/packages/altboot/files/altboot-menu/Advanced/80-copyrootfs @@ -4,11 +4,6 @@ M_TITLE="Copy rootfs to SD/CF" # Unfinished script. exit 0 -die() { - echo "ERROR: $1" >/dev/tty0 - exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 -} - ask_target() { available_disks="`mount | grep "/media" | grep -v ram | awk '{print $3}'`" diff --git a/packages/altboot/files/altboot.func b/packages/altboot/files/altboot.func index 31b79c52a5..13ee515d6a 100644 --- a/packages/altboot/files/altboot.func +++ b/packages/altboot/files/altboot.func @@ -1,4 +1,12 @@ #! /bin/sh + +C_RED="\033[31m" +C_YELLOW="\033[35m" +C_BLUE="\033[34m" +C_WHITE="\033[38m" +C_RESET="\033[0m" + + # This function checks for the presence of a real filesystem and loop-images on the target # $1 = folder of rootfs, $2 = runlevel (defaults to 5) # $2 = name of calling module @@ -180,9 +188,7 @@ pivot_image() { } #$1=mountpoint of the soon-to-be rootfs, $2=Runlevel -do_pivot(){ - - echo "[$USE_KEXEC_ON_NEXT_BOOT]" +do_pivot(){ if test "$USE_KEXEC_ON_NEXT_BOOT" = yes then @@ -233,7 +239,8 @@ do_pivot(){ boot_new_rootfs_splash echo "Calling INIT" - exec /usr/sbin/chroot . /sbin/init $2 >/dev/tty0 2>&1 + exec /usr/sbin/chroot . $REAL_INIT $2 >/dev/tty0 2>&1 + #exec /usr/sbin/chroot . /sbin/init $2 >/dev/tty0 2>&1 else echo "FAILED" die "* * * pivot_root failed! * * *" @@ -283,7 +290,7 @@ image_conf(){ while true do echo -e "Wasting RAM is never a good idea.\nOnly say Y if your rootfs is very small in size" - echo -n "Do you want to store ipkg package data in RAM? [N|y] " + echo -en "Do you want to store ipkg package data\nin RAM? [N|y] " read junk if test "$junk" = "" -o "$junk" = n -o "$junk" = N @@ -303,7 +310,7 @@ image_conf(){ then while true do - echo -n "Do you want to keep the SD, CF and /home ipkg install targets? [N|y] " + echo -en "Do you want to keep the SD, CF and /home\nipkg install targets? [N|y] " read junk if test "$junk" = "" -o "$junk" = n -o "$junk" = N @@ -559,7 +566,7 @@ show_menu() { } mdie() { - echo "ERROR: $1" >/dev/tty0 + echo -e "${C_RED}ERROR:${C_RESET}${C_WHITE} $1${C_RESET}" >/dev/tty0 echo -e "\nPress <ENTER> to return to the menu" read junk @@ -614,8 +621,14 @@ get_pref() { test -n "$data_value" && return 0 } +debug_echo() { + test "$ENABLE_DEBUG" = "yes" && echo -e "${C_YELLOW}DEBUG:${C_RESET}${C_WHITE} $1 ${C_RESET}" >/dev/tty0 2>&1 +} + start_networking() { + test -z "$1" && mdie "No remote host configured, check /etc/fstab for NFS hosts" + if test "$USB_NETWORKING_AVAILABLE" = "yes" then echo "" @@ -638,7 +651,7 @@ start_networking() { junk="`cat /etc/.altboot-lanselect.last`" test -z "$junk" && junk=1 - echo -n "Connection Type: $junk (autoboot)" + echo "Connection Type: $junk (autoboot)" fi case "$junk" in @@ -671,12 +684,16 @@ start_networking() { if test -x /etc/init.d/pcmcia then + echo -e "\nRunning cardctl to setup networking..." /etc/init.d/pcmcia start >/dev/null 2>&1 || die "/etc/init.d/pcmcia start failed!" + sleep 1 else # With kernel 2.6.16+ udev is used - ps ax| grep -v grep | grep -q udevd || /etc/init.d/udev start >/dev/null 2>&1 || die "/etc/init.d/udev start failed!" + echo -e "\nRunning udevd to setup networking..." + ps ax | grep -v grep | grep -q udevd || /etc/init.d/udev start >/dev/null 2>&1 || die "/etc/init.d/udev start failed!" - /etc/init.d/udev stop + # Stop udev to work around some very ugly (yet harmless) error messages on boot + /etc/init.d/udev stop >/dev/null 2>&1 fi fi @@ -697,9 +714,19 @@ start_networking() { ifup "$USB_NW_DEVICE" fi + + WLAN_NIC="`iwconfig 2>/dev/null | grep ESSID | grep -v wifi | awk '{print $1}'`" + + if test -z "$WLAN_NIC" + then + debug_echo "WARNING: WLAN_NIC is empty!\n" + debug_echo "Filter result: [$WLAN_NIC]" + debug_echo "iwconfig: [`iwconfig`]" + mdie "No network interface found" + fi # WLAN with DHCP needs some time to get a lease, set up the routing, etc. - echo -n "Waiting for Network." + echo -n "Waiting for host [$1] on [$WLAN_NIC]." cnt=0 while true do diff --git a/packages/altboot/files/init.altboot b/packages/altboot/files/init.altboot index a987918760..3dc7c60240 100644 --- a/packages/altboot/files/init.altboot +++ b/packages/altboot/files/init.altboot @@ -27,16 +27,31 @@ esac test -e "$ALTBOOT_CFG_FILE" && . "$ALTBOOT_CFG_FILE" || echo "WARNING: No $ALTBOOT_CFG_FILE found! Check your installation of Altboot!" > /dev/tty1 C_RED="\033[31m" +C_YELLOW="\033[33m" C_BLUE="\033[34m" C_WHITE="\033[37m" C_RESET="\033[0m" die() { - echo -e "ERROR: $1" >/dev/tty0 + echo -e "${C_RED}ERROR: $1${C_RESET}" >/dev/tty0 exec $SH_SHELL </dev/tty0 >/dev/tty0 2>&1 } +debug_shell() { + # VT 2 = Opie, VT 3 = GPE + test -z "$1" && VT=4 || VT=$1 + + echo -e "\033c" > /dev/tty$VT + + echo -en "\nPress <ENTER> to activate the debug shell." > /dev/tty$VT + read junk </dev/tty$VT + + echo "" > /dev/tty$VT + /bin/sh </dev/tty$VT >/dev/tty$VT 2>&1 + + #openvt -lf -c$VT -- /bin/sh </dev/tty$VT >/dev/tty$VT 2>&1 +} # This function prints the boot-menu # $1: Directory containing the scripts for the menu-items @@ -299,6 +314,13 @@ wait_for_input() { # Note: this is positively ugly. If someone knows a better way to detect wheter # we are already booted into a runlevel _without_ reading /var and / or using `runlevel` # PLEASE let me know. + +if ( echo "$VERSION" | egrep -iq "(snapshot|-rc)" ) +then + ENABLE_DEBUG="yes" + debug_shell 4 >/dev/null 2>&1 & +fi + if test -f /proc/cmdline -a "`ps ax|wc -l|tr -d " "`" -gt 30 -a "$1" != "-force" then echo "altboot: Using real init [$REAL_INIT] [$*] [`ps ax|wc -l|tr -d " "`] *" >/dev/tty1 diff --git a/packages/nonworking/polypaudio/.mtn2git_empty b/packages/base-files/base-files/h2200/.mtn2git_empty index e69de29bb2..e69de29bb2 100644 --- a/packages/nonworking/polypaudio/.mtn2git_empty +++ b/packages/base-files/base-files/h2200/.mtn2git_empty diff --git a/packages/base-files/base-files/h2200/fstab b/packages/base-files/base-files/h2200/fstab new file mode 100644 index 0000000000..397da6c123 --- /dev/null +++ b/packages/base-files/base-files/h2200/fstab @@ -0,0 +1,6 @@ +/dev/mtdblock3 / jffs2 defaults 1 1 +proc /proc proc defaults 0 0 +sys /sys sysfs defaults 0 0 +tmpfs /var tmpfs defaults 0 0 +/dev/hda1 /media/cf auto defaults,sync,noauto,noatime,exec,suid 0 0 +/dev/mmcblk0p1 /media/card auto defaults,sync,noauto,noatime,exec,suid 0 0 diff --git a/packages/billiardz/billiardz_0.1.4.bb b/packages/billiardz/billiardz_0.1.4.bb index e87bab1986..fcba6d2f30 100644 --- a/packages/billiardz/billiardz_0.1.4.bb +++ b/packages/billiardz/billiardz_0.1.4.bb @@ -12,7 +12,7 @@ SRC_URI = "http://www.chipx86.com/packages/ipkg/billiardz-${PV}.tar.gz" inherit palmtop QMAKE_PROFILES = "billiardz.arm.pro" -EXTRA_QMAKEVARS_POST = "DEFINES-=FPM_INTEL" +EXTRA_QMAKEVARS_POST += "DEFINES-=FPM_INTEL" do_install() { install -d ${D}${palmtopdir}/bin \ diff --git a/packages/busybox/busybox-1.01/slugos/sysctl.conf b/packages/busybox/busybox-1.01/slugos/sysctl.conf index 20d573c124..cfaa3c7f92 100644 --- a/packages/busybox/busybox-1.01/slugos/sysctl.conf +++ b/packages/busybox/busybox-1.01/slugos/sysctl.conf @@ -29,4 +29,4 @@ net/ipv4/icmp_echo_ignore_broadcasts=0 #net/ipv6/ip_forward=1 # This sets the app to run on a hotplug event -sys/kernel/hotplug=/sbin/udevsend +kernel/hotplug=/sbin/udevsend diff --git a/packages/busybox/busybox_1.01.bb b/packages/busybox/busybox_1.01.bb index cbef98d992..7df9d5ad02 100644 --- a/packages/busybox/busybox_1.01.bb +++ b/packages/busybox/busybox_1.01.bb @@ -10,7 +10,7 @@ HOMEPAGE = "http://www.busybox.net" LICENSE = "GPL" SECTION = "base" PRIORITY = "required" -PR = "r9" +PR = "r10" SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://udhcppidfile.patch;patch=1 \ diff --git a/packages/busybox/slingbox-1.00/defconfig b/packages/busybox/slingbox-1.00/defconfig index d35d7d5956..6b15e1944b 100644 --- a/packages/busybox/slingbox-1.00/defconfig +++ b/packages/busybox/slingbox-1.00/defconfig @@ -311,7 +311,7 @@ CONFIG_FREERAMDISK=y # CONFIG_GETOPT is not set CONFIG_HEXDUMP=y # CONFIG_HWCLOCK is not set -# CONFIG_LOSETUP is not set +CONFIG_LOSETUP=y # CONFIG_MKSWAP is not set # CONFIG_MORE is not set CONFIG_PIVOT_ROOT=y diff --git a/packages/busybox/slingbox_1.00.bb b/packages/busybox/slingbox_1.00.bb index a275cbbc73..8e11a09e6c 100644 --- a/packages/busybox/slingbox_1.00.bb +++ b/packages/busybox/slingbox_1.00.bb @@ -4,7 +4,7 @@ HOMEPAGE = "http://www.busybox.net" LICENSE = "GPL" SECTION = "base" PRIORITY = "required" -PR = "r8" +PR = "r9" SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://defconfig \ diff --git a/packages/corsair/corsair_0.2.0.bb b/packages/corsair/corsair_0.2.0.bb index 2b6bfe0f9c..b98e0df671 100644 --- a/packages/corsair/corsair_0.2.0.bb +++ b/packages/corsair/corsair_0.2.0.bb @@ -15,7 +15,7 @@ SRCDATE = "20050911" inherit palmtop -SRC_URI = "cvs://anonymous@cvs.sourceforge.net/cvsroot/corsair;module=corsair \ +SRC_URI = "http://ewi546.ewi.utwente.nl/mirror/hrw-oe-sources/corsair_cvs.sourceforge.net__20050911.tar.gz \ file://corsair-024.patch;patch=1 \ file://corsair-opie.patch;patch=1" diff --git a/packages/cumulus/cumulus_1.2.1.bb b/packages/cumulus/cumulus_1.2.1.bb index 18f12203de..1d0d598a6f 100644 --- a/packages/cumulus/cumulus_1.2.1.bb +++ b/packages/cumulus/cumulus_1.2.1.bb @@ -14,7 +14,7 @@ S = "${WORKDIR}/cumulus_${PV}/cumulus" inherit opie export OE_QMAKE_LINK="${CXX}" -EXTRA_QMAKEVARS_POST = "INCLUDEPATH+=-I." +EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=-I." # # nasty hack since cumulus doesn't obey the qmake standard which requires just one .pro file per directory diff --git a/packages/cumulus/cumulus_cvs.bb b/packages/cumulus/cumulus_cvs.bb index 9fdad829b9..07ef0ccf1a 100644 --- a/packages/cumulus/cumulus_cvs.bb +++ b/packages/cumulus/cumulus_cvs.bb @@ -17,7 +17,7 @@ inherit opie DEFAULT_PREFERENCE = "-1" export OE_QMAKE_LINK="${CXX}" -EXTRA_QMAKEVARS_POST = "INCLUDEPATH+=-I." +EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=-I." # # nasty hack since cumulus doesn't obey the qmake standard which requires just one .pro file per directory diff --git a/packages/e2fsprogs/e2fsprogs_1.38.bb b/packages/e2fsprogs/e2fsprogs_1.38.bb index e13aac5951..c27cf4c3fa 100644 --- a/packages/e2fsprogs/e2fsprogs_1.38.bb +++ b/packages/e2fsprogs/e2fsprogs_1.38.bb @@ -2,7 +2,7 @@ DESCRIPTION = "EXT2 Filesystem Utilities" HOMEPAGE = "http://e2fsprogs.sourceforge.net" LICENSE = "GPL" SECTION = "base" -PR = "r5" +PR = "r6" SRC_URI = "${SOURCEFORGE_MIRROR}/e2fsprogs/e2fsprogs-${PV}.tar.gz \ file://no-hardlinks.patch;patch=1" @@ -38,12 +38,13 @@ do_stage () { # blkid used to be part of e2fsprogs but is useful outside, add it # as an RDEPENDS so that anything relying on it being in e2fsprogs # still works -RDEPENDS_e2fsprogs = "e2fsprogs-blkid e2fsprogs-uuidgen" +RDEPENDS_e2fsprogs = "e2fsprogs-blkid e2fsprogs-uuidgen e2fsprogs-badblocks" -PACKAGES =+ "e2fsprogs-blkid e2fsprogs-uuidgen e2fsprogs-e2fsck e2fsprogs-mke2fs e2fsprogs-fsck e2fsprogs-tune2fs" +PACKAGES =+ "e2fsprogs-blkid e2fsprogs-uuidgen e2fsprogs-e2fsck e2fsprogs-mke2fs e2fsprogs-fsck e2fsprogs-tune2fs e2fsprogs-badblocks" FILES_e2fsprogs-blkid = "${base_sbindir}/blkid" FILES_e2fsprogs-uuidgen = "${bindir}/uuidgen" FILES_e2fsprogs-fsck = "${base_sbindir}/fsck" FILES_e2fsprogs-e2fsck = "${base_sbindir}/e2fsck ${base_sbindir}/fsck.ext*" FILES_e2fsprogs-mke2fs = "${base_sbindir}/mke2fs ${base_sbindir}/mkfs.ext*" FILES_e2fsprogs-tune2fs = "${base_sbindir}/tune2fs ${base_sbindir}/e2label ${base_sbindir}/findfs" +FILES_e2fsprogs-badblocks = "${base_sbindir}/badblocks"
\ No newline at end of file diff --git a/packages/flexis-zaurus/flexis-zaurus_1.0.0.bb b/packages/flexis-zaurus/flexis-zaurus_1.0.0.bb index b3c0119470..eb3784d104 100644 --- a/packages/flexis-zaurus/flexis-zaurus_1.0.0.bb +++ b/packages/flexis-zaurus/flexis-zaurus_1.0.0.bb @@ -10,7 +10,7 @@ S = "${WORKDIR}/flexis-zaurus" inherit palmtop -EXTRA_QMAKEVARS_POST = "CONFIG-=qtopia" +EXTRA_QMAKEVARS_POST += "CONFIG-=qtopia" do_install() { oe_libinstall libqflexis ${D}${palmtopdir}/plugins/inputmethods/ diff --git a/packages/freedroid/freedroid-1.0.2/icon.png b/packages/freedroid/freedroid-1.0.2/freedroid.png Binary files differindex 6db9f21c38..6db9f21c38 100644 --- a/packages/freedroid/freedroid-1.0.2/icon.png +++ b/packages/freedroid/freedroid-1.0.2/freedroid.png diff --git a/packages/freedroid/freedroid_1.0.2.bb b/packages/freedroid/freedroid_1.0.2.bb index e51d22ca0b..be1087d691 100644 --- a/packages/freedroid/freedroid_1.0.2.bb +++ b/packages/freedroid/freedroid_1.0.2.bb @@ -1,42 +1,25 @@ -DESCRIPTION = "Clone of the classic Paradroid from C64 for Qtopia/Opie - based on SDL" +DESCRIPTION = "Clone of the classic Paradroid from C64 - SDL version." SECTION = "opie/games" PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" LICENSE = "GPL" HOMEPAGE = "http://freedroid.sourceforge.net/" -DEPENDS = "virtual/libqpe libsdl-qpe libsdl-image" -PR = "r1" +PR = "r2" + +APPIMAGE = "${WORKDIR}/freedroid.png" SRC_URI = "${SOURCEFORGE_MIRROR}/freedroid/freedroid-${PV}.tar.gz \ - file://icon.png" + file://freedroid.png" -inherit autotools +inherit autotools sdl do_compile() { - oe_runmake pkgdatadir=${palmtopdir}/share/freedroid + oe_runmake pkgdatadir=${datadir}/freedroid } do_install() { - install -d ${D}${palmtopdir}/bin \ - ${D}${palmtopdir}/apps/Games \ - ${D}${palmtopdir}/pics \ - ${D}${palmtopdir}/share/freedroid/graphics \ - ${D}${palmtopdir}/share/freedroid/map \ - ${D}${palmtopdir}/share/freedroid/sound - install -D -m 0755 src/freedroid ${D}${palmtopdir}/bin/freedroid - install -D -m 0644 ${WORKDIR}/icon.png ${D}${palmtopdir}/pics/freedroid.png - - cp -pPR graphics/* ${D}${palmtopdir}/share/freedroid/graphics - cp -pPR map/* ${D}${palmtopdir}/share/freedroid/map - cp -pPR sound/* ${D}${palmtopdir}/share/freedroid/sound - - echo "[Desktop Entry]" >${D}${palmtopdir}/apps/Games/freedroid.desktop - echo "Comment=A Paradroid Clone" >>${D}${palmtopdir}/apps/Games/freedroid.desktop - echo "Exec=freedroid" >>${D}${palmtopdir}/apps/Games/freedroid.desktop - echo "Icon=freedroid" >>${D}${palmtopdir}/apps/Games/freedroid.desktop - echo "Type=Application" >>${D}${palmtopdir}/apps/Games/freedroid.desktop - echo "Name=Freedroid" >>${D}${palmtopdir}/apps/Games/freedroid.desktop + install -d ${D}${bindir} + install -m 0755 src/freedroid ${D}${bindir} + install -d ${D}${datadir}/freedroid/ + cp -a graphics map sound ${D}${datadir}/freedroid/ } - -FILES_${PN} = "" -FILES_${PN} = "${palmtopdir}/" diff --git a/packages/qte/qte-4.0.0-snapshot/.mtn2git_empty b/packages/gbluezconf/.mtn2git_empty index e69de29bb2..e69de29bb2 100644 --- a/packages/qte/qte-4.0.0-snapshot/.mtn2git_empty +++ b/packages/gbluezconf/.mtn2git_empty diff --git a/packages/gbluezconf/gbluezconf_00.10.bb b/packages/gbluezconf/gbluezconf_00.10.bb new file mode 100644 index 0000000000..2b0f210954 --- /dev/null +++ b/packages/gbluezconf/gbluezconf_00.10.bb @@ -0,0 +1,12 @@ +DESCRIPTION = "GTK panel applet to control bluetooth stuff" +LICENSE = "GPLv2" +MAINTAINER = "Koen Kooi <koen@dominion.kabel.utwente.nl>" + +DEPENDS = "bluez-utils-dbus libglade dbus libnotify popt gtk+" +SRC_URI = "http://www.cin.ufpe.br/~ckt/gbluezconf/${P}.tar.gz" + +inherit autotools pkgconfig + + + + diff --git a/packages/gcc/gcc-package.inc b/packages/gcc/gcc-package.inc index b31a209b34..4dcc72e879 100644 --- a/packages/gcc/gcc-package.inc +++ b/packages/gcc/gcc-package.inc @@ -67,7 +67,7 @@ do_install () { rm -r ${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/install-tools # Hack around specs file assumptions - sed -i -e '/^*cross_compile:$/ { n; s/1/0/; }' ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/specs + sed -i -e '/^*cross_compile:$/ { n; s/1/0/; }' ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/specs &>/dev/null || true # Move libgcc_s into /lib mkdir -p ${D}${base_libdir} @@ -79,7 +79,8 @@ do_install () { ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/libgcc_s.so # We don't need libtool libraries - rm ${D}${libdir}/libg2c.la + rm ${D}${libdir}/libg2c.la &>/dev/null || true + # Cleanup manpages.. rm -r ${D}${mandir}/man7 diff --git a/packages/gemdropx/gemdropx-0.9/directories.patch b/packages/gemdropx/gemdropx-0.9/directories.patch deleted file mode 100644 index 4c3de83465..0000000000 --- a/packages/gemdropx/gemdropx-0.9/directories.patch +++ /dev/null @@ -1,16 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- gemdropx-0.9/gemdropx.c~directories 2002-02-12 09:45:34.000000000 +0100 -+++ gemdropx-0.9/gemdropx.c 2004-01-27 13:47:53.000000000 +0100 -@@ -21,7 +21,7 @@ - Qt/Embedded Support: February 11, 2002 - February 12, 2002 - */ - -- -+#define DATA_PREFIX "/opt/QtPalmtop/share/gemdropx/" - #include <stdio.h> - #include <stdlib.h> - #include <string.h> diff --git a/packages/gemdropx/gemdropx-0.9/icon.png b/packages/gemdropx/gemdropx-0.9/gemdropx.png Binary files differindex 654825a599..654825a599 100644 --- a/packages/gemdropx/gemdropx-0.9/icon.png +++ b/packages/gemdropx/gemdropx-0.9/gemdropx.png diff --git a/packages/gemdropx/gemdropx_0.9.bb b/packages/gemdropx/gemdropx_0.9.bb index 836c44c8b5..a50fd6b567 100644 --- a/packages/gemdropx/gemdropx_0.9.bb +++ b/packages/gemdropx/gemdropx_0.9.bb @@ -1,38 +1,33 @@ -DESCRIPTION = "Classic arcade puzzle game Qtopia/Opie - based on SDL" -SECTION = "opie/games" +DESCRIPTION = "Classic arcade puzzle game - SDL edition." PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" LICENSE = "GPL" HOMEPAGE = "http://www.newbreedsoftware.com/gemdropx/" -DEPENDS = "virtual/libqpe libsdl-qpe" -PR = "r3" +PR = "r4" + +APPIMAGE = "${WORKDIR}/gemdropx.png" SRC_URI = "ftp://ftp.billsgames.com/unix/x/gemdropx/src/gemdropx-${PV}.tar.gz \ - file://directories.patch;patch=1 \ - file://icon.png" + file://gemdropx.png" -inherit palmtop +inherit qmake sdl -EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=${STAGING_INCDIR}/SDL LIBS+=-lSDL LIBS+=-lSDL_mixer \ - LIBS+=-lSDLmain LIBS+=-lSDL_image LIBS+=-lpthread" +EXTRA_QMAKEVARS_POST += "CONFIG-=qt \ + INCLUDEPATH+=${STAGING_INCDIR}/SDL \ + LIBS+=-lSDL \ + LIBS+=-lSDL_mixer \ + LIBS+=-lSDL_image \ + LIBS+=-lpthread \ + DEFINES+=DATA_PREFIX=\\"\"${datadir}/gemdropx/\\"\"" do_configure_prepend() { - qmake -project -o gemdropx.pro + qmake -project -nopwd gemdropx.c -o gemdropx.pro } do_install() { - install -d ${D}${palmtopdir}/bin \ - ${D}${palmtopdir}/apps/Games \ - ${D}${palmtopdir}/pics \ - ${D}${palmtopdir}/share/gemdropx - install -D -m 0755 gemdropx ${D}${palmtopdir}/bin/gemdropx - install -D -m 0644 ${WORKDIR}/icon.png ${D}${palmtopdir}/pics/gemdropx.png - cp -pPR data/* ${D}${palmtopdir}/share/gemdropx + install -d ${D}${bindir} + install -m 0755 gemdropx ${D}${bindir}/gemdropx + install -d ${D}${datadir}/gemdropx/ + cp -pPR data/* ${D}${datadir}/gemdropx/ - echo "[Desktop Entry]" >${D}${palmtopdir}/apps/Games/gemdropx.desktop - echo "Comment=Puzzle game" >>${D}${palmtopdir}/apps/Games/gemdropx.desktop - echo "Exec=gemdropx" >>${D}${palmtopdir}/apps/Games/gemdropx.desktop - echo "Icon=gemdropx" >>${D}${palmtopdir}/apps/Games/gemdropx.desktop - echo "Type=Application" >>${D}${palmtopdir}/apps/Games/gemdropx.desktop - echo "Name=GemdropX" >>${D}${palmtopdir}/apps/Games/gemdropx.desktop } diff --git a/packages/gpe-session-scripts/gpe-session-scripts_0.67.bb b/packages/gpe-session-scripts/gpe-session-scripts_0.67.bb new file mode 100644 index 0000000000..6a373cbd4b --- /dev/null +++ b/packages/gpe-session-scripts/gpe-session-scripts_0.67.bb @@ -0,0 +1,35 @@ +inherit gpe + +DESCRIPTION = "GPE session startup scripts" +LICENSE = "GPL" +SECTION = "gpe" +PRIORITY = "optional" +MAINTAINER = "Koen Kooi <koen@dominion.kabel.utwente.nl>" +RDEPENDS_${PN} = "matchbox matchbox-panel (>= 0.9.2-r12) matchbox-desktop (>= 0.9.1-r1) matchbox-common (>= 0.9.1-r2) gpe-session-starter gpe-bluetooth xstroke xtscal gpe-question gpe-clock matchbox-applet-inputmanager xrandr xmodmap xdpyinfo xserver-common" +# more rdepends: keylaunch ipaq-sleep apmd blueprobe +DEPENDS = "matchbox-wm matchbox-panel gpe-bluetooth xstroke xtscal gpe-question matchbox-applet-inputmanager gpe-clock xrandr xmodmap xdpyinfo xserver-common" + +SRC_URI += "file://matchbox-session \ + file://disable-composite.xsettings" + +#apply a patch to set the fontsize for bigdpi (200+) devices to 5 +SRC_URI_append_ipaq-pxa270 = " file://highdpifontfix.patch;patch=1" +SRC_URI_append_spitz = " file://highdpifontfix.patch;patch=1" +SRC_URI_append_akita = " file://highdpifontfix.patch;patch=1" +SRC_URI_append_c7x0 = " file://highdpifontfix.patch;patch=1" +SRC_URI_append_nokia770 = " file://highdpifontfix.patch;patch=1" + +do_install_append() { + install -d ${D}${sysconfdir}/gpe/xsettings-default.d + if [ "${GUI_MACHINE_CLASS}" != "bigscreen" ]; then + echo "Gtk/ToolbarStyle:S:icons" > ${D}${sysconfdir}/gpe/xsettings-default.d/toolbar + fi + install -d ${D}${sysconfdir}/matchbox + install ${WORKDIR}/matchbox-session ${D}${sysconfdir}/matchbox/session + + install -d ${D}${sysconfdir}/gpe/xsettings-default.d + install -m 0644 ${WORKDIR}/disable-composite.xsettings ${D}${sysconfdir}/gpe/xsettings-default.d/disable-composite +} + +# This makes use of GUI_MACHINE_CLASS, so set PACKAGE_ARCH appropriately +PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/packages/gpe-today/gpe-today_0.11.bb b/packages/gpe-today/gpe-today_0.11.bb new file mode 100644 index 0000000000..b34bab9d2b --- /dev/null +++ b/packages/gpe-today/gpe-today_0.11.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Displays a summary of appointments and tasks for the day ahead" +DEPENDS = "gtk+ libxrandr libxsettings libxsettings-client libgpewidget libdisplaymigration libeventdb libgpepimc libtododb" +SECTION = "gpe" +PRIORITY = "optional" +MAINTAINER = "Koen Kooi <koen@dominion.kabel.utwente.nl>" + +LICENSE = "GPL" +inherit gpe pkgconfig + + diff --git a/packages/iaimaster/iaimaster_0.5.bb b/packages/iaimaster/iaimaster_0.5.bb index d47b81dfba..371b39924a 100644 --- a/packages/iaimaster/iaimaster_0.5.bb +++ b/packages/iaimaster/iaimaster_0.5.bb @@ -14,7 +14,7 @@ S = "${WORKDIR}/IaiMaster" inherit opie -EXTRA_QMAKEVARS_POST = "TARGET=${PN}" +EXTRA_QMAKEVARS_POST += "TARGET=${PN}" do_configure_prepend() { qmake -project diff --git a/packages/ixp425-eth/ixp400-eth_1.5.bb b/packages/ixp425-eth/ixp400-eth_1.5.bb index 99851a8c12..4430e295fb 100644 --- a/packages/ixp425-eth/ixp400-eth_1.5.bb +++ b/packages/ixp425-eth/ixp400-eth_1.5.bb @@ -4,7 +4,7 @@ MAINTAINER = "NSLU2 Linux <nslu2-linux@yahoogroups.com>" HOMEPAGE = "http://www.intel.com/design/network/products/npfamily/ixp420.htm" LICENSE = "GPL" -PR = "r9" +PR = "r10" DEPENDS = "ixp4xx-csr" RDEPENDS = "ixp4xx-csr" @@ -15,7 +15,6 @@ SRC_URI += "file://2.6.15.patch;patch=1" SRC_URI += "file://device-name.patch;patch=1" SRC_URI += "file://poll-controller.patch;patch=1" SRC_URI += "file://le.patch;patch=1" -SRC_URI += "file://mac-address.patch;patch=1" SRC_URI += "file://int-random.patch;patch=1" SRC_URI += "file://stop-on-rmmod.patch;patch=1" SRC_URI += "file://continue-if-qmgr-init-fails.patch;patch=1" diff --git a/packages/juce/.mtn2git_empty b/packages/juce/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/juce/.mtn2git_empty diff --git a/packages/juce/files/.mtn2git_empty b/packages/juce/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/juce/files/.mtn2git_empty diff --git a/packages/juce/files/no-opengl.patch b/packages/juce/files/no-opengl.patch new file mode 100644 index 0000000000..dd379349f4 --- /dev/null +++ b/packages/juce/files/no-opengl.patch @@ -0,0 +1,4477 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- juce/demo/build/linux/JuceDemo.make~no-opengl ++++ juce/demo/build/linux/JuceDemo.make +@@ -13,7 +13,7 @@ + CPPFLAGS := -MD -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" + CFLAGS += $(CPPFLAGS) -g -D_DEBUG -ggdb + CXXFLAGS := $(CFLAGS) +- LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lGL -lGLU -lXinerama -lasound -ljuce_debug ++ LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lasound -ljuce_debug + LDDEPS := + TARGET := jucedemo + endif +@@ -26,7 +26,7 @@ + CPPFLAGS := -MD -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" + CFLAGS += $(CPPFLAGS) -O2 + CXXFLAGS := $(CFLAGS) +- LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lGL -lGLU -lXinerama -lasound -ljuce ++ LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lasound -ljuce + LDDEPS := + TARGET := jucedemo + endif +@@ -39,7 +39,6 @@ + $(OBJDIR)/DragAndDropDemo.o \ + $(OBJDIR)/FontsAndTextDemo.o \ + $(OBJDIR)/InterprocessCommsDemo.o \ +- $(OBJDIR)/OpenGLDemo.o \ + $(OBJDIR)/PathsAndTransformsDemo.o \ + $(OBJDIR)/QuickTimeDemo.o \ + $(OBJDIR)/ThreadingDemo.o \ +--- juce/platform_specific_code/juce_linux_Windowing.cpp ++++ /dev/null +--- juce/linux/platform_specific_code/juce_linux_Windowing.cpp ++++ /dev/null +--- juce/build/linux/platform_specific_code/juce_linux_Windowing.cpp~no-opengl ++++ juce/build/linux/platform_specific_code/juce_linux_Windowing.cpp +@@ -1,2218 +1,2219 @@ +-/*
+- ==============================================================================
+-
+- This file is part of the JUCE library - "Jules' Utility Class Extensions"
+- Copyright 2004-6 by Raw Material Software ltd.
+-
+- ------------------------------------------------------------------------------
+-
+- JUCE can be redistributed and/or modified 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.
+-
+- JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
+- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+- Boston, MA 02111-1307 USA
+-
+- ------------------------------------------------------------------------------
+-
+- If you'd like to release a closed-source product which uses JUCE, commercial
+- licenses are also available: visit www.rawmaterialsoftware.com/juce for
+- more information.
+-
+- ==============================================================================
+-*/
+-
+-#include "juce_Config.h"
+-#if JUCE_BUILD_GUI_CLASSES
+-
+-#include "linuxincludes.h"
+-#include <X11/Xlib.h>
+-#include <X11/Xutil.h>
+-#include <X11/Xatom.h>
+-#include <X11/Xmd.h>
+-#include <X11/keysym.h>
+-#include <X11/cursorfont.h>
+-
+-#include "../../../juce_Config.h"
+-
+-#if JUCE_USE_XINERAMA
+-#include <X11/extensions/Xinerama.h>
+-#endif
+-
+-#if JUCE_OPENGL
+-#include <X11/Xlib.h>
+-#include <GL/glx.h>
+-#endif
+-
+-#undef KeyPress
+-
+-#include "../../../src/juce_core/basics/juce_StandardHeader.h"
+-
+-BEGIN_JUCE_NAMESPACE
+-
+-#include "../../../src/juce_appframework/events/juce_Timer.h"
+-#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
+-#include "../../../src/juce_appframework/gui/components/keyboard/juce_KeyPress.h"
+-#include "../../../src/juce_appframework/application/juce_SystemClipboard.h"
+-#include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h"
+-#include "../../../src/juce_appframework/gui/components/special/juce_OpenGLComponent.h"
+-#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
+-#include "../../../src/juce_appframework/events/juce_MessageManager.h"
+-#include "../../../src/juce_appframework/gui/components/juce_RepaintManager.h"
+-#include "../../../src/juce_appframework/gui/components/juce_ComponentDeletionWatcher.h"
+-#include "../../../src/juce_appframework/gui/graphics/geometry/juce_RectangleList.h"
+-#include "../../../src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.h"
+-#include "../../../src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h"
+-#include "../../../src/juce_core/basics/juce_Logger.h"
+-#include "../../../src/juce_core/threads/juce_Process.h"
+-#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
+-
+-
+-//==============================================================================
+-static Atom wm_ChangeState = None;
+-static Atom wm_State = None;
+-static Atom wm_Protocols = None;
+-static Atom wm_ProtocolList [2] = { None, None };
+-static Atom wm_ActiveWin = None;
+-static Atom repaintId = None;
+-
+-#define TAKE_FOCUS 0
+-#define DELETE_WINDOW 1
+-
+-//==============================================================================
+-static bool isActiveApplication = false;
+-
+-bool Process::isForegroundProcess()
+-{
+- return isActiveApplication;
+-}
+-
+-//==============================================================================
+-// These are defined in juce_linux_Messages.cpp
+-extern Display* display;
+-extern XContext improbableNumber;
+-
+-const int juce_windowIsSemiTransparentFlag = (1 << 31); // also in component.cpp
+-
+-static const int eventMask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
+- | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask
+- | ExposureMask | StructureNotifyMask | FocusChangeMask;
+-
+-//==============================================================================
+-static int pointerMap[5];
+-static int lastMousePosX = 0, lastMousePosY = 0;
+-
+-enum MouseButtons
+-{
+- NoButton = 0,
+- LeftButton = 1,
+- MiddleButton = 2,
+- RightButton = 3,
+- WheelUp = 4,
+- WheelDown = 5
+-};
+-
+-static void getMousePos (int& x, int& y, int& mouseMods)
+-{
+- Window root, child;
+- int winx, winy;
+- unsigned int mask;
+-
+- mouseMods = 0;
+-
+- if (XQueryPointer (display,
+- RootWindow (display, DefaultScreen (display)),
+- &root, &child,
+- &x, &y, &winx, &winy, &mask) == False)
+- {
+- // Pointer not on the default screen
+- x = y = -1;
+- }
+- else
+- {
+- if ((mask & Button1Mask) != 0)
+- mouseMods |= ModifierKeys::leftButtonModifier;
+-
+- if ((mask & Button2Mask) != 0)
+- mouseMods |= ModifierKeys::middleButtonModifier;
+-
+- if ((mask & Button3Mask) != 0)
+- mouseMods |= ModifierKeys::rightButtonModifier;
+- }
+-}
+-
+-//==============================================================================
+-static int AltMask = 0;
+-static int NumLockMask = 0;
+-static bool numLock = 0;
+-static bool capsLock = 0;
+-static char keyStates [32];
+-
+-static void updateKeyStates (const int keycode, const bool press)
+-{
+- const int keybyte = keycode >> 3;
+- const int keybit = (1 << (keycode & 7));
+-
+- if (press)
+- keyStates [keybyte] |= keybit;
+- else
+- keyStates [keybyte] &= ~keybit;
+-}
+-
+-static bool keyDown (const int keycode)
+-{
+- const int keybyte = keycode >> 3;
+- const int keybit = (1 << (keycode & 7));
+-
+- return (keyStates [keybyte] & keybit) != 0;
+-}
+-
+-static const int nonAsciiModifier = 0x10000;
+-
+-bool KeyPress::isKeyCurrentlyDown (int keyCode)
+-{
+- int keysym;
+-
+- if (keyCode & nonAsciiModifier)
+- {
+- keysym = 0xff00 | (keyCode & 0xff);
+- }
+- else
+- {
+- keysym = keyCode;
+-
+- if (keysym == (XK_Tab & 0xff)
+- || keysym == (XK_Return & 0xff)
+- || keysym == (XK_Escape & 0xff)
+- || keysym == (XK_BackSpace & 0xff))
+- {
+- keysym |= 0xff00;
+- }
+- }
+-
+- return keyDown (XKeysymToKeycode (display, keysym));
+-}
+-
+-//==============================================================================
+-// Alt and Num lock are not defined by standard X
+-// modifier constants: check what they're mapped to
+-static void getModifierMapping()
+-{
+- const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L);
+- const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock);
+-
+- AltMask = 0;
+- NumLockMask = 0;
+-
+- XModifierKeymap* mapping = XGetModifierMapping (display);
+-
+- if (mapping)
+- {
+- for (int i = 0; i < 8; i++)
+- {
+- if (mapping->modifiermap [i << 1] == altLeftCode)
+- AltMask = 1 << i;
+- else if (mapping->modifiermap [i << 1] == numLockCode)
+- NumLockMask = 1 << i;
+- }
+-
+- XFreeModifiermap (mapping);
+- }
+-}
+-
+-static int currentModifiers = 0;
+-
+-void ModifierKeys::updateCurrentModifiers()
+-{
+- currentModifierFlags = currentModifiers;
+-}
+-
+-const ModifierKeys ModifierKeys::getCurrentModifiersRealtime()
+-{
+- int x, y, mouseMods;
+- getMousePos (x, y, mouseMods);
+-
+- currentModifiers &= ~ModifierKeys::allMouseButtonModifiers;
+- currentModifiers |= mouseMods;
+-
+- return ModifierKeys (currentModifiers);
+-}
+-
+-static void updateKeyModifiers (const int status)
+-{
+- currentModifiers &= ~(ModifierKeys::shiftModifier
+- | ModifierKeys::ctrlModifier
+- | ModifierKeys::altModifier);
+-
+- if (status & ShiftMask)
+- currentModifiers |= ModifierKeys::shiftModifier;
+-
+- if (status & ControlMask)
+- currentModifiers |= ModifierKeys::ctrlModifier;
+-
+- if (status & AltMask)
+- currentModifiers |= ModifierKeys::altModifier;
+-
+- numLock = ((status & NumLockMask) != 0);
+- capsLock = ((status & LockMask) != 0);
+-}
+-
+-static bool updateKeyModifiersFromSym (KeySym sym, const bool press)
+-{
+- int modifier = 0;
+- bool isModifier = true;
+-
+- switch (sym)
+- {
+- case XK_Shift_L:
+- case XK_Shift_R:
+- modifier = ModifierKeys::shiftModifier;
+- break;
+-
+- case XK_Control_L:
+- case XK_Control_R:
+- modifier = ModifierKeys::ctrlModifier;
+- break;
+-
+- case XK_Alt_L:
+- case XK_Alt_R:
+- modifier = ModifierKeys::altModifier;
+- break;
+-
+- case XK_Num_Lock:
+- if (press)
+- numLock = ! numLock;
+-
+- break;
+-
+- case XK_Caps_Lock:
+- if (press)
+- capsLock = ! capsLock;
+-
+- break;
+-
+- case XK_Scroll_Lock:
+- break;
+-
+- default:
+- isModifier = false;
+- break;
+- }
+-
+- if (modifier != 0)
+- {
+- if (press)
+- currentModifiers |= modifier;
+- else
+- currentModifiers &= ~modifier;
+- }
+-
+- return isModifier;
+-}
+-
+-
+-//==============================================================================
+-class XBitmapImage : public Image
+-{
+-public:
+- //==============================================================================
+- XBitmapImage (const PixelFormat format_, const int w, const int h, const bool clearImage)
+- : Image (format_, w, h)
+- {
+- jassert (format_ == RGB || format_ == ARGB);
+-
+- pixelStride = (format_ == RGB) ? 3 : 4;
+- lineStride = ((w * pixelStride + 3) & ~3);
+- imageData = (uint8*) juce_malloc (lineStride * h);
+-
+- if (format_ == ARGB && clearImage)
+- zeromem (xImage->data, h * lineStride);
+-
+- xImage = new XImage();
+- xImage->width = w;
+- xImage->height = h;
+- xImage->xoffset = 0;
+- xImage->format = ZPixmap;
+- xImage->data = (char*) imageData;
+- xImage->byte_order = ImageByteOrder (display);
+- xImage->bitmap_unit = BitmapUnit (display);
+- xImage->bitmap_bit_order = BitmapBitOrder (display);
+- xImage->bitmap_pad = 32;
+- xImage->depth = pixelStride * 8;
+- xImage->bytes_per_line = lineStride;
+- xImage->bits_per_pixel = pixelStride * 8;
+- xImage->red_mask = 0x00FF0000;
+- xImage->green_mask = 0x0000FF00;
+- xImage->blue_mask = 0x000000FF;
+-
+- if (! XInitImage (xImage))
+- {
+- jassertfalse
+- }
+- }
+-
+- ~XBitmapImage()
+- {
+- juce_free (xImage->data);
+- xImage->data = 0;
+- XDestroyImage (xImage);
+- imageData = 0; // to stop the base class freeing this
+- }
+-
+- void blitToWindow (Window window, int dx, int dy, int dw, int dh, int sx, int sy)
+- {
+- static GC gc = 0;
+-
+- if (gc == 0)
+- gc = DefaultGC (display, DefaultScreen (display));
+-
+- // blit results to screen.
+- XPutImage (display, (Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh);
+- }
+-
+- //==============================================================================
+- juce_UseDebuggingNewOperator
+-
+-private:
+- XImage* xImage;
+-};
+-
+-
+-//==============================================================================
+-class LinuxComponentPeer : public ComponentPeer
+-{
+-public:
+- //==============================================================================
+- LinuxComponentPeer (Component* const component, const int windowStyleFlags)
+- : ComponentPeer (component, windowStyleFlags),
+- windowH (0),
+- wx (0),
+- wy (0),
+- ww (0),
+- wh (0),
+- fullScreen (false),
+- entered (false),
+- mapped (false)
+- {
+- repainter = new LinuxRepaintManager (this, component, 3000);
+-
+- MessageManager::getInstance()
+- ->callFunctionOnMessageThread (&createWindowCallback, (void*) this);
+-
+- setTitle (component->getName());
+- }
+-
+- ~LinuxComponentPeer()
+- {
+- MessageManager::getInstance()
+- ->callFunctionOnMessageThread (&destroyWindowCallback, (void*) windowH);
+-
+- windowH = 0;
+- delete repainter;
+- }
+-
+- //==============================================================================
+- void* getNativeHandle() const
+- {
+- return (void*) windowH;
+- }
+-
+- void setVisible (bool shouldBeVisible)
+- {
+- if (shouldBeVisible)
+- XMapWindow (display, windowH);
+- else
+- XUnmapWindow (display, windowH);
+- }
+-
+- void setTitle (const String& title)
+- {
+- setWindowTitle (windowH, title);
+- }
+-
+- void setPosition (int x, int y)
+- {
+- setBounds (x, y, ww, wh, false);
+- }
+-
+- void setSize (int w, int h)
+- {
+- setBounds (wx, wy, w, h, false);
+- }
+-
+- void setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
+- {
+- fullScreen = isNowFullScreen;
+-
+- if (windowH != 0)
+- {
+- const ComponentDeletionWatcher deletionChecker (component);
+-
+- wx = x;
+- wy = y;
+- ww = jmax (1, w);
+- wh = jmax (1, h);
+-
+- if (! mapped)
+- {
+- // Make sure the Window manager does what we want
+- XSizeHints* hints = XAllocSizeHints();
+- hints->flags = USSize | USPosition;
+- hints->width = ww + windowBorder.getLeftAndRight();
+- hints->height = wh + windowBorder.getTopAndBottom();
+- hints->x = wx - windowBorder.getLeft();
+- hints->y = wy - windowBorder.getTop();
+- XSetWMNormalHints (display, windowH, hints);
+- XFree (hints);
+- }
+-
+- XMoveResizeWindow (display, windowH,
+- wx - windowBorder.getLeft(),
+- wy - windowBorder.getTop(),
+- ww + windowBorder.getLeftAndRight(),
+- wh + windowBorder.getTopAndBottom());
+-
+- if (! deletionChecker.hasBeenDeleted())
+- {
+- updateBorderSize();
+- handleMovedOrResized();
+- }
+- }
+- }
+-
+- void getBounds (int& x, int& y, int& w, int& h) const
+- {
+- x = wx;
+- y = wy;
+- w = ww;
+- h = wh;
+- }
+-
+- int getScreenX() const
+- {
+- return wx;
+- }
+-
+- int getScreenY() const
+- {
+- return wy;
+- }
+-
+- void setMinimised (bool shouldBeMinimised)
+- {
+- if (shouldBeMinimised)
+- {
+- Window root = RootWindow (display, DefaultScreen (display));
+-
+- XClientMessageEvent clientMsg;
+- clientMsg.display = display;
+- clientMsg.window = windowH;
+- clientMsg.type = ClientMessage;
+- clientMsg.format = 32;
+- clientMsg.message_type = wm_ChangeState;
+- clientMsg.data.l[0] = IconicState;
+-
+- XSendEvent (display, root, false,
+- SubstructureRedirectMask | SubstructureNotifyMask,
+- (XEvent*) &clientMsg);
+- }
+- else
+- {
+- setVisible (true);
+- }
+- }
+-
+- bool isMinimised() const
+- {
+- bool minimised = false;
+-
+- CARD32* stateProp;
+- unsigned long nitems, bytesLeft;
+- Atom actualType;
+- int actualFormat;
+-
+- if (XGetWindowProperty (display, windowH, wm_State, 0, 64, False,
+- wm_State, &actualType, &actualFormat, &nitems, &bytesLeft,
+- (unsigned char**) &stateProp) == Success
+- && actualType == wm_State
+- && actualFormat == 32
+- && nitems > 0)
+- {
+- if (stateProp[0] == IconicState)
+- minimised = true;
+-
+- XFree (stateProp);
+- }
+-
+- return minimised;
+- }
+-
+- void setFullScreen (bool shouldBeFullScreen)
+- {
+- setMinimised (false);
+-
+- if (fullScreen != shouldBeFullScreen)
+- {
+- Rectangle r (lastNonFullscreenBounds);
+-
+- if (shouldBeFullScreen)
+- r = Desktop::getInstance().getMainMonitorArea();
+-
+- if (! r.isEmpty())
+- setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
+-
+- getComponent()->repaint();
+- }
+- }
+-
+- bool isFullScreen() const
+- {
+- return fullScreen;
+- }
+-
+- bool isChildWindowOf (Window possibleParent) const
+- {
+- Window* windowList = 0;
+- uint32 windowListSize = 0;
+- Window parent, root;
+-
+- if (XQueryTree (display, windowH, &root, &parent, &windowList, &windowListSize) != 0)
+- {
+- if (windowList != 0)
+- XFree (windowList);
+-
+- return parent == possibleParent;
+- }
+-
+- return false;
+- }
+-
+- bool contains (int x, int y, bool trueIfInAChildWindow) const
+- {
+- jassert (x >= 0 && y >= 0 && x < ww && y < wh); // should only be called for points that are actually inside the bounds
+-
+- x += wx;
+- y += wy;
+-
+- // the XQueryTree stuff later on is VERY slow, so if this call's just to check the mouse pos, it's
+- // much more efficient to cheat..
+- if (x == lastMousePosX && y == lastMousePosY)
+- {
+- Window root, child;
+- int winx, winy;
+- unsigned int mask;
+-
+- if (XQueryPointer (display,
+- RootWindow (display, DefaultScreen (display)),
+- &root, &child,
+- &x, &y, &winx, &winy, &mask) != False)
+- {
+- return child == windowH
+- || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (child));
+- }
+- }
+-
+- bool result = false;
+-
+- Window* windowList = 0;
+- uint32 windowListSize = 0;
+-
+- Window parent, root = RootWindow (display, DefaultScreen (display));
+-
+- if (XQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0)
+- {
+- for (int i = windowListSize; --i >= 0;)
+- {
+- XWindowAttributes atts;
+-
+- if (windowList[i] == windowH
+- || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (windowList[i])))
+- {
+- result = true;
+-
+- if (! trueIfInAChildWindow)
+- {
+- Window child;
+- int tempX, tempY;
+-
+- result = XTranslateCoordinates (display, windowH, windowH,
+- x - wx - windowBorder.getLeft(),
+- y - wy - windowBorder.getTop(),
+- &tempX, &tempY,
+- &child)
+- && (child == None);
+- }
+-
+- break;
+- }
+- else if (XGetWindowAttributes (display, windowList[i], &atts)
+- && atts.map_state == IsViewable
+- && x >= atts.x && y >= atts.y
+- && x < atts.x + atts.width
+- && y < atts.y + atts.height)
+- {
+- break;
+- }
+- }
+- }
+-
+- if (windowList != 0)
+- XFree (windowList);
+-
+- return result;
+- }
+-
+- const BorderSize getFrameSize() const
+- {
+- return BorderSize();
+- }
+-
+- bool setAlwaysOnTop (bool alwaysOnTop)
+- {
+- if (windowH != 0)
+- {
+- XSetWindowAttributes swa;
+- swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False;
+-
+- XChangeWindowAttributes (display, windowH, CWOverrideRedirect, &swa);
+- }
+-
+- return true;
+- }
+-
+- void toFront (bool makeActive)
+- {
+- if (makeActive)
+- {
+- setVisible (true);
+- grabFocus();
+- }
+-
+- XEvent ev;
+- ev.xclient.type = ClientMessage;
+- ev.xclient.serial = 0;
+- ev.xclient.send_event = True;
+- ev.xclient.message_type = wm_ActiveWin;
+- ev.xclient.window = windowH;
+- ev.xclient.format = 32;
+- ev.xclient.data.l[0] = 2;
+- ev.xclient.data.l[1] = CurrentTime;
+- ev.xclient.data.l[2] = 0;
+- ev.xclient.data.l[3] = 0;
+- ev.xclient.data.l[4] = 0;
+-
+- XSendEvent (display, RootWindow (display, DefaultScreen (display)),
+- False,
+- SubstructureRedirectMask | SubstructureNotifyMask,
+- &ev);
+-
+- XSync (display, False);
+- }
+-
+- void toBehind (ComponentPeer* other)
+- {
+- LinuxComponentPeer* const otherPeer = dynamic_cast <LinuxComponentPeer*> (other);
+- jassert (otherPeer != 0); // wrong type of window?
+-
+- if (otherPeer != 0)
+- {
+- setMinimised (false);
+-
+- Window newStack[] = { otherPeer->windowH, windowH };
+-
+- XRestackWindows (display, newStack, 2);
+- }
+- }
+-
+- bool isFocused() const
+- {
+- int revert;
+- Window focus = 0;
+- XGetInputFocus (display, &focus, &revert);
+-
+- if (focus == 0 || focus == None || focus == PointerRoot)
+- return 0;
+-
+- ComponentPeer* focusedPeer = 0;
+- if (XFindContext (display, (XID) focus, improbableNumber, (XPointer*) &focusedPeer) != 0)
+- focusedPeer = 0;
+-
+- return this == focusedPeer;
+- }
+-
+- void grabFocus()
+- {
+- XWindowAttributes atts;
+-
+- if (windowH != 0
+- && XGetWindowAttributes (display, windowH, &atts)
+- && atts.map_state == IsViewable)
+- {
+- XSetInputFocus (display, windowH, RevertToParent, CurrentTime);
+-
+- if (! isActiveApplication)
+- {
+- isActiveApplication = true;
+- handleFocusGain();
+- }
+- }
+- }
+-
+- void repaint (int x, int y, int w, int h)
+- {
+- repainter->invalidateCache (x, y, w, h);
+- repainter->repaint (x, y, w, h);
+- }
+-
+- void performPendingRepaints()
+- {
+- repainter->performPendingRepaints();
+- }
+-
+- //==============================================================================
+- void handleWindowMessage (XEvent* event)
+- {
+- switch (event->xany.type)
+- {
+- case 2: // 'KeyPress'
+- {
+- XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey;
+- updateKeyStates (keyEvent->keycode, true);
+-
+- int index = currentModifiers & ModifierKeys::shiftModifier ? 1 : 0;
+- KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, index);
+-
+- const int oldMods = currentModifiers;
+- bool keyPressed = false;
+-
+- const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false);
+-
+- if ((sym & 0xff00) == 0xff00)
+- {
+- // Translate keypad
+- if (sym == XK_KP_Divide)
+- sym = XK_slash;
+- else if (sym == XK_KP_Multiply)
+- sym = XK_asterisk;
+- else if (sym == XK_KP_Subtract)
+- sym = XK_hyphen;
+- else if (sym == XK_KP_Add)
+- sym = XK_plus;
+- else if (sym == XK_KP_Enter)
+- sym = XK_Return;
+- else if (sym == XK_KP_Decimal)
+- sym = numLock ? XK_period : XK_Delete;
+- else if (sym == XK_KP_0)
+- sym = numLock ? XK_0 : XK_Insert;
+- else if (sym == XK_KP_1)
+- sym = numLock ? XK_1 : XK_End;
+- else if (sym == XK_KP_2)
+- sym = numLock ? XK_2 : XK_Down;
+- else if (sym == XK_KP_3)
+- sym = numLock ? XK_3 : XK_Page_Down;
+- else if (sym == XK_KP_4)
+- sym = numLock ? XK_4 : XK_Left;
+- else if (sym == XK_KP_5)
+- sym = XK_5;
+- else if (sym == XK_KP_6)
+- sym = numLock ? XK_6 : XK_Right;
+- else if (sym == XK_KP_7)
+- sym = numLock ? XK_7 : XK_Home;
+- else if (sym == XK_KP_8)
+- sym = numLock ? XK_8 : XK_Up;
+- else if (sym == XK_KP_9)
+- sym = numLock ? XK_9 : XK_Page_Up;
+-
+- switch (sym)
+- {
+- case XK_Left:
+- case XK_Right:
+- case XK_Up:
+- case XK_Down:
+- case XK_Page_Up:
+- case XK_Page_Down:
+- case XK_End:
+- case XK_Home:
+- case XK_Delete:
+- case XK_Insert:
+- keyPressed = true;
+- sym = (sym & 0xff) | nonAsciiModifier;
+- break;
+- case XK_Tab:
+- case XK_Return:
+- case XK_Escape:
+- case XK_BackSpace:
+- keyPressed = true;
+- sym &= 0xff;
+- break;
+- default:
+- {
+- if (sym >= XK_F1 && sym <= XK_F12)
+- {
+- keyPressed = true;
+- sym = (sym & 0xff) | nonAsciiModifier;
+- }
+- break;
+- }
+- }
+- }
+-
+- if ((sym & 0xff00) == 0 && sym >= 8)
+- keyPressed = true;
+-
+- if (capsLock && ((sym >= XK_A && sym <= XK_Z) || (sym >= XK_a && sym <= XK_z)))
+- {
+- index ^= 1;
+- sym = XKeycodeToKeysym (display, keyEvent->keycode, index);
+- }
+-
+- if (oldMods != currentModifiers)
+- handleModifierKeysChange();
+-
+- if (keyDownChange)
+- handleKeyUpOrDown();
+-
+- if (keyPressed)
+- handleKeyPress (sym);
+-
+- break;
+- }
+-
+- case KeyRelease:
+- {
+- XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey;
+- updateKeyStates (keyEvent->keycode, false);
+-
+- KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0);
+-
+- const int oldMods = currentModifiers;
+- const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false);
+-
+- if (oldMods != currentModifiers)
+- handleModifierKeysChange();
+-
+- if (keyDownChange)
+- handleKeyUpOrDown();
+-
+- break;
+- }
+-
+- case ButtonPress:
+- {
+- XButtonPressedEvent* buttonPressEvent = (XButtonPressedEvent*) &event->xbutton;
+-
+- bool buttonMsg = false;
+- bool wheelUpMsg = false;
+- bool wheelDownMsg = false;
+-
+- const int map = pointerMap [buttonPressEvent->button - Button1];
+-
+- if (map == LeftButton)
+- {
+- currentModifiers |= ModifierKeys::leftButtonModifier;
+- buttonMsg = true;
+- }
+- else if (map == RightButton)
+- {
+- currentModifiers |= ModifierKeys::rightButtonModifier;
+- buttonMsg = true;
+- }
+- else if (map == MiddleButton)
+- {
+- currentModifiers |= ModifierKeys::middleButtonModifier;
+- buttonMsg = true;
+- }
+- else if (map == WheelUp)
+- {
+- wheelUpMsg = true;
+- }
+- else if (map == WheelDown)
+- {
+- wheelDownMsg = true;
+- }
+-
+- updateKeyModifiers (buttonPressEvent->state);
+-
+- if (buttonMsg)
+- {
+- toFront (true);
+- handleMouseDown (buttonPressEvent->x, buttonPressEvent->y,
+- getEventTime (buttonPressEvent->time));
+- }
+- else if (wheelUpMsg || wheelDownMsg)
+- {
+- handleMouseWheel (wheelDownMsg ? -84 : 84,
+- getEventTime (buttonPressEvent->time));
+- }
+-
+- lastMousePosX = lastMousePosY = 0x100000;
+- break;
+- }
+-
+- case ButtonRelease:
+- {
+- XButtonReleasedEvent* buttonRelEvent = (XButtonReleasedEvent*) &event->xbutton;
+-
+- const int oldModifiers = currentModifiers;
+- const int map = pointerMap [buttonRelEvent->button - Button1];
+-
+- if (map == LeftButton)
+- currentModifiers &= ~ModifierKeys::leftButtonModifier;
+- else if (map == RightButton)
+- currentModifiers &= ~ModifierKeys::rightButtonModifier;
+- else if (map == MiddleButton)
+- currentModifiers &= ~ModifierKeys::middleButtonModifier;
+-
+- updateKeyModifiers (buttonRelEvent->state);
+-
+- handleMouseUp (oldModifiers,
+- buttonRelEvent->x, buttonRelEvent->y,
+- getEventTime (buttonRelEvent->time));
+-
+- lastMousePosX = lastMousePosY = 0x100000;
+- break;
+- }
+-
+- case MotionNotify:
+- {
+- XPointerMovedEvent* movedEvent = (XPointerMovedEvent*) &event->xmotion;
+-
+- updateKeyModifiers (movedEvent->state);
+-
+- int x, y, mouseMods;
+- getMousePos (x, y, mouseMods);
+-
+- if (lastMousePosX != x || lastMousePosY != y)
+- {
+- lastMousePosX = x;
+- lastMousePosY = y;
+-
+- x -= getScreenX();
+- y -= getScreenY();
+-
+- if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0)
+- handleMouseMove (x, y, getEventTime (movedEvent->time));
+- else
+- handleMouseDrag (x, y, getEventTime (movedEvent->time));
+- }
+-
+- break;
+- }
+-
+- case EnterNotify:
+- {
+- lastMousePosX = lastMousePosY = 0x100000;
+- XEnterWindowEvent* enterEvent = (XEnterWindowEvent*) &event->xcrossing;
+-
+- if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0
+- && ! entered)
+- {
+- updateKeyModifiers (enterEvent->state);
+-
+- handleMouseEnter (enterEvent->x, enterEvent->y, getEventTime (enterEvent->time));
+-
+- entered = true;
+- }
+-
+- break;
+- }
+-
+- case LeaveNotify:
+- {
+- XLeaveWindowEvent* leaveEvent = (XLeaveWindowEvent*) &event->xcrossing;
+-
+- // Suppress the normal leave if we've got a pointer grab, or if
+- // it's a bogus one caused by clicking a mouse button when running
+- // in a Window manager
+- if (((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0
+- && leaveEvent->mode == NotifyNormal)
+- || leaveEvent->mode == NotifyUngrab)
+- {
+- updateKeyModifiers (leaveEvent->state);
+-
+- handleMouseExit (leaveEvent->x, leaveEvent->y, getEventTime (leaveEvent->time));
+-
+- entered = false;
+- }
+-
+- break;
+- }
+-
+- case FocusIn:
+- {
+- isActiveApplication = true;
+- handleFocusGain();
+- break;
+- }
+-
+- case FocusOut:
+- {
+- isActiveApplication = false;
+- handleFocusLoss();
+- break;
+- }
+-
+- case Expose:
+- {
+- // Batch together all pending expose events
+- XExposeEvent* exposeEvent = (XExposeEvent*) &event->xexpose;
+- XEvent nextEvent;
+-
+- repaint (exposeEvent->x, exposeEvent->y,
+- exposeEvent->width, exposeEvent->height);
+-
+- while (XEventsQueued (display, QueuedAfterFlush) > 0)
+- {
+- XPeekEvent (display, (XEvent*) &nextEvent);
+- if (nextEvent.type != Expose || nextEvent.xany.window != event->xany.window)
+- break;
+-
+- XNextEvent (display, (XEvent*)&nextEvent);
+- XExposeEvent* nextExposeEvent = (XExposeEvent*)(&nextEvent.xexpose);
+- repaint (nextExposeEvent->x, nextExposeEvent->y,
+- nextExposeEvent->width, nextExposeEvent->height);
+- }
+-
+- break;
+- }
+-
+- case CreateNotify:
+- case DestroyNotify:
+- // Think we can ignore these
+- break;
+-
+- case CirculateNotify:
+- break;
+-
+- case ConfigureNotify:
+- case ReparentNotify:
+- case GravityNotify:
+- updateBounds();
+- break;
+-
+- case MapNotify:
+- mapped = true;
+- handleBroughtToFront();
+- break;
+-
+- case UnmapNotify:
+- mapped = false;
+- break;
+-
+- case MappingNotify:
+- {
+- XMappingEvent* mappingEvent = (XMappingEvent*) &event->xmapping;
+-
+- if (mappingEvent->request != MappingPointer)
+- {
+- // Deal with modifier/keyboard mapping
+- XRefreshKeyboardMapping (mappingEvent);
+- getModifierMapping();
+- }
+-
+- break;
+- }
+-
+- case ClientMessage:
+- {
+- XClientMessageEvent* clientMsg = (XClientMessageEvent*) &event->xclient;
+-
+- if (clientMsg->message_type == wm_Protocols && clientMsg->format == 32)
+- {
+- const Atom atom = (Atom) clientMsg->data.l[0];
+-
+- if (atom == wm_ProtocolList [TAKE_FOCUS])
+- {
+- XWindowAttributes atts;
+-
+- if (clientMsg->window != 0
+- && XGetWindowAttributes (display, clientMsg->window, &atts))
+- {
+- if (atts.map_state == IsViewable)
+- XSetInputFocus (display, clientMsg->window, RevertToParent, clientMsg->data.l[1]);
+- }
+- }
+- else if (atom == wm_ProtocolList [DELETE_WINDOW])
+- {
+- handleUserClosingWindow();
+- }
+- }
+- else if (clientMsg->message_type == repaintId)
+- {
+- // Get rid of all pending repaint events
+- XEvent nextEvent;
+-
+- while (XEventsQueued (display, QueuedAfterFlush) > 0)
+- {
+- XPeekEvent (display, &nextEvent);
+- if (nextEvent.xany.type != ClientMessage ||
+- nextEvent.xany.window != event->xany.window)
+- break;
+-
+- XClientMessageEvent* nextClientMsg = (XClientMessageEvent*) (&nextEvent.xclient);
+- if (nextClientMsg->message_type != repaintId)
+- break;
+-
+- XNextEvent (display, &nextEvent);
+- }
+-
+- static bool reentrancyCheck = false;
+- if (! reentrancyCheck)
+- {
+- reentrancyCheck = true;
+-
+- int ox, oy, ow, oh;
+- getBounds (ox, oy, ow, oh);
+- repaint (0, 0, ow, oh);
+- performPendingRepaints();
+-
+- reentrancyCheck = false;
+- }
+- }
+-
+- break;
+- }
+-
+- case SelectionClear:
+- case SelectionNotify:
+- case SelectionRequest:
+- // We shouldn't get these on normal windows
+- break;
+-
+- default:
+- break;
+- }
+- }
+-
+- void showMouseCursor (Cursor cursor)
+- {
+- XDefineCursor (display, windowH, cursor);
+- }
+-
+- //==============================================================================
+- juce_UseDebuggingNewOperator
+-
+- bool dontRepaint;
+-
+-private:
+- //==============================================================================
+- class LinuxRepaintManager : public RepaintManager
+- {
+- public:
+- LinuxRepaintManager (LinuxComponentPeer* const peer_,
+- Component* const component,
+- const int timeBeforeReleasingImage)
+- : RepaintManager (component, timeBeforeReleasingImage),
+- peer (peer_)
+- {
+- }
+-
+- Image* createNewImage (int w, int h)
+- {
+- return new XBitmapImage (Image::RGB, w, h, false);
+- }
+-
+- void repaintNow (const RectangleList& areasToPaint)
+- {
+- peer->clearMaskedRegion();
+-
+- renderCacheAreasNeedingRepaint();
+-
+- int x, y;
+- XBitmapImage* const paintingBuffer = (XBitmapImage*) getImage (x, y);
+-
+- if (paintingBuffer != 0)
+- {
+- const RectangleList* repaintRegion = &areasToPaint;
+- RectangleList temp;
+-
+- if (! peer->maskedRegion.isEmpty())
+- {
+- temp = areasToPaint;
+- temp.subtract (peer->maskedRegion);
+- repaintRegion = &temp;
+- }
+-
+- for (RectangleList::Iterator i (*repaintRegion); i.next();)
+- {
+- const Rectangle& r = i.getRectangle();
+-
+- paintingBuffer->blitToWindow (peer->windowH,
+- r.getX(), r.getY(), r.getWidth(), r.getHeight(),
+- r.getX() - x, r.getY() - y);
+- }
+- }
+- }
+-
+- private:
+- LinuxComponentPeer* const peer;
+-
+- LinuxRepaintManager (const LinuxRepaintManager&);
+- const LinuxRepaintManager& operator= (const LinuxRepaintManager&);
+- };
+-
+- LinuxRepaintManager* repainter;
+-
+- friend class LinuxRepaintManager;
+- Window windowH;
+- int wx, wy, ww, wh;
+- bool fullScreen, entered, mapped;
+- BorderSize windowBorder;
+-
+- //==============================================================================
+- void removeWindowDecorations (Window wndH)
+- {
+- Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);
+-
+- if (hints != None)
+- {
+- typedef struct
+- {
+- CARD32 flags;
+- CARD32 functions;
+- CARD32 decorations;
+- INT32 input_mode;
+- CARD32 status;
+- } MotifWmHints;
+-
+- MotifWmHints motifHints;
+- motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */
+- motifHints.decorations = 0;
+-
+- XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
+- (unsigned char*) &motifHints, 4);
+- }
+-
+- hints = XInternAtom (display, "_WIN_HINTS", True);
+-
+- if (hints != None)
+- {
+- long gnomeHints = 0;
+-
+- XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
+- (unsigned char*) &gnomeHints, 1);
+- }
+-
+- hints = XInternAtom (display, "KWM_WIN_DECORATION", True);
+-
+- if (hints != None)
+- {
+- long kwmHints = 2; /*KDE_tinyDecoration*/
+-
+- XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
+- (unsigned char*) &kwmHints, 1);
+- }
+-
+- hints = XInternAtom (display, "_NET_WM_WINDOW_TYPE", True);
+-
+- if (hints != None)
+- {
+- Atom netHints [2];
+- netHints[0] = XInternAtom (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True);
+-
+- if ((styleFlags & windowIsTemporary) != 0)
+- netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_MENU", True);
+- else
+- netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_NORMAL", True);
+-
+- XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,
+- (unsigned char*) &netHints, 2);
+- }
+- }
+-
+- void addWindowButtons (Window wndH)
+- {
+- Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);
+-
+- if (hints != None)
+- {
+- typedef struct
+- {
+- CARD32 flags;
+- CARD32 functions;
+- CARD32 decorations;
+- INT32 input_mode;
+- CARD32 status;
+- } MotifWmHints;
+-
+- MotifWmHints motifHints;
+-
+- motifHints.flags = 1 | 2; /* MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS */
+- motifHints.decorations = 2 /* MWM_DECOR_BORDER */ | 8 /* MWM_DECOR_TITLE */ | 16; /* MWM_DECOR_MENU */
+-
+- motifHints.functions = 4 /* MWM_FUNC_MOVE */;
+-
+- if ((styleFlags & windowHasCloseButton) != 0)
+- motifHints.functions |= 32; /* MWM_FUNC_CLOSE */
+-
+- if ((styleFlags & windowHasMinimiseButton) != 0)
+- {
+- motifHints.functions |= 8; /* MWM_FUNC_MINIMIZE */
+- motifHints.decorations |= 0x20; /* MWM_DECOR_MINIMIZE */
+- }
+-
+- if ((styleFlags & windowHasMaximiseButton) != 0)
+- {
+- motifHints.functions |= 0x10; /* MWM_FUNC_MAXIMIZE */
+- motifHints.decorations |= 0x40; /* MWM_DECOR_MAXIMIZE */
+- }
+-
+- if ((styleFlags & windowIsResizable) != 0)
+- {
+- motifHints.functions |= 2; /* MWM_FUNC_RESIZE */
+- motifHints.decorations |= 0x4; /* MWM_DECOR_RESIZEH */
+- }
+-
+- XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
+- (unsigned char*) &motifHints, 4);
+- }
+-
+- hints = XInternAtom (display, "_NET_WM_ALLOWED_ACTIONS", True);
+-
+- if (hints != None)
+- {
+- Atom netHints [6];
+- int num = 0;
+-
+- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_RESIZE", (styleFlags & windowIsResizable) ? True : False);
+- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_FULLSCREEN", (styleFlags & windowHasMaximiseButton) ? True : False);
+- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_MINIMIZE", (styleFlags & windowHasMinimiseButton) ? True : False);
+- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_CLOSE", (styleFlags & windowHasCloseButton) ? True : False);
+-
+- XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,
+- (unsigned char*) &netHints, num);
+- }
+- }
+-
+- static void* createWindowCallback (void* userData)
+- {
+- ((LinuxComponentPeer*) userData)->createWindow();
+- return 0;
+- }
+-
+- void createWindow()
+- {
+- static bool atomsInitialised = false;
+-
+- if (! atomsInitialised)
+- {
+- atomsInitialised = true;
+-
+- wm_Protocols = XInternAtom (display, "WM_PROTOCOLS", 1);
+- wm_ProtocolList [TAKE_FOCUS] = XInternAtom (display, "WM_TAKE_FOCUS", 1);
+- wm_ProtocolList [DELETE_WINDOW] = XInternAtom (display, "WM_DELETE_WINDOW", 1);
+- wm_ChangeState = XInternAtom (display, "WM_CHANGE_STATE", 1);
+- wm_State = XInternAtom (display, "WM_STATE", 1);
+- wm_ActiveWin = XInternAtom (display, "_NET_ACTIVE_WINDOW", False);
+- repaintId = XInternAtom (display, "JUCERepaintAtom", 1);
+- }
+-
+- // Get defaults for various properties
+- const int screen = DefaultScreen (display);
+- Window root = RootWindow (display, screen);
+-
+- // Attempt to create a 24-bit window on the default screen. If this is not
+- // possible then exit
+- XVisualInfo desiredVisual;
+- desiredVisual.screen = screen;
+- desiredVisual.depth = 24;
+-
+- int numVisuals;
+- XVisualInfo* visuals = XGetVisualInfo (display, VisualScreenMask | VisualDepthMask,
+- &desiredVisual, &numVisuals);
+-
+- if (numVisuals < 1 || visuals == 0)
+- {
+- Logger::outputDebugString ("ERROR: System doesn't support 24-bit RGB display.\n");
+- Process::terminate();
+- }
+-
+- // Just choose the first one
+- Visual* visual = visuals[0].visual;
+- const int depth = visuals[0].depth;
+- XFree (visuals);
+-
+- // Set up the window attributes
+- XSetWindowAttributes swa;
+- swa.border_pixel = 0;
+- swa.colormap = DefaultColormap (display, screen);
+- swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False;
+- swa.event_mask = eventMask;
+-
+- Window wndH = XCreateWindow (display, root,
+- 0, 0, 1, 1, 0,
+- depth, InputOutput, visual,
+- CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
+- &swa);
+-
+- XGrabButton (display, AnyButton, AnyModifier, wndH, False,
+- ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
+- GrabModeAsync, GrabModeAsync, None, None);
+-
+- // Set the window context to identify the window handle object
+- if (XSaveContext (display, (XID) wndH, improbableNumber, (XPointer) this))
+- {
+- // Failed
+- jassertfalse
+- Logger::outputDebugString ("Failed to create context information for window.\n");
+- XDestroyWindow (display, wndH);
+- wndH = 0;
+- }
+-
+- // Set window manager hints
+- XWMHints* wmHints = XAllocWMHints();
+- wmHints->flags = InputHint | StateHint;
+- wmHints->input = True; // Locally active input model
+- wmHints->initial_state = NormalState;
+- XSetWMHints (display, wndH, wmHints);
+- XFree (wmHints);
+-
+- if ((styleFlags & juce_windowIsSemiTransparentFlag) != 0)
+- {
+- //xxx
+- jassertfalse
+- }
+-
+- if ((styleFlags & windowAppearsOnTaskbar) != 0)
+- {
+- //xxx
+- }
+-
+- if ((styleFlags & windowHasTitleBar) == 0)
+- removeWindowDecorations (wndH);
+- else
+- addWindowButtons (wndH);
+-
+- XSetTransientForHint (display, wndH, RootWindow (display, DefaultScreen (display)));
+-
+- // Set window manager protocols
+- XChangeProperty (display, wndH, wm_Protocols, XA_ATOM, 32, PropModeReplace,
+- (unsigned char*) wm_ProtocolList, 2);
+-
+- // Set window name
+- setWindowTitle (wndH, getComponent()->getName());
+-
+- // Initialise the pointer and keyboard mapping
+- // This is not the same as the logical pointer mapping the X server uses:
+- // we don't mess with this.
+- static bool mappingInitialised = false;
+-
+- if (! mappingInitialised)
+- {
+- mappingInitialised = true;
+-
+- const int numButtons = XGetPointerMapping (display, 0, 0);
+-
+- if (numButtons == 2)
+- {
+- pointerMap[0] = LeftButton;
+- pointerMap[1] = RightButton;
+- pointerMap[2] = pointerMap[3] = pointerMap[4] = NoButton;
+- }
+- else if (numButtons >= 3)
+- {
+- pointerMap[0] = LeftButton;
+- pointerMap[1] = MiddleButton;
+- pointerMap[2] = RightButton;
+-
+- if (numButtons >= 5)
+- {
+- pointerMap[3] = WheelUp;
+- pointerMap[4] = WheelDown;
+- }
+- }
+-
+- getModifierMapping();
+- }
+-
+- windowH = wndH;
+- }
+-
+- static void* destroyWindowCallback (void* userData)
+- {
+- Window windowH = (Window) userData;
+-
+- XPointer handlePointer;
+- if (! XFindContext (display, (XID) windowH, improbableNumber, &handlePointer))
+- XDeleteContext (display, (XID) windowH, improbableNumber);
+-
+- XDestroyWindow (display, windowH);
+-
+- // Wait for it to complete and then remove any events for this
+- // window from the event queue.
+- XSync (display, false);
+-
+- XEvent event;
+- while (XCheckWindowEvent (display, windowH, eventMask, &event) == True)
+- {}
+-
+- return 0;
+- }
+-
+- static int64 getEventTime (::Time t)
+- {
+- static int64 eventTimeOffset = 0x12345678;
+- const int64 thisMessageTime = t;
+-
+- if (eventTimeOffset == 0x12345678)
+- eventTimeOffset = Time::currentTimeMillis() - thisMessageTime;
+-
+- return eventTimeOffset + thisMessageTime;
+- }
+-
+- static void setWindowTitle (Window xwin, const char* const title)
+- {
+- XTextProperty nameProperty;
+- char* strings[] = { (char*) title };
+-
+- if (XStringListToTextProperty (strings, 1, &nameProperty))
+- {
+- XSetWMName (display, xwin, &nameProperty);
+- XSetWMIconName (display, xwin, &nameProperty);
+- }
+- }
+-
+- void updateBorderSize()
+- {
+- if ((styleFlags & windowHasTitleBar) == 0)
+- {
+- windowBorder = BorderSize (0);
+- }
+- else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0)
+- {
+- Atom hints = XInternAtom (display, "_NET_FRAME_EXTENTS", True);
+-
+- if (hints != None)
+- {
+- CARD32* sizes = 0;
+- unsigned long nitems, bytesLeft;
+- Atom actualType;
+- int actualFormat;
+-
+- if (XGetWindowProperty (display, windowH, hints, 0, 4, False,
+- XA_CARDINAL, &actualType, &actualFormat, &nitems, &bytesLeft,
+- (unsigned char**) &sizes) == Success)
+- {
+- if (actualFormat == 32)
+- windowBorder = BorderSize ((int) sizes[2], (int) sizes[0],
+- (int) sizes[3], (int) sizes[1]);
+-
+- XFree (sizes);
+- }
+- }
+- }
+- }
+-
+- void updateBounds()
+- {
+- jassert (windowH != 0);
+- if (windowH != 0)
+- {
+- Window root, child;
+- unsigned int bw, depth;
+-
+- if (! XGetGeometry (display, (Drawable) windowH, &root,
+- &wx, &wy, (unsigned int*) &ww, (unsigned int*) &wh,
+- &bw, &depth))
+- {
+- wx = wy = ww = wh = 0;
+- }
+- else if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child))
+- {
+- wx = wy = 0;
+- }
+-
+- updateBorderSize();
+- handleMovedOrResized();
+- }
+- }
+-};
+-
+-//==============================================================================
+-ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/)
+-{
+- return new LinuxComponentPeer (this, styleFlags);
+-}
+-
+-
+-//==============================================================================
+-// (this callback is hooked up in the messaging code)
+-void juce_windowMessageReceive (XEvent* event)
+-{
+- if (event->xany.window != None)
+- {
+- // Check if the event is for one of our windows
+- LinuxComponentPeer* peer = 0;
+-
+- if (! XFindContext (display, (XID) event->xany.window, improbableNumber, (XPointer*) &peer))
+- {
+- if (peer != 0 && peer->isValidMessageListener())
+- peer->handleWindowMessage (event);
+- }
+- }
+- else
+- {
+- switch (event->xany.type)
+- {
+- case KeymapNotify:
+- {
+- const XKeymapEvent* const keymapEvent = (const XKeymapEvent*) &event->xkeymap;
+- memcpy (keyStates, keymapEvent->key_vector, 32);
+- break;
+- }
+-
+- default:
+- break;
+- }
+- }
+-}
+-
+-//==============================================================================
+-void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea)
+-{
+-#if JUCE_USE_XINERAMA
+- int major_opcode, first_event, first_error;
+-
+- if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)
+- && XineramaIsActive (display))
+- {
+- int numMonitors = 0;
+- XineramaScreenInfo* const screens = XineramaQueryScreens (display, &numMonitors);
+-
+- if (screens != 0)
+- {
+- for (int i = numMonitors; --i >= 0;)
+- {
+- int index = screens[i].screen_number;
+-
+- if (index >= 0)
+- {
+- while (monitorCoords.size() < index)
+- monitorCoords.add (Rectangle (0, 0, 0, 0));
+-
+- monitorCoords.set (index, Rectangle (screens[i].x_org,
+- screens[i].y_org,
+- screens[i].width,
+- screens[i].height));
+- }
+- }
+-
+- XFree (screens);
+- }
+- }
+-
+- if (monitorCoords.size() == 0)
+-#endif
+- {
+- monitorCoords.add (Rectangle (0, 0,
+- DisplayWidth (display, DefaultScreen (display)),
+- DisplayHeight (display, DefaultScreen (display))));
+- }
+-}
+-
+-//==============================================================================
+-bool Desktop::canUseSemiTransparentWindows()
+-{
+- return false;
+-}
+-
+-void Desktop::getMousePosition (int& x, int& y)
+-{
+- int mouseMods;
+- getMousePos (x, y, mouseMods);
+-}
+-
+-void Desktop::setMousePosition (int x, int y)
+-{
+- Window root = RootWindow (display, DefaultScreen (display));
+- XWarpPointer (display, None, root, 0, 0, 0, 0, x, y);
+-}
+-
+-
+-//==============================================================================
+-void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY)
+-{
+- Window root = RootWindow (display, DefaultScreen (display));
+- const unsigned int imageW = image.getWidth();
+- const unsigned int imageH = image.getHeight();
+- unsigned int cursorW, cursorH;
+-
+- if (! XQueryBestCursor (display, root, imageW, imageH, &cursorW, &cursorH))
+- return 0;
+-
+- Image im (Image::ARGB, cursorW, cursorH, true);
+- Graphics g (im);
+-
+- if (imageW > cursorW || imageH > cursorH)
+- {
+- hotspotX = (hotspotX * cursorW) / imageW;
+- hotspotY = (hotspotY * cursorH) / imageH;
+-
+- g.drawImageWithin (&image, 0, 0, imageW, imageH,
+- Justification::topLeft,
+- false, false);
+- }
+- else
+- {
+- g.drawImageAt (&image, 0, 0);
+- }
+-
+- const int stride = (cursorW + 7) >> 3;
+- unsigned char* const maskPlane = (unsigned char*)juce_calloc (stride*cursorH);
+- unsigned char* const sourcePlane = (unsigned char*)juce_calloc (stride*cursorH);
+-
+- bool msbfirst = (BitmapBitOrder (display) == MSBFirst);
+-
+- for (int y = cursorH; --y >= 0;)
+- {
+- for (int x = cursorW; --x >= 0;)
+- {
+- const unsigned char mask = (unsigned char)(1 << (msbfirst ? (7 - (x & 7)) : (x & 7)));
+- const int offset = y * stride + (x >> 3);
+-
+- const Colour c (im.getPixelAt (x, y));
+-
+- if (c.getAlpha() >= 128)
+- maskPlane[offset] |= mask;
+-
+- if (c.getBrightness() >= 0.5f)
+- sourcePlane[offset] |= mask;
+- }
+- }
+-
+- Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, (char*)sourcePlane, cursorW, cursorH, 0xffff, 0, 1);
+- Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, (char*)maskPlane, cursorW, cursorH, 0xffff, 0, 1);
+-
+- juce_free (maskPlane);
+- juce_free (sourcePlane);
+-
+- XColor white, black;
+- black.red = black.green = black.blue = 0;
+- white.red = white.green = white.blue = 0xffff;
+-
+- void* result = (void*) XCreatePixmapCursor (display, sourcePixmap, maskPixmap, &white, &black, hotspotX, hotspotY);
+-
+- XFreePixmap (display, sourcePixmap);
+- XFreePixmap (display, maskPixmap);
+-
+- return result;
+-}
+-
+-void juce_deleteMouseCursor (void* cursorHandle, bool)
+-{
+- if (cursorHandle != None)
+- XFreeCursor (display, (Cursor)cursorHandle);
+-}
+-
+-void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type)
+-{
+- unsigned int shape;
+-
+- switch (type)
+- {
+- case MouseCursor::NoCursor:
+- {
+- void* invisibleCursor;
+-
+- Image im (Image::ARGB, 16, 16, true);
+- invisibleCursor = juce_createMouseCursorFromImage (im, 0, 0);
+-
+- return invisibleCursor;
+- }
+-
+- case MouseCursor::NormalCursor:
+- return (void*) None; // Use parent cursor
+-
+- case MouseCursor::DraggingHandCursor:
+- {
+- void* dragHandCursor;
+- static unsigned char dragHandData[] = {71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,
+- 0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,
+- 16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,
+- 132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217,
+- 247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
+- const int dragHandDataSize = 99;
+-
+- Image* im = ImageFileFormat::loadFrom ((const char*) dragHandData, dragHandDataSize);
+- dragHandCursor = juce_createMouseCursorFromImage (*im, 8, 7);
+- delete im;
+-
+- return dragHandCursor;
+- }
+-
+- case MouseCursor::CopyingCursor:
+- {
+- void* copyCursor;
+-
+- static unsigned char copyCursorData[] = {71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,
+- 128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0,
+- 21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,
+- 78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174,
+- 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112,
+- 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 };
+- const int copyCursorSize = 119;
+-
+- Image* im = ImageFileFormat::loadFrom ((const char*)copyCursorData, copyCursorSize);
+- copyCursor = juce_createMouseCursorFromImage (*im, 1, 3);
+- delete im;
+-
+- return copyCursor;
+- }
+-
+- case MouseCursor::WaitCursor:
+- shape = XC_watch;
+- break;
+-
+- case MouseCursor::IBeamCursor:
+- shape = XC_xterm;
+- break;
+-
+- case MouseCursor::PointingHandCursor:
+- shape = XC_hand2;
+- break;
+-
+- case MouseCursor::LeftRightResizeCursor:
+- shape = XC_sb_h_double_arrow;
+- break;
+-
+- case MouseCursor::UpDownResizeCursor:
+- shape = XC_sb_v_double_arrow;
+- break;
+-
+- case MouseCursor::UpDownLeftRightResizeCursor:
+- shape = XC_fleur;
+- break;
+-
+- case MouseCursor::TopEdgeResizeCursor:
+- shape = XC_top_side;
+- break;
+-
+- case MouseCursor::BottomEdgeResizeCursor:
+- shape = XC_bottom_side;
+- break;
+-
+- case MouseCursor::LeftEdgeResizeCursor:
+- shape = XC_left_side;
+- break;
+-
+- case MouseCursor::RightEdgeResizeCursor:
+- shape = XC_right_side;
+- break;
+-
+- case MouseCursor::TopLeftCornerResizeCursor:
+- shape = XC_top_left_corner;
+- break;
+-
+- case MouseCursor::TopRightCornerResizeCursor:
+- shape = XC_top_right_corner;
+- break;
+-
+- case MouseCursor::BottomLeftCornerResizeCursor:
+- shape = XC_bottom_left_corner;
+- break;
+-
+- case MouseCursor::BottomRightCornerResizeCursor:
+- shape = XC_bottom_right_corner;
+- break;
+-
+- case MouseCursor::CrosshairCursor:
+- shape = XC_crosshair;
+- break;
+-
+- default:
+- return (void*) None; // Use parent cursor
+- }
+-
+- return (void*) XCreateFontCursor (display, shape);
+-}
+-
+-void MouseCursor::showInWindow (ComponentPeer* peer) const
+-{
+- LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (peer);
+-
+- if (lp != 0)
+- lp->showMouseCursor ((Cursor) getHandle());
+-}
+-
+-void MouseCursor::showInAllWindows() const
+-{
+- for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
+- showInWindow (ComponentPeer::getPeer (i));
+-}
+-
+-//==============================================================================
+-Image* juce_createIconForFile (const File& file)
+-{
+- return 0;
+-}
+-
+-
+-//==============================================================================
+-#if JUCE_OPENGL
+-
+-struct OpenGLContextInfo
+-{
+- Window embeddedWindow;
+- GLXContext renderContext;
+-};
+-
+-void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
+-{
+- XSync (display, False);
+- jassert (component != 0);
+-
+- if (component == 0)
+- return 0;
+-
+- LinuxComponentPeer* const peer
+- = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
+-
+- if (peer == 0)
+- return 0;
+-
+- GLint attribList[] =
+- {
+- GLX_RGBA,
+- GLX_DOUBLEBUFFER,
+- GLX_RED_SIZE, 8,
+- GLX_GREEN_SIZE, 8,
+- GLX_BLUE_SIZE, 8,
+- GLX_ALPHA_SIZE, 8,
+- GLX_DEPTH_SIZE, 8,
+- None
+- };
+-
+- XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribList);
+-
+- if (bestVisual == 0)
+- return 0;
+-
+- OpenGLContextInfo* const oc = new OpenGLContextInfo();
+-
+- oc->renderContext = glXCreateContext (display, bestVisual,
+- (sharedContext != 0) ? ((OpenGLContextInfo*) sharedContext)->renderContext
+- : 0,
+- GL_TRUE);
+-
+- Window windowH = (Window) peer->getNativeHandle();
+-
+- Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
+- XSetWindowAttributes swa;
+- swa.colormap = colourMap;
+- swa.border_pixel = 0;
+- swa.event_mask = StructureNotifyMask;
+-
+- oc->embeddedWindow = XCreateWindow (display, windowH,
+- 0, 0, 1, 1, 0,
+- bestVisual->depth,
+- InputOutput,
+- bestVisual->visual,
+- CWBorderPixel | CWColormap | CWEventMask,
+- &swa);
+-
+- XMapWindow (display, oc->embeddedWindow);
+- XFreeColormap (display, colourMap);
+-
+- XFree (bestVisual);
+- XSync (display, False);
+-
+- return oc;
+-}
+-
+-void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)
+-{
+- jassert (context != 0);
+- OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
+-
+- XMoveResizeWindow (display, oc->embeddedWindow,
+- owner->getScreenX() - topComp->getScreenX(),
+- owner->getScreenY() - topComp->getScreenY(),
+- jmax (1, owner->getWidth()),
+- jmax (1, owner->getHeight()));
+-}
+-
+-void juce_deleteOpenGLContext (void* context)
+-{
+- OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
+-
+- if (oc != 0)
+- {
+- glXDestroyContext (display, oc->renderContext);
+-
+- XUnmapWindow (display, oc->embeddedWindow);
+- XDestroyWindow (display, oc->embeddedWindow);
+-
+- delete oc;
+- }
+-}
+-
+-bool juce_makeOpenGLContextCurrent (void* context)
+-{
+- OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
+-
+- if (oc != 0)
+- return glXMakeCurrent (display, oc->embeddedWindow, oc->renderContext)
+- && XSync (display, False);
+- else
+- return glXMakeCurrent (display, None, 0);
+-}
+-
+-void juce_swapOpenGLBuffers (void* context)
+-{
+- OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
+-
+- if (oc != 0)
+- glXSwapBuffers (display, oc->embeddedWindow);
+-}
+-
+-void juce_repaintOpenGLWindow (void* context)
+-{
+-}
+-
+-#endif
+-
+-
+-//==============================================================================
+-static void initClipboard (Window root, Atom* cutBuffers)
+-{
+- static bool init = false;
+-
+- if (! init)
+- {
+- init = true;
+-
+- // Make sure all cut buffers exist before use
+- for (int i = 0; i < 8; i++)
+- {
+- XChangeProperty (display, root, cutBuffers[i],
+- XA_STRING, 8, PropModeAppend, NULL, 0);
+- }
+- }
+-}
+-
+-// Clipboard implemented currently using cut buffers
+-// rather than the more powerful selection method
+-void SystemClipboard::copyTextToClipboard (const String& clipText)
+-{
+- Window root = RootWindow (display, DefaultScreen (display));
+- Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,
+- XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };
+-
+- initClipboard (root, cutBuffers);
+-
+- XRotateWindowProperties (display, root, cutBuffers, 8, 1);
+- XChangeProperty (display, root, cutBuffers[0],
+- XA_STRING, 8, PropModeReplace, (const unsigned char*)((const char*)clipText),
+- clipText.length());
+-}
+-
+-const String SystemClipboard::getTextFromClipboard()
+-{
+- char* clipData;
+- const int bufSize = 64; // in words
+- int actualFormat;
+- int byteOffset = 0;
+- unsigned long bytesLeft, nitems;
+- Atom actualType;
+- String returnData;
+-
+- Window root = RootWindow (display, DefaultScreen (display));
+-
+- Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,
+- XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };
+-
+- initClipboard (root, cutBuffers);
+-
+- do
+- {
+- if (XGetWindowProperty (display, root, cutBuffers[0], byteOffset >> 2, bufSize,
+- False, XA_STRING, &actualType, &actualFormat, &nitems, &bytesLeft,
+- (unsigned char**) &clipData) != Success
+- || actualType != XA_STRING
+- || actualFormat != 8)
+- return String();
+-
+- byteOffset += nitems;
+- returnData += String(clipData, nitems);
+- XFree (clipData);
+- }
+- while (bytesLeft);
+-
+- return returnData;
+-}
+-
+-//==============================================================================
+-bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)
+-{
+- jassertfalse // not implemented!
+- return false;
+-}
+-
+-bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
+-{
+- jassertfalse // not implemented!
+- return false;
+-}
+-
+-
+-//==============================================================================
+-void PlatformUtilities::beep()
+-{
+- //xxx
+-}
+-
+-
+-//==============================================================================
+-bool AlertWindow::showNativeDialogBox (const String& title,
+- const String& bodyText,
+- bool isOkCancel)
+-{
+- // xxx this is supposed to pop up an alert!
+- Logger::outputDebugString (title + ": " + bodyText);
+- return true;
+-}
+-
+-//==============================================================================
+-const int KeyPress::spaceKey = XK_space & 0xff;
+-const int KeyPress::returnKey = XK_Return & 0xff;
+-const int KeyPress::escapeKey = XK_Escape & 0xff;
+-const int KeyPress::backspaceKey = XK_BackSpace & 0xff;
+-const int KeyPress::leftKey = (XK_Left & 0xff) | nonAsciiModifier;
+-const int KeyPress::rightKey = (XK_Right & 0xff) | nonAsciiModifier;
+-const int KeyPress::upKey = (XK_Up & 0xff) | nonAsciiModifier;
+-const int KeyPress::downKey = (XK_Down & 0xff) | nonAsciiModifier;
+-const int KeyPress::pageUpKey = (XK_Page_Up & 0xff) | nonAsciiModifier;
+-const int KeyPress::pageDownKey = (XK_Page_Down & 0xff) | nonAsciiModifier;
+-const int KeyPress::endKey = (XK_End & 0xff) | nonAsciiModifier;
+-const int KeyPress::homeKey = (XK_Home & 0xff) | nonAsciiModifier;
+-const int KeyPress::insertKey = (XK_Insert & 0xff) | nonAsciiModifier;
+-const int KeyPress::deleteKey = (XK_Delete & 0xff) | nonAsciiModifier;
+-const int KeyPress::tabKey = XK_Tab & 0xff;
+-const int KeyPress::F1Key = (XK_F1 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F2Key = (XK_F2 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F3Key = (XK_F3 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F4Key = (XK_F4 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F5Key = (XK_F5 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F6Key = (XK_F6 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F7Key = (XK_F7 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F8Key = (XK_F8 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F9Key = (XK_F9 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F10Key = (XK_F10 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F11Key = (XK_F11 & 0xff) | nonAsciiModifier;
+-const int KeyPress::F12Key = (XK_F12 & 0xff) | nonAsciiModifier;
+-const int KeyPress::playKey = (0xffeeff00) | nonAsciiModifier;
+-const int KeyPress::stopKey = (0xffeeff01) | nonAsciiModifier;
+-const int KeyPress::fastForwardKey = (0xffeeff02) | nonAsciiModifier;
+-const int KeyPress::rewindKey = (0xffeeff03) | nonAsciiModifier;
+-
+-
+-END_JUCE_NAMESPACE
+-
+-#endif
++/* ++ ============================================================================== ++ ++ This file is part of the JUCE library - "Jules' Utility Class Extensions" ++ Copyright 2004-6 by Raw Material Software ltd. ++ ++ ------------------------------------------------------------------------------ ++ ++ JUCE can be redistributed and/or modified 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. ++ ++ JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the ++ Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ Boston, MA 02111-1307 USA ++ ++ ------------------------------------------------------------------------------ ++ ++ If you'd like to release a closed-source product which uses JUCE, commercial ++ licenses are also available: visit www.rawmaterialsoftware.com/juce for ++ more information. ++ ++ ============================================================================== ++*/ ++ ++#include "juce_Config.h" ++#if JUCE_BUILD_GUI_CLASSES ++ ++#include "linuxincludes.h" ++#include <X11/Xlib.h> ++#include <X11/Xutil.h> ++#include <X11/Xatom.h> ++#include <X11/Xmd.h> ++#include <X11/keysym.h> ++#include <X11/cursorfont.h> ++ ++#include "../../../juce_Config.h" ++#undef JUCE_USE_XINERAMA ++#undef JUCE_OPENGL ++#if JUCE_USE_XINERAMA ++#include <X11/extensions/Xinerama.h> ++#endif ++ ++#if JUCE_OPENGL ++#include <X11/Xlib.h> ++#include <GL/glx.h> ++#endif ++ ++#undef KeyPress ++ ++#include "../../../src/juce_core/basics/juce_StandardHeader.h" ++ ++BEGIN_JUCE_NAMESPACE ++ ++#include "../../../src/juce_appframework/events/juce_Timer.h" ++#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h" ++#include "../../../src/juce_appframework/gui/components/keyboard/juce_KeyPress.h" ++#include "../../../src/juce_appframework/application/juce_SystemClipboard.h" ++#include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h" ++#include "../../../src/juce_appframework/gui/components/special/juce_OpenGLComponent.h" ++#include "../../../src/juce_appframework/gui/components/juce_Desktop.h" ++#include "../../../src/juce_appframework/events/juce_MessageManager.h" ++#include "../../../src/juce_appframework/gui/components/juce_RepaintManager.h" ++#include "../../../src/juce_appframework/gui/components/juce_ComponentDeletionWatcher.h" ++#include "../../../src/juce_appframework/gui/graphics/geometry/juce_RectangleList.h" ++#include "../../../src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.h" ++#include "../../../src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h" ++#include "../../../src/juce_core/basics/juce_Logger.h" ++#include "../../../src/juce_core/threads/juce_Process.h" ++#include "../../../src/juce_core/misc/juce_PlatformUtilities.h" ++ ++ ++//============================================================================== ++static Atom wm_ChangeState = None; ++static Atom wm_State = None; ++static Atom wm_Protocols = None; ++static Atom wm_ProtocolList [2] = { None, None }; ++static Atom wm_ActiveWin = None; ++static Atom repaintId = None; ++ ++#define TAKE_FOCUS 0 ++#define DELETE_WINDOW 1 ++ ++//============================================================================== ++static bool isActiveApplication = false; ++ ++bool Process::isForegroundProcess() ++{ ++ return isActiveApplication; ++} ++ ++//============================================================================== ++// These are defined in juce_linux_Messages.cpp ++extern Display* display; ++extern XContext improbableNumber; ++ ++const int juce_windowIsSemiTransparentFlag = (1 << 31); // also in component.cpp ++ ++static const int eventMask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask ++ | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask ++ | ExposureMask | StructureNotifyMask | FocusChangeMask; ++ ++//============================================================================== ++static int pointerMap[5]; ++static int lastMousePosX = 0, lastMousePosY = 0; ++ ++enum MouseButtons ++{ ++ NoButton = 0, ++ LeftButton = 1, ++ MiddleButton = 2, ++ RightButton = 3, ++ WheelUp = 4, ++ WheelDown = 5 ++}; ++ ++static void getMousePos (int& x, int& y, int& mouseMods) ++{ ++ Window root, child; ++ int winx, winy; ++ unsigned int mask; ++ ++ mouseMods = 0; ++ ++ if (XQueryPointer (display, ++ RootWindow (display, DefaultScreen (display)), ++ &root, &child, ++ &x, &y, &winx, &winy, &mask) == False) ++ { ++ // Pointer not on the default screen ++ x = y = -1; ++ } ++ else ++ { ++ if ((mask & Button1Mask) != 0) ++ mouseMods |= ModifierKeys::leftButtonModifier; ++ ++ if ((mask & Button2Mask) != 0) ++ mouseMods |= ModifierKeys::middleButtonModifier; ++ ++ if ((mask & Button3Mask) != 0) ++ mouseMods |= ModifierKeys::rightButtonModifier; ++ } ++} ++ ++//============================================================================== ++static int AltMask = 0; ++static int NumLockMask = 0; ++static bool numLock = 0; ++static bool capsLock = 0; ++static char keyStates [32]; ++ ++static void updateKeyStates (const int keycode, const bool press) ++{ ++ const int keybyte = keycode >> 3; ++ const int keybit = (1 << (keycode & 7)); ++ ++ if (press) ++ keyStates [keybyte] |= keybit; ++ else ++ keyStates [keybyte] &= ~keybit; ++} ++ ++static bool keyDown (const int keycode) ++{ ++ const int keybyte = keycode >> 3; ++ const int keybit = (1 << (keycode & 7)); ++ ++ return (keyStates [keybyte] & keybit) != 0; ++} ++ ++static const int nonAsciiModifier = 0x10000; ++ ++bool KeyPress::isKeyCurrentlyDown (int keyCode) ++{ ++ int keysym; ++ ++ if (keyCode & nonAsciiModifier) ++ { ++ keysym = 0xff00 | (keyCode & 0xff); ++ } ++ else ++ { ++ keysym = keyCode; ++ ++ if (keysym == (XK_Tab & 0xff) ++ || keysym == (XK_Return & 0xff) ++ || keysym == (XK_Escape & 0xff) ++ || keysym == (XK_BackSpace & 0xff)) ++ { ++ keysym |= 0xff00; ++ } ++ } ++ ++ return keyDown (XKeysymToKeycode (display, keysym)); ++} ++ ++//============================================================================== ++// Alt and Num lock are not defined by standard X ++// modifier constants: check what they're mapped to ++static void getModifierMapping() ++{ ++ const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L); ++ const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock); ++ ++ AltMask = 0; ++ NumLockMask = 0; ++ ++ XModifierKeymap* mapping = XGetModifierMapping (display); ++ ++ if (mapping) ++ { ++ for (int i = 0; i < 8; i++) ++ { ++ if (mapping->modifiermap [i << 1] == altLeftCode) ++ AltMask = 1 << i; ++ else if (mapping->modifiermap [i << 1] == numLockCode) ++ NumLockMask = 1 << i; ++ } ++ ++ XFreeModifiermap (mapping); ++ } ++} ++ ++static int currentModifiers = 0; ++ ++void ModifierKeys::updateCurrentModifiers() ++{ ++ currentModifierFlags = currentModifiers; ++} ++ ++const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() ++{ ++ int x, y, mouseMods; ++ getMousePos (x, y, mouseMods); ++ ++ currentModifiers &= ~ModifierKeys::allMouseButtonModifiers; ++ currentModifiers |= mouseMods; ++ ++ return ModifierKeys (currentModifiers); ++} ++ ++static void updateKeyModifiers (const int status) ++{ ++ currentModifiers &= ~(ModifierKeys::shiftModifier ++ | ModifierKeys::ctrlModifier ++ | ModifierKeys::altModifier); ++ ++ if (status & ShiftMask) ++ currentModifiers |= ModifierKeys::shiftModifier; ++ ++ if (status & ControlMask) ++ currentModifiers |= ModifierKeys::ctrlModifier; ++ ++ if (status & AltMask) ++ currentModifiers |= ModifierKeys::altModifier; ++ ++ numLock = ((status & NumLockMask) != 0); ++ capsLock = ((status & LockMask) != 0); ++} ++ ++static bool updateKeyModifiersFromSym (KeySym sym, const bool press) ++{ ++ int modifier = 0; ++ bool isModifier = true; ++ ++ switch (sym) ++ { ++ case XK_Shift_L: ++ case XK_Shift_R: ++ modifier = ModifierKeys::shiftModifier; ++ break; ++ ++ case XK_Control_L: ++ case XK_Control_R: ++ modifier = ModifierKeys::ctrlModifier; ++ break; ++ ++ case XK_Alt_L: ++ case XK_Alt_R: ++ modifier = ModifierKeys::altModifier; ++ break; ++ ++ case XK_Num_Lock: ++ if (press) ++ numLock = ! numLock; ++ ++ break; ++ ++ case XK_Caps_Lock: ++ if (press) ++ capsLock = ! capsLock; ++ ++ break; ++ ++ case XK_Scroll_Lock: ++ break; ++ ++ default: ++ isModifier = false; ++ break; ++ } ++ ++ if (modifier != 0) ++ { ++ if (press) ++ currentModifiers |= modifier; ++ else ++ currentModifiers &= ~modifier; ++ } ++ ++ return isModifier; ++} ++ ++ ++//============================================================================== ++class XBitmapImage : public Image ++{ ++public: ++ //============================================================================== ++ XBitmapImage (const PixelFormat format_, const int w, const int h, const bool clearImage) ++ : Image (format_, w, h) ++ { ++ jassert (format_ == RGB || format_ == ARGB); ++ ++ pixelStride = (format_ == RGB) ? 3 : 4; ++ lineStride = ((w * pixelStride + 3) & ~3); ++ imageData = (uint8*) juce_malloc (lineStride * h); ++ ++ if (format_ == ARGB && clearImage) ++ zeromem (xImage->data, h * lineStride); ++ ++ xImage = new XImage(); ++ xImage->width = w; ++ xImage->height = h; ++ xImage->xoffset = 0; ++ xImage->format = ZPixmap; ++ xImage->data = (char*) imageData; ++ xImage->byte_order = ImageByteOrder (display); ++ xImage->bitmap_unit = BitmapUnit (display); ++ xImage->bitmap_bit_order = BitmapBitOrder (display); ++ xImage->bitmap_pad = 32; ++ xImage->depth = pixelStride * 8; ++ xImage->bytes_per_line = lineStride; ++ xImage->bits_per_pixel = pixelStride * 8; ++ xImage->red_mask = 0x00FF0000; ++ xImage->green_mask = 0x0000FF00; ++ xImage->blue_mask = 0x000000FF; ++ ++ if (! XInitImage (xImage)) ++ { ++ jassertfalse ++ } ++ } ++ ++ ~XBitmapImage() ++ { ++ juce_free (xImage->data); ++ xImage->data = 0; ++ XDestroyImage (xImage); ++ imageData = 0; // to stop the base class freeing this ++ } ++ ++ void blitToWindow (Window window, int dx, int dy, int dw, int dh, int sx, int sy) ++ { ++ static GC gc = 0; ++ ++ if (gc == 0) ++ gc = DefaultGC (display, DefaultScreen (display)); ++ ++ // blit results to screen. ++ XPutImage (display, (Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh); ++ } ++ ++ //============================================================================== ++ juce_UseDebuggingNewOperator ++ ++private: ++ XImage* xImage; ++}; ++ ++ ++//============================================================================== ++class LinuxComponentPeer : public ComponentPeer ++{ ++public: ++ //============================================================================== ++ LinuxComponentPeer (Component* const component, const int windowStyleFlags) ++ : ComponentPeer (component, windowStyleFlags), ++ windowH (0), ++ wx (0), ++ wy (0), ++ ww (0), ++ wh (0), ++ fullScreen (false), ++ entered (false), ++ mapped (false) ++ { ++ repainter = new LinuxRepaintManager (this, component, 3000); ++ ++ MessageManager::getInstance() ++ ->callFunctionOnMessageThread (&createWindowCallback, (void*) this); ++ ++ setTitle (component->getName()); ++ } ++ ++ ~LinuxComponentPeer() ++ { ++ MessageManager::getInstance() ++ ->callFunctionOnMessageThread (&destroyWindowCallback, (void*) windowH); ++ ++ windowH = 0; ++ delete repainter; ++ } ++ ++ //============================================================================== ++ void* getNativeHandle() const ++ { ++ return (void*) windowH; ++ } ++ ++ void setVisible (bool shouldBeVisible) ++ { ++ if (shouldBeVisible) ++ XMapWindow (display, windowH); ++ else ++ XUnmapWindow (display, windowH); ++ } ++ ++ void setTitle (const String& title) ++ { ++ setWindowTitle (windowH, title); ++ } ++ ++ void setPosition (int x, int y) ++ { ++ setBounds (x, y, ww, wh, false); ++ } ++ ++ void setSize (int w, int h) ++ { ++ setBounds (wx, wy, w, h, false); ++ } ++ ++ void setBounds (int x, int y, int w, int h, const bool isNowFullScreen) ++ { ++ fullScreen = isNowFullScreen; ++ ++ if (windowH != 0) ++ { ++ const ComponentDeletionWatcher deletionChecker (component); ++ ++ wx = x; ++ wy = y; ++ ww = jmax (1, w); ++ wh = jmax (1, h); ++ ++ if (! mapped) ++ { ++ // Make sure the Window manager does what we want ++ XSizeHints* hints = XAllocSizeHints(); ++ hints->flags = USSize | USPosition; ++ hints->width = ww + windowBorder.getLeftAndRight(); ++ hints->height = wh + windowBorder.getTopAndBottom(); ++ hints->x = wx - windowBorder.getLeft(); ++ hints->y = wy - windowBorder.getTop(); ++ XSetWMNormalHints (display, windowH, hints); ++ XFree (hints); ++ } ++ ++ XMoveResizeWindow (display, windowH, ++ wx - windowBorder.getLeft(), ++ wy - windowBorder.getTop(), ++ ww + windowBorder.getLeftAndRight(), ++ wh + windowBorder.getTopAndBottom()); ++ ++ if (! deletionChecker.hasBeenDeleted()) ++ { ++ updateBorderSize(); ++ handleMovedOrResized(); ++ } ++ } ++ } ++ ++ void getBounds (int& x, int& y, int& w, int& h) const ++ { ++ x = wx; ++ y = wy; ++ w = ww; ++ h = wh; ++ } ++ ++ int getScreenX() const ++ { ++ return wx; ++ } ++ ++ int getScreenY() const ++ { ++ return wy; ++ } ++ ++ void setMinimised (bool shouldBeMinimised) ++ { ++ if (shouldBeMinimised) ++ { ++ Window root = RootWindow (display, DefaultScreen (display)); ++ ++ XClientMessageEvent clientMsg; ++ clientMsg.display = display; ++ clientMsg.window = windowH; ++ clientMsg.type = ClientMessage; ++ clientMsg.format = 32; ++ clientMsg.message_type = wm_ChangeState; ++ clientMsg.data.l[0] = IconicState; ++ ++ XSendEvent (display, root, false, ++ SubstructureRedirectMask | SubstructureNotifyMask, ++ (XEvent*) &clientMsg); ++ } ++ else ++ { ++ setVisible (true); ++ } ++ } ++ ++ bool isMinimised() const ++ { ++ bool minimised = false; ++ ++ CARD32* stateProp; ++ unsigned long nitems, bytesLeft; ++ Atom actualType; ++ int actualFormat; ++ ++ if (XGetWindowProperty (display, windowH, wm_State, 0, 64, False, ++ wm_State, &actualType, &actualFormat, &nitems, &bytesLeft, ++ (unsigned char**) &stateProp) == Success ++ && actualType == wm_State ++ && actualFormat == 32 ++ && nitems > 0) ++ { ++ if (stateProp[0] == IconicState) ++ minimised = true; ++ ++ XFree (stateProp); ++ } ++ ++ return minimised; ++ } ++ ++ void setFullScreen (bool shouldBeFullScreen) ++ { ++ setMinimised (false); ++ ++ if (fullScreen != shouldBeFullScreen) ++ { ++ Rectangle r (lastNonFullscreenBounds); ++ ++ if (shouldBeFullScreen) ++ r = Desktop::getInstance().getMainMonitorArea(); ++ ++ if (! r.isEmpty()) ++ setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen); ++ ++ getComponent()->repaint(); ++ } ++ } ++ ++ bool isFullScreen() const ++ { ++ return fullScreen; ++ } ++ ++ bool isChildWindowOf (Window possibleParent) const ++ { ++ Window* windowList = 0; ++ uint32 windowListSize = 0; ++ Window parent, root; ++ ++ if (XQueryTree (display, windowH, &root, &parent, &windowList, &windowListSize) != 0) ++ { ++ if (windowList != 0) ++ XFree (windowList); ++ ++ return parent == possibleParent; ++ } ++ ++ return false; ++ } ++ ++ bool contains (int x, int y, bool trueIfInAChildWindow) const ++ { ++ jassert (x >= 0 && y >= 0 && x < ww && y < wh); // should only be called for points that are actually inside the bounds ++ ++ x += wx; ++ y += wy; ++ ++ // the XQueryTree stuff later on is VERY slow, so if this call's just to check the mouse pos, it's ++ // much more efficient to cheat.. ++ if (x == lastMousePosX && y == lastMousePosY) ++ { ++ Window root, child; ++ int winx, winy; ++ unsigned int mask; ++ ++ if (XQueryPointer (display, ++ RootWindow (display, DefaultScreen (display)), ++ &root, &child, ++ &x, &y, &winx, &winy, &mask) != False) ++ { ++ return child == windowH ++ || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (child)); ++ } ++ } ++ ++ bool result = false; ++ ++ Window* windowList = 0; ++ uint32 windowListSize = 0; ++ ++ Window parent, root = RootWindow (display, DefaultScreen (display)); ++ ++ if (XQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0) ++ { ++ for (int i = windowListSize; --i >= 0;) ++ { ++ XWindowAttributes atts; ++ ++ if (windowList[i] == windowH ++ || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (windowList[i]))) ++ { ++ result = true; ++ ++ if (! trueIfInAChildWindow) ++ { ++ Window child; ++ int tempX, tempY; ++ ++ result = XTranslateCoordinates (display, windowH, windowH, ++ x - wx - windowBorder.getLeft(), ++ y - wy - windowBorder.getTop(), ++ &tempX, &tempY, ++ &child) ++ && (child == None); ++ } ++ ++ break; ++ } ++ else if (XGetWindowAttributes (display, windowList[i], &atts) ++ && atts.map_state == IsViewable ++ && x >= atts.x && y >= atts.y ++ && x < atts.x + atts.width ++ && y < atts.y + atts.height) ++ { ++ break; ++ } ++ } ++ } ++ ++ if (windowList != 0) ++ XFree (windowList); ++ ++ return result; ++ } ++ ++ const BorderSize getFrameSize() const ++ { ++ return BorderSize(); ++ } ++ ++ bool setAlwaysOnTop (bool alwaysOnTop) ++ { ++ if (windowH != 0) ++ { ++ XSetWindowAttributes swa; ++ swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False; ++ ++ XChangeWindowAttributes (display, windowH, CWOverrideRedirect, &swa); ++ } ++ ++ return true; ++ } ++ ++ void toFront (bool makeActive) ++ { ++ if (makeActive) ++ { ++ setVisible (true); ++ grabFocus(); ++ } ++ ++ XEvent ev; ++ ev.xclient.type = ClientMessage; ++ ev.xclient.serial = 0; ++ ev.xclient.send_event = True; ++ ev.xclient.message_type = wm_ActiveWin; ++ ev.xclient.window = windowH; ++ ev.xclient.format = 32; ++ ev.xclient.data.l[0] = 2; ++ ev.xclient.data.l[1] = CurrentTime; ++ ev.xclient.data.l[2] = 0; ++ ev.xclient.data.l[3] = 0; ++ ev.xclient.data.l[4] = 0; ++ ++ XSendEvent (display, RootWindow (display, DefaultScreen (display)), ++ False, ++ SubstructureRedirectMask | SubstructureNotifyMask, ++ &ev); ++ ++ XSync (display, False); ++ } ++ ++ void toBehind (ComponentPeer* other) ++ { ++ LinuxComponentPeer* const otherPeer = dynamic_cast <LinuxComponentPeer*> (other); ++ jassert (otherPeer != 0); // wrong type of window? ++ ++ if (otherPeer != 0) ++ { ++ setMinimised (false); ++ ++ Window newStack[] = { otherPeer->windowH, windowH }; ++ ++ XRestackWindows (display, newStack, 2); ++ } ++ } ++ ++ bool isFocused() const ++ { ++ int revert; ++ Window focus = 0; ++ XGetInputFocus (display, &focus, &revert); ++ ++ if (focus == 0 || focus == None || focus == PointerRoot) ++ return 0; ++ ++ ComponentPeer* focusedPeer = 0; ++ if (XFindContext (display, (XID) focus, improbableNumber, (XPointer*) &focusedPeer) != 0) ++ focusedPeer = 0; ++ ++ return this == focusedPeer; ++ } ++ ++ void grabFocus() ++ { ++ XWindowAttributes atts; ++ ++ if (windowH != 0 ++ && XGetWindowAttributes (display, windowH, &atts) ++ && atts.map_state == IsViewable) ++ { ++ XSetInputFocus (display, windowH, RevertToParent, CurrentTime); ++ ++ if (! isActiveApplication) ++ { ++ isActiveApplication = true; ++ handleFocusGain(); ++ } ++ } ++ } ++ ++ void repaint (int x, int y, int w, int h) ++ { ++ repainter->invalidateCache (x, y, w, h); ++ repainter->repaint (x, y, w, h); ++ } ++ ++ void performPendingRepaints() ++ { ++ repainter->performPendingRepaints(); ++ } ++ ++ //============================================================================== ++ void handleWindowMessage (XEvent* event) ++ { ++ switch (event->xany.type) ++ { ++ case 2: // 'KeyPress' ++ { ++ XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey; ++ updateKeyStates (keyEvent->keycode, true); ++ ++ int index = currentModifiers & ModifierKeys::shiftModifier ? 1 : 0; ++ KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, index); ++ ++ const int oldMods = currentModifiers; ++ bool keyPressed = false; ++ ++ const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); ++ ++ if ((sym & 0xff00) == 0xff00) ++ { ++ // Translate keypad ++ if (sym == XK_KP_Divide) ++ sym = XK_slash; ++ else if (sym == XK_KP_Multiply) ++ sym = XK_asterisk; ++ else if (sym == XK_KP_Subtract) ++ sym = XK_hyphen; ++ else if (sym == XK_KP_Add) ++ sym = XK_plus; ++ else if (sym == XK_KP_Enter) ++ sym = XK_Return; ++ else if (sym == XK_KP_Decimal) ++ sym = numLock ? XK_period : XK_Delete; ++ else if (sym == XK_KP_0) ++ sym = numLock ? XK_0 : XK_Insert; ++ else if (sym == XK_KP_1) ++ sym = numLock ? XK_1 : XK_End; ++ else if (sym == XK_KP_2) ++ sym = numLock ? XK_2 : XK_Down; ++ else if (sym == XK_KP_3) ++ sym = numLock ? XK_3 : XK_Page_Down; ++ else if (sym == XK_KP_4) ++ sym = numLock ? XK_4 : XK_Left; ++ else if (sym == XK_KP_5) ++ sym = XK_5; ++ else if (sym == XK_KP_6) ++ sym = numLock ? XK_6 : XK_Right; ++ else if (sym == XK_KP_7) ++ sym = numLock ? XK_7 : XK_Home; ++ else if (sym == XK_KP_8) ++ sym = numLock ? XK_8 : XK_Up; ++ else if (sym == XK_KP_9) ++ sym = numLock ? XK_9 : XK_Page_Up; ++ ++ switch (sym) ++ { ++ case XK_Left: ++ case XK_Right: ++ case XK_Up: ++ case XK_Down: ++ case XK_Page_Up: ++ case XK_Page_Down: ++ case XK_End: ++ case XK_Home: ++ case XK_Delete: ++ case XK_Insert: ++ keyPressed = true; ++ sym = (sym & 0xff) | nonAsciiModifier; ++ break; ++ case XK_Tab: ++ case XK_Return: ++ case XK_Escape: ++ case XK_BackSpace: ++ keyPressed = true; ++ sym &= 0xff; ++ break; ++ default: ++ { ++ if (sym >= XK_F1 && sym <= XK_F12) ++ { ++ keyPressed = true; ++ sym = (sym & 0xff) | nonAsciiModifier; ++ } ++ break; ++ } ++ } ++ } ++ ++ if ((sym & 0xff00) == 0 && sym >= 8) ++ keyPressed = true; ++ ++ if (capsLock && ((sym >= XK_A && sym <= XK_Z) || (sym >= XK_a && sym <= XK_z))) ++ { ++ index ^= 1; ++ sym = XKeycodeToKeysym (display, keyEvent->keycode, index); ++ } ++ ++ if (oldMods != currentModifiers) ++ handleModifierKeysChange(); ++ ++ if (keyDownChange) ++ handleKeyUpOrDown(); ++ ++ if (keyPressed) ++ handleKeyPress (sym); ++ ++ break; ++ } ++ ++ case KeyRelease: ++ { ++ XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey; ++ updateKeyStates (keyEvent->keycode, false); ++ ++ KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0); ++ ++ const int oldMods = currentModifiers; ++ const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); ++ ++ if (oldMods != currentModifiers) ++ handleModifierKeysChange(); ++ ++ if (keyDownChange) ++ handleKeyUpOrDown(); ++ ++ break; ++ } ++ ++ case ButtonPress: ++ { ++ XButtonPressedEvent* buttonPressEvent = (XButtonPressedEvent*) &event->xbutton; ++ ++ bool buttonMsg = false; ++ bool wheelUpMsg = false; ++ bool wheelDownMsg = false; ++ ++ const int map = pointerMap [buttonPressEvent->button - Button1]; ++ ++ if (map == LeftButton) ++ { ++ currentModifiers |= ModifierKeys::leftButtonModifier; ++ buttonMsg = true; ++ } ++ else if (map == RightButton) ++ { ++ currentModifiers |= ModifierKeys::rightButtonModifier; ++ buttonMsg = true; ++ } ++ else if (map == MiddleButton) ++ { ++ currentModifiers |= ModifierKeys::middleButtonModifier; ++ buttonMsg = true; ++ } ++ else if (map == WheelUp) ++ { ++ wheelUpMsg = true; ++ } ++ else if (map == WheelDown) ++ { ++ wheelDownMsg = true; ++ } ++ ++ updateKeyModifiers (buttonPressEvent->state); ++ ++ if (buttonMsg) ++ { ++ toFront (true); ++ handleMouseDown (buttonPressEvent->x, buttonPressEvent->y, ++ getEventTime (buttonPressEvent->time)); ++ } ++ else if (wheelUpMsg || wheelDownMsg) ++ { ++ handleMouseWheel (wheelDownMsg ? -84 : 84, ++ getEventTime (buttonPressEvent->time)); ++ } ++ ++ lastMousePosX = lastMousePosY = 0x100000; ++ break; ++ } ++ ++ case ButtonRelease: ++ { ++ XButtonReleasedEvent* buttonRelEvent = (XButtonReleasedEvent*) &event->xbutton; ++ ++ const int oldModifiers = currentModifiers; ++ const int map = pointerMap [buttonRelEvent->button - Button1]; ++ ++ if (map == LeftButton) ++ currentModifiers &= ~ModifierKeys::leftButtonModifier; ++ else if (map == RightButton) ++ currentModifiers &= ~ModifierKeys::rightButtonModifier; ++ else if (map == MiddleButton) ++ currentModifiers &= ~ModifierKeys::middleButtonModifier; ++ ++ updateKeyModifiers (buttonRelEvent->state); ++ ++ handleMouseUp (oldModifiers, ++ buttonRelEvent->x, buttonRelEvent->y, ++ getEventTime (buttonRelEvent->time)); ++ ++ lastMousePosX = lastMousePosY = 0x100000; ++ break; ++ } ++ ++ case MotionNotify: ++ { ++ XPointerMovedEvent* movedEvent = (XPointerMovedEvent*) &event->xmotion; ++ ++ updateKeyModifiers (movedEvent->state); ++ ++ int x, y, mouseMods; ++ getMousePos (x, y, mouseMods); ++ ++ if (lastMousePosX != x || lastMousePosY != y) ++ { ++ lastMousePosX = x; ++ lastMousePosY = y; ++ ++ x -= getScreenX(); ++ y -= getScreenY(); ++ ++ if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0) ++ handleMouseMove (x, y, getEventTime (movedEvent->time)); ++ else ++ handleMouseDrag (x, y, getEventTime (movedEvent->time)); ++ } ++ ++ break; ++ } ++ ++ case EnterNotify: ++ { ++ lastMousePosX = lastMousePosY = 0x100000; ++ XEnterWindowEvent* enterEvent = (XEnterWindowEvent*) &event->xcrossing; ++ ++ if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0 ++ && ! entered) ++ { ++ updateKeyModifiers (enterEvent->state); ++ ++ handleMouseEnter (enterEvent->x, enterEvent->y, getEventTime (enterEvent->time)); ++ ++ entered = true; ++ } ++ ++ break; ++ } ++ ++ case LeaveNotify: ++ { ++ XLeaveWindowEvent* leaveEvent = (XLeaveWindowEvent*) &event->xcrossing; ++ ++ // Suppress the normal leave if we've got a pointer grab, or if ++ // it's a bogus one caused by clicking a mouse button when running ++ // in a Window manager ++ if (((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0 ++ && leaveEvent->mode == NotifyNormal) ++ || leaveEvent->mode == NotifyUngrab) ++ { ++ updateKeyModifiers (leaveEvent->state); ++ ++ handleMouseExit (leaveEvent->x, leaveEvent->y, getEventTime (leaveEvent->time)); ++ ++ entered = false; ++ } ++ ++ break; ++ } ++ ++ case FocusIn: ++ { ++ isActiveApplication = true; ++ handleFocusGain(); ++ break; ++ } ++ ++ case FocusOut: ++ { ++ isActiveApplication = false; ++ handleFocusLoss(); ++ break; ++ } ++ ++ case Expose: ++ { ++ // Batch together all pending expose events ++ XExposeEvent* exposeEvent = (XExposeEvent*) &event->xexpose; ++ XEvent nextEvent; ++ ++ repaint (exposeEvent->x, exposeEvent->y, ++ exposeEvent->width, exposeEvent->height); ++ ++ while (XEventsQueued (display, QueuedAfterFlush) > 0) ++ { ++ XPeekEvent (display, (XEvent*) &nextEvent); ++ if (nextEvent.type != Expose || nextEvent.xany.window != event->xany.window) ++ break; ++ ++ XNextEvent (display, (XEvent*)&nextEvent); ++ XExposeEvent* nextExposeEvent = (XExposeEvent*)(&nextEvent.xexpose); ++ repaint (nextExposeEvent->x, nextExposeEvent->y, ++ nextExposeEvent->width, nextExposeEvent->height); ++ } ++ ++ break; ++ } ++ ++ case CreateNotify: ++ case DestroyNotify: ++ // Think we can ignore these ++ break; ++ ++ case CirculateNotify: ++ break; ++ ++ case ConfigureNotify: ++ case ReparentNotify: ++ case GravityNotify: ++ updateBounds(); ++ break; ++ ++ case MapNotify: ++ mapped = true; ++ handleBroughtToFront(); ++ break; ++ ++ case UnmapNotify: ++ mapped = false; ++ break; ++ ++ case MappingNotify: ++ { ++ XMappingEvent* mappingEvent = (XMappingEvent*) &event->xmapping; ++ ++ if (mappingEvent->request != MappingPointer) ++ { ++ // Deal with modifier/keyboard mapping ++ XRefreshKeyboardMapping (mappingEvent); ++ getModifierMapping(); ++ } ++ ++ break; ++ } ++ ++ case ClientMessage: ++ { ++ XClientMessageEvent* clientMsg = (XClientMessageEvent*) &event->xclient; ++ ++ if (clientMsg->message_type == wm_Protocols && clientMsg->format == 32) ++ { ++ const Atom atom = (Atom) clientMsg->data.l[0]; ++ ++ if (atom == wm_ProtocolList [TAKE_FOCUS]) ++ { ++ XWindowAttributes atts; ++ ++ if (clientMsg->window != 0 ++ && XGetWindowAttributes (display, clientMsg->window, &atts)) ++ { ++ if (atts.map_state == IsViewable) ++ XSetInputFocus (display, clientMsg->window, RevertToParent, clientMsg->data.l[1]); ++ } ++ } ++ else if (atom == wm_ProtocolList [DELETE_WINDOW]) ++ { ++ handleUserClosingWindow(); ++ } ++ } ++ else if (clientMsg->message_type == repaintId) ++ { ++ // Get rid of all pending repaint events ++ XEvent nextEvent; ++ ++ while (XEventsQueued (display, QueuedAfterFlush) > 0) ++ { ++ XPeekEvent (display, &nextEvent); ++ if (nextEvent.xany.type != ClientMessage || ++ nextEvent.xany.window != event->xany.window) ++ break; ++ ++ XClientMessageEvent* nextClientMsg = (XClientMessageEvent*) (&nextEvent.xclient); ++ if (nextClientMsg->message_type != repaintId) ++ break; ++ ++ XNextEvent (display, &nextEvent); ++ } ++ ++ static bool reentrancyCheck = false; ++ if (! reentrancyCheck) ++ { ++ reentrancyCheck = true; ++ ++ int ox, oy, ow, oh; ++ getBounds (ox, oy, ow, oh); ++ repaint (0, 0, ow, oh); ++ performPendingRepaints(); ++ ++ reentrancyCheck = false; ++ } ++ } ++ ++ break; ++ } ++ ++ case SelectionClear: ++ case SelectionNotify: ++ case SelectionRequest: ++ // We shouldn't get these on normal windows ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ void showMouseCursor (Cursor cursor) ++ { ++ XDefineCursor (display, windowH, cursor); ++ } ++ ++ //============================================================================== ++ juce_UseDebuggingNewOperator ++ ++ bool dontRepaint; ++ ++private: ++ //============================================================================== ++ class LinuxRepaintManager : public RepaintManager ++ { ++ public: ++ LinuxRepaintManager (LinuxComponentPeer* const peer_, ++ Component* const component, ++ const int timeBeforeReleasingImage) ++ : RepaintManager (component, timeBeforeReleasingImage), ++ peer (peer_) ++ { ++ } ++ ++ Image* createNewImage (int w, int h) ++ { ++ return new XBitmapImage (Image::RGB, w, h, false); ++ } ++ ++ void repaintNow (const RectangleList& areasToPaint) ++ { ++ peer->clearMaskedRegion(); ++ ++ renderCacheAreasNeedingRepaint(); ++ ++ int x, y; ++ XBitmapImage* const paintingBuffer = (XBitmapImage*) getImage (x, y); ++ ++ if (paintingBuffer != 0) ++ { ++ const RectangleList* repaintRegion = &areasToPaint; ++ RectangleList temp; ++ ++ if (! peer->maskedRegion.isEmpty()) ++ { ++ temp = areasToPaint; ++ temp.subtract (peer->maskedRegion); ++ repaintRegion = &temp; ++ } ++ ++ for (RectangleList::Iterator i (*repaintRegion); i.next();) ++ { ++ const Rectangle& r = i.getRectangle(); ++ ++ paintingBuffer->blitToWindow (peer->windowH, ++ r.getX(), r.getY(), r.getWidth(), r.getHeight(), ++ r.getX() - x, r.getY() - y); ++ } ++ } ++ } ++ ++ private: ++ LinuxComponentPeer* const peer; ++ ++ LinuxRepaintManager (const LinuxRepaintManager&); ++ const LinuxRepaintManager& operator= (const LinuxRepaintManager&); ++ }; ++ ++ LinuxRepaintManager* repainter; ++ ++ friend class LinuxRepaintManager; ++ Window windowH; ++ int wx, wy, ww, wh; ++ bool fullScreen, entered, mapped; ++ BorderSize windowBorder; ++ ++ //============================================================================== ++ void removeWindowDecorations (Window wndH) ++ { ++ Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True); ++ ++ if (hints != None) ++ { ++ typedef struct ++ { ++ CARD32 flags; ++ CARD32 functions; ++ CARD32 decorations; ++ INT32 input_mode; ++ CARD32 status; ++ } MotifWmHints; ++ ++ MotifWmHints motifHints; ++ motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */ ++ motifHints.decorations = 0; ++ ++ XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace, ++ (unsigned char*) &motifHints, 4); ++ } ++ ++ hints = XInternAtom (display, "_WIN_HINTS", True); ++ ++ if (hints != None) ++ { ++ long gnomeHints = 0; ++ ++ XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace, ++ (unsigned char*) &gnomeHints, 1); ++ } ++ ++ hints = XInternAtom (display, "KWM_WIN_DECORATION", True); ++ ++ if (hints != None) ++ { ++ long kwmHints = 2; /*KDE_tinyDecoration*/ ++ ++ XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace, ++ (unsigned char*) &kwmHints, 1); ++ } ++ ++ hints = XInternAtom (display, "_NET_WM_WINDOW_TYPE", True); ++ ++ if (hints != None) ++ { ++ Atom netHints [2]; ++ netHints[0] = XInternAtom (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True); ++ ++ if ((styleFlags & windowIsTemporary) != 0) ++ netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_MENU", True); ++ else ++ netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_NORMAL", True); ++ ++ XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace, ++ (unsigned char*) &netHints, 2); ++ } ++ } ++ ++ void addWindowButtons (Window wndH) ++ { ++ Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True); ++ ++ if (hints != None) ++ { ++ typedef struct ++ { ++ CARD32 flags; ++ CARD32 functions; ++ CARD32 decorations; ++ INT32 input_mode; ++ CARD32 status; ++ } MotifWmHints; ++ ++ MotifWmHints motifHints; ++ ++ motifHints.flags = 1 | 2; /* MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS */ ++ motifHints.decorations = 2 /* MWM_DECOR_BORDER */ | 8 /* MWM_DECOR_TITLE */ | 16; /* MWM_DECOR_MENU */ ++ ++ motifHints.functions = 4 /* MWM_FUNC_MOVE */; ++ ++ if ((styleFlags & windowHasCloseButton) != 0) ++ motifHints.functions |= 32; /* MWM_FUNC_CLOSE */ ++ ++ if ((styleFlags & windowHasMinimiseButton) != 0) ++ { ++ motifHints.functions |= 8; /* MWM_FUNC_MINIMIZE */ ++ motifHints.decorations |= 0x20; /* MWM_DECOR_MINIMIZE */ ++ } ++ ++ if ((styleFlags & windowHasMaximiseButton) != 0) ++ { ++ motifHints.functions |= 0x10; /* MWM_FUNC_MAXIMIZE */ ++ motifHints.decorations |= 0x40; /* MWM_DECOR_MAXIMIZE */ ++ } ++ ++ if ((styleFlags & windowIsResizable) != 0) ++ { ++ motifHints.functions |= 2; /* MWM_FUNC_RESIZE */ ++ motifHints.decorations |= 0x4; /* MWM_DECOR_RESIZEH */ ++ } ++ ++ XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace, ++ (unsigned char*) &motifHints, 4); ++ } ++ ++ hints = XInternAtom (display, "_NET_WM_ALLOWED_ACTIONS", True); ++ ++ if (hints != None) ++ { ++ Atom netHints [6]; ++ int num = 0; ++ ++ netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_RESIZE", (styleFlags & windowIsResizable) ? True : False); ++ netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_FULLSCREEN", (styleFlags & windowHasMaximiseButton) ? True : False); ++ netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_MINIMIZE", (styleFlags & windowHasMinimiseButton) ? True : False); ++ netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_CLOSE", (styleFlags & windowHasCloseButton) ? True : False); ++ ++ XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace, ++ (unsigned char*) &netHints, num); ++ } ++ } ++ ++ static void* createWindowCallback (void* userData) ++ { ++ ((LinuxComponentPeer*) userData)->createWindow(); ++ return 0; ++ } ++ ++ void createWindow() ++ { ++ static bool atomsInitialised = false; ++ ++ if (! atomsInitialised) ++ { ++ atomsInitialised = true; ++ ++ wm_Protocols = XInternAtom (display, "WM_PROTOCOLS", 1); ++ wm_ProtocolList [TAKE_FOCUS] = XInternAtom (display, "WM_TAKE_FOCUS", 1); ++ wm_ProtocolList [DELETE_WINDOW] = XInternAtom (display, "WM_DELETE_WINDOW", 1); ++ wm_ChangeState = XInternAtom (display, "WM_CHANGE_STATE", 1); ++ wm_State = XInternAtom (display, "WM_STATE", 1); ++ wm_ActiveWin = XInternAtom (display, "_NET_ACTIVE_WINDOW", False); ++ repaintId = XInternAtom (display, "JUCERepaintAtom", 1); ++ } ++ ++ // Get defaults for various properties ++ const int screen = DefaultScreen (display); ++ Window root = RootWindow (display, screen); ++ ++ // Attempt to create a 24-bit window on the default screen. If this is not ++ // possible then exit ++ XVisualInfo desiredVisual; ++ desiredVisual.screen = screen; ++ desiredVisual.depth = 24; ++ ++ int numVisuals; ++ XVisualInfo* visuals = XGetVisualInfo (display, VisualScreenMask | VisualDepthMask, ++ &desiredVisual, &numVisuals); ++ ++ if (numVisuals < 1 || visuals == 0) ++ { ++ Logger::outputDebugString ("ERROR: System doesn't support 24-bit RGB display.\n"); ++ Process::terminate(); ++ } ++ ++ // Just choose the first one ++ Visual* visual = visuals[0].visual; ++ const int depth = visuals[0].depth; ++ XFree (visuals); ++ ++ // Set up the window attributes ++ XSetWindowAttributes swa; ++ swa.border_pixel = 0; ++ swa.colormap = DefaultColormap (display, screen); ++ swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False; ++ swa.event_mask = eventMask; ++ ++ Window wndH = XCreateWindow (display, root, ++ 0, 0, 1, 1, 0, ++ depth, InputOutput, visual, ++ CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, ++ &swa); ++ ++ XGrabButton (display, AnyButton, AnyModifier, wndH, False, ++ ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask, ++ GrabModeAsync, GrabModeAsync, None, None); ++ ++ // Set the window context to identify the window handle object ++ if (XSaveContext (display, (XID) wndH, improbableNumber, (XPointer) this)) ++ { ++ // Failed ++ jassertfalse ++ Logger::outputDebugString ("Failed to create context information for window.\n"); ++ XDestroyWindow (display, wndH); ++ wndH = 0; ++ } ++ ++ // Set window manager hints ++ XWMHints* wmHints = XAllocWMHints(); ++ wmHints->flags = InputHint | StateHint; ++ wmHints->input = True; // Locally active input model ++ wmHints->initial_state = NormalState; ++ XSetWMHints (display, wndH, wmHints); ++ XFree (wmHints); ++ ++ if ((styleFlags & juce_windowIsSemiTransparentFlag) != 0) ++ { ++ //xxx ++ jassertfalse ++ } ++ ++ if ((styleFlags & windowAppearsOnTaskbar) != 0) ++ { ++ //xxx ++ } ++ ++ if ((styleFlags & windowHasTitleBar) == 0) ++ removeWindowDecorations (wndH); ++ else ++ addWindowButtons (wndH); ++ ++ XSetTransientForHint (display, wndH, RootWindow (display, DefaultScreen (display))); ++ ++ // Set window manager protocols ++ XChangeProperty (display, wndH, wm_Protocols, XA_ATOM, 32, PropModeReplace, ++ (unsigned char*) wm_ProtocolList, 2); ++ ++ // Set window name ++ setWindowTitle (wndH, getComponent()->getName()); ++ ++ // Initialise the pointer and keyboard mapping ++ // This is not the same as the logical pointer mapping the X server uses: ++ // we don't mess with this. ++ static bool mappingInitialised = false; ++ ++ if (! mappingInitialised) ++ { ++ mappingInitialised = true; ++ ++ const int numButtons = XGetPointerMapping (display, 0, 0); ++ ++ if (numButtons == 2) ++ { ++ pointerMap[0] = LeftButton; ++ pointerMap[1] = RightButton; ++ pointerMap[2] = pointerMap[3] = pointerMap[4] = NoButton; ++ } ++ else if (numButtons >= 3) ++ { ++ pointerMap[0] = LeftButton; ++ pointerMap[1] = MiddleButton; ++ pointerMap[2] = RightButton; ++ ++ if (numButtons >= 5) ++ { ++ pointerMap[3] = WheelUp; ++ pointerMap[4] = WheelDown; ++ } ++ } ++ ++ getModifierMapping(); ++ } ++ ++ windowH = wndH; ++ } ++ ++ static void* destroyWindowCallback (void* userData) ++ { ++ Window windowH = (Window) userData; ++ ++ XPointer handlePointer; ++ if (! XFindContext (display, (XID) windowH, improbableNumber, &handlePointer)) ++ XDeleteContext (display, (XID) windowH, improbableNumber); ++ ++ XDestroyWindow (display, windowH); ++ ++ // Wait for it to complete and then remove any events for this ++ // window from the event queue. ++ XSync (display, false); ++ ++ XEvent event; ++ while (XCheckWindowEvent (display, windowH, eventMask, &event) == True) ++ {} ++ ++ return 0; ++ } ++ ++ static int64 getEventTime (::Time t) ++ { ++ static int64 eventTimeOffset = 0x12345678; ++ const int64 thisMessageTime = t; ++ ++ if (eventTimeOffset == 0x12345678) ++ eventTimeOffset = Time::currentTimeMillis() - thisMessageTime; ++ ++ return eventTimeOffset + thisMessageTime; ++ } ++ ++ static void setWindowTitle (Window xwin, const char* const title) ++ { ++ XTextProperty nameProperty; ++ char* strings[] = { (char*) title }; ++ ++ if (XStringListToTextProperty (strings, 1, &nameProperty)) ++ { ++ XSetWMName (display, xwin, &nameProperty); ++ XSetWMIconName (display, xwin, &nameProperty); ++ } ++ } ++ ++ void updateBorderSize() ++ { ++ if ((styleFlags & windowHasTitleBar) == 0) ++ { ++ windowBorder = BorderSize (0); ++ } ++ else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0) ++ { ++ Atom hints = XInternAtom (display, "_NET_FRAME_EXTENTS", True); ++ ++ if (hints != None) ++ { ++ CARD32* sizes = 0; ++ unsigned long nitems, bytesLeft; ++ Atom actualType; ++ int actualFormat; ++ ++ if (XGetWindowProperty (display, windowH, hints, 0, 4, False, ++ XA_CARDINAL, &actualType, &actualFormat, &nitems, &bytesLeft, ++ (unsigned char**) &sizes) == Success) ++ { ++ if (actualFormat == 32) ++ windowBorder = BorderSize ((int) sizes[2], (int) sizes[0], ++ (int) sizes[3], (int) sizes[1]); ++ ++ XFree (sizes); ++ } ++ } ++ } ++ } ++ ++ void updateBounds() ++ { ++ jassert (windowH != 0); ++ if (windowH != 0) ++ { ++ Window root, child; ++ unsigned int bw, depth; ++ ++ if (! XGetGeometry (display, (Drawable) windowH, &root, ++ &wx, &wy, (unsigned int*) &ww, (unsigned int*) &wh, ++ &bw, &depth)) ++ { ++ wx = wy = ww = wh = 0; ++ } ++ else if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child)) ++ { ++ wx = wy = 0; ++ } ++ ++ updateBorderSize(); ++ handleMovedOrResized(); ++ } ++ } ++}; ++ ++//============================================================================== ++ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) ++{ ++ return new LinuxComponentPeer (this, styleFlags); ++} ++ ++ ++//============================================================================== ++// (this callback is hooked up in the messaging code) ++void juce_windowMessageReceive (XEvent* event) ++{ ++ if (event->xany.window != None) ++ { ++ // Check if the event is for one of our windows ++ LinuxComponentPeer* peer = 0; ++ ++ if (! XFindContext (display, (XID) event->xany.window, improbableNumber, (XPointer*) &peer)) ++ { ++ if (peer != 0 && peer->isValidMessageListener()) ++ peer->handleWindowMessage (event); ++ } ++ } ++ else ++ { ++ switch (event->xany.type) ++ { ++ case KeymapNotify: ++ { ++ const XKeymapEvent* const keymapEvent = (const XKeymapEvent*) &event->xkeymap; ++ memcpy (keyStates, keymapEvent->key_vector, 32); ++ break; ++ } ++ ++ default: ++ break; ++ } ++ } ++} ++ ++//============================================================================== ++void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea) ++{ ++#if JUCE_USE_XINERAMA ++ int major_opcode, first_event, first_error; ++ ++ if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error) ++ && XineramaIsActive (display)) ++ { ++ int numMonitors = 0; ++ XineramaScreenInfo* const screens = XineramaQueryScreens (display, &numMonitors); ++ ++ if (screens != 0) ++ { ++ for (int i = numMonitors; --i >= 0;) ++ { ++ int index = screens[i].screen_number; ++ ++ if (index >= 0) ++ { ++ while (monitorCoords.size() < index) ++ monitorCoords.add (Rectangle (0, 0, 0, 0)); ++ ++ monitorCoords.set (index, Rectangle (screens[i].x_org, ++ screens[i].y_org, ++ screens[i].width, ++ screens[i].height)); ++ } ++ } ++ ++ XFree (screens); ++ } ++ } ++ ++ if (monitorCoords.size() == 0) ++#endif ++ { ++ monitorCoords.add (Rectangle (0, 0, ++ DisplayWidth (display, DefaultScreen (display)), ++ DisplayHeight (display, DefaultScreen (display)))); ++ } ++} ++ ++//============================================================================== ++bool Desktop::canUseSemiTransparentWindows() ++{ ++ return false; ++} ++ ++void Desktop::getMousePosition (int& x, int& y) ++{ ++ int mouseMods; ++ getMousePos (x, y, mouseMods); ++} ++ ++void Desktop::setMousePosition (int x, int y) ++{ ++ Window root = RootWindow (display, DefaultScreen (display)); ++ XWarpPointer (display, None, root, 0, 0, 0, 0, x, y); ++} ++ ++ ++//============================================================================== ++void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) ++{ ++ Window root = RootWindow (display, DefaultScreen (display)); ++ const unsigned int imageW = image.getWidth(); ++ const unsigned int imageH = image.getHeight(); ++ unsigned int cursorW, cursorH; ++ ++ if (! XQueryBestCursor (display, root, imageW, imageH, &cursorW, &cursorH)) ++ return 0; ++ ++ Image im (Image::ARGB, cursorW, cursorH, true); ++ Graphics g (im); ++ ++ if (imageW > cursorW || imageH > cursorH) ++ { ++ hotspotX = (hotspotX * cursorW) / imageW; ++ hotspotY = (hotspotY * cursorH) / imageH; ++ ++ g.drawImageWithin (&image, 0, 0, imageW, imageH, ++ Justification::topLeft, ++ false, false); ++ } ++ else ++ { ++ g.drawImageAt (&image, 0, 0); ++ } ++ ++ const int stride = (cursorW + 7) >> 3; ++ unsigned char* const maskPlane = (unsigned char*)juce_calloc (stride*cursorH); ++ unsigned char* const sourcePlane = (unsigned char*)juce_calloc (stride*cursorH); ++ ++ bool msbfirst = (BitmapBitOrder (display) == MSBFirst); ++ ++ for (int y = cursorH; --y >= 0;) ++ { ++ for (int x = cursorW; --x >= 0;) ++ { ++ const unsigned char mask = (unsigned char)(1 << (msbfirst ? (7 - (x & 7)) : (x & 7))); ++ const int offset = y * stride + (x >> 3); ++ ++ const Colour c (im.getPixelAt (x, y)); ++ ++ if (c.getAlpha() >= 128) ++ maskPlane[offset] |= mask; ++ ++ if (c.getBrightness() >= 0.5f) ++ sourcePlane[offset] |= mask; ++ } ++ } ++ ++ Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, (char*)sourcePlane, cursorW, cursorH, 0xffff, 0, 1); ++ Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, (char*)maskPlane, cursorW, cursorH, 0xffff, 0, 1); ++ ++ juce_free (maskPlane); ++ juce_free (sourcePlane); ++ ++ XColor white, black; ++ black.red = black.green = black.blue = 0; ++ white.red = white.green = white.blue = 0xffff; ++ ++ void* result = (void*) XCreatePixmapCursor (display, sourcePixmap, maskPixmap, &white, &black, hotspotX, hotspotY); ++ ++ XFreePixmap (display, sourcePixmap); ++ XFreePixmap (display, maskPixmap); ++ ++ return result; ++} ++ ++void juce_deleteMouseCursor (void* cursorHandle, bool) ++{ ++ if (cursorHandle != None) ++ XFreeCursor (display, (Cursor)cursorHandle); ++} ++ ++void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) ++{ ++ unsigned int shape; ++ ++ switch (type) ++ { ++ case MouseCursor::NoCursor: ++ { ++ void* invisibleCursor; ++ ++ Image im (Image::ARGB, 16, 16, true); ++ invisibleCursor = juce_createMouseCursorFromImage (im, 0, 0); ++ ++ return invisibleCursor; ++ } ++ ++ case MouseCursor::NormalCursor: ++ return (void*) None; // Use parent cursor ++ ++ case MouseCursor::DraggingHandCursor: ++ { ++ void* dragHandCursor; ++ static unsigned char dragHandData[] = {71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0, ++ 0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0, ++ 16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39, ++ 132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217, ++ 247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; ++ const int dragHandDataSize = 99; ++ ++ Image* im = ImageFileFormat::loadFrom ((const char*) dragHandData, dragHandDataSize); ++ dragHandCursor = juce_createMouseCursorFromImage (*im, 8, 7); ++ delete im; ++ ++ return dragHandCursor; ++ } ++ ++ case MouseCursor::CopyingCursor: ++ { ++ void* copyCursor; ++ ++ static unsigned char copyCursorData[] = {71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0, ++ 128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0, ++ 21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111, ++ 78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174, ++ 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112, ++ 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 }; ++ const int copyCursorSize = 119; ++ ++ Image* im = ImageFileFormat::loadFrom ((const char*)copyCursorData, copyCursorSize); ++ copyCursor = juce_createMouseCursorFromImage (*im, 1, 3); ++ delete im; ++ ++ return copyCursor; ++ } ++ ++ case MouseCursor::WaitCursor: ++ shape = XC_watch; ++ break; ++ ++ case MouseCursor::IBeamCursor: ++ shape = XC_xterm; ++ break; ++ ++ case MouseCursor::PointingHandCursor: ++ shape = XC_hand2; ++ break; ++ ++ case MouseCursor::LeftRightResizeCursor: ++ shape = XC_sb_h_double_arrow; ++ break; ++ ++ case MouseCursor::UpDownResizeCursor: ++ shape = XC_sb_v_double_arrow; ++ break; ++ ++ case MouseCursor::UpDownLeftRightResizeCursor: ++ shape = XC_fleur; ++ break; ++ ++ case MouseCursor::TopEdgeResizeCursor: ++ shape = XC_top_side; ++ break; ++ ++ case MouseCursor::BottomEdgeResizeCursor: ++ shape = XC_bottom_side; ++ break; ++ ++ case MouseCursor::LeftEdgeResizeCursor: ++ shape = XC_left_side; ++ break; ++ ++ case MouseCursor::RightEdgeResizeCursor: ++ shape = XC_right_side; ++ break; ++ ++ case MouseCursor::TopLeftCornerResizeCursor: ++ shape = XC_top_left_corner; ++ break; ++ ++ case MouseCursor::TopRightCornerResizeCursor: ++ shape = XC_top_right_corner; ++ break; ++ ++ case MouseCursor::BottomLeftCornerResizeCursor: ++ shape = XC_bottom_left_corner; ++ break; ++ ++ case MouseCursor::BottomRightCornerResizeCursor: ++ shape = XC_bottom_right_corner; ++ break; ++ ++ case MouseCursor::CrosshairCursor: ++ shape = XC_crosshair; ++ break; ++ ++ default: ++ return (void*) None; // Use parent cursor ++ } ++ ++ return (void*) XCreateFontCursor (display, shape); ++} ++ ++void MouseCursor::showInWindow (ComponentPeer* peer) const ++{ ++ LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (peer); ++ ++ if (lp != 0) ++ lp->showMouseCursor ((Cursor) getHandle()); ++} ++ ++void MouseCursor::showInAllWindows() const ++{ ++ for (int i = ComponentPeer::getNumPeers(); --i >= 0;) ++ showInWindow (ComponentPeer::getPeer (i)); ++} ++ ++//============================================================================== ++Image* juce_createIconForFile (const File& file) ++{ ++ return 0; ++} ++ ++ ++//============================================================================== ++#if JUCE_OPENGL ++ ++struct OpenGLContextInfo ++{ ++ Window embeddedWindow; ++ GLXContext renderContext; ++}; ++ ++void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext) ++{ ++ XSync (display, False); ++ jassert (component != 0); ++ ++ if (component == 0) ++ return 0; ++ ++ LinuxComponentPeer* const peer ++ = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer()); ++ ++ if (peer == 0) ++ return 0; ++ ++ GLint attribList[] = ++ { ++ GLX_RGBA, ++ GLX_DOUBLEBUFFER, ++ GLX_RED_SIZE, 8, ++ GLX_GREEN_SIZE, 8, ++ GLX_BLUE_SIZE, 8, ++ GLX_ALPHA_SIZE, 8, ++ GLX_DEPTH_SIZE, 8, ++ None ++ }; ++ ++ XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribList); ++ ++ if (bestVisual == 0) ++ return 0; ++ ++ OpenGLContextInfo* const oc = new OpenGLContextInfo(); ++ ++ oc->renderContext = glXCreateContext (display, bestVisual, ++ (sharedContext != 0) ? ((OpenGLContextInfo*) sharedContext)->renderContext ++ : 0, ++ GL_TRUE); ++ ++ Window windowH = (Window) peer->getNativeHandle(); ++ ++ Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone); ++ XSetWindowAttributes swa; ++ swa.colormap = colourMap; ++ swa.border_pixel = 0; ++ swa.event_mask = StructureNotifyMask; ++ ++ oc->embeddedWindow = XCreateWindow (display, windowH, ++ 0, 0, 1, 1, 0, ++ bestVisual->depth, ++ InputOutput, ++ bestVisual->visual, ++ CWBorderPixel | CWColormap | CWEventMask, ++ &swa); ++ ++ XMapWindow (display, oc->embeddedWindow); ++ XFreeColormap (display, colourMap); ++ ++ XFree (bestVisual); ++ XSync (display, False); ++ ++ return oc; ++} ++ ++void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp) ++{ ++ jassert (context != 0); ++ OpenGLContextInfo* const oc = (OpenGLContextInfo*) context; ++ ++ XMoveResizeWindow (display, oc->embeddedWindow, ++ owner->getScreenX() - topComp->getScreenX(), ++ owner->getScreenY() - topComp->getScreenY(), ++ jmax (1, owner->getWidth()), ++ jmax (1, owner->getHeight())); ++} ++ ++void juce_deleteOpenGLContext (void* context) ++{ ++ OpenGLContextInfo* const oc = (OpenGLContextInfo*) context; ++ ++ if (oc != 0) ++ { ++ glXDestroyContext (display, oc->renderContext); ++ ++ XUnmapWindow (display, oc->embeddedWindow); ++ XDestroyWindow (display, oc->embeddedWindow); ++ ++ delete oc; ++ } ++} ++ ++bool juce_makeOpenGLContextCurrent (void* context) ++{ ++ OpenGLContextInfo* const oc = (OpenGLContextInfo*) context; ++ ++ if (oc != 0) ++ return glXMakeCurrent (display, oc->embeddedWindow, oc->renderContext) ++ && XSync (display, False); ++ else ++ return glXMakeCurrent (display, None, 0); ++} ++ ++void juce_swapOpenGLBuffers (void* context) ++{ ++ OpenGLContextInfo* const oc = (OpenGLContextInfo*) context; ++ ++ if (oc != 0) ++ glXSwapBuffers (display, oc->embeddedWindow); ++} ++ ++void juce_repaintOpenGLWindow (void* context) ++{ ++} ++ ++#endif ++ ++ ++//============================================================================== ++static void initClipboard (Window root, Atom* cutBuffers) ++{ ++ static bool init = false; ++ ++ if (! init) ++ { ++ init = true; ++ ++ // Make sure all cut buffers exist before use ++ for (int i = 0; i < 8; i++) ++ { ++ XChangeProperty (display, root, cutBuffers[i], ++ XA_STRING, 8, PropModeAppend, NULL, 0); ++ } ++ } ++} ++ ++// Clipboard implemented currently using cut buffers ++// rather than the more powerful selection method ++void SystemClipboard::copyTextToClipboard (const String& clipText) ++{ ++ Window root = RootWindow (display, DefaultScreen (display)); ++ Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3, ++ XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 }; ++ ++ initClipboard (root, cutBuffers); ++ ++ XRotateWindowProperties (display, root, cutBuffers, 8, 1); ++ XChangeProperty (display, root, cutBuffers[0], ++ XA_STRING, 8, PropModeReplace, (const unsigned char*)((const char*)clipText), ++ clipText.length()); ++} ++ ++const String SystemClipboard::getTextFromClipboard() ++{ ++ char* clipData; ++ const int bufSize = 64; // in words ++ int actualFormat; ++ int byteOffset = 0; ++ unsigned long bytesLeft, nitems; ++ Atom actualType; ++ String returnData; ++ ++ Window root = RootWindow (display, DefaultScreen (display)); ++ ++ Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3, ++ XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 }; ++ ++ initClipboard (root, cutBuffers); ++ ++ do ++ { ++ if (XGetWindowProperty (display, root, cutBuffers[0], byteOffset >> 2, bufSize, ++ False, XA_STRING, &actualType, &actualFormat, &nitems, &bytesLeft, ++ (unsigned char**) &clipData) != Success ++ || actualType != XA_STRING ++ || actualFormat != 8) ++ return String(); ++ ++ byteOffset += nitems; ++ returnData += String(clipData, nitems); ++ XFree (clipData); ++ } ++ while (bytesLeft); ++ ++ return returnData; ++} ++ ++//============================================================================== ++bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) ++{ ++ jassertfalse // not implemented! ++ return false; ++} ++ ++bool DragAndDropContainer::performExternalDragDropOfText (const String& text) ++{ ++ jassertfalse // not implemented! ++ return false; ++} ++ ++ ++//============================================================================== ++void PlatformUtilities::beep() ++{ ++ //xxx ++} ++ ++ ++//============================================================================== ++bool AlertWindow::showNativeDialogBox (const String& title, ++ const String& bodyText, ++ bool isOkCancel) ++{ ++ // xxx this is supposed to pop up an alert! ++ Logger::outputDebugString (title + ": " + bodyText); ++ return true; ++} ++ ++//============================================================================== ++const int KeyPress::spaceKey = XK_space & 0xff; ++const int KeyPress::returnKey = XK_Return & 0xff; ++const int KeyPress::escapeKey = XK_Escape & 0xff; ++const int KeyPress::backspaceKey = XK_BackSpace & 0xff; ++const int KeyPress::leftKey = (XK_Left & 0xff) | nonAsciiModifier; ++const int KeyPress::rightKey = (XK_Right & 0xff) | nonAsciiModifier; ++const int KeyPress::upKey = (XK_Up & 0xff) | nonAsciiModifier; ++const int KeyPress::downKey = (XK_Down & 0xff) | nonAsciiModifier; ++const int KeyPress::pageUpKey = (XK_Page_Up & 0xff) | nonAsciiModifier; ++const int KeyPress::pageDownKey = (XK_Page_Down & 0xff) | nonAsciiModifier; ++const int KeyPress::endKey = (XK_End & 0xff) | nonAsciiModifier; ++const int KeyPress::homeKey = (XK_Home & 0xff) | nonAsciiModifier; ++const int KeyPress::insertKey = (XK_Insert & 0xff) | nonAsciiModifier; ++const int KeyPress::deleteKey = (XK_Delete & 0xff) | nonAsciiModifier; ++const int KeyPress::tabKey = XK_Tab & 0xff; ++const int KeyPress::F1Key = (XK_F1 & 0xff) | nonAsciiModifier; ++const int KeyPress::F2Key = (XK_F2 & 0xff) | nonAsciiModifier; ++const int KeyPress::F3Key = (XK_F3 & 0xff) | nonAsciiModifier; ++const int KeyPress::F4Key = (XK_F4 & 0xff) | nonAsciiModifier; ++const int KeyPress::F5Key = (XK_F5 & 0xff) | nonAsciiModifier; ++const int KeyPress::F6Key = (XK_F6 & 0xff) | nonAsciiModifier; ++const int KeyPress::F7Key = (XK_F7 & 0xff) | nonAsciiModifier; ++const int KeyPress::F8Key = (XK_F8 & 0xff) | nonAsciiModifier; ++const int KeyPress::F9Key = (XK_F9 & 0xff) | nonAsciiModifier; ++const int KeyPress::F10Key = (XK_F10 & 0xff) | nonAsciiModifier; ++const int KeyPress::F11Key = (XK_F11 & 0xff) | nonAsciiModifier; ++const int KeyPress::F12Key = (XK_F12 & 0xff) | nonAsciiModifier; ++const int KeyPress::playKey = (0xffeeff00) | nonAsciiModifier; ++const int KeyPress::stopKey = (0xffeeff01) | nonAsciiModifier; ++const int KeyPress::fastForwardKey = (0xffeeff02) | nonAsciiModifier; ++const int KeyPress::rewindKey = (0xffeeff03) | nonAsciiModifier; ++ ++ ++END_JUCE_NAMESPACE ++ ++#endif diff --git a/packages/juce/files/remove-x86isms.patch b/packages/juce/files/remove-x86isms.patch new file mode 100644 index 0000000000..83016f733a --- /dev/null +++ b/packages/juce/files/remove-x86isms.patch @@ -0,0 +1,2353 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- juce/src/juce_core/basics/juce_Atomic.h~remove-x86isms.patch ++++ juce/src/juce_core/basics/juce_Atomic.h +@@ -1,188 +1,200 @@ +-/*
+- ==============================================================================
+-
+- This file is part of the JUCE library - "Jules' Utility Class Extensions"
+- Copyright 2004-6 by Raw Material Software ltd.
+-
+- ------------------------------------------------------------------------------
+-
+- JUCE can be redistributed and/or modified 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.
+-
+- JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
+- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+- Boston, MA 02111-1307 USA
+-
+- ------------------------------------------------------------------------------
+-
+- If you'd like to release a closed-source product which uses JUCE, commercial
+- licenses are also available: visit www.rawmaterialsoftware.com/juce for
+- more information.
+-
+- ==============================================================================
+-*/
+-
+-#ifndef __JUCE_ATOMIC_JUCEHEADER__
+-#define __JUCE_ATOMIC_JUCEHEADER__
+-
+-// Atomic increment/decrement operations..
+-
+-//==============================================================================
+-#if JUCE_MAC && ! DOXYGEN
+- #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+- #include <libkern/OSAtomic.h>
+-
+- forcedinline void atomicIncrement (int& variable) throw()
+- {
+- OSAtomicIncrement32 ((int32_t*) &variable);
+- }
+-
+- forcedinline int atomicIncrementAndReturn (int& variable) throw()
+- {
+- return OSAtomicIncrement32 ((int32_t*) &variable);
+- }
+-
+- forcedinline void atomicDecrement (int& variable) throw()
+- {
+- OSAtomicDecrement32 ((int32_t*) &variable);
+- }
+-
+- forcedinline int atomicDecrementAndReturn (int& variable) throw()
+- {
+- return OSAtomicDecrement32 ((int32_t*) &variable);
+- }
+-
+- #else
+- forcedinline void atomicIncrement (int& variable) throw()
+- {
+- OTAtomicAdd32 (1, (SInt32*) &variable);
+- }
+-
+- forcedinline int atomicIncrementAndReturn (int& variable) throw()
+- {
+- return OTAtomicAdd32 (1, (SInt32*) &variable);
+- }
+-
+- forcedinline void atomicDecrement (int& variable) throw()
+- {
+- OTAtomicAdd32 (-1, (SInt32*) &variable);
+- }
+-
+- forcedinline int atomicDecrementAndReturn (int& variable) throw()
+- {
+- return OTAtomicAdd32 (-1, (SInt32*) &variable);
+- }
+- #endif
+-#else
+-#ifdef __GNUC__
+-
+- /** Increments an integer in a thread-safe way. */
+- forcedinline void atomicIncrement (int& variable) throw()
+- {
+- __asm__ __volatile (
+- "lock incl (%%ecx)"
+- :
+- : "c" (&variable));
+- }
+-
+- /** Increments an integer in a thread-safe way and returns the incremented value. */
+- forcedinline int atomicIncrementAndReturn (int& variable) throw()
+- {
+- int result;
+-
+- __asm__ __volatile (
+- "lock xaddl %%eax, (%%ebx) \n\
+- incl %%eax"
+- : "=a" (result)
+- : "b" (&variable), "a" (1)
+- : "cc", "memory");
+-
+- return result;
+- }
+-
+- /** Decrememts an integer in a thread-safe way. */
+- forcedinline void atomicDecrement (int& variable) throw()
+- {
+- __asm__ __volatile (
+- "lock decl (%%ecx)"
+- :
+- : "c" (&variable));
+- }
+-
+- /** Decrememts an integer in a thread-safe way and returns the incremented value. */
+- forcedinline int atomicDecrementAndReturn (int& variable) throw()
+- {
+- int result;
+-
+- __asm__ __volatile (
+- "lock xaddl %%eax, (%%ebx) \n\
+- decl %%eax"
+- : "=a" (result)
+- : "b" (&variable), "a" (-1)
+- : "cc", "memory");
+-
+- return result;
+- }
+-
+-#else
+-
+- /** Increments an integer in a thread-safe way. */
+- inline_assembly void __fastcall atomicIncrement (int& variable) throw()
+- {
+- __asm {
+- mov ecx, dword ptr [variable]
+- lock inc dword ptr [ecx]
+- }
+- }
+-
+- /** Increments an integer in a thread-safe way and returns the incremented value. */
+- inline_assembly int __fastcall atomicIncrementAndReturn (int& variable) throw()
+- {
+- int result;
+-
+- __asm {
+- mov ecx, dword ptr [variable]
+- mov eax, 1
+- lock xadd dword ptr [ecx], eax
+- inc eax
+- mov result, eax
+- }
+-
+- return result;
+- }
+-
+- /** Decrememts an integer in a thread-safe way. */
+- inline_assembly void __fastcall atomicDecrement (int& variable) throw()
+- {
+- __asm {
+- mov ecx, dword ptr [variable]
+- lock dec dword ptr [ecx]
+- }
+- }
+-
+- /** Decrememts an integer in a thread-safe way and returns the incremented value. */
+- inline_assembly int __fastcall atomicDecrementAndReturn (int& variable) throw()
+- {
+- int result;
+-
+- __asm {
+- mov ecx, dword ptr [variable]
+- mov eax, -1
+- lock xadd dword ptr [ecx], eax
+- dec eax
+- mov result, eax
+- }
+-
+- return result;
+- }
+-#endif
+-#endif
+-
+-#endif // __JUCE_ATOMIC_JUCEHEADER__
++/* ++ ============================================================================== ++ ++ This file is part of the JUCE library - "Jules' Utility Class Extensions" ++ Copyright 2004-6 by Raw Material Software ltd. ++ ++ ------------------------------------------------------------------------------ ++ ++ JUCE can be redistributed and/or modified 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. ++ ++ JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the ++ Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ Boston, MA 02111-1307 USA ++ ++ ------------------------------------------------------------------------------ ++ ++ If you'd like to release a closed-source product which uses JUCE, commercial ++ licenses are also available: visit www.rawmaterialsoftware.com/juce for ++ more information. ++ ++ ============================================================================== ++*/ ++ ++#ifndef __JUCE_ATOMIC_JUCEHEADER__ ++#define __JUCE_ATOMIC_JUCEHEADER__ ++ ++// Atomic increment/decrement operations.. ++ ++//============================================================================== ++#if JUCE_MAC && ! DOXYGEN ++ #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) ++ #include <libkern/OSAtomic.h> ++ ++ forcedinline void atomicIncrement (int& variable) throw() ++ { ++ OSAtomicIncrement32 ((int32_t*) &variable); ++ } ++ ++ forcedinline int atomicIncrementAndReturn (int& variable) throw() ++ { ++ return OSAtomicIncrement32 ((int32_t*) &variable); ++ } ++ ++ forcedinline void atomicDecrement (int& variable) throw() ++ { ++ OSAtomicDecrement32 ((int32_t*) &variable); ++ } ++ ++ forcedinline int atomicDecrementAndReturn (int& variable) throw() ++ { ++ return OSAtomicDecrement32 ((int32_t*) &variable); ++ } ++ ++ #else ++ forcedinline void atomicIncrement (int& variable) throw() ++ { ++ OTAtomicAdd32 (1, (SInt32*) &variable); ++ } ++ ++ forcedinline int atomicIncrementAndReturn (int& variable) throw() ++ { ++ return OTAtomicAdd32 (1, (SInt32*) &variable); ++ } ++ ++ forcedinline void atomicDecrement (int& variable) throw() ++ { ++ OTAtomicAdd32 (-1, (SInt32*) &variable); ++ } ++ ++ forcedinline int atomicDecrementAndReturn (int& variable) throw() ++ { ++ return OTAtomicAdd32 (-1, (SInt32*) &variable); ++ } ++ #endif ++#else ++#ifdef __GNUC__ ++ ++ /** Increments an integer in a thread-safe way. */ ++ forcedinline void atomicIncrement (int& variable) throw() ++ { ++#ifndef __x86__ ++ variable++; ++#else ++ __asm__ __volatile ( ++ "lock incl (%%ecx)" ++ : ++ : "c" (&variable)); ++#endif ++ } ++ ++ /** Increments an integer in a thread-safe way and returns the incremented value. */ ++ forcedinline int atomicIncrementAndReturn (int& variable) throw() ++ { ++ int result; ++#ifndef __x86__ ++ result = ++variable; ++#else ++ __asm__ __volatile ( ++ "lock xaddl %%eax, (%%ebx) \n\ ++ incl %%eax" ++ : "=a" (result) ++ : "b" (&variable), "a" (1) ++ : "cc", "memory"); ++#endif ++ return result; ++ } ++ ++ /** Decrememts an integer in a thread-safe way. */ ++ forcedinline void atomicDecrement (int& variable) throw() ++ { ++#ifndef __x86__ ++ variable--; ++#else ++ __asm__ __volatile ( ++ "lock decl (%%ecx)" ++ : ++ : "c" (&variable)); ++#endif ++ } ++ ++ /** Decrememts an integer in a thread-safe way and returns the incremented value. */ ++ forcedinline int atomicDecrementAndReturn (int& variable) throw() ++ { ++ int result; ++#ifndef __x86__ ++ result = --variable; ++#else ++ __asm__ __volatile ( ++ "lock xaddl %%eax, (%%ebx) \n\ ++ decl %%eax" ++ : "=a" (result) ++ : "b" (&variable), "a" (-1) ++ : "cc", "memory"); ++#endif ++ return result; ++ } ++ ++#else ++ ++ /** Increments an integer in a thread-safe way. */ ++ inline_assembly void __fastcall atomicIncrement (int& variable) throw() ++ { ++ __asm { ++ mov ecx, dword ptr [variable] ++ lock inc dword ptr [ecx] ++ } ++ } ++ ++ /** Increments an integer in a thread-safe way and returns the incremented value. */ ++ inline_assembly int __fastcall atomicIncrementAndReturn (int& variable) throw() ++ { ++ int result; ++ ++ __asm { ++ mov ecx, dword ptr [variable] ++ mov eax, 1 ++ lock xadd dword ptr [ecx], eax ++ inc eax ++ mov result, eax ++ } ++ ++ return result; ++ } ++ ++ /** Decrememts an integer in a thread-safe way. */ ++ inline_assembly void __fastcall atomicDecrement (int& variable) throw() ++ { ++ __asm { ++ mov ecx, dword ptr [variable] ++ lock dec dword ptr [ecx] ++ } ++ } ++ ++ /** Decrememts an integer in a thread-safe way and returns the incremented value. */ ++ inline_assembly int __fastcall atomicDecrementAndReturn (int& variable) throw() ++ { ++ int result; ++ ++ __asm { ++ mov ecx, dword ptr [variable] ++ mov eax, -1 ++ lock xadd dword ptr [ecx], eax ++ dec eax ++ mov result, eax ++ } ++ ++ return result; ++ } ++#endif ++#endif ++ ++#endif // __JUCE_ATOMIC_JUCEHEADER__ +--- juce/src/juce_core/basics/juce_PlatformDefs.h~remove-x86isms.patch ++++ juce/src/juce_core/basics/juce_PlatformDefs.h +@@ -1,326 +1,330 @@ +-/*
+- ==============================================================================
+-
+- This file is part of the JUCE library - "Jules' Utility Class Extensions"
+- Copyright 2004-6 by Raw Material Software ltd.
+-
+- ------------------------------------------------------------------------------
+-
+- JUCE can be redistributed and/or modified 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.
+-
+- JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
+- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+- Boston, MA 02111-1307 USA
+-
+- ------------------------------------------------------------------------------
+-
+- If you'd like to release a closed-source product which uses JUCE, commercial
+- licenses are also available: visit www.rawmaterialsoftware.com/juce for
+- more information.
+-
+- ==============================================================================
+-*/
+-
+-#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__
+-#define __JUCE_PLATFORMDEFS_JUCEHEADER__
+-
+-
+-//==============================================================================
+-// set up platform definitions..
+-#ifdef _WIN32
+- #define JUCE_WIN32 1
+- #define JUCE_WINDOWS 1
+-#else
+- #ifdef LINUX
+- #define JUCE_LINUX 1
+- #else
+- #define JUCE_MAC 1
+- #endif
+-#endif
+-
+-//==============================================================================
+-#ifdef JUCE_WINDOWS
+- #ifdef _MSC_VER
+- #ifdef _WIN64
+- #define JUCE_64BIT 1
+- #else
+- #define JUCE_32BIT 1
+- #endif
+- #endif
+-
+- #ifdef _DEBUG
+- #define JUCE_DEBUG 1
+- #endif
+-
+- /** If defined, this indicates that the processor is little-endian. */
+- #define JUCE_LITTLE_ENDIAN 1
+-
+- #define JUCE_INTEL 1
+-#endif
+-
+-//==============================================================================
+-#ifdef JUCE_MAC
+-
+- #include <CoreServices/CoreServices.h>
+- #include <wchar.h>
+-
+- #ifndef NDEBUG
+- #define JUCE_DEBUG 1
+- #endif
+-
+- #ifdef __LITTLE_ENDIAN__
+- #define JUCE_LITTLE_ENDIAN 1
+- #else
+- #define JUCE_BIG_ENDIAN 1
+- #endif
+-
+- #if defined (__ppc__) || defined (__ppc64__)
+- #define JUCE_PPC 1
+- #else
+- #define JUCE_INTEL 1
+- #endif
+-
+- #ifdef __LP64__
+- #define JUCE_64BIT 1
+- #else
+- #define JUCE_32BIT 1
+- #endif
+-#endif
+-
+-//==============================================================================
+-#ifdef JUCE_LINUX
+-
+- #ifdef _DEBUG
+- #define JUCE_DEBUG 1
+- #endif
+-
+- #include <wchar.h>
+-
+- // Allow override for big-endian Linux platforms
+- #ifndef JUCE_BIG_ENDIAN
+- #define JUCE_LITTLE_ENDIAN 1
+- #endif
+-
+- #if defined (__LP64__) || defined (_LP64)
+- #define JUCE_64BIT 1
+- #else
+- #define JUCE_32BIT 1
+- #endif
+-
+- #define JUCE_INTEL 1
+-#endif
+-
+-//==============================================================================
+-#if defined (__GNUC__) || defined (__MWERKS__)
+- /** A platform-independent 64-bit integer type. */
+- typedef long long int64;
+- /** A platform-independent 64-bit unsigned integer type. */
+- typedef unsigned long long uint64;
+- /** A platform-independent unicode character type. */
+- typedef wchar_t juce_wchar;
+-
+- /** A platform-independent way of forcing an inline function.
+-
+- Use the syntax: @code
+- forcedinline void myfunction (int x)
+- @endcode
+- */
+- #ifndef JUCE_DEBUG
+- #define forcedinline inline __attribute__((always_inline))
+- #else
+- #define forcedinline inline
+- #endif
+-
+- /** A platform-independent way of stopping the compiler inlining a function.
+-
+- Use the syntax: @code
+- juce_noinline void myfunction (int x)
+- @endcode
+- */
+- #define juce_noinline __attribute__((noinline))
+-
+-#else
+- //==============================================================================
+- /** A platform-independent 64-bit integer type. */
+- typedef __int64 int64;
+- /** A platform-independent 64-bit unsigned integer type. */
+- typedef unsigned __int64 uint64;
+-
+- /** A platform-independent unicode character type. */
+- typedef wchar_t juce_wchar;
+-
+- /** A platform-independent way of forcing an inline function.
+-
+- Use the syntax: @code
+- forcedinline void myfunction (int x)
+- @endcode
+- */
+- #ifdef _MSC_VER
+- #define forcedinline __forceinline
+- #else
+- #define forcedinline inline
+- #endif
+-
+- /** A platform-independent way of stopping the compiler inlining a function.
+-
+- Use the syntax: @code
+- juce_noinline void myfunction (int x)
+- @endcode
+- */
+- #define juce_noinline
+-
+-#endif
+-
+-#if JUCE_64BIT
+- typedef int64 pointer_sized_int;
+- typedef uint64 pointer_sized_uint;
+-#else
+- #if _MSC_VER >= 1300
+- typedef _W64 int pointer_sized_int;
+- typedef _W64 unsigned int pointer_sized_uint;
+- #else
+- typedef int pointer_sized_int;
+- typedef unsigned int pointer_sized_uint;
+- #endif
+-#endif
+-
+-
+-// borland can't handle inline functions containing asm code, so define a
+-// special type of inline modifier for this kind of function. Sigh..
+-#ifdef __BORLANDC__
+- #define inline_assembly
+-#else
+- #define inline_assembly forcedinline
+-#endif
+-
+-//==============================================================================
+-typedef signed char int8;
+-typedef unsigned char uint8;
+-typedef signed short int16;
+-typedef unsigned short uint16;
+-typedef signed int int32;
+-typedef unsigned int uint32;
+-
+-
+-//==============================================================================
+-// Debugging macros
+-//
+-
+-#ifdef JUCE_DEBUG
+- //==============================================================================
+- // If debugging is enabled..
+-
+- /** Writes a string to the standard error stream.
+-
+- This is only compiled in a debug build.
+-
+- @see Logger::outputDebugString
+- */
+- #define DBG(dbgtext) Logger::outputDebugString (dbgtext);
+-
+- /** Printf's a string to the standard error stream.
+-
+- This is only compiled in a debug build.
+-
+- @see Logger::outputDebugString
+- */
+- #define DBG_PRINTF(dbgprintf) Logger::outputDebugPrintf dbgprintf;
+-
+- // Assertions..
+- #if defined (_MSC_VER) || DOXYGEN
+- /** This will always cause an assertion failure.
+-
+- This is only compiled in a debug build.
+-
+- @see jassert()
+- */
+- #ifdef __BORLANDC__
+- extern void juce_StopInDebugger();
+- #define jassertfalse { juce_StopInDebugger(); }
+- #else
+- #define jassertfalse { __asm int 3 }
+- #endif
+- #elif defined (JUCE_MAC)
+- #define jassertfalse { Debugger(); }
+- #elif defined (__GNUC__) || defined (JUCE_LINUX)
+- #define jassertfalse { asm("int $3"); }
+- #endif
+-
+- //==============================================================================
+- /** Platform-independent assertion macro.
+-
+- This gets optimised out when not being built with debugging turned on.
+-
+- Be careful not to call any functions within its arguments that are vital to
+- the behaviour of the program, because these won't get called in the release
+- build.
+-
+- @see jassertfalse
+- */
+- #define jassert(a) { if (! (a)) jassertfalse }
+-
+-#else
+- //==============================================================================
+- // If debugging is disabled, disable all the assertions and debugging stuff..
+-
+- #define DBG(dbgtext)
+- #define DBG_PRINTF(dbgprintf)
+-
+- #define jassert(a) {}
+- #define jassertfalse {}
+-
+-#endif
+-
+-//==============================================================================
+-#ifndef DOXYGEN
+- template <bool b> struct JuceStaticAssert;
+- template <> struct JuceStaticAssert <true> { static void dummy() {} };
+-#endif
+-
+-/** A compile-time assertion macro.
+-
+- If the expression parameter is false, the macro will cause a compile error.
+-*/
+-#define static_jassert(expression) JuceStaticAssert<expression>::dummy();
+-
+-
+-//==============================================================================
+-#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
+-
+- #define JUCE_TRY try
+-
+- /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication
+- object so they can be logged by the application if it wants to.
+- */
+- #define JUCE_CATCH_EXCEPTION \
+- catch (const std::exception& e) \
+- { \
+- JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \
+- } \
+- catch (...) \
+- { \
+- JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__); \
+- }
+-
+- #define JUCE_CATCH_ALL catch (...) {}
+- #define JUCE_CATCH_ALL_ASSERT catch (...) { jassertfalse }
+-
+-#else
+-
+- #define JUCE_TRY
+- #define JUCE_CATCH_EXCEPTION
+- #define JUCE_CATCH_ALL
+- #define JUCE_CATCH_ALL_ASSERT
+-
+-#endif
+-
+-
+-#endif // __JUCE_PLATFORMDEFS_JUCEHEADER__
++/* ++ ============================================================================== ++ ++ This file is part of the JUCE library - "Jules' Utility Class Extensions" ++ Copyright 2004-6 by Raw Material Software ltd. ++ ++ ------------------------------------------------------------------------------ ++ ++ JUCE can be redistributed and/or modified 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. ++ ++ JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the ++ Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ Boston, MA 02111-1307 USA ++ ++ ------------------------------------------------------------------------------ ++ ++ If you'd like to release a closed-source product which uses JUCE, commercial ++ licenses are also available: visit www.rawmaterialsoftware.com/juce for ++ more information. ++ ++ ============================================================================== ++*/ ++ ++#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__ ++#define __JUCE_PLATFORMDEFS_JUCEHEADER__ ++ ++ ++//============================================================================== ++// set up platform definitions.. ++#ifdef _WIN32 ++ #define JUCE_WIN32 1 ++ #define JUCE_WINDOWS 1 ++#else ++ #ifdef LINUX ++ #define JUCE_LINUX 1 ++ #else ++ #define JUCE_MAC 1 ++ #endif ++#endif ++ ++//============================================================================== ++#ifdef JUCE_WINDOWS ++ #ifdef _MSC_VER ++ #ifdef _WIN64 ++ #define JUCE_64BIT 1 ++ #else ++ #define JUCE_32BIT 1 ++ #endif ++ #endif ++ ++ #ifdef _DEBUG ++ #define JUCE_DEBUG 1 ++ #endif ++ ++ /** If defined, this indicates that the processor is little-endian. */ ++ #define JUCE_LITTLE_ENDIAN 1 ++ ++ #define JUCE_INTEL 1 ++#endif ++ ++//============================================================================== ++#ifdef JUCE_MAC ++ ++ #include <CoreServices/CoreServices.h> ++ #include <wchar.h> ++ ++ #ifndef NDEBUG ++ #define JUCE_DEBUG 1 ++ #endif ++ ++ #ifdef __LITTLE_ENDIAN__ ++ #define JUCE_LITTLE_ENDIAN 1 ++ #else ++ #define JUCE_BIG_ENDIAN 1 ++ #endif ++ ++ #if defined (__ppc__) || defined (__ppc64__) ++ #define JUCE_PPC 1 ++ #else ++ #define JUCE_INTEL 1 ++ #endif ++ ++ #ifdef __LP64__ ++ #define JUCE_64BIT 1 ++ #else ++ #define JUCE_32BIT 1 ++ #endif ++#endif ++ ++//============================================================================== ++#ifdef JUCE_LINUX ++ ++ #ifdef _DEBUG ++ #define JUCE_DEBUG 1 ++ #endif ++ ++ #include <wchar.h> ++ ++ // Allow override for big-endian Linux platforms ++ #ifndef JUCE_BIG_ENDIAN ++ #define JUCE_LITTLE_ENDIAN 1 ++ #endif ++ ++ #if defined (__LP64__) || defined (_LP64) ++ #define JUCE_64BIT 1 ++ #else ++ #define JUCE_32BIT 1 ++ #endif ++ ++ #define JUCE_INTEL 1 ++#endif ++ ++//============================================================================== ++#if defined (__GNUC__) || defined (__MWERKS__) ++ /** A platform-independent 64-bit integer type. */ ++ typedef long long int64; ++ /** A platform-independent 64-bit unsigned integer type. */ ++ typedef unsigned long long uint64; ++ /** A platform-independent unicode character type. */ ++ typedef wchar_t juce_wchar; ++ ++ /** A platform-independent way of forcing an inline function. ++ ++ Use the syntax: @code ++ forcedinline void myfunction (int x) ++ @endcode ++ */ ++ #ifndef JUCE_DEBUG ++ #define forcedinline inline __attribute__((always_inline)) ++ #else ++ #define forcedinline inline ++ #endif ++ ++ /** A platform-independent way of stopping the compiler inlining a function. ++ ++ Use the syntax: @code ++ juce_noinline void myfunction (int x) ++ @endcode ++ */ ++ #define juce_noinline __attribute__((noinline)) ++ ++#else ++ //============================================================================== ++ /** A platform-independent 64-bit integer type. */ ++ typedef __int64 int64; ++ /** A platform-independent 64-bit unsigned integer type. */ ++ typedef unsigned __int64 uint64; ++ ++ /** A platform-independent unicode character type. */ ++ typedef wchar_t juce_wchar; ++ ++ /** A platform-independent way of forcing an inline function. ++ ++ Use the syntax: @code ++ forcedinline void myfunction (int x) ++ @endcode ++ */ ++ #ifdef _MSC_VER ++ #define forcedinline __forceinline ++ #else ++ #define forcedinline inline ++ #endif ++ ++ /** A platform-independent way of stopping the compiler inlining a function. ++ ++ Use the syntax: @code ++ juce_noinline void myfunction (int x) ++ @endcode ++ */ ++ #define juce_noinline ++ ++#endif ++ ++#if JUCE_64BIT ++ typedef int64 pointer_sized_int; ++ typedef uint64 pointer_sized_uint; ++#else ++ #if _MSC_VER >= 1300 ++ typedef _W64 int pointer_sized_int; ++ typedef _W64 unsigned int pointer_sized_uint; ++ #else ++ typedef int pointer_sized_int; ++ typedef unsigned int pointer_sized_uint; ++ #endif ++#endif ++ ++ ++// borland can't handle inline functions containing asm code, so define a ++// special type of inline modifier for this kind of function. Sigh.. ++#ifdef __BORLANDC__ ++ #define inline_assembly ++#else ++ #define inline_assembly forcedinline ++#endif ++ ++//============================================================================== ++typedef signed char int8; ++typedef unsigned char uint8; ++typedef signed short int16; ++typedef unsigned short uint16; ++typedef signed int int32; ++typedef unsigned int uint32; ++ ++ ++//============================================================================== ++// Debugging macros ++// ++ ++#ifdef JUCE_DEBUG ++ //============================================================================== ++ // If debugging is enabled.. ++ ++ /** Writes a string to the standard error stream. ++ ++ This is only compiled in a debug build. ++ ++ @see Logger::outputDebugString ++ */ ++ #define DBG(dbgtext) Logger::outputDebugString (dbgtext); ++ ++ /** Printf's a string to the standard error stream. ++ ++ This is only compiled in a debug build. ++ ++ @see Logger::outputDebugString ++ */ ++ #define DBG_PRINTF(dbgprintf) Logger::outputDebugPrintf dbgprintf; ++ ++ // Assertions.. ++ #if defined (_MSC_VER) || DOXYGEN ++ /** This will always cause an assertion failure. ++ ++ This is only compiled in a debug build. ++ ++ @see jassert() ++ */ ++ #ifdef __BORLANDC__ ++ extern void juce_StopInDebugger(); ++ #define jassertfalse { juce_StopInDebugger(); } ++ #else ++ #define jassertfalse { __asm int 3 } ++ #endif ++ #elif defined (JUCE_MAC) ++ #define jassertfalse { Debugger(); } ++ #elif defined (__GNUC__) || defined (JUCE_LINUX) ++ #ifndef __x86__ ++ #define jassertfalse { 1/0; } ++ #else ++ #define jassertfalse { asm("int $3"); } ++ #endif ++ #endif ++ ++ //============================================================================== ++ /** Platform-independent assertion macro. ++ ++ This gets optimised out when not being built with debugging turned on. ++ ++ Be careful not to call any functions within its arguments that are vital to ++ the behaviour of the program, because these won't get called in the release ++ build. ++ ++ @see jassertfalse ++ */ ++ #define jassert(a) { if (! (a)) jassertfalse } ++ ++#else ++ //============================================================================== ++ // If debugging is disabled, disable all the assertions and debugging stuff.. ++ ++ #define DBG(dbgtext) ++ #define DBG_PRINTF(dbgprintf) ++ ++ #define jassert(a) {} ++ #define jassertfalse {} ++ ++#endif ++ ++//============================================================================== ++#ifndef DOXYGEN ++ template <bool b> struct JuceStaticAssert; ++ template <> struct JuceStaticAssert <true> { static void dummy() {} }; ++#endif ++ ++/** A compile-time assertion macro. ++ ++ If the expression parameter is false, the macro will cause a compile error. ++*/ ++#define static_jassert(expression) JuceStaticAssert<expression>::dummy(); ++ ++ ++//============================================================================== ++#if JUCE_CATCH_UNHANDLED_EXCEPTIONS ++ ++ #define JUCE_TRY try ++ ++ /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication ++ object so they can be logged by the application if it wants to. ++ */ ++ #define JUCE_CATCH_EXCEPTION \ ++ catch (const std::exception& e) \ ++ { \ ++ JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \ ++ } \ ++ catch (...) \ ++ { \ ++ JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__); \ ++ } ++ ++ #define JUCE_CATCH_ALL catch (...) {} ++ #define JUCE_CATCH_ALL_ASSERT catch (...) { jassertfalse } ++ ++#else ++ ++ #define JUCE_TRY ++ #define JUCE_CATCH_EXCEPTION ++ #define JUCE_CATCH_ALL ++ #define JUCE_CATCH_ALL_ASSERT ++ ++#endif ++ ++ ++#endif // __JUCE_PLATFORMDEFS_JUCEHEADER__ +--- juce/src/juce_core/basics/juce_DataConversions.h~remove-x86isms.patch ++++ juce/src/juce_core/basics/juce_DataConversions.h +@@ -1,172 +1,176 @@ +-/*
+- ==============================================================================
+-
+- This file is part of the JUCE library - "Jules' Utility Class Extensions"
+- Copyright 2004-6 by Raw Material Software ltd.
+-
+- ------------------------------------------------------------------------------
+-
+- JUCE can be redistributed and/or modified 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.
+-
+- JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
+- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+- Boston, MA 02111-1307 USA
+-
+- ------------------------------------------------------------------------------
+-
+- If you'd like to release a closed-source product which uses JUCE, commercial
+- licenses are also available: visit www.rawmaterialsoftware.com/juce for
+- more information.
+-
+- ==============================================================================
+-*/
+-
+-#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
+-#define __JUCE_DATACONVERSIONS_JUCEHEADER__
+-
+-#include "juce_PlatformDefs.h"
+-
+-//==============================================================================
+-// Endianness conversions..
+-
+-/** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */
+-inline_assembly uint32 swapByteOrder (uint32 n) throw()
+-{
+-#ifdef JUCE_MAC
+- return CFSwapInt32 (n);
+-#else
+- #ifdef __GNUC__
+- // Inpenetrable GCC version..
+- asm("bswap %%eax" : "=a"(n) : "a"(n));
+- return n;
+- #else
+- // Win32 version..
+- __asm {
+- mov eax, n
+- bswap eax
+- mov n, eax
+- }
+- return n;
+- #endif
+-#endif
+-}
+-
+-/** Swaps the byte-order of a 16-bit short. */
+-inline uint16 swapByteOrder (const uint16 n) throw()
+-{
+- return (uint16) ((n << 8) | (n >> 8));
+-}
+-
+-inline uint64 swapByteOrder (const uint64 value) throw()
+-{
+-#ifdef JUCE_MAC
+- return CFSwapInt64 (value);
+-#else
+- return (((int64) swapByteOrder ((uint32) value)) << 32)
+- | swapByteOrder ((uint32) (value >> 32));
+-#endif
+-}
+-
+-#ifdef JUCE_LITTLE_ENDIAN
+- /** Swaps the byte order of a 16-bit int if the CPU is big-endian */
+- inline uint16 swapIfBigEndian (const uint16 v) throw() { return v; }
+- /** Swaps the byte order of a 32-bit int if the CPU is big-endian */
+- inline uint32 swapIfBigEndian (const uint32 v) throw() { return v; }
+- /** Swaps the byte order of a 16-bit int if the CPU is little-endian */
+- inline uint16 swapIfLittleEndian (const uint16 v) throw() { return swapByteOrder (v); }
+- /** Swaps the byte order of a 32-bit int if the CPU is little-endian */
+- inline uint32 swapIfLittleEndian (const uint32 v) throw() { return swapByteOrder (v); }
+-
+- /** Turns 4 bytes into a little-endian integer. */
+- inline uint32 littleEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; }
+-
+- /** Turns 2 bytes into a little-endian integer. */
+- inline uint16 littleEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; }
+-
+- /** Turns 4 bytes into a big-endian integer. */
+- inline uint32 bigEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); }
+-
+- /** Turns 2 bytes into a big-endian integer. */
+- inline uint16 bigEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); }
+-
+-#else
+- /** Swaps the byte order of a 16-bit int if the CPU is big-endian */
+- inline uint16 swapIfBigEndian (const uint16 v) throw() { return swapByteOrder (v); }
+- /** Swaps the byte order of a 32-bit int if the CPU is big-endian */
+- inline uint32 swapIfBigEndian (const uint32 v) throw() { return swapByteOrder (v); }
+- /** Swaps the byte order of a 16-bit int if the CPU is little-endian */
+- inline uint16 swapIfLittleEndian (const uint16 v) throw() { return v; }
+- /** Swaps the byte order of a 32-bit int if the CPU is little-endian */
+- inline uint32 swapIfLittleEndian (const uint32 v) throw() { return v; }
+-
+- /** Turns 4 bytes into a little-endian integer. */
+- inline uint32 littleEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); }
+-
+- /** Turns 2 bytes into a little-endian integer. */
+- inline uint16 littleEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); }
+-
+- /** Turns 4 bytes into a big-endian integer. */
+- inline uint32 bigEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; }
+-
+- /** Turns 2 bytes into a big-endian integer. */
+- inline uint16 bigEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; }
+-#endif
+-
+-/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
+-inline int littleEndian24Bit (const char* const bytes) throw() { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); }
+-/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
+-inline int bigEndian24Bit (const char* const bytes) throw() { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); }
+-
+-/** Copies a 24-bit number to 3 little-endian bytes. */
+-inline void littleEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }
+-/** Copies a 24-bit number to 3 big-endian bytes. */
+-inline void bigEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }
+-
+-
+-//==============================================================================
+-/** Fast floating-point-to-integer conversion.
+-
+- This is faster than using the normal c++ cast to convert a double to an int, and
+- it will round the value to the nearest integer, rather than rounding it down
+- like the normal cast does.
+-*/
+-inline int roundDoubleToInt (const double value) throw()
+-{
+- union { int asInt[2]; double asDouble; } n;
+- n.asDouble = value + 6755399441055744.0;
+-
+-#if JUCE_BIG_ENDIAN
+- return n.asInt [1];
+-#else
+- return n.asInt [0];
+-#endif
+-}
+-
+-/** Fast floating-point-to-integer conversion.
+-
+- This is faster than using the normal c++ cast to convert a float to an int, and
+- it will round the value to the nearest integer, rather than rounding it down
+- like the normal cast does.
+-*/
+-inline int roundFloatToInt (const float value) throw()
+-{
+- union { int asInt[2]; double asDouble; } n;
+- n.asDouble = value + 6755399441055744.0;
+-
+-#if JUCE_BIG_ENDIAN
+- return n.asInt [1];
+-#else
+- return n.asInt [0];
+-#endif
+-}
+-
+-
+-#endif // __JUCE_DATACONVERSIONS_JUCEHEADER__
++/* ++ ============================================================================== ++ ++ This file is part of the JUCE library - "Jules' Utility Class Extensions" ++ Copyright 2004-6 by Raw Material Software ltd. ++ ++ ------------------------------------------------------------------------------ ++ ++ JUCE can be redistributed and/or modified 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. ++ ++ JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the ++ Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ Boston, MA 02111-1307 USA ++ ++ ------------------------------------------------------------------------------ ++ ++ If you'd like to release a closed-source product which uses JUCE, commercial ++ licenses are also available: visit www.rawmaterialsoftware.com/juce for ++ more information. ++ ++ ============================================================================== ++*/ ++ ++#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ ++#define __JUCE_DATACONVERSIONS_JUCEHEADER__ ++ ++#include "juce_PlatformDefs.h" ++ ++//============================================================================== ++// Endianness conversions.. ++ ++/** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */ ++inline_assembly uint32 swapByteOrder (uint32 n) throw() ++{ ++#ifdef JUCE_MAC ++ return CFSwapInt32 (n); ++#else ++ #ifdef __GNUC__ ++ #ifndef __x86__ ++ return ( ((n)&0xff)<<24) | (((n)&0xff00)<<8) | (((n)>>8)&0xff00) | (((n)>>24)&0xff); ++ #else ++ // Inpenetrable GCC version.. ++ asm("bswap %%eax" : "=a"(n) : "a"(n)); ++ return n; ++ #endif ++ #else ++ // Win32 version.. ++ __asm { ++ mov eax, n ++ bswap eax ++ mov n, eax ++ } ++ return n; ++ #endif ++#endif ++} ++ ++/** Swaps the byte-order of a 16-bit short. */ ++inline uint16 swapByteOrder (const uint16 n) throw() ++{ ++ return (uint16) ((n << 8) | (n >> 8)); ++} ++ ++inline uint64 swapByteOrder (const uint64 value) throw() ++{ ++#ifdef JUCE_MAC ++ return CFSwapInt64 (value); ++#else ++ return (((int64) swapByteOrder ((uint32) value)) << 32) ++ | swapByteOrder ((uint32) (value >> 32)); ++#endif ++} ++ ++#ifdef JUCE_LITTLE_ENDIAN ++ /** Swaps the byte order of a 16-bit int if the CPU is big-endian */ ++ inline uint16 swapIfBigEndian (const uint16 v) throw() { return v; } ++ /** Swaps the byte order of a 32-bit int if the CPU is big-endian */ ++ inline uint32 swapIfBigEndian (const uint32 v) throw() { return v; } ++ /** Swaps the byte order of a 16-bit int if the CPU is little-endian */ ++ inline uint16 swapIfLittleEndian (const uint16 v) throw() { return swapByteOrder (v); } ++ /** Swaps the byte order of a 32-bit int if the CPU is little-endian */ ++ inline uint32 swapIfLittleEndian (const uint32 v) throw() { return swapByteOrder (v); } ++ ++ /** Turns 4 bytes into a little-endian integer. */ ++ inline uint32 littleEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; } ++ ++ /** Turns 2 bytes into a little-endian integer. */ ++ inline uint16 littleEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; } ++ ++ /** Turns 4 bytes into a big-endian integer. */ ++ inline uint32 bigEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); } ++ ++ /** Turns 2 bytes into a big-endian integer. */ ++ inline uint16 bigEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); } ++ ++#else ++ /** Swaps the byte order of a 16-bit int if the CPU is big-endian */ ++ inline uint16 swapIfBigEndian (const uint16 v) throw() { return swapByteOrder (v); } ++ /** Swaps the byte order of a 32-bit int if the CPU is big-endian */ ++ inline uint32 swapIfBigEndian (const uint32 v) throw() { return swapByteOrder (v); } ++ /** Swaps the byte order of a 16-bit int if the CPU is little-endian */ ++ inline uint16 swapIfLittleEndian (const uint16 v) throw() { return v; } ++ /** Swaps the byte order of a 32-bit int if the CPU is little-endian */ ++ inline uint32 swapIfLittleEndian (const uint32 v) throw() { return v; } ++ ++ /** Turns 4 bytes into a little-endian integer. */ ++ inline uint32 littleEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); } ++ ++ /** Turns 2 bytes into a little-endian integer. */ ++ inline uint16 littleEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); } ++ ++ /** Turns 4 bytes into a big-endian integer. */ ++ inline uint32 bigEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; } ++ ++ /** Turns 2 bytes into a big-endian integer. */ ++ inline uint16 bigEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; } ++#endif ++ ++/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */ ++inline int littleEndian24Bit (const char* const bytes) throw() { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); } ++/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */ ++inline int bigEndian24Bit (const char* const bytes) throw() { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); } ++ ++/** Copies a 24-bit number to 3 little-endian bytes. */ ++inline void littleEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); } ++/** Copies a 24-bit number to 3 big-endian bytes. */ ++inline void bigEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); } ++ ++ ++//============================================================================== ++/** Fast floating-point-to-integer conversion. ++ ++ This is faster than using the normal c++ cast to convert a double to an int, and ++ it will round the value to the nearest integer, rather than rounding it down ++ like the normal cast does. ++*/ ++inline int roundDoubleToInt (const double value) throw() ++{ ++ union { int asInt[2]; double asDouble; } n; ++ n.asDouble = value + 6755399441055744.0; ++ ++#if JUCE_BIG_ENDIAN ++ return n.asInt [1]; ++#else ++ return n.asInt [0]; ++#endif ++} ++ ++/** Fast floating-point-to-integer conversion. ++ ++ This is faster than using the normal c++ cast to convert a float to an int, and ++ it will round the value to the nearest integer, rather than rounding it down ++ like the normal cast does. ++*/ ++inline int roundFloatToInt (const float value) throw() ++{ ++ union { int asInt[2]; double asDouble; } n; ++ n.asDouble = value + 6755399441055744.0; ++ ++#if JUCE_BIG_ENDIAN ++ return n.asInt [1]; ++#else ++ return n.asInt [0]; ++#endif ++} ++ ++ ++#endif // __JUCE_DATACONVERSIONS_JUCEHEADER__ +--- juce/build/linux/platform_specific_code/juce_linux_SystemStats.cpp~remove-x86isms.patch ++++ juce/build/linux/platform_specific_code/juce_linux_SystemStats.cpp +@@ -1,472 +1,472 @@ +-/*
+- ==============================================================================
+-
+- This file is part of the JUCE library - "Jules' Utility Class Extensions"
+- Copyright 2004-6 by Raw Material Software ltd.
+-
+- ------------------------------------------------------------------------------
+-
+- JUCE can be redistributed and/or modified 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.
+-
+- JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
+- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+- Boston, MA 02111-1307 USA
+-
+- ------------------------------------------------------------------------------
+-
+- If you'd like to release a closed-source product which uses JUCE, commercial
+- licenses are also available: visit www.rawmaterialsoftware.com/juce for
+- more information.
+-
+- ==============================================================================
+-*/
+-
+-#include "linuxincludes.h"
+-#include "../../../src/juce_core/basics/juce_StandardHeader.h"
+-
+-#ifdef __CYGWIN__
+- #include <apr_uuid.h>
+- #include <malloc.h>
+-#else
+- #include <sys/sysinfo.h>
+- #include <dlfcn.h>
+-#endif
+-
+-#ifdef JUCE_UUID
+- #include <uuid/uuid.h>
+-#endif
+-
+-#ifndef CPU_ISSET
+- #undef SUPPORT_AFFINITIES
+-#endif
+-
+-BEGIN_JUCE_NAMESPACE
+-
+-#include "../../../src/juce_core/io/files/juce_File.h"
+-#include "../../../src/juce_core/basics/juce_SystemStats.h"
+-#include "../../../src/juce_core/basics/juce_Logger.h"
+-#include "../../../src/juce_core/misc/juce_Uuid.h"
+-#include "../../../src/juce_core/threads/juce_Process.h"
+-#include "../../../src/juce_appframework/events/juce_Timer.h"
+-#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
+-
+-static struct _LogicalCpuInfo
+-{
+- bool htSupported;
+- bool htAvailable;
+- int numPackages;
+- int numLogicalPerPackage;
+- uint32 physicalAffinityMask;
+-} logicalCpuInfo;
+-
+-//==============================================================================
+-static unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0) __attribute__ ((noinline));
+-
+-static unsigned int getCPUIDWord (int* familyModel, int* extFeatures)
+-{
+- unsigned int cpu = 0;
+- unsigned int ext = 0;
+- unsigned int family = 0;
+-
+- __asm__ __volatile__ (
+-" pushf \n"
+-#if JUCE_64BIT
+-" pop %%rax \n"
+-#else
+-" pop %%eax \n"
+-#endif
+-" movl %%eax, %%ecx \n"
+-" xorl $0x200000, %%eax \n"
+-#if JUCE_64BIT
+-" push %%rax \n"
+-#else
+-" push %%eax \n"
+-#endif
+-" popf \n"
+-" pushf \n"
+-#if JUCE_64BIT
+-" pop %%rax \n"
+-#else
+-" pop %%eax \n"
+-#endif
+-" andl $0x200000, %%eax \n"
+-" andl $0x200000, %%ecx \n"
+-" cmpl %%eax, %%ecx \n"
+-" movl $0, %%edx \n"
+-" je noCpuId \n"
+-" movl $1, %%eax \n"
+-" cpuid \n"
+-"noCpuId: \n"
+- : "=a"(family), /* Output in eax */
+- "=d"(cpu), /* Output in ebx */
+- "=b"(ext) /* Output in edx */
+- : /* No inputs */
+- : "cc", "ecx" /* Clobber list */
+- );
+-
+- if (familyModel)
+- *familyModel = family;
+- if (extFeatures)
+- *extFeatures = ext;
+-
+- return cpu;
+-}
+-
+-void juce_initLogicalCpuInfo()
+-{
+- int familyModelWord, extFeaturesWord;
+- int featuresWord = getCPUIDWord (&familyModelWord, &extFeaturesWord);
+-
+- logicalCpuInfo.htSupported = false;
+- logicalCpuInfo.htAvailable = false;
+- logicalCpuInfo.numLogicalPerPackage = 1;
+- logicalCpuInfo.numPackages = 0;
+- logicalCpuInfo.physicalAffinityMask = 0;
+-
+-#if SUPPORT_AFFINITIES
+- cpu_set_t processAffinity;
+-
+- /*
+- N.B. If this line causes a compile error, then you've probably not got the latest
+- version of glibc installed.
+-
+- If you don't want to update your copy of glibc and don't care about cpu affinities,
+- then you can just disable all this stuff by removing the SUPPORT_AFFINITIES macro
+- from the linuxincludes.h file.
+- */
+- if (sched_getaffinity (getpid(),
+- sizeof (cpu_set_t),
+- &processAffinity) != sizeof (cpu_set_t))
+- {
+- return;
+- }
+-
+- // Checks: CPUID supported, model >= Pentium 4, Hyperthreading bit set, logical CPUs per package > 1
+- if (featuresWord == 0
+- || ((familyModelWord >> 8) & 0xf) < 15
+- || (featuresWord & (1 << 28)) == 0
+- || ((extFeaturesWord >> 16) & 0xff) < 2)
+- {
+- for (int i = 0; i < 64; ++i)
+- if (CPU_ISSET (i, &processAffinity))
+- logicalCpuInfo.physicalAffinityMask |= (1 << i);
+-
+- return;
+- }
+-
+- logicalCpuInfo.htSupported = true;
+- logicalCpuInfo.numLogicalPerPackage = (extFeaturesWord >> 16) & 0xff;
+-
+- cpu_set_t affinityMask;
+- cpu_set_t physAff;
+- CPU_ZERO (&physAff);
+-
+- unsigned char i = 1;
+- unsigned char physIdMask = 0xFF;
+- unsigned char physIdShift = 0;
+-
+- //unsigned char apicId, logId, physId;
+-
+- while (i < logicalCpuInfo.numLogicalPerPackage)
+- {
+- i *= 2;
+- physIdMask <<= 1;
+- physIdShift++;
+- }
+-
+- CPU_SET (0, &affinityMask);
+- logicalCpuInfo.numPackages = 0;
+-
+-//xxx revisit this at some point..
+-/* while ((affinityMask != 0) && (affinityMask <= processAffinity))
+- {
+- int ret;
+- if (! sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinityMask))
+- {
+- sched_yield(); // schedule onto correct CPU
+-
+- featuresWord = getCPUIDWord(&familyModelWord, &extFeaturesWord);
+- apicId = (unsigned char)(extFeaturesWord >> 24);
+- logId = (unsigned char)(apicId & ~physIdMask);
+- physId = (unsigned char)(apicId >> physIdShift);
+-
+- if (logId != 0)
+- logicalCpuInfo.htAvailable = true;
+-
+- if ((((int)logId) % logicalCpuInfo.numLogicalPerPackage) == 0)
+- {
+- // This is a physical CPU
+- physAff |= affinityMask;
+- logicalCpuInfo.numPackages++;
+- }
+- }
+-
+- affinityMask = affinityMask << 1;
+- }
+-
+- sched_setaffinity (getpid(), sizeof(unsigned long), &processAffinity);
+-*/
+-
+- logicalCpuInfo.physicalAffinityMask = 0;
+-
+- for (int i = 0; i < 64; ++i)
+- if (CPU_ISSET (i, &physAff))
+- logicalCpuInfo.physicalAffinityMask |= (1 << i);
+-
+-#endif
+-}
+-
+-//==============================================================================
+-void Logger::outputDebugString (const String& text)
+-{
+- fprintf (stdout, (const char*) (text + T("\n")));
+-}
+-
+-void Logger::outputDebugPrintf (const tchar* format, ...)
+-{
+- String text;
+- va_list args;
+- va_start (args, format);
+- text.vprintf(format, args);
+- outputDebugString(text);
+-}
+-
+-const String SystemStats::getOSType()
+-{
+- return SystemStats::Linux;
+-}
+-
+-static const String getCpuInfo (const char* key, bool lastOne = false)
+-{
+- String info;
+- char buf [256];
+-
+- FILE* f = fopen ("/proc/cpuinfo", "r");
+-
+- while (f != 0 && fgets (buf, sizeof(buf), f))
+- {
+- if (strncmp (buf, key, strlen (key)) == 0)
+- {
+- char* p = buf;
+-
+- while (*p && *p != '\n')
+- ++p;
+-
+- if (*p != 0)
+- *p = 0;
+-
+- p = buf;
+-
+- while (*p != 0 && *p != ':')
+- ++p;
+-
+- if (*p != 0 && *(p + 1) != 0)
+- info = p + 2;
+-
+- if (! lastOne)
+- break;
+- }
+- }
+-
+- fclose (f);
+- return info;
+-}
+-
+-bool SystemStats::hasMMX()
+-{
+- return getCpuInfo ("flags").contains (T("mmx"));
+-}
+-
+-bool SystemStats::hasSSE()
+-{
+- return getCpuInfo ("flags").contains (T("sse"));
+-}
+-
+-bool SystemStats::hasSSE2()
+-{
+- return getCpuInfo ("flags").contains (T("sse2"));
+-}
+-
+-bool SystemStats::has3DNow()
+-{
+- return getCpuInfo ("flags").contains (T("3dnow"));
+-}
+-
+-const String SystemStats::getCpuVendor()
+-{
+- return getCpuInfo ("vendor_id");
+-}
+-
+-int SystemStats::getCpuSpeedInMegaherz()
+-{
+- const String speed (getCpuInfo ("cpu MHz"));
+-
+- return (int) (speed.getFloatValue() + 0.5f);
+-}
+-
+-bool SystemStats::hasHyperThreading()
+-{
+- return logicalCpuInfo.htAvailable;
+-}
+-
+-int SystemStats::getMemorySizeInMegabytes()
+-{
+-#ifndef __CYGWIN__
+- struct sysinfo sysi;
+-
+- if (sysinfo (&sysi) == 0)
+- return (sysi.totalram * sysi.mem_unit / (1024 * 1024));
+-
+- return 0;
+-
+-#else
+- jassertfalse
+- return 256;
+-#endif
+-}
+-
+-unsigned int juce_millisecondsSinceStartup()
+-{
+- static unsigned int calibrate = 0;
+- static bool calibrated = false;
+- timeval t;
+- unsigned int ret = 0;
+-
+- if (! gettimeofday (&t, 0))
+- {
+- if (! calibrated)
+- {
+-#ifndef __CYGWIN__
+- struct sysinfo sysi;
+-
+- if (sysinfo (&sysi) == 0)
+- // Safe to assume system was not brought up earlier than 1970!
+- calibrate = t.tv_sec - sysi.uptime;
+-#else
+- // bit of a hack, but things should all still work, as we're not often
+- // really interested in how long the machine's been turned on, and just
+- // use this call for relative times..
+- calibrate = t.tv_sec;
+-#endif
+-
+- calibrated = true;
+- }
+-
+- ret = 1000 * (t.tv_sec - calibrate) + (t.tv_usec / 1000);
+- }
+-
+- return ret;
+-}
+-
+-double juce_millisecondsSinceStartupHiRes()
+-{
+- return Time::getHighResolutionTicks() * (1.0 / 1000000.0);
+-}
+-
+-int64 Time::getHighResolutionTicks()
+-{
+- timeval t;
+- if (gettimeofday(&t,NULL))
+- return 0;
+-
+- return ((int64) t.tv_sec * (int64) 1000000) + (int64) t.tv_usec;
+-}
+-
+-int64 Time::getHighResolutionTicksPerSecond()
+-{
+- // Microseconds
+- return 1000000;
+-}
+-
+-bool Time::setSystemTimeToThisTime() const
+-{
+- timeval t;
+- t.tv_sec = millisSinceEpoch % 1000000;
+- t.tv_usec = millisSinceEpoch - t.tv_sec;
+-
+- return settimeofday (&t, NULL) ? false : true;
+-}
+-
+-const String Uuid::generateUuid()
+-{
+-#ifdef JUCE_UUID
+- uuid_t uuid;
+- char *s = new char[37];
+- String uuidStr;
+-
+- uuid_generate (uuid);
+- uuid_unparse (uuid, s);
+-
+- uuidStr = s;
+- delete[] s;
+-
+- return uuidStr;
+-#else
+- jassertfalse
+- return String::empty;
+-#endif
+-}
+-
+-int SystemStats::getPageSize()
+-{
+- static int systemPageSize = 0;
+-
+- if (systemPageSize == 0)
+- systemPageSize = sysconf (_SC_PAGESIZE);
+-
+- return systemPageSize;
+-}
+-
+-int SystemStats::getNumPhysicalCpus()
+-{
+- if (logicalCpuInfo.numPackages)
+- return logicalCpuInfo.numPackages;
+-
+- return getNumLogicalCpus();
+-}
+-
+-int SystemStats::getNumLogicalCpus()
+-{
+- const int lastCpu = getCpuInfo ("processor", true).getIntValue();
+-
+- return lastCpu + 1;
+-}
+-
+-uint32 SystemStats::getPhysicalAffinityMask()
+-{
+-#if SUPPORT_AFFINITIES
+- return logicalCpuInfo.physicalAffinityMask;
+-#else
+- /* affinities aren't supported because either the appropriate header files weren't found,
+- or the SUPPORT_AFFINITIES macro was turned off in linuxheaders.h
+- */
+- jassertfalse
+- return 0;
+-#endif
+-
+-}
+-
+-//==============================================================================
+-void SystemStats::initialiseStats()
+-{
+- // Process starts off as root when running suid
+- Process::lowerPrivilege();
+-
+- String s (SystemStats::getJUCEVersion());
+-
+- juce_initLogicalCpuInfo();
+-}
+-
+-void PlatformUtilities::fpuReset()
+-{
+-}
+-
+-END_JUCE_NAMESPACE
++/* ++ ============================================================================== ++ ++ This file is part of the JUCE library - "Jules' Utility Class Extensions" ++ Copyright 2004-6 by Raw Material Software ltd. ++ ++ ------------------------------------------------------------------------------ ++ ++ JUCE can be redistributed and/or modified 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. ++ ++ JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the ++ Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++ Boston, MA 02111-1307 USA ++ ++ ------------------------------------------------------------------------------ ++ ++ If you'd like to release a closed-source product which uses JUCE, commercial ++ licenses are also available: visit www.rawmaterialsoftware.com/juce for ++ more information. ++ ++ ============================================================================== ++*/ ++ ++#include "linuxincludes.h" ++#include "../../../src/juce_core/basics/juce_StandardHeader.h" ++ ++#ifdef __CYGWIN__ ++ #include <apr_uuid.h> ++ #include <malloc.h> ++#else ++ #include <sys/sysinfo.h> ++ #include <dlfcn.h> ++#endif ++ ++#ifdef JUCE_UUID ++ #include <uuid/uuid.h> ++#endif ++ ++#ifndef CPU_ISSET ++ #undef SUPPORT_AFFINITIES ++#endif ++ ++BEGIN_JUCE_NAMESPACE ++ ++#include "../../../src/juce_core/io/files/juce_File.h" ++#include "../../../src/juce_core/basics/juce_SystemStats.h" ++#include "../../../src/juce_core/basics/juce_Logger.h" ++#include "../../../src/juce_core/misc/juce_Uuid.h" ++#include "../../../src/juce_core/threads/juce_Process.h" ++#include "../../../src/juce_appframework/events/juce_Timer.h" ++#include "../../../src/juce_core/misc/juce_PlatformUtilities.h" ++ ++static struct _LogicalCpuInfo ++{ ++ bool htSupported; ++ bool htAvailable; ++ int numPackages; ++ int numLogicalPerPackage; ++ uint32 physicalAffinityMask; ++} logicalCpuInfo; ++ ++//============================================================================== ++static unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0) __attribute__ ((noinline)); ++ ++static unsigned int getCPUIDWord (int* familyModel, int* extFeatures) ++{ ++ unsigned int cpu = 0; ++ unsigned int ext = 0; ++ unsigned int family = 0; ++#ifdef __x86__ ++ __asm__ __volatile__ ( ++" pushf \n" ++#if JUCE_64BIT ++" pop %%rax \n" ++#else ++" pop %%eax \n" ++#endif ++" movl %%eax, %%ecx \n" ++" xorl $0x200000, %%eax \n" ++#if JUCE_64BIT ++" push %%rax \n" ++#else ++" push %%eax \n" ++#endif ++" popf \n" ++" pushf \n" ++#if JUCE_64BIT ++" pop %%rax \n" ++#else ++" pop %%eax \n" ++#endif ++" andl $0x200000, %%eax \n" ++" andl $0x200000, %%ecx \n" ++" cmpl %%eax, %%ecx \n" ++" movl $0, %%edx \n" ++" je noCpuId \n" ++" movl $1, %%eax \n" ++" cpuid \n" ++"noCpuId: \n" ++ : "=a"(family), /* Output in eax */ ++ "=d"(cpu), /* Output in ebx */ ++ "=b"(ext) /* Output in edx */ ++ : /* No inputs */ ++ : "cc", "ecx" /* Clobber list */ ++ ); ++#endif ++ if (familyModel) ++ *familyModel = family; ++ if (extFeatures) ++ *extFeatures = ext; ++ ++ return cpu; ++} ++ ++void juce_initLogicalCpuInfo() ++{ ++ int familyModelWord, extFeaturesWord; ++ int featuresWord = getCPUIDWord (&familyModelWord, &extFeaturesWord); ++ ++ logicalCpuInfo.htSupported = false; ++ logicalCpuInfo.htAvailable = false; ++ logicalCpuInfo.numLogicalPerPackage = 1; ++ logicalCpuInfo.numPackages = 0; ++ logicalCpuInfo.physicalAffinityMask = 0; ++ ++#if SUPPORT_AFFINITIES ++ cpu_set_t processAffinity; ++ ++ /* ++ N.B. If this line causes a compile error, then you've probably not got the latest ++ version of glibc installed. ++ ++ If you don't want to update your copy of glibc and don't care about cpu affinities, ++ then you can just disable all this stuff by removing the SUPPORT_AFFINITIES macro ++ from the linuxincludes.h file. ++ */ ++ if (sched_getaffinity (getpid(), ++ sizeof (cpu_set_t), ++ &processAffinity) != sizeof (cpu_set_t)) ++ { ++ return; ++ } ++ ++ // Checks: CPUID supported, model >= Pentium 4, Hyperthreading bit set, logical CPUs per package > 1 ++ if (featuresWord == 0 ++ || ((familyModelWord >> 8) & 0xf) < 15 ++ || (featuresWord & (1 << 28)) == 0 ++ || ((extFeaturesWord >> 16) & 0xff) < 2) ++ { ++ for (int i = 0; i < 64; ++i) ++ if (CPU_ISSET (i, &processAffinity)) ++ logicalCpuInfo.physicalAffinityMask |= (1 << i); ++ ++ return; ++ } ++ ++ logicalCpuInfo.htSupported = true; ++ logicalCpuInfo.numLogicalPerPackage = (extFeaturesWord >> 16) & 0xff; ++ ++ cpu_set_t affinityMask; ++ cpu_set_t physAff; ++ CPU_ZERO (&physAff); ++ ++ unsigned char i = 1; ++ unsigned char physIdMask = 0xFF; ++ unsigned char physIdShift = 0; ++ ++ //unsigned char apicId, logId, physId; ++ ++ while (i < logicalCpuInfo.numLogicalPerPackage) ++ { ++ i *= 2; ++ physIdMask <<= 1; ++ physIdShift++; ++ } ++ ++ CPU_SET (0, &affinityMask); ++ logicalCpuInfo.numPackages = 0; ++ ++//xxx revisit this at some point.. ++/* while ((affinityMask != 0) && (affinityMask <= processAffinity)) ++ { ++ int ret; ++ if (! sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinityMask)) ++ { ++ sched_yield(); // schedule onto correct CPU ++ ++ featuresWord = getCPUIDWord(&familyModelWord, &extFeaturesWord); ++ apicId = (unsigned char)(extFeaturesWord >> 24); ++ logId = (unsigned char)(apicId & ~physIdMask); ++ physId = (unsigned char)(apicId >> physIdShift); ++ ++ if (logId != 0) ++ logicalCpuInfo.htAvailable = true; ++ ++ if ((((int)logId) % logicalCpuInfo.numLogicalPerPackage) == 0) ++ { ++ // This is a physical CPU ++ physAff |= affinityMask; ++ logicalCpuInfo.numPackages++; ++ } ++ } ++ ++ affinityMask = affinityMask << 1; ++ } ++ ++ sched_setaffinity (getpid(), sizeof(unsigned long), &processAffinity); ++*/ ++ ++ logicalCpuInfo.physicalAffinityMask = 0; ++ ++ for (int i = 0; i < 64; ++i) ++ if (CPU_ISSET (i, &physAff)) ++ logicalCpuInfo.physicalAffinityMask |= (1 << i); ++ ++#endif ++} ++ ++//============================================================================== ++void Logger::outputDebugString (const String& text) ++{ ++ fprintf (stdout, (const char*) (text + T("\n"))); ++} ++ ++void Logger::outputDebugPrintf (const tchar* format, ...) ++{ ++ String text; ++ va_list args; ++ va_start (args, format); ++ text.vprintf(format, args); ++ outputDebugString(text); ++} ++ ++const String SystemStats::getOSType() ++{ ++ return SystemStats::Linux; ++} ++ ++static const String getCpuInfo (const char* key, bool lastOne = false) ++{ ++ String info; ++ char buf [256]; ++ ++ FILE* f = fopen ("/proc/cpuinfo", "r"); ++ ++ while (f != 0 && fgets (buf, sizeof(buf), f)) ++ { ++ if (strncmp (buf, key, strlen (key)) == 0) ++ { ++ char* p = buf; ++ ++ while (*p && *p != '\n') ++ ++p; ++ ++ if (*p != 0) ++ *p = 0; ++ ++ p = buf; ++ ++ while (*p != 0 && *p != ':') ++ ++p; ++ ++ if (*p != 0 && *(p + 1) != 0) ++ info = p + 2; ++ ++ if (! lastOne) ++ break; ++ } ++ } ++ ++ fclose (f); ++ return info; ++} ++ ++bool SystemStats::hasMMX() ++{ ++ return getCpuInfo ("flags").contains (T("mmx")); ++} ++ ++bool SystemStats::hasSSE() ++{ ++ return getCpuInfo ("flags").contains (T("sse")); ++} ++ ++bool SystemStats::hasSSE2() ++{ ++ return getCpuInfo ("flags").contains (T("sse2")); ++} ++ ++bool SystemStats::has3DNow() ++{ ++ return getCpuInfo ("flags").contains (T("3dnow")); ++} ++ ++const String SystemStats::getCpuVendor() ++{ ++ return getCpuInfo ("vendor_id"); ++} ++ ++int SystemStats::getCpuSpeedInMegaherz() ++{ ++ const String speed (getCpuInfo ("cpu MHz")); ++ ++ return (int) (speed.getFloatValue() + 0.5f); ++} ++ ++bool SystemStats::hasHyperThreading() ++{ ++ return logicalCpuInfo.htAvailable; ++} ++ ++int SystemStats::getMemorySizeInMegabytes() ++{ ++#ifndef __CYGWIN__ ++ struct sysinfo sysi; ++ ++ if (sysinfo (&sysi) == 0) ++ return (sysi.totalram * sysi.mem_unit / (1024 * 1024)); ++ ++ return 0; ++ ++#else ++ jassertfalse ++ return 256; ++#endif ++} ++ ++unsigned int juce_millisecondsSinceStartup() ++{ ++ static unsigned int calibrate = 0; ++ static bool calibrated = false; ++ timeval t; ++ unsigned int ret = 0; ++ ++ if (! gettimeofday (&t, 0)) ++ { ++ if (! calibrated) ++ { ++#ifndef __CYGWIN__ ++ struct sysinfo sysi; ++ ++ if (sysinfo (&sysi) == 0) ++ // Safe to assume system was not brought up earlier than 1970! ++ calibrate = t.tv_sec - sysi.uptime; ++#else ++ // bit of a hack, but things should all still work, as we're not often ++ // really interested in how long the machine's been turned on, and just ++ // use this call for relative times.. ++ calibrate = t.tv_sec; ++#endif ++ ++ calibrated = true; ++ } ++ ++ ret = 1000 * (t.tv_sec - calibrate) + (t.tv_usec / 1000); ++ } ++ ++ return ret; ++} ++ ++double juce_millisecondsSinceStartupHiRes() ++{ ++ return Time::getHighResolutionTicks() * (1.0 / 1000000.0); ++} ++ ++int64 Time::getHighResolutionTicks() ++{ ++ timeval t; ++ if (gettimeofday(&t,NULL)) ++ return 0; ++ ++ return ((int64) t.tv_sec * (int64) 1000000) + (int64) t.tv_usec; ++} ++ ++int64 Time::getHighResolutionTicksPerSecond() ++{ ++ // Microseconds ++ return 1000000; ++} ++ ++bool Time::setSystemTimeToThisTime() const ++{ ++ timeval t; ++ t.tv_sec = millisSinceEpoch % 1000000; ++ t.tv_usec = millisSinceEpoch - t.tv_sec; ++ ++ return settimeofday (&t, NULL) ? false : true; ++} ++ ++const String Uuid::generateUuid() ++{ ++#ifdef JUCE_UUID ++ uuid_t uuid; ++ char *s = new char[37]; ++ String uuidStr; ++ ++ uuid_generate (uuid); ++ uuid_unparse (uuid, s); ++ ++ uuidStr = s; ++ delete[] s; ++ ++ return uuidStr; ++#else ++ jassertfalse ++ return String::empty; ++#endif ++} ++ ++int SystemStats::getPageSize() ++{ ++ static int systemPageSize = 0; ++ ++ if (systemPageSize == 0) ++ systemPageSize = sysconf (_SC_PAGESIZE); ++ ++ return systemPageSize; ++} ++ ++int SystemStats::getNumPhysicalCpus() ++{ ++ if (logicalCpuInfo.numPackages) ++ return logicalCpuInfo.numPackages; ++ ++ return getNumLogicalCpus(); ++} ++ ++int SystemStats::getNumLogicalCpus() ++{ ++ const int lastCpu = getCpuInfo ("processor", true).getIntValue(); ++ ++ return lastCpu + 1; ++} ++ ++uint32 SystemStats::getPhysicalAffinityMask() ++{ ++#if SUPPORT_AFFINITIES ++ return logicalCpuInfo.physicalAffinityMask; ++#else ++ /* affinities aren't supported because either the appropriate header files weren't found, ++ or the SUPPORT_AFFINITIES macro was turned off in linuxheaders.h ++ */ ++ jassertfalse ++ return 0; ++#endif ++ ++} ++ ++//============================================================================== ++void SystemStats::initialiseStats() ++{ ++ // Process starts off as root when running suid ++ Process::lowerPrivilege(); ++ ++ String s (SystemStats::getJUCEVersion()); ++ ++ juce_initLogicalCpuInfo(); ++} ++ ++void PlatformUtilities::fpuReset() ++{ ++} ++ ++END_JUCE_NAMESPACE diff --git a/packages/juce/juce_1.29.bb b/packages/juce/juce_1.29.bb new file mode 100644 index 0000000000..0127a355a0 --- /dev/null +++ b/packages/juce/juce_1.29.bb @@ -0,0 +1,34 @@ +DESCRIPTION = "JUCE is a cross-platform application framework" +HOMEPAGE = "http://www.rawmaterialsoftware.com/juce" +AUTHOR = "Julian Stoerer" +MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" +LICENSE = "GPL" +DEPENDS = "alsa-lib freetype x11" +PR = "r0" + +#FIXME the patches are a) HACKS and b) something's wrong with lineend conversion +SRC_URI = "http://www.rawmaterialsoftware.com/juce/downloads/juce_1_29.zip \ + file://remove-x86isms.patch;patch=1 \ + file://no-opengl.patch;patch=1" +S = "${WORKDIR}/juce" + +LIB = "libjuce_debug" + +do_compile() { + cd ${S}/build/linux && oe_runmake + cd ${S}/demo/build/linux && oe_runmake +} + +do_stage() { + oe_libinstall -a -C bin ${LIB} ${STAGING_LIBDIR} + #FIXME add includes +} + +do_install() { + install -d ${D}${bindir} + install -m 0655 demo/build/linux/build/jucedemo ${D}${bindir} +} + +PACKAGES = "jucedemo" +FILES_jucedemo = "${bindir}" + diff --git a/packages/justreader/justreader_2.0k.bb b/packages/justreader/justreader_2.0k.bb index 70ee709436..fc08ea6102 100644 --- a/packages/justreader/justreader_2.0k.bb +++ b/packages/justreader/justreader_2.0k.bb @@ -13,7 +13,7 @@ S = "${WORKDIR}/TextReader2" inherit palmtop -EXTRA_QMAKEVARS_POST = 'INCLUDEPATH+="${STAGING_INCDIR}/qpe" LIBS+=-lqpe' +EXTRA_QMAKEVARS_POST += 'INCLUDEPATH+="${STAGING_INCDIR}/qpe" LIBS+=-lqpe' export OE_QMAKE_LINK="${CXX}" do_configure_prepend() { diff --git a/packages/konqueror/konqueror-embedded_svn.bb b/packages/konqueror/konqueror-embedded_20060404.bb index c561af3b28..1d269e611e 100644 --- a/packages/konqueror/konqueror-embedded_svn.bb +++ b/packages/konqueror/konqueror-embedded_20060404.bb @@ -2,21 +2,18 @@ DESCRIPTION = "KDE Web Browser Konqueror, QtE based Palmtop Environments Edition SECTION = "opie/applications" PRIORITY = "optional" HOMEPAGE = "http://www.konqueror.org/" -DEPENDS = "openssl pcre qte-mt-static dcopidl-native" +DEPENDS = "openssl pcre virtual/libqte2 dcopidl-native" LICENSE = "LGPL/GPL" -DEFAULT_PREFERENCE = "-1" -FILES_${PN} = "${palmtopdir} /usr/share" -PR = "r1" -PV = "3.5.1+svn${SRCDATE}" +PR = "r2" # this Konqueror needs the KDEDIR set and the font helvetica installed on the target inherit autotools -SRC_URI = "svn://anonsvn.kde.org/home/kde/tags/KDE/3.5.1;module=kdelibs \ - svn://anonsvn.kde.org/home/kde/trunk;module=kdenox \ - file://inject-extraflags.patch;patch=1" - +SRC_URI = "svn://anonsvn.kde.org/home/kde/tags/KDE/3.5.1;module=kdelibs;date=${PV} \ + svn://anonsvn.kde.org/home/kde/trunk;module=kdenox;date=${PV}" +# uncomment this for a static build +# file://inject-extraflags.patch;patch=1" S = "${WORKDIR}/kdenox" export QMAKE = "${STAGING_BINDIR}/qmake" @@ -25,12 +22,13 @@ export UIC = "${STAGING_BINDIR}/uic" export exec_prefix = "${palmtopdir}" export CXXFLAGS = "-fexceptions -frtti -DKJS_VERBOSE=1 -DQT_THREAD_SUPPORT -DQ_OS_UNIX -DQT_NO_DOM -DENABLE_BOOKMARKS" export PCRE_CONFIG = "invalid" -EXTRAFLAGS = "-lts" -EXTRAFLAGS_c7x0 = "-lts -laticore" +# uncomment this for a static build +# EXTRAFLAGS = "-lts" +# EXTRAFLAGS_c7x0 = "-lts -laticore" export EXTRA_OEMAKE = "EXTRA_LDFLAGS='${EXTRAFLAGS}'" EXTRA_OECONF = '--prefix=${palmtopdir} \ - --exec-prefix=${palmtopdir} \ + --exec-prefix=${palmtopdir} \ --includedir=${STAGING_INCDIR} \ --with-extra-includes=${STAGING_INCDIR} \ --with-extra-libs=${STAGING_LIBDIR} \ @@ -40,11 +38,11 @@ EXTRA_OECONF = '--prefix=${palmtopdir} \ --with-qt-libraries=${STAGING_DIR}/${HOST_SYS}/qt2/lib \ --enable-fontsubs \ --with-konq-tmp-prefix=/tmp/kde-cache \ - --enable-static \ -# --disable-static \ -# --enable-shared \ +# --enable-static \ + --disable-static \ + --enable-shared \ --disable-debug \ - --with-gui=road \ + --with-gui=road \ --with-ipv6-lookup=no \ --without-xinerama \ --disable-scrollbars \ @@ -77,3 +75,6 @@ do_configure_prepend() { do_compile_prepend() { perl admin/am_edit } + +FILES_${PN} = "${palmtopdir} ${datadir}" + diff --git a/packages/libopie/libopie2.inc b/packages/libopie/libopie2.inc index 4a05010dea..390de9c9ad 100644 --- a/packages/libopie/libopie2.inc +++ b/packages/libopie/libopie2.inc @@ -15,13 +15,13 @@ PARALLEL_MAKE = "" #FIXME: Add machine specific bits here. Best use oe_machinstall and read from a given file -EXTRA_QMAKEVARS_POST = 'DEFINES+=OPIE_NEW_MALLOC \ +EXTRA_QMAKEVARS_POST += 'DEFINES+=OPIE_NEW_MALLOC \ DEFINES+="OPIE_SOUND_FRAGMENT_SHIFT=16" \ DEFINES+=OPIE_NO_ERASE_RECT_HACKFIX \ LIBS+=-L${S} LIBS+="-Wl,-rpath-link,${S}"' #NOTE: We no longer enable the sqlite PIM backend here, since a) using it means no sync and b) it's too large for 16MB images -EXTRA_QMAKEVARS_PRE = 'ENABLE_SQL_PIM_BACKEND=n' +EXTRA_QMAKEVARS_PRE += 'ENABLE_SQL_PIM_BACKEND=n' MODULES = "opiecore opiedb opiemm opienet opiepim opiesecurity opieui opiebluez" LIBS = "core2 db2 mm2 net2 pim2 security2 ui2 bluez2" diff --git a/packages/libqpe/libqpe-opie.inc b/packages/libqpe/libqpe-opie.inc index 3e7c74e7ef..57759a1681 100644 --- a/packages/libqpe/libqpe-opie.inc +++ b/packages/libqpe/libqpe-opie.inc @@ -1,21 +1,22 @@ -DESCRIPTION = "Base library for the Qt Palmtop Environment" +DESCRIPTION = "Base library for the Qt/Embedded based palmtop environments" +HOMEPAGE = "http://www.trolltech.com" +AUTHOR = "The Trolls" SECTION = "opie/libs" PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" LICENSE = "GPL" -DEPENDS = "uicmoc-native qte" -PROVIDES = "virtual/libqpe" +DEPENDS = "uicmoc-native virtual/libqte2" +PROVIDES = "virtual/libqpe1" S = "${WORKDIR}/library" -inherit qmake +inherit palmtop QMAKE_PROFILES = "library.pro" -EXTRA_QMAKEVARS_PRE = "CONFIG+=LIBQPE_WITHROHFEEDBACK" -EXTRA_QMAKEVARS_POST = "DESTDIR= DEFINES+=LIBQPE_NO_INLINE_IMAGES" -# EXTRA_QMAKEVARS_POST = "DESTDIR=" +EXTRA_QMAKEVARS_PRE += "CONFIG+=LIBQPE_WITHROHFEEDBACK" +EXTRA_QMAKEVARS_POST += "DESTDIR= DEFINES+=LIBQPE_NO_INLINE_IMAGES" -CXXFLAGS_append = " -DQWS -DOPIE_NO_ERASE_RECT_HACKFIX -DOPIE_NEW_MALLOC -fno-rtti -fno-exceptions" +CXXFLAGS_append = " -DOPIE_NO_ERASE_RECT_HACKFIX -DOPIE_NEW_MALLOC" CXXFLAGS_append_c7x0 = " -DOPIE_NO_WINDOWED " CXXFLAGS_append_tosa = " -DOPIE_NO_WINDOWED " CXXFLAGS_append_spitz = " -DOPIE_NO_WINDOWED " diff --git a/packages/libqpe/libqpe-opie_1.2.1.bb b/packages/libqpe/libqpe-opie_1.2.1.bb index 6cd4368187..fd806b8ca6 100644 --- a/packages/libqpe/libqpe-opie_1.2.1.bb +++ b/packages/libqpe/libqpe-opie_1.2.1.bb @@ -1,6 +1,7 @@ include ${PN}.inc TAG = "${@'v' + bb.data.getVar('PV',d,1).replace('.', '_')}" +PR = "r1" SRC_URI = "${HANDHELDS_CVS};tag=${TAG};module=opie/library \ file://0905_datebookmonth.patch;patch=1;pnum=0 \ diff --git a/packages/libqpe/libqpe-opie_cvs.bb b/packages/libqpe/libqpe-opie_cvs.bb index 8e0278daa1..9657868b0f 100644 --- a/packages/libqpe/libqpe-opie_cvs.bb +++ b/packages/libqpe/libqpe-opie_cvs.bb @@ -2,6 +2,7 @@ include ${PN}.inc # Remove the dash below when 1.2.1 changes PV = "1.2.1+cvs-${SRCDATE}" +PR = "r1" SRC_URI = "${HANDHELDS_CVS};module=opie/library \ file://fix-titleheight.patch;patch=1" diff --git a/packages/linux/ixp4xx-kernel/2.6.16/10-mtdpart-redboot-fis-byteswap.patch b/packages/linux/ixp4xx-kernel/2.6.16/10-mtdpart-redboot-fis-byteswap.patch deleted file mode 100644 index 3fa0535abf..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/10-mtdpart-redboot-fis-byteswap.patch +++ /dev/null @@ -1,70 +0,0 @@ -drivers/mtd/redboot.c: recognise a foreign byte sex partition table - -The RedBoot boot loader writes flash partition tables containing native -byte sex 32 bit values. When booting an opposite byte sex kernel (e.g. an -LE kernel from BE RedBoot) the current MTD driver fails to handle the -partition table and therefore is unable to generate the correct partition -map for the flash. - -The patch recognises that the FIS directory (the partition table) is -byte-reversed by examining the partition table size, which is known to be -one erase block (this is an assumption made elsewhere in redboot.c). If -the size matches the erase block after byte swapping the value then -byte-reversal is assumed, if not no further action is taken. The patched -code is fail safe; should redboot.c be changed to support a partition table -with a modified size field the test will fail and the partition table will -be assumed to have the host byte sex. - -If byte-reversal is detected the patch byte swaps the remainder of the 32 -bit fields in the copy of the table; this copy is then used to set up the -MTD partition map. - -Signed-off-by: John Bowler <jbowler@acm.org> -Signed-off-by: Andrew Morton <akpm@osdl.org> -Modified slightly and -Signed-off-by: David Woodhouse <dwmw2@infradead.org> - -Index: drivers/mtd/redboot.c -=================================================================== -RCS file: /home/cvs/mtd/drivers/mtd/redboot.c,v -retrieving revision 1.18 -retrieving revision 1.19 -diff -u -p -r1.18 -r1.19 ---- linux-2.6.15/drivers/mtd/redboot.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/mtd/redboot.c 1970-01-01 00:00:00.000000000 +0000 -@@ -89,8 +89,32 @@ static int parse_redboot_partitions(stru - i = numslots; - break; - } -- if (!memcmp(buf[i].name, "FIS directory", 14)) -+ if (!memcmp(buf[i].name, "FIS directory", 14)) { -+ /* This is apparently the FIS directory entry for the -+ * FIS directory itself. The FIS directory size is -+ * one erase block; if the buf[i].size field is -+ * swab32(erasesize) then we know we are looking at -+ * a byte swapped FIS directory - swap all the entries! -+ * (NOTE: this is 'size' not 'data_length'; size is -+ * the full size of the entry.) -+ */ -+ if (swab32(buf[i].size) == master->erasesize) { -+ int j; -+ for (j = 0; j < numslots && buf[j].name[0] != 0xff; ++j) { -+ /* The unsigned long fields were written with the -+ * wrong byte sex, name and pad have no byte sex. -+ */ -+ swab32s(&buf[j].flash_base); -+ swab32s(&buf[j].mem_base); -+ swab32s(&buf[j].size); -+ swab32s(&buf[j].entry_point); -+ swab32s(&buf[j].data_length); -+ swab32s(&buf[j].desc_cksum); -+ swab32s(&buf[j].file_cksum); -+ } -+ } - break; -+ } - } - if (i == numslots) { - /* Didn't find it */ - - diff --git a/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch b/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch index 3cc84b2a9b..044bd3abc1 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/40-rtc-class.patch @@ -1,6 +1,365 @@ ---- linux-rtc.orig/include/linux/rtc.h 2006-02-19 23:33:10.000000000 +0100 -+++ linux-rtc/include/linux/rtc.h 2006-02-19 23:33:15.000000000 +0100 -@@ -93,8 +93,97 @@ struct rtc_pll_info { +--- + CREDITS | 5 + MAINTAINERS | 6 + arch/arm/Kconfig | 3 + arch/arm/common/rtctime.c | 108 -- + arch/arm/mach-integrator/time.c | 16 + arch/arm/mach-pxa/generic.c | 6 + arch/arm/mach-sa1100/generic.c | 6 + arch/mips/ddb5xxx/common/rtc_ds1386.c | 4 + arch/mips/dec/time.c | 4 + arch/mips/ite-boards/generic/time.c | 4 + arch/mips/jmr3927/common/rtc_ds1742.c | 4 + arch/mips/kernel/time.c | 22 + arch/mips/lasat/setup.c | 4 + arch/mips/mips-boards/atlas/atlas_setup.c | 2 + arch/mips/mips-boards/malta/malta_setup.c | 2 + arch/mips/momentum/jaguar_atx/setup.c | 4 + arch/mips/momentum/ocelot_3/setup.c | 4 + arch/mips/momentum/ocelot_c/setup.c | 4 + arch/mips/pmc-sierra/yosemite/setup.c | 4 + arch/mips/sgi-ip22/ip22-time.c | 4 + arch/mips/sgi-ip32/ip32-setup.c | 4 + arch/mips/sibyte/swarm/setup.c | 8 + arch/mips/sni/setup.c | 4 + arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c | 4 + arch/mips/tx4938/common/rtc_rx5c348.c | 4 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/char/Kconfig | 2 + drivers/i2c/chips/Kconfig | 18 + drivers/i2c/chips/Makefile | 2 + drivers/i2c/chips/rtc8564.c | 385 ------- + drivers/i2c/chips/rtc8564.h | 78 - + drivers/i2c/chips/x1205.c | 698 ------------- + drivers/rtc/Kconfig | 156 ++ + drivers/rtc/Makefile | 20 + drivers/rtc/class.c | 145 ++ + drivers/rtc/hctosys.c | 69 + + drivers/rtc/interface.c | 277 +++++ + drivers/rtc/rtc-dev.c | 382 +++++++ + drivers/rtc/rtc-ds1672.c | 233 ++++ + drivers/rtc/rtc-ep93xx.c | 163 +++ + drivers/rtc/rtc-lib.c | 99 + + drivers/rtc/rtc-pcf8563.c | 355 ++++++ + drivers/rtc/rtc-proc.c | 162 +++ + drivers/rtc/rtc-rs5c372.c | 295 +++++ + drivers/rtc/rtc-sa1100.c | 392 +++++++ + drivers/rtc/rtc-sysfs.c | 124 ++ + drivers/rtc/rtc-test.c | 205 +++ + drivers/rtc/rtc-x1205.c | 619 +++++++++++ + include/asm-arm/rtc.h | 3 + include/asm-mips/time.h | 12 + include/linux/rtc.h | 92 + + include/linux/x1205.h | 31 + 53 files changed, 3888 insertions(+), 1372 deletions(-) + +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/rtc/rtc-lib.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,99 @@ ++/* ++ * rtc and date/time utility functions ++ * ++ * Copyright (C) 2005-06 Tower Technologies ++ * Author: Alessandro Zummo <a.zummo@towertech.it> ++ * ++ * based on arch/arm/common/rtctime.c and other bits ++ * ++ * 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; version 2 of the License. ++*/ ++ ++#include <linux/module.h> ++#include <linux/rtc.h> ++ ++static const unsigned char rtc_days_in_month[] = { ++ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ++}; ++ ++#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) ++#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) ++ ++int rtc_month_days(unsigned int month, unsigned int year) ++{ ++ return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); ++} ++EXPORT_SYMBOL(rtc_month_days); ++ ++/* ++ * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. ++ */ ++void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) ++{ ++ register int days, month, year; ++ ++ days = time / 86400; ++ time -= days * 86400; ++ ++ /* day of the week, 1970-01-01 was a Thursday */ ++ tm->tm_wday = (days + 4) % 7; ++ ++ year = 1970 + days / 365; ++ days -= (year - 1970) * 365 ++ + LEAPS_THRU_END_OF(year - 1) ++ - LEAPS_THRU_END_OF(1970 - 1); ++ if (days < 0) { ++ year -= 1; ++ days += 365 + LEAP_YEAR(year); ++ } ++ tm->tm_year = year - 1900; ++ tm->tm_yday = days + 1; ++ ++ for (month = 0; month < 11; month++) { ++ int newdays; ++ ++ newdays = days - rtc_month_days(month, year); ++ if (newdays < 0) ++ break; ++ days = newdays; ++ } ++ tm->tm_mon = month; ++ tm->tm_mday = days + 1; ++ ++ tm->tm_hour = time / 3600; ++ time -= tm->tm_hour * 3600; ++ tm->tm_min = time / 60; ++ tm->tm_sec = time - tm->tm_min * 60; ++} ++EXPORT_SYMBOL(rtc_time_to_tm); ++ ++/* ++ * Does the rtc_time represent a valid date/time? ++ */ ++int rtc_valid_tm(struct rtc_time *tm) ++{ ++ if (tm->tm_year < 70 ++ || tm->tm_mon >= 12 ++ || tm->tm_mday < 1 ++ || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900) ++ || tm->tm_hour >= 24 ++ || tm->tm_min >= 60 ++ || tm->tm_sec >= 60) ++ return -EINVAL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtc_valid_tm); ++ ++/* ++ * Convert Gregorian date to seconds since 01-01-1970 00:00:00. ++ */ ++int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) ++{ ++ *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, ++ tm->tm_hour, tm->tm_min, tm->tm_sec); ++ return 0; ++} ++EXPORT_SYMBOL(rtc_tm_to_time); +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/rtc/Makefile 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,20 @@ ++# ++# Makefile for RTC class/drivers. ++# ++ ++obj-$(CONFIG_RTC_LIB) += rtc-lib.o ++obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o ++obj-$(CONFIG_RTC_CLASS) += rtc-core.o ++rtc-core-y := class.o interface.o ++ ++obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o ++obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o ++obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o ++ ++obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o ++obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o ++obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o ++obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o ++obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o ++obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o ++obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/rtc/Kconfig 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,156 @@ ++\# ++# RTC class/drivers configuration ++# ++ ++menu "Real Time Clock" ++ ++config RTC_LIB ++ bool ++ ++config RTC_CLASS ++ tristate "RTC class" ++ depends on EXPERIMENTAL ++ default n ++ select RTC_LIB ++ help ++ Generic RTC class support. If you say yes here, you will ++ be allowed to plug one or more RTCs to your system. You will ++ probably want to enable one of more of the interfaces below. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-class. ++ ++config RTC_HCTOSYS ++ bool "Set system time from RTC on startup" ++ depends on RTC_CLASS = y ++ default y ++ help ++ If you say yes here, the system time will be set using ++ the value read from the specified RTC device. This is useful ++ in order to avoid unnecessary fschk runs. ++ ++config RTC_HCTOSYS_DEVICE ++ string "The RTC to read the time from" ++ depends on RTC_HCTOSYS = y ++ default "rtc0" ++ help ++ The RTC device that will be used as the source for ++ the system time, usually rtc0. ++ ++comment "RTC interfaces" ++ depends on RTC_CLASS ++ ++config RTC_INTF_SYSFS ++ tristate "sysfs" ++ depends on RTC_CLASS && SYSFS ++ default RTC_CLASS ++ help ++ Say yes here if you want to use your RTC using the sysfs ++ interface, /sys/class/rtc/rtcX . ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-sysfs. ++ ++config RTC_INTF_PROC ++ tristate "proc" ++ depends on RTC_CLASS && PROC_FS ++ default RTC_CLASS ++ help ++ Say yes here if you want to use your RTC using the proc ++ interface, /proc/driver/rtc . ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-proc. ++ ++config RTC_INTF_DEV ++ tristate "dev" ++ depends on RTC_CLASS ++ default RTC_CLASS ++ help ++ Say yes here if you want to use your RTC using the dev ++ interface, /dev/rtc . ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-dev. ++ ++comment "RTC drivers" ++ depends on RTC_CLASS ++ ++config RTC_DRV_X1205 ++ tristate "Xicor/Intersil X1205 RTC chip" ++ depends on RTC_CLASS && I2C ++ help ++ If you say yes here you get support for the ++ Xicor/Intersil X1205 RTC chip. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-x1205. ++ ++config RTC_DRV_DS1672 ++ tristate "Dallas/Maxim DS1672" ++ depends on RTC_CLASS && I2C ++ help ++ If you say yes here you get support for the ++ Dallas/Maxim DS1672 timekeeping chip. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-ds1672. ++ ++config RTC_DRV_PCF8563 ++ tristate "Philips PCF8563/Epson RTC8564" ++ depends on RTC_CLASS && I2C ++ help ++ If you say yes here you get support for the ++ Philips PCF8563 RTC chip. The Epson RTC8564 ++ should work as well. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-pcf8563. ++ ++config RTC_DRV_RS5C372 ++ tristate "Ricoh RS5C372A/B" ++ depends on RTC_CLASS && I2C ++ help ++ If you say yes here you get support for the ++ Ricoh RS5C372A and RS5C372B RTC chips. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-rs5c372. ++ ++config RTC_DRV_EP93XX ++ tristate "Cirrus Logic EP93XX" ++ depends on RTC_CLASS && ARCH_EP93XX ++ help ++ If you say yes here you get support for the ++ RTC embedded in the Cirrus Logic EP93XX processors. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-ep93xx. ++ ++ ++config RTC_DRV_SA1100 ++ bool "SA11x0/PXA2xx RTC support" ++ depends on ARCH_SA1100 || ARCH_PXA ++ help ++ If you say Y here you will get access to the real time clock ++ built into your SA11x0 or PXA2xx CPU. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called rtc-sa1100. ++ ++config RTC_DRV_TEST ++ tristate "Test driver/device" ++ depends on RTC_CLASS ++ help ++ If you say yes here you get support for the ++ RTC test driver. It's a software RTC which can be ++ used to test the RTC subsystem APIs. It gets ++ the time from the system clock. ++ You want this driver only if you are doing development ++ on the RTC subsystem. Please read the source code ++ for further details. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-test. ++ ++endmenu +--- linux-ixp4xx.orig/drivers/Kconfig 2006-03-08 01:59:18.000000000 +0100 ++++ linux-ixp4xx/drivers/Kconfig 2006-03-08 01:59:26.000000000 +0100 +@@ -72,4 +72,6 @@ source "drivers/sn/Kconfig" + + source "drivers/edac/Kconfig" + ++source "drivers/rtc/Kconfig" ++ + endmenu +--- linux-ixp4xx.orig/drivers/Makefile 2006-03-08 01:59:18.000000000 +0100 ++++ linux-ixp4xx/drivers/Makefile 2006-03-08 01:59:26.000000000 +0100 +@@ -56,6 +56,7 @@ obj-$(CONFIG_USB_GADGET) += usb/gadget/ + obj-$(CONFIG_GAMEPORT) += input/gameport/ + obj-$(CONFIG_INPUT) += input/ + obj-$(CONFIG_I2O) += message/ ++obj-$(CONFIG_RTC_LIB) += rtc/ + obj-$(CONFIG_I2C) += i2c/ + obj-$(CONFIG_W1) += w1/ + obj-$(CONFIG_HWMON) += hwmon/ +--- linux-ixp4xx.orig/include/linux/rtc.h 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/include/linux/rtc.h 2006-03-08 01:59:26.000000000 +0100 +@@ -93,8 +93,100 @@ struct rtc_pll_info { #define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */ #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ @@ -12,12 +371,19 @@ + #ifdef __KERNEL__ ++extern int rtc_month_days(unsigned int month, unsigned int year); ++extern int rtc_valid_tm(struct rtc_time *tm); ++extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time); ++extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); ++ +#include <linux/device.h> +#include <linux/seq_file.h> +#include <linux/cdev.h> +#include <linux/poll.h> +#include <linux/mutex.h> + ++extern struct class *rtc_class; ++ +struct rtc_class_ops { + int (*open)(struct device *); + void (*release)(struct device *); @@ -47,6 +413,7 @@ + struct rtc_class_ops *ops; + struct mutex ops_lock; + ++ struct class_device *rtc_dev; + struct cdev char_dev; + struct mutex char_lock; + @@ -68,11 +435,6 @@ +extern void rtc_device_unregister(struct rtc_device *rdev); +extern int rtc_interface_register(struct class_interface *intf); + -+extern int rtc_month_days(unsigned int month, unsigned int year); -+extern int rtc_valid_tm(struct rtc_time *tm); -+extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time); -+extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); -+ +extern int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm); +extern int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm); +extern int rtc_set_mmss(struct class_device *class_dev, unsigned long secs); @@ -98,28 +460,609 @@ typedef struct rtc_task { void (*func)(void *private_data); void *private_data; ---- linux-rtc.orig/drivers/Kconfig 2006-02-19 23:33:10.000000000 +0100 -+++ linux-rtc/drivers/Kconfig 2006-02-19 23:33:15.000000000 +0100 -@@ -70,4 +70,6 @@ source "drivers/sn/Kconfig" +--- linux-ixp4xx.orig/arch/arm/common/rtctime.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/arm/common/rtctime.c 2006-03-08 01:59:26.000000000 +0100 +@@ -20,6 +20,7 @@ + #include <linux/capability.h> + #include <linux/device.h> + #include <linux/mutex.h> ++#include <linux/rtc.h> - source "drivers/edac/Kconfig" + #include <asm/rtc.h> + #include <asm/semaphore.h> +@@ -42,89 +43,6 @@ static struct rtc_ops *rtc_ops; + + #define rtc_epoch 1900UL + +-static const unsigned char days_in_month[] = { +- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +-}; +- +-#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) +-#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) +- +-static int month_days(unsigned int month, unsigned int year) +-{ +- return days_in_month[month] + (LEAP_YEAR(year) && month == 1); +-} +- +-/* +- * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. +- */ +-void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) +-{ +- int days, month, year; +- +- days = time / 86400; +- time -= days * 86400; +- +- tm->tm_wday = (days + 4) % 7; +- +- year = 1970 + days / 365; +- days -= (year - 1970) * 365 +- + LEAPS_THRU_END_OF(year - 1) +- - LEAPS_THRU_END_OF(1970 - 1); +- if (days < 0) { +- year -= 1; +- days += 365 + LEAP_YEAR(year); +- } +- tm->tm_year = year - 1900; +- tm->tm_yday = days + 1; +- +- for (month = 0; month < 11; month++) { +- int newdays; +- +- newdays = days - month_days(month, year); +- if (newdays < 0) +- break; +- days = newdays; +- } +- tm->tm_mon = month; +- tm->tm_mday = days + 1; +- +- tm->tm_hour = time / 3600; +- time -= tm->tm_hour * 3600; +- tm->tm_min = time / 60; +- tm->tm_sec = time - tm->tm_min * 60; +-} +-EXPORT_SYMBOL(rtc_time_to_tm); +- +-/* +- * Does the rtc_time represent a valid date/time? +- */ +-int rtc_valid_tm(struct rtc_time *tm) +-{ +- if (tm->tm_year < 70 || +- tm->tm_mon >= 12 || +- tm->tm_mday < 1 || +- tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) || +- tm->tm_hour >= 24 || +- tm->tm_min >= 60 || +- tm->tm_sec >= 60) +- return -EINVAL; +- +- return 0; +-} +-EXPORT_SYMBOL(rtc_valid_tm); +- +-/* +- * Convert Gregorian date to seconds since 01-01-1970 00:00:00. +- */ +-int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) +-{ +- *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, +- tm->tm_hour, tm->tm_min, tm->tm_sec); +- +- return 0; +-} +-EXPORT_SYMBOL(rtc_tm_to_time); +- + /* + * Calculate the next alarm time given the requested alarm time mask + * and the current time. +@@ -151,13 +69,13 @@ void rtc_next_alarm_time(struct rtc_time + } + } + +-static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) ++static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) + { + memset(tm, 0, sizeof(struct rtc_time)); + return ops->read_time(tm); + } + +-static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) ++static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) + { + int ret; + +@@ -168,7 +86,7 @@ static inline int rtc_set_time(struct rt + return ret; + } + +-static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) ++static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) + { + int ret = -EINVAL; + if (ops->read_alarm) { +@@ -178,7 +96,7 @@ static inline int rtc_read_alarm(struct + return ret; + } + +-static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) ++static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) + { + int ret = -EINVAL; + if (ops->set_alarm) +@@ -266,7 +184,7 @@ static int rtc_ioctl(struct inode *inode + + switch (cmd) { + case RTC_ALM_READ: +- ret = rtc_read_alarm(ops, &alrm); ++ ret = rtc_arm_read_alarm(ops, &alrm); + if (ret) + break; + ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); +@@ -288,11 +206,11 @@ static int rtc_ioctl(struct inode *inode + alrm.time.tm_wday = -1; + alrm.time.tm_yday = -1; + alrm.time.tm_isdst = -1; +- ret = rtc_set_alarm(ops, &alrm); ++ ret = rtc_arm_set_alarm(ops, &alrm); + break; + + case RTC_RD_TIME: +- ret = rtc_read_time(ops, &tm); ++ ret = rtc_arm_read_time(ops, &tm); + if (ret) + break; + ret = copy_to_user(uarg, &tm, sizeof(tm)); +@@ -310,7 +228,7 @@ static int rtc_ioctl(struct inode *inode + ret = -EFAULT; + break; + } +- ret = rtc_set_time(ops, &tm); ++ ret = rtc_arm_set_time(ops, &tm); + break; + + case RTC_EPOCH_SET: +@@ -341,11 +259,11 @@ static int rtc_ioctl(struct inode *inode + ret = -EFAULT; + break; + } +- ret = rtc_set_alarm(ops, &alrm); ++ ret = rtc_arm_set_alarm(ops, &alrm); + break; + + case RTC_WKALM_RD: +- ret = rtc_read_alarm(ops, &alrm); ++ ret = rtc_arm_read_alarm(ops, &alrm); + if (ret) + break; + ret = copy_to_user(uarg, &alrm, sizeof(alrm)); +@@ -435,7 +353,7 @@ static int rtc_read_proc(char *page, cha + struct rtc_time tm; + char *p = page; + +- if (rtc_read_time(ops, &tm) == 0) { ++ if (rtc_arm_read_time(ops, &tm) == 0) { + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" +@@ -445,7 +363,7 @@ static int rtc_read_proc(char *page, cha + rtc_epoch); + } + +- if (rtc_read_alarm(ops, &alrm) == 0) { ++ if (rtc_arm_read_alarm(ops, &alrm) == 0) { + p += sprintf(p, "alrm_time\t: "); + if ((unsigned int)alrm.time.tm_hour <= 24) + p += sprintf(p, "%02d:", alrm.time.tm_hour); +--- linux-ixp4xx.orig/include/asm-arm/rtc.h 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/rtc.h 2006-03-08 01:59:26.000000000 +0100 +@@ -25,9 +25,6 @@ struct rtc_ops { + int (*proc)(char *buf); + }; + +-void rtc_time_to_tm(unsigned long, struct rtc_time *); +-int rtc_tm_to_time(struct rtc_time *, unsigned long *); +-int rtc_valid_tm(struct rtc_time *); + void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *); + void rtc_update(unsigned long, unsigned long); + int register_rtc(struct rtc_ops *); +--- linux-ixp4xx.orig/drivers/char/Kconfig 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/drivers/char/Kconfig 2006-03-08 01:59:26.000000000 +0100 +@@ -695,7 +695,7 @@ config NVRAM + + config RTC + tristate "Enhanced Real Time Clock Support" +- depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV ++ depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM + ---help--- + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you +--- linux-ixp4xx.orig/arch/arm/Kconfig 2006-03-08 01:59:18.000000000 +0100 ++++ linux-ixp4xx/arch/arm/Kconfig 2006-03-08 01:59:26.000000000 +0100 +@@ -8,6 +8,7 @@ mainmenu "Linux Kernel Configuration" + config ARM + bool + default y ++ select RTC_LIB + help + The ARM series is a line of low-power-consumption RISC chip designs + licensed by ARM Ltd and targeted at embedded applications and +@@ -819,6 +820,8 @@ source "drivers/usb/Kconfig" + + source "drivers/mmc/Kconfig" +source "drivers/rtc/Kconfig" + endmenu ---- linux-rtc.orig/drivers/Makefile 2006-02-19 23:33:10.000000000 +0100 -+++ linux-rtc/drivers/Makefile 2006-02-19 23:33:15.000000000 +0100 -@@ -56,6 +56,7 @@ obj-$(CONFIG_USB_GADGET) += usb/gadget/ - obj-$(CONFIG_GAMEPORT) += input/gameport/ - obj-$(CONFIG_INPUT) += input/ - obj-$(CONFIG_I2O) += message/ -+obj-y += rtc/ - obj-$(CONFIG_I2C) += i2c/ - obj-$(CONFIG_W1) += w1/ - obj-$(CONFIG_HWMON) += hwmon/ + + source "fs/Kconfig" +--- linux-ixp4xx.orig/arch/arm/mach-integrator/time.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-integrator/time.c 2006-03-08 01:59:26.000000000 +0100 +@@ -40,13 +40,13 @@ static int integrator_set_rtc(void) + return 1; + } + +-static int rtc_read_alarm(struct rtc_wkalrm *alrm) ++static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm) + { + rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); + return 0; + } + +-static inline int rtc_set_alarm(struct rtc_wkalrm *alrm) ++static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm) + { + unsigned long time; + int ret; +@@ -62,7 +62,7 @@ static inline int rtc_set_alarm(struct r + return ret; + } + +-static int rtc_read_time(struct rtc_time *tm) ++static int integrator_rtc_read_time(struct rtc_time *tm) + { + rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); + return 0; +@@ -76,7 +76,7 @@ static int rtc_read_time(struct rtc_time + * edge of the 1Hz clock, we must write the time one second + * in advance. + */ +-static inline int rtc_set_time(struct rtc_time *tm) ++static inline int integrator_rtc_set_time(struct rtc_time *tm) + { + unsigned long time; + int ret; +@@ -90,10 +90,10 @@ static inline int rtc_set_time(struct rt + + static struct rtc_ops rtc_ops = { + .owner = THIS_MODULE, +- .read_time = rtc_read_time, +- .set_time = rtc_set_time, +- .read_alarm = rtc_read_alarm, +- .set_alarm = rtc_set_alarm, ++ .read_time = integrator_rtc_read_time, ++ .set_time = integrator_rtc_set_time, ++ .read_alarm = integrator_rtc_read_alarm, ++ .set_alarm = integrator_rtc_set_alarm, + }; + + static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id, +--- linux-ixp4xx.orig/arch/mips/ddb5xxx/common/rtc_ds1386.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/ddb5xxx/common/rtc_ds1386.c 2006-03-08 01:59:26.000000000 +0100 +@@ -165,6 +165,6 @@ rtc_ds1386_init(unsigned long base) + WRITE_RTC(0xB, byte); + + /* set the function pointers */ +- rtc_get_time = rtc_ds1386_get_time; +- rtc_set_time = rtc_ds1386_set_time; ++ rtc_mips_get_time = rtc_ds1386_get_time; ++ rtc_mips_set_time = rtc_ds1386_set_time; + } +--- linux-ixp4xx.orig/arch/mips/dec/time.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/dec/time.c 2006-03-08 01:59:26.000000000 +0100 +@@ -193,8 +193,8 @@ static void dec_ioasic_hpt_init(unsigned + + void __init dec_time_init(void) + { +- rtc_get_time = dec_rtc_get_time; +- rtc_set_mmss = dec_rtc_set_mmss; ++ rtc_mips_get_time = dec_rtc_get_time; ++ rtc_mips_set_mmss = dec_rtc_set_mmss; + + mips_timer_state = dec_timer_state; + mips_timer_ack = dec_timer_ack; +--- linux-ixp4xx.orig/arch/mips/ite-boards/generic/time.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/ite-boards/generic/time.c 2006-03-08 01:59:26.000000000 +0100 +@@ -227,8 +227,8 @@ void __init it8172_time_init(void) + + local_irq_restore(flags); + +- rtc_get_time = it8172_rtc_get_time; +- rtc_set_time = it8172_rtc_set_time; ++ rtc_mips_get_time = it8172_rtc_get_time; ++ rtc_mips_set_time = it8172_rtc_set_time; + } + + #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) +--- linux-ixp4xx.orig/arch/mips/jmr3927/common/rtc_ds1742.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/jmr3927/common/rtc_ds1742.c 2006-03-08 01:59:26.000000000 +0100 +@@ -159,8 +159,8 @@ rtc_ds1742_init(unsigned long base) + db_assert((rtc_base & 0xe0000000) == KSEG1); + + /* set the function pointers */ +- rtc_get_time = rtc_ds1742_get_time; +- rtc_set_time = rtc_ds1742_set_time; ++ rtc_mips_get_time = rtc_ds1742_get_time; ++ rtc_mips_set_time = rtc_ds1742_set_time; + + /* clear oscillator stop bit */ + CMOS_WRITE(RTC_READ, RTC_CONTROL); +--- linux-ixp4xx.orig/arch/mips/kernel/time.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/kernel/time.c 2006-03-08 01:59:26.000000000 +0100 +@@ -65,9 +65,9 @@ static int null_rtc_set_time(unsigned lo + return 0; + } + +-unsigned long (*rtc_get_time)(void) = null_rtc_get_time; +-int (*rtc_set_time)(unsigned long) = null_rtc_set_time; +-int (*rtc_set_mmss)(unsigned long); ++unsigned long (*rtc_mips_get_time)(void) = null_rtc_get_time; ++int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time; ++int (*rtc_mips_set_mmss)(unsigned long); + + + /* usecs per counter cycle, shifted to left by 32 bits */ +@@ -438,7 +438,7 @@ irqreturn_t timer_interrupt(int irq, voi + + /* + * If we have an externally synchronized Linux clock, then update +- * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be ++ * CMOS clock accordingly every ~11 minutes. rtc_mips_set_time() has to be + * called as close as possible to 500 ms before the new second starts. + */ + write_seqlock(&xtime_lock); +@@ -446,7 +446,7 @@ irqreturn_t timer_interrupt(int irq, voi + xtime.tv_sec > last_rtc_update + 660 && + (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && + (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { +- if (rtc_set_mmss(xtime.tv_sec) == 0) { ++ if (rtc_mips_set_mmss(xtime.tv_sec) == 0) { + last_rtc_update = xtime.tv_sec; + } else { + /* do it again in 60 s */ +@@ -563,7 +563,7 @@ asmlinkage void ll_local_timer_interrupt + * b) (optional) calibrate and set the mips_hpt_frequency + * (only needed if you intended to use fixed_rate_gettimeoffset + * or use cpu counter as timer interrupt source) +- * 2) setup xtime based on rtc_get_time(). ++ * 2) setup xtime based on rtc_mips_get_time(). + * 3) choose a appropriate gettimeoffset routine. + * 4) calculate a couple of cached variables for later usage + * 5) board_timer_setup() - +@@ -631,10 +631,10 @@ void __init time_init(void) + if (board_time_init) + board_time_init(); + +- if (!rtc_set_mmss) +- rtc_set_mmss = rtc_set_time; ++ if (!rtc_mips_set_mmss) ++ rtc_mips_set_mmss = rtc_mips_set_time; + +- xtime.tv_sec = rtc_get_time(); ++ xtime.tv_sec = rtc_mips_get_time(); + xtime.tv_nsec = 0; + + set_normalized_timespec(&wall_to_monotonic, +@@ -770,8 +770,8 @@ void to_tm(unsigned long tim, struct rtc + + EXPORT_SYMBOL(rtc_lock); + EXPORT_SYMBOL(to_tm); +-EXPORT_SYMBOL(rtc_set_time); +-EXPORT_SYMBOL(rtc_get_time); ++EXPORT_SYMBOL(rtc_mips_set_time); ++EXPORT_SYMBOL(rtc_mips_get_time); + + unsigned long long sched_clock(void) + { +--- linux-ixp4xx.orig/arch/mips/lasat/setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/lasat/setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -174,8 +174,8 @@ void __init plat_setup(void) + + #ifdef CONFIG_DS1603 + ds1603 = &ds_defs[mips_machtype]; +- rtc_get_time = ds1603_read; +- rtc_set_time = ds1603_set; ++ rtc_mips_get_time = ds1603_read; ++ rtc_mips_set_time = ds1603_set; + #endif + + #ifdef DYNAMIC_SERIAL_INIT +--- linux-ixp4xx.orig/arch/mips/mips-boards/atlas/atlas_setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/mips-boards/atlas/atlas_setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -65,7 +65,7 @@ void __init plat_setup(void) + + board_time_init = mips_time_init; + board_timer_setup = mips_timer_setup; +- rtc_get_time = mips_rtc_get_time; ++ rtc_mips_get_time = mips_rtc_get_time; + } + + static void __init serial_init(void) +--- linux-ixp4xx.orig/arch/mips/mips-boards/malta/malta_setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/mips-boards/malta/malta_setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -225,5 +225,5 @@ void __init plat_setup(void) + + board_time_init = mips_time_init; + board_timer_setup = mips_timer_setup; +- rtc_get_time = mips_rtc_get_time; ++ rtc_mips_get_time = mips_rtc_get_time; + } +--- linux-ixp4xx.orig/arch/mips/momentum/jaguar_atx/setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/momentum/jaguar_atx/setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -228,8 +228,8 @@ void momenco_time_init(void) + mips_hpt_frequency = cpu_clock / 2; + board_timer_setup = momenco_timer_setup; + +- rtc_get_time = m48t37y_get_time; +- rtc_set_time = m48t37y_set_time; ++ rtc_mips_get_time = m48t37y_get_time; ++ rtc_mips_set_time = m48t37y_set_time; + } + + static struct resource mv_pci_io_mem0_resource = { +--- linux-ixp4xx.orig/arch/mips/momentum/ocelot_3/setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/momentum/ocelot_3/setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -215,8 +215,8 @@ void momenco_time_init(void) + mips_hpt_frequency = cpu_clock / 2; + board_timer_setup = momenco_timer_setup; + +- rtc_get_time = m48t37y_get_time; +- rtc_set_time = m48t37y_set_time; ++ rtc_mips_get_time = m48t37y_get_time; ++ rtc_mips_set_time = m48t37y_set_time; + } + + /* +--- linux-ixp4xx.orig/arch/mips/momentum/ocelot_c/setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/momentum/ocelot_c/setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -226,8 +226,8 @@ void momenco_time_init(void) + printk("momenco_time_init cpu_clock=%d\n", cpu_clock); + board_timer_setup = momenco_timer_setup; + +- rtc_get_time = m48t37y_get_time; +- rtc_set_time = m48t37y_set_time; ++ rtc_mips_get_time = m48t37y_get_time; ++ rtc_mips_set_time = m48t37y_set_time; + } + + void __init plat_setup(void) +--- linux-ixp4xx.orig/arch/mips/pmc-sierra/yosemite/setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/pmc-sierra/yosemite/setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -198,8 +198,8 @@ static void __init py_rtc_setup(void) + if (!m48t37_base) + printk(KERN_ERR "Mapping the RTC failed\n"); + +- rtc_get_time = m48t37y_get_time; +- rtc_set_time = m48t37y_set_time; ++ rtc_mips_get_time = m48t37y_get_time; ++ rtc_mips_set_time = m48t37y_set_time; + + write_seqlock(&xtime_lock); + xtime.tv_sec = m48t37y_get_time(); +--- linux-ixp4xx.orig/arch/mips/sgi-ip22/ip22-time.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/sgi-ip22/ip22-time.c 2006-03-08 01:59:26.000000000 +0100 +@@ -212,8 +212,8 @@ static void indy_timer_setup(struct irqa + void __init ip22_time_init(void) + { + /* setup hookup functions */ +- rtc_get_time = indy_rtc_get_time; +- rtc_set_time = indy_rtc_set_time; ++ rtc_mips_get_time = indy_rtc_get_time; ++ rtc_mips_set_time = indy_rtc_set_time; + + board_time_init = indy_time_init; + board_timer_setup = indy_timer_setup; +--- linux-ixp4xx.orig/arch/mips/sgi-ip32/ip32-setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/sgi-ip32/ip32-setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -91,8 +91,8 @@ void __init plat_setup(void) + { + board_be_init = ip32_be_init; + +- rtc_get_time = mc146818_get_cmos_time; +- rtc_set_mmss = mc146818_set_rtc_mmss; ++ rtc_mips_get_time = mc146818_get_cmos_time; ++ rtc_mips_set_mmss = mc146818_set_rtc_mmss; + + board_time_init = ip32_time_init; + board_timer_setup = ip32_timer_setup; +--- linux-ixp4xx.orig/arch/mips/sibyte/swarm/setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/sibyte/swarm/setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -114,14 +114,14 @@ void __init plat_setup(void) + + if (xicor_probe()) { + printk("swarm setup: Xicor 1241 RTC detected.\n"); +- rtc_get_time = xicor_get_time; +- rtc_set_time = xicor_set_time; ++ rtc_mips_get_time = xicor_get_time; ++ rtc_mips_set_time = xicor_set_time; + } + + if (m41t81_probe()) { + printk("swarm setup: M41T81 RTC detected.\n"); +- rtc_get_time = m41t81_get_time; +- rtc_set_time = m41t81_set_time; ++ rtc_mips_get_time = m41t81_get_time; ++ rtc_mips_set_time = m41t81_set_time; + } + + printk("This kernel optimized for " +--- linux-ixp4xx.orig/arch/mips/sni/setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/sni/setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -164,8 +164,8 @@ static struct pci_controller sni_control + + static inline void sni_pcimt_time_init(void) + { +- rtc_get_time = mc146818_get_cmos_time; +- rtc_set_time = mc146818_set_rtc_mmss; ++ rtc_mips_get_time = mc146818_get_cmos_time; ++ rtc_mips_set_time = mc146818_set_rtc_mmss; + } + + void __init plat_setup(void) +--- linux-ixp4xx.orig/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2006-03-08 01:59:26.000000000 +0100 +@@ -1036,8 +1036,8 @@ toshiba_rbtx4927_time_init(void) + + #ifdef CONFIG_RTC_DS1742 + +- rtc_get_time = rtc_ds1742_get_time; +- rtc_set_time = rtc_ds1742_set_time; ++ rtc_mips_get_time = rtc_ds1742_get_time; ++ rtc_mips_set_time = rtc_ds1742_set_time; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()-\n"); +--- linux-ixp4xx.orig/arch/mips/tx4938/common/rtc_rx5c348.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/mips/tx4938/common/rtc_rx5c348.c 2006-03-08 01:59:26.000000000 +0100 +@@ -197,6 +197,6 @@ rtc_rx5c348_init(int chipid) + srtc_24h = 1; + + /* set the function pointers */ +- rtc_get_time = rtc_rx5c348_get_time; +- rtc_set_time = rtc_rx5c348_set_time; ++ rtc_mips_get_time = rtc_rx5c348_get_time; ++ rtc_mips_set_time = rtc_rx5c348_set_time; + } +--- linux-ixp4xx.orig/include/asm-mips/time.h 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/include/asm-mips/time.h 2006-03-08 01:59:26.000000000 +0100 +@@ -26,14 +26,14 @@ extern spinlock_t rtc_lock; + + /* + * RTC ops. By default, they point to no-RTC functions. +- * rtc_get_time - mktime(year, mon, day, hour, min, sec) in seconds. +- * rtc_set_time - reverse the above translation and set time to RTC. +- * rtc_set_mmss - similar to rtc_set_time, but only min and sec need ++ * rtc_mips_get_time - mktime(year, mon, day, hour, min, sec) in seconds. ++ * rtc_mips_set_time - reverse the above translation and set time to RTC. ++ * rtc_mips_set_mmss - similar to rtc_set_time, but only min and sec need + * to be set. Used by RTC sync-up. + */ +-extern unsigned long (*rtc_get_time)(void); +-extern int (*rtc_set_time)(unsigned long); +-extern int (*rtc_set_mmss)(unsigned long); ++extern unsigned long (*rtc_mips_get_time)(void); ++extern int (*rtc_mips_set_time)(unsigned long); ++extern int (*rtc_mips_set_mmss)(unsigned long); + + /* + * Timer interrupt functions. --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/class.c 2006-02-19 23:33:15.000000000 +0100 -@@ -0,0 +1,143 @@ ++++ linux-ixp4xx/drivers/rtc/class.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,145 @@ +/* + * RTC subsystem, base class + * @@ -182,7 +1125,8 @@ + + id = id & MAX_ID_MASK; + -+ if ((rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL)) == NULL) { ++ rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); ++ if (rtc == NULL) { + err = -ENOMEM; + goto exit_idr; + } @@ -201,7 +1145,8 @@ + strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); + snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id); + -+ if ((err = class_device_register(&rtc->class_dev))) ++ err = class_device_register(&rtc->class_dev); ++ if (err) + goto exit_kfree; + + dev_info(dev, "rtc core: registered %s as %s\n", @@ -264,163 +1209,8 @@ +MODULE_DESCRIPTION("RTC class support"); +MODULE_LICENSE("GPL"); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/Kconfig 2006-02-21 00:36:43.000000000 +0100 -@@ -0,0 +1,131 @@ -+# -+# RTC class/drivers configuration -+# -+ -+menu "Real Time Clock" -+ -+config RTC_CLASS -+ tristate "RTC class" -+ depends on EXPERIMENTAL -+ default y -+ help -+ Generic RTC class support. If you say yes here, you will -+ be allowed to plug one or more RTCs to your system. You will -+ probably want to enable one of more of the interfaces below. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-class. -+ -+config RTC_HCTOSYS -+ bool "Set system time from RTC on startup" -+ depends on RTC_CLASS = y -+ default y -+ help -+ If you say yes here, the system time will be set using -+ the value read from the specified RTC device. This is useful -+ in order to avoid unnecessary fschk runs. -+ -+config RTC_HCTOSYS_DEVICE -+ string "The RTC to read the time from" -+ depends on RTC_HCTOSYS = y -+ default "rtc0" -+ help -+ The RTC device that will be used as the source for -+ the system time, usually rtc0. -+ -+comment "RTC interfaces" -+ depends on RTC_CLASS -+ -+config RTC_INTF_SYSFS -+ tristate "sysfs" -+ depends on RTC_CLASS && SYSFS -+ default RTC_CLASS -+ help -+ Say yes here if you want to use your RTC using the sysfs -+ interface, /sys/class/rtc/rtcX . -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-sysfs. -+ -+config RTC_INTF_PROC -+ tristate "proc" -+ depends on RTC_CLASS && PROC_FS -+ default RTC_CLASS -+ help -+ Say yes here if you want to use your RTC using the proc -+ interface, /proc/driver/rtc . -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-proc. -+ -+config RTC_INTF_DEV -+ tristate "dev" -+ depends on RTC_CLASS -+ default RTC_CLASS -+ help -+ Say yes here if you want to use your RTC using the dev -+ interface, /dev/rtc . -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-dev. -+ -+comment "RTC drivers" -+ depends on RTC_CLASS -+ -+config RTC_DRV_X1205 -+ tristate "Xicor/Intersil X1205 RTC chip" -+ depends on RTC_CLASS && I2C -+ help -+ If you say yes here you get support for the -+ Xicor/Intersil X1205 RTC chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-x1205. -+ -+config RTC_DRV_DS1672 -+ tristate "Dallas/Maxim DS1672" -+ depends on RTC_CLASS && I2C -+ help -+ If you say yes here you get support for the -+ Dallas/Maxim DS1672 timekeeping chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-ds1672. -+ -+config RTC_DRV_PCF8563 -+ tristate "Philips PCF8563/Epson RTC8564" -+ depends on RTC_CLASS && I2C -+ help -+ If you say yes here you get support for the -+ Philips PCF8563 RTC chip. The Epson RTC8564 -+ should work as well. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-pcf8563. -+ -+config RTC_DRV_RS5C372 -+ tristate "Ricoh RS5C372A/B" -+ depends on RTC_CLASS && I2C -+ help -+ If you say yes here you get support for the -+ Ricoh RS5C372A and RS5C372B RTC chips. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-rs5c372. -+ -+config RTC_DRV_TEST -+ tristate "Test driver/device" -+ depends on RTC_CLASS -+ help -+ If you say yes here you get support for the -+ RTC test driver. It's a software RTC which can be -+ used to test the RTC subsystem APIs. It gets -+ the time from the system clock. -+ You want this driver only if you are doing development -+ on the RTC subsystem. Please read the source code -+ for further details. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-test. -+ -+endmenu ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/Makefile 2006-02-21 00:36:43.000000000 +0100 -@@ -0,0 +1,18 @@ -+# -+# Makefile for RTC class/drivers. -+# -+ -+obj-y += utils.o -+obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o -+obj-$(CONFIG_RTC_CLASS) += rtc-core.o -+rtc-core-y := class.o interface.o -+obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o -+obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o -+obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o -+ -+obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o -+obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o -+obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o -+obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o -+obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o -+ ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/interface.c 2006-02-19 23:33:15.000000000 +0100 -@@ -0,0 +1,274 @@ ++++ linux-ixp4xx/drivers/rtc/interface.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,277 @@ +/* + * RTC subsystem, interface functions + * @@ -436,15 +1226,14 @@ + +#include <linux/rtc.h> + -+extern struct class *rtc_class; -+ +int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) +{ + int err; + struct rtc_device *rtc = to_rtc_device(class_dev); + -+ if ((err = mutex_lock_interruptible(&rtc->ops_lock))) -+ return err; ++ err = mutex_lock_interruptible(&rtc->ops_lock); ++ if (err) ++ return -EBUSY; + + if (!rtc->ops) + err = -ENODEV; @@ -458,18 +1247,20 @@ + mutex_unlock(&rtc->ops_lock); + return err; +} -+EXPORT_SYMBOL(rtc_read_time); ++EXPORT_SYMBOL_GPL(rtc_read_time); + +int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) +{ + int err; + struct rtc_device *rtc = to_rtc_device(class_dev); + -+ if ((err = rtc_valid_tm(tm)) != 0) ++ err = rtc_valid_tm(tm); ++ if (err != 0) + return err; + -+ if ((err = mutex_lock_interruptible(&rtc->ops_lock))) -+ return err; ++ err = mutex_lock_interruptible(&rtc->ops_lock); ++ if (err) ++ return -EBUSY; + + if (!rtc->ops) + err = -ENODEV; @@ -481,57 +1272,56 @@ + mutex_unlock(&rtc->ops_lock); + return err; +} -+EXPORT_SYMBOL(rtc_set_time); ++EXPORT_SYMBOL_GPL(rtc_set_time); + +int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) +{ + int err; + struct rtc_device *rtc = to_rtc_device(class_dev); + -+ if ((err = mutex_lock_interruptible(&rtc->ops_lock))) -+ return err; ++ err = mutex_lock_interruptible(&rtc->ops_lock); ++ if (err) ++ return -EBUSY; + + if (!rtc->ops) + err = -ENODEV; -+ else if (!rtc->ops->set_mmss) { -+ if (rtc->ops->read_time && rtc->ops->set_time) { -+ struct rtc_time new, old; -+ -+ new.tm_sec = secs % 60; -+ secs /= 60; -+ new.tm_min = secs % 60; -+ secs /= 60; -+ new.tm_hour = secs % 24; -+ -+ /* -+ * avoid writing when we're going to change the day -+ * of the month. We will retry in the next minute. -+ * This basically means that if the RTC must not drift -+ * by more than 1 minute in 11 minutes. -+ */ ++ else if (rtc->ops->set_mmss) ++ err = rtc->ops->set_mmss(class_dev->dev, secs); ++ else if (rtc->ops->read_time && rtc->ops->set_time) { ++ struct rtc_time new, old; ++ ++ err = rtc->ops->read_time(class_dev->dev, &old); ++ if (err == 0) { ++ rtc_time_to_tm(secs, &new); ++ ++ /* ++ * avoid writing when we're going to change the day of ++ * the month. We will retry in the next minute. This ++ * basically means that if the RTC must not drift ++ * by more than 1 minute in 11 minutes. ++ */ + if (!((old.tm_hour == 23 && old.tm_min == 59) || -+ (new.tm_hour == 23 && new.tm_min == 59))) ++ (new.tm_hour == 23 && new.tm_min == 59))) + err = rtc->ops->set_time(class_dev->dev, &new); + } -+ else -+ err = -EINVAL; + } + else -+ err = rtc->ops->set_mmss(class_dev->dev, secs); ++ err = -EINVAL; + + mutex_unlock(&rtc->ops_lock); + + return err; +} -+EXPORT_SYMBOL(rtc_set_mmss); ++EXPORT_SYMBOL_GPL(rtc_set_mmss); + +int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) +{ + int err; + struct rtc_device *rtc = to_rtc_device(class_dev); + -+ if ((err = mutex_lock_interruptible(&rtc->ops_lock))) -+ return err; ++ err = mutex_lock_interruptible(&rtc->ops_lock); ++ if (err) ++ return -EBUSY; + + if (rtc->ops == NULL) + err = -ENODEV; @@ -545,15 +1335,16 @@ + mutex_unlock(&rtc->ops_lock); + return err; +} -+EXPORT_SYMBOL(rtc_read_alarm); ++EXPORT_SYMBOL_GPL(rtc_read_alarm); + +int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) +{ + int err; + struct rtc_device *rtc = to_rtc_device(class_dev); + -+ if ((err = mutex_lock_interruptible(&rtc->ops_lock))) -+ return err; ++ err = mutex_lock_interruptible(&rtc->ops_lock); ++ if (err) ++ return -EBUSY; + + if (!rtc->ops) + err = -ENODEV; @@ -565,7 +1356,7 @@ + mutex_unlock(&rtc->ops_lock); + return err; +} -+EXPORT_SYMBOL(rtc_set_alarm); ++EXPORT_SYMBOL_GPL(rtc_set_alarm); + +void rtc_update_irq(struct class_device *class_dev, + unsigned long num, unsigned long events) @@ -584,7 +1375,7 @@ + wake_up_interruptible(&rtc->irq_queue); + kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); +} -+EXPORT_SYMBOL(rtc_update_irq); ++EXPORT_SYMBOL_GPL(rtc_update_irq); + +struct class_device *rtc_class_open(char *name) +{ @@ -607,13 +1398,13 @@ + + return class_dev; +} -+EXPORT_SYMBOL(rtc_class_open); ++EXPORT_SYMBOL_GPL(rtc_class_open); + +void rtc_class_close(struct class_device *class_dev) +{ + module_put(to_rtc_device(class_dev)->owner); +} -+EXPORT_SYMBOL(rtc_class_close); ++EXPORT_SYMBOL_GPL(rtc_class_close); + +int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) +{ @@ -632,7 +1423,7 @@ + + return retval; +} -+EXPORT_SYMBOL(rtc_irq_register); ++EXPORT_SYMBOL_GPL(rtc_irq_register); + +void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) +{ @@ -643,7 +1434,7 @@ + rtc->irq_task = NULL; + spin_unlock(&rtc->irq_task_lock); +} -+EXPORT_SYMBOL(rtc_irq_unregister); ++EXPORT_SYMBOL_GPL(rtc_irq_unregister); + +int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled) +{ @@ -661,7 +1452,7 @@ + + return err; +} -+EXPORT_SYMBOL(rtc_irq_set_state); ++EXPORT_SYMBOL_GPL(rtc_irq_set_state); + +int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) +{ @@ -672,8 +1463,10 @@ + /* allowed range is 2-8192 */ + if (freq < 2 || freq > 8192) + return -EINVAL; -+ -+/* if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) ++/* ++ FIXME: this does not belong here, will move where appropriate ++ at a later stage. It cannot hurt right now, trust me :) ++ if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) + return -EACCES; +*/ + /* check if freq is a power of 2 */ @@ -689,115 +1482,15 @@ + spin_unlock_irqrestore(&rtc->irq_task_lock, flags); + + if (err == 0) { -+ if ((err = rtc->ops->irq_set_freq(class_dev->dev, freq)) == 0) ++ err = rtc->ops->irq_set_freq(class_dev->dev, freq); ++ if (err == 0) + rtc->irq_freq = freq; + } + return err; -+ +} --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/utils.c 2006-02-19 23:33:15.000000000 +0100 -@@ -0,0 +1,97 @@ -+/* -+ * RTC subsystem, utility functions -+ * -+ * Copyright (C) 2005 Tower Technologies -+ * Author: Alessandro Zummo <a.zummo@towertech.it> -+ * -+ * based on arch/arm/common/rtctime.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+*/ -+ -+#include <linux/rtc.h> -+ -+static const unsigned char rtc_days_in_month[] = { -+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -+}; -+ -+#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) -+#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) -+ -+int rtc_month_days(unsigned int month, unsigned int year) -+{ -+ return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); -+} -+EXPORT_SYMBOL(rtc_month_days); -+ -+/* -+ * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. -+ */ -+void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) -+{ -+ int days, month, year; -+ -+ days = time / 86400; -+ time -= days * 86400; -+ -+ tm->tm_wday = (days + 4) % 7; -+ -+ year = 1970 + days / 365; -+ days -= (year - 1970) * 365 -+ + LEAPS_THRU_END_OF(year - 1) -+ - LEAPS_THRU_END_OF(1970 - 1); -+ if (days < 0) { -+ year -= 1; -+ days += 365 + LEAP_YEAR(year); -+ } -+ tm->tm_year = year - 1900; -+ tm->tm_yday = days + 1; -+ -+ for (month = 0; month < 11; month++) { -+ int newdays; -+ -+ newdays = days - rtc_month_days(month, year); -+ if (newdays < 0) -+ break; -+ days = newdays; -+ } -+ tm->tm_mon = month; -+ tm->tm_mday = days + 1; -+ -+ tm->tm_hour = time / 3600; -+ time -= tm->tm_hour * 3600; -+ tm->tm_min = time / 60; -+ tm->tm_sec = time - tm->tm_min * 60; -+} -+EXPORT_SYMBOL(rtc_time_to_tm); -+ -+/* -+ * Does the rtc_time represent a valid date/time? -+ */ -+int rtc_valid_tm(struct rtc_time *tm) -+{ -+ if (tm->tm_year < 70 || -+ tm->tm_mon >= 12 || -+ tm->tm_mday < 1 || -+ tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900) || -+ tm->tm_hour >= 24 || -+ tm->tm_min >= 60 || -+ tm->tm_sec >= 60) -+ return -EINVAL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(rtc_valid_tm); -+ -+/* -+ * Convert Gregorian date to seconds since 01-01-1970 00:00:00. -+ */ -+int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) -+{ -+ *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, -+ tm->tm_hour, tm->tm_min, tm->tm_sec); -+ return 0; -+} -+EXPORT_SYMBOL(rtc_tm_to_time); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/hctosys.c 2006-02-21 00:34:57.000000000 +0100 -@@ -0,0 +1,67 @@ ++++ linux-ixp4xx/drivers/rtc/hctosys.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,69 @@ +/* + * RTC subsystem, initialize system time on startup + * @@ -834,8 +1527,10 @@ + return -ENODEV; + } + -+ if ((err = rtc_read_time(class_dev, &tm)) == 0) { -+ if (rtc_valid_tm(&tm) == 0) { ++ err = rtc_read_time(class_dev, &tm); ++ if (err == 0) { ++ err = rtc_valid_tm(&tm); ++ if (err == 0) { + struct timespec tv; + + tv.tv_nsec = NSEC_PER_SEC >> 1; @@ -865,231 +1560,38 @@ +} + +late_initcall(rtc_hctosys); ---- linux-rtc.orig/arch/arm/Kconfig 2006-02-21 00:34:27.000000000 +0100 -+++ linux-rtc/arch/arm/Kconfig 2006-02-21 00:36:42.000000000 +0100 -@@ -817,6 +817,8 @@ source "drivers/usb/Kconfig" - - source "drivers/mmc/Kconfig" - -+source "drivers/rtc/Kconfig" -+ - endmenu - - source "fs/Kconfig" ---- linux-rtc.orig/arch/arm/common/rtctime.c 2006-02-21 00:34:27.000000000 +0100 -+++ linux-rtc/arch/arm/common/rtctime.c 2006-02-21 00:36:42.000000000 +0100 -@@ -42,89 +42,6 @@ static struct rtc_ops *rtc_ops; - - #define rtc_epoch 1900UL - --static const unsigned char days_in_month[] = { -- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 --}; -- --#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) --#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) -- --static int month_days(unsigned int month, unsigned int year) --{ -- return days_in_month[month] + (LEAP_YEAR(year) && month == 1); --} -- --/* -- * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. -- */ --void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) --{ -- int days, month, year; -- -- days = time / 86400; -- time -= days * 86400; -- -- tm->tm_wday = (days + 4) % 7; -- -- year = 1970 + days / 365; -- days -= (year - 1970) * 365 -- + LEAPS_THRU_END_OF(year - 1) -- - LEAPS_THRU_END_OF(1970 - 1); -- if (days < 0) { -- year -= 1; -- days += 365 + LEAP_YEAR(year); -- } -- tm->tm_year = year - 1900; -- tm->tm_yday = days + 1; -- -- for (month = 0; month < 11; month++) { -- int newdays; -- -- newdays = days - month_days(month, year); -- if (newdays < 0) -- break; -- days = newdays; -- } -- tm->tm_mon = month; -- tm->tm_mday = days + 1; -- -- tm->tm_hour = time / 3600; -- time -= tm->tm_hour * 3600; -- tm->tm_min = time / 60; -- tm->tm_sec = time - tm->tm_min * 60; --} --EXPORT_SYMBOL(rtc_time_to_tm); -- --/* -- * Does the rtc_time represent a valid date/time? -- */ --int rtc_valid_tm(struct rtc_time *tm) --{ -- if (tm->tm_year < 70 || -- tm->tm_mon >= 12 || -- tm->tm_mday < 1 || -- tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) || -- tm->tm_hour >= 24 || -- tm->tm_min >= 60 || -- tm->tm_sec >= 60) -- return -EINVAL; -- -- return 0; --} --EXPORT_SYMBOL(rtc_valid_tm); -- --/* -- * Convert Gregorian date to seconds since 01-01-1970 00:00:00. -- */ --int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) --{ -- *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, -- tm->tm_hour, tm->tm_min, tm->tm_sec); -- -- return 0; --} --EXPORT_SYMBOL(rtc_tm_to_time); -- - /* - * Calculate the next alarm time given the requested alarm time mask - * and the current time. -@@ -143,13 +60,13 @@ void rtc_next_alarm_time(struct rtc_time - next->tm_sec = alrm->tm_sec; - } - --static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) -+static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) - { - memset(tm, 0, sizeof(struct rtc_time)); - return ops->read_time(tm); - } - --static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) -+static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) - { - int ret; - -@@ -160,7 +77,7 @@ static inline int rtc_set_time(struct rt - return ret; - } - --static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -+static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) - { - int ret = -EINVAL; - if (ops->read_alarm) { -@@ -170,7 +87,7 @@ static inline int rtc_read_alarm(struct - return ret; - } - --static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -+static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) - { - int ret = -EINVAL; - if (ops->set_alarm) -@@ -258,7 +175,7 @@ static int rtc_ioctl(struct inode *inode - - switch (cmd) { - case RTC_ALM_READ: -- ret = rtc_read_alarm(ops, &alrm); -+ ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); -@@ -280,11 +197,11 @@ static int rtc_ioctl(struct inode *inode - alrm.time.tm_wday = -1; - alrm.time.tm_yday = -1; - alrm.time.tm_isdst = -1; -- ret = rtc_set_alarm(ops, &alrm); -+ ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_RD_TIME: -- ret = rtc_read_time(ops, &tm); -+ ret = rtc_arm_read_time(ops, &tm); - if (ret) - break; - ret = copy_to_user(uarg, &tm, sizeof(tm)); -@@ -302,7 +219,7 @@ static int rtc_ioctl(struct inode *inode - ret = -EFAULT; - break; - } -- ret = rtc_set_time(ops, &tm); -+ ret = rtc_arm_set_time(ops, &tm); - break; - - case RTC_EPOCH_SET: -@@ -333,11 +250,11 @@ static int rtc_ioctl(struct inode *inode - ret = -EFAULT; - break; - } -- ret = rtc_set_alarm(ops, &alrm); -+ ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_WKALM_RD: -- ret = rtc_read_alarm(ops, &alrm); -+ ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm, sizeof(alrm)); -@@ -427,7 +344,7 @@ static int rtc_read_proc(char *page, cha - struct rtc_time tm; - char *p = page; - -- if (rtc_read_time(ops, &tm) == 0) { -+ if (rtc_arm_read_time(ops, &tm) == 0) { - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" -@@ -437,7 +354,7 @@ static int rtc_read_proc(char *page, cha - rtc_epoch); - } +--- linux-ixp4xx.orig/CREDITS 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/CREDITS 2006-03-08 01:59:26.000000000 +0100 +@@ -3741,10 +3741,11 @@ D: Mylex DAC960 PCI RAID driver + D: Miscellaneous kernel fixes -- if (rtc_read_alarm(ops, &alrm) == 0) { -+ if (rtc_arm_read_alarm(ops, &alrm) == 0) { - p += sprintf(p, "alrm_time\t: "); - if ((unsigned int)alrm.time.tm_hour <= 24) - p += sprintf(p, "%02d:", alrm.time.tm_hour); ---- linux-rtc.orig/include/asm-arm/rtc.h 2006-02-21 00:34:27.000000000 +0100 -+++ linux-rtc/include/asm-arm/rtc.h 2006-02-21 00:36:42.000000000 +0100 -@@ -25,9 +25,6 @@ struct rtc_ops { - int (*proc)(char *buf); - }; + N: Alessandro Zummo +-E: azummo@ita.flashnet.it +-W: http://freepage.logicom.it/azummo/ ++E: a.zummo@towertech.it + D: CMI8330 support is sb_card.c + D: ISAPnP fixes in sb_card.c ++D: ZyXEL omni.net lcd plus driver ++D: RTC subsystem + S: Italy --void rtc_time_to_tm(unsigned long, struct rtc_time *); --int rtc_tm_to_time(struct rtc_time *, unsigned long *); --int rtc_valid_tm(struct rtc_time *); - void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *); - void rtc_update(unsigned long, unsigned long); - int register_rtc(struct rtc_ops *); ---- linux-rtc.orig/drivers/char/Kconfig 2006-02-21 00:34:27.000000000 +0100 -+++ linux-rtc/drivers/char/Kconfig 2006-02-21 00:36:42.000000000 +0100 -@@ -695,7 +695,7 @@ config NVRAM + N: Marc Zyngier +--- linux-ixp4xx.orig/MAINTAINERS 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/MAINTAINERS 2006-03-08 01:59:26.000000000 +0100 +@@ -2193,6 +2193,12 @@ M: p_gortmaker@yahoo.com + L: linux-kernel@vger.kernel.org + S: Maintained - config RTC - tristate "Enhanced Real Time Clock Support" -- depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV -+ depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM - ---help--- - If you say Y here and create a character special file /dev/rtc with - major number 10 and minor number 135 using mknod ("man mknod"), you ---- linux-rtc.orig/drivers/i2c/chips/x1205.c 2006-02-21 00:34:27.000000000 +0100 ++REAL TIME CLOCK (RTC) SUBSYSTEM ++P: Alessandro Zummo ++M: a.zummo@towertech.it ++L: linux-kernel@vger.kernel.org ++S: Maintained ++ + REISERFS FILE SYSTEM + P: Hans Reiser + M: reiserfs-dev@namesys.com +--- linux-ixp4xx.orig/drivers/i2c/chips/x1205.c 2006-03-08 01:59:09.000000000 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,698 +0,0 @@ -/* @@ -1790,8 +2292,8 @@ - -module_init(x1205_init); -module_exit(x1205_exit); ---- linux-rtc.orig/drivers/i2c/chips/Makefile 2006-02-21 00:34:27.000000000 +0100 -+++ linux-rtc/drivers/i2c/chips/Makefile 2006-02-21 00:36:43.000000000 +0100 +--- linux-ixp4xx.orig/drivers/i2c/chips/Makefile 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/drivers/i2c/chips/Makefile 2006-03-08 01:59:26.000000000 +0100 @@ -10,10 +10,8 @@ obj-$(CONFIG_SENSORS_M41T00) += m41t00.o obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o @@ -1803,7 +2305,7 @@ ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG ---- linux-rtc.orig/drivers/i2c/chips/rtc8564.c 2006-02-21 00:34:27.000000000 +0100 +--- linux-ixp4xx.orig/drivers/i2c/chips/rtc8564.c 2006-03-08 01:59:09.000000000 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,385 +0,0 @@ -/* @@ -2191,7 +2693,7 @@ - -module_init(rtc8564_init); -module_exit(rtc8564_exit); ---- linux-rtc.orig/drivers/i2c/chips/rtc8564.h 2006-02-21 00:34:27.000000000 +0100 +--- linux-ixp4xx.orig/drivers/i2c/chips/rtc8564.h 2006-03-08 01:59:09.000000000 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -/* @@ -2272,7 +2774,7 @@ -#define RTC8564_TD_1_60HZ (0x3) - -#define I2C_DRIVERID_RTC8564 0xf000 ---- linux-rtc.orig/include/linux/x1205.h 2006-02-21 00:34:27.000000000 +0100 +--- linux-ixp4xx.orig/include/linux/x1205.h 2006-03-08 01:59:09.000000000 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -/* @@ -2306,9 +2808,9 @@ - struct i2c_client_address_data *address_data); - -#endif /* __LINUX_X1205_H__ */ ---- linux-rtc.orig/drivers/i2c/chips/Kconfig 2006-02-21 00:34:27.000000000 +0100 -+++ linux-rtc/drivers/i2c/chips/Kconfig 2006-02-21 00:36:43.000000000 +0100 -@@ -65,15 +65,6 @@ config SENSORS_PCF8591 +--- linux-ixp4xx.orig/drivers/i2c/chips/Kconfig 2006-03-08 01:59:09.000000000 +0100 +1+++ linux-ixp4xx/drivers/i2c/chips/Kconfig 2006-03-08 01:59:26.000000000 +0100 +@@ -74,15 +74,6 @@ config SENSORS_RTC8564 This driver can also be built as a module. If so, the module will be called pcf8591. @@ -2324,7 +2826,7 @@ config ISP1301_OMAP tristate "Philips ISP1301 with OMAP OTG" depends on I2C && ARCH_OMAP_OTG -@@ -126,13 +117,4 @@ config SENSORS_MAX6875 +@@ -144,13 +135,4 @@ config RTC_X1205_I2C This driver can also be built as a module. If so, the module will be called max6875. @@ -2339,8 +2841,8 @@ - endmenu --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-sysfs.c 2006-02-21 00:36:43.000000000 +0100 -@@ -0,0 +1,120 @@ ++++ linux-ixp4xx/drivers/rtc/rtc-sysfs.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,124 @@ +/* + * RTC subsystem, sysfs interface + * @@ -2368,7 +2870,8 @@ + ssize_t retval; + struct rtc_time tm; + -+ if ((retval = rtc_read_time(dev, &tm)) == 0) { ++ retval = rtc_read_time(dev, &tm); ++ if (retval == 0) { + retval = sprintf(buf, "%04d-%02d-%02d\n", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + } @@ -2382,7 +2885,8 @@ + ssize_t retval; + struct rtc_time tm; + -+ if ((retval = rtc_read_time(dev, &tm)) == 0) { ++ retval = rtc_read_time(dev, &tm); ++ if (retval == 0) { + retval = sprintf(buf, "%02d:%02d:%02d\n", + tm.tm_hour, tm.tm_min, tm.tm_sec); + } @@ -2396,7 +2900,8 @@ + ssize_t retval; + struct rtc_time tm; + -+ if ((retval = rtc_read_time(dev, &tm)) == 0) { ++ retval = rtc_read_time(dev, &tm); ++ if (retval == 0) { + unsigned long time; + rtc_tm_to_time(&tm, &time); + retval = sprintf(buf, "%lu\n", time); @@ -2407,25 +2912,26 @@ +static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL); + +static struct attribute *rtc_attrs[] = { -+ &class_device_attr_name.attr, -+ &class_device_attr_date.attr, -+ &class_device_attr_time.attr, -+ &class_device_attr_since_epoch.attr, -+ NULL, ++ &class_device_attr_name.attr, ++ &class_device_attr_date.attr, ++ &class_device_attr_time.attr, ++ &class_device_attr_since_epoch.attr, ++ NULL, +}; + +static struct attribute_group rtc_attr_group = { -+ .attrs = rtc_attrs, ++ .attrs = rtc_attrs, +}; + +static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, -+ struct class_interface *class_intf) ++ struct class_interface *class_intf) +{ + int err; + + dev_info(class_dev->dev, "rtc intf: sysfs\n"); + -+ if ((err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group)) != 0) ++ err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group); ++ if (err) + dev_err(class_dev->dev, + "failed to create sysfs attributes\n"); + @@ -2433,14 +2939,14 @@ +} + +static void rtc_sysfs_remove_device(struct class_device *class_dev, -+ struct class_interface *class_intf) ++ struct class_interface *class_intf) +{ + sysfs_remove_group(&class_dev->kobj, &rtc_attr_group); +} + +/* interface registration */ + -+struct class_interface rtc_sysfs_interface = { ++static struct class_interface rtc_sysfs_interface = { + .add = &rtc_sysfs_add_device, + .remove = &rtc_sysfs_remove_device, +}; @@ -2462,12 +2968,12 @@ +MODULE_DESCRIPTION("RTC class sysfs interface"); +MODULE_LICENSE("GPL"); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-proc.c 2006-02-21 00:36:43.000000000 +0100 -@@ -0,0 +1,158 @@ ++++ linux-ixp4xx/drivers/rtc/rtc-proc.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,162 @@ +/* + * RTC subsystem, proc interface + * -+ * Copyright (C) 2005 Tower Technologies ++ * Copyright (C) 2005-06 Tower Technologies + * Author: Alessandro Zummo <a.zummo@towertech.it> + * + * based on arch/arm/common/rtctime.c @@ -2487,12 +2993,14 @@ + +static int rtc_proc_show(struct seq_file *seq, void *offset) +{ ++ int err; + struct class_device *class_dev = seq->private; + struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; + struct rtc_wkalrm alrm; + struct rtc_time tm; + -+ if (rtc_read_time(class_dev, &tm) == 0) { ++ err = rtc_read_time(class_dev, &tm); ++ if (err == 0) { + seq_printf(seq, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n", @@ -2500,7 +3008,8 @@ + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + } + -+ if (rtc_read_alarm(class_dev, &alrm) == 0) { ++ err = rtc_read_alarm(class_dev, &alrm); ++ if (err == 0) { + seq_printf(seq, "alrm_time\t: "); + if ((unsigned int)alrm.time.tm_hour <= 24) + seq_printf(seq, "%02d:", alrm.time.tm_hour); @@ -2529,9 +3038,9 @@ + else + seq_printf(seq, "**\n"); + seq_printf(seq, "alrm_wakeup\t: %s\n", -+ alrm.enabled ? "yes" : "no"); ++ alrm.enabled ? "yes" : "no"); + seq_printf(seq, "alrm_pending\t: %s\n", -+ alrm.pending ? "yes" : "no"); ++ alrm.pending ? "yes" : "no"); + } + + if (ops->proc) @@ -2565,7 +3074,7 @@ +}; + +static int rtc_proc_add_device(struct class_device *class_dev, -+ struct class_interface *class_intf) ++ struct class_interface *class_intf) +{ + mutex_lock(&rtc_lock); + if (rtc_dev == NULL) { @@ -2573,7 +3082,8 @@ + + rtc_dev = class_dev; + -+ if ((ent = create_proc_entry("driver/rtc", 0, NULL))) { ++ ent = create_proc_entry("driver/rtc", 0, NULL); ++ if (ent) { + struct rtc_device *rtc = to_rtc_device(class_dev); + + ent->proc_fops = &rtc_proc_fops; @@ -2591,7 +3101,7 @@ +} + +static void rtc_proc_remove_device(struct class_device *class_dev, -+ struct class_interface *class_intf) ++ struct class_interface *class_intf) +{ + mutex_lock(&rtc_lock); + if (rtc_dev == class_dev) { @@ -2601,7 +3111,7 @@ + mutex_unlock(&rtc_lock); +} + -+struct class_interface rtc_proc_interface = { ++static struct class_interface rtc_proc_interface = { + .add = &rtc_proc_add_device, + .remove = &rtc_proc_remove_device, +}; @@ -2623,8 +3133,8 @@ +MODULE_DESCRIPTION("RTC class proc interface"); +MODULE_LICENSE("GPL"); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-dev.c 2006-02-21 00:36:43.000000000 +0100 -@@ -0,0 +1,370 @@ ++++ linux-ixp4xx/drivers/rtc/rtc-dev.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,382 @@ +/* + * RTC subsystem, dev interface + * @@ -2641,6 +3151,7 @@ +#include <linux/module.h> +#include <linux/rtc.h> + ++static struct class *rtc_dev_class; +static dev_t rtc_devt; + +#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */ @@ -2662,7 +3173,6 @@ + + err = ops->open ? ops->open(rtc->class_dev.dev) : 0; + if (err == 0) { -+ + spin_lock_irq(&rtc->irq_lock); + rtc->irq_data = 0; + spin_unlock_irq(&rtc->irq_lock); @@ -2738,8 +3248,8 @@ + return (data != 0) ? (POLLIN | POLLRDNORM) : 0; +} + -+static int rtc_dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, -+ unsigned long arg) ++static int rtc_dev_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) +{ + int err = 0; + struct class_device *class_dev = file->private_data; @@ -2774,15 +3284,16 @@ + + switch (cmd) { + case RTC_ALM_READ: -+ if ((err = rtc_read_alarm(class_dev, &alarm)) < 0) ++ err = rtc_read_alarm(class_dev, &alarm); ++ if (err < 0) + return err; + -+ if ((err = copy_to_user(uarg, &alarm.time, sizeof(tm)))) ++ if (copy_to_user(uarg, &alarm.time, sizeof(tm))) + return -EFAULT; + break; + + case RTC_ALM_SET: -+ if ((err = copy_from_user(&alarm.time, uarg, sizeof(tm)))) ++ if (copy_from_user(&alarm.time, uarg, sizeof(tm))) + return -EFAULT; + + alarm.enabled = 0; @@ -2797,10 +3308,11 @@ + break; + + case RTC_RD_TIME: -+ if ((err = rtc_read_time(class_dev, &tm)) < 0) ++ err = rtc_read_time(class_dev, &tm); ++ if (err < 0) + return err; + -+ if ((err = copy_to_user(uarg, &tm, sizeof(tm)))) ++ if (copy_to_user(uarg, &tm, sizeof(tm))) + return -EFAULT; + break; + @@ -2808,7 +3320,7 @@ + if (!capable(CAP_SYS_TIME)) + return -EACCES; + -+ if ((err = copy_from_user(&tm, uarg, sizeof(tm)))) ++ if (copy_from_user(&tm, uarg, sizeof(tm))) + return -EFAULT; + + err = rtc_set_time(class_dev, &tm); @@ -2837,17 +3349,18 @@ + break; +#endif + case RTC_WKALM_SET: -+ if ((err = copy_from_user(&alarm, uarg, sizeof(alarm)))) ++ if (copy_from_user(&alarm, uarg, sizeof(alarm))) + return -EFAULT; + + err = rtc_set_alarm(class_dev, &alarm); + break; + + case RTC_WKALM_RD: -+ if ((err = rtc_read_alarm(class_dev, &alarm)) < 0) ++ err = rtc_read_alarm(class_dev, &alarm); ++ if (err < 0) + return err; + -+ if ((err = copy_to_user(uarg, &alarm, sizeof(alarm)))) ++ if (copy_to_user(uarg, &alarm, sizeof(alarm))) + return -EFAULT; + break; + @@ -2887,17 +3400,12 @@ + .fasync = rtc_dev_fasync, +}; + -+static ssize_t rtc_dev_show_dev(struct class_device *class_dev, char *buf) -+{ -+ return print_dev_t(buf, class_dev->devt); -+} -+static CLASS_DEVICE_ATTR(dev, S_IRUGO, rtc_dev_show_dev, NULL); -+ +/* insertion/removal hooks */ + +static int rtc_dev_add_device(struct class_device *class_dev, + struct class_interface *class_intf) +{ ++ int err = 0; + struct rtc_device *rtc = to_rtc_device(class_dev); + + if (rtc->id >= RTC_DEV_MAX) { @@ -2911,29 +3419,34 @@ + + cdev_init(&rtc->char_dev, &rtc_dev_fops); + rtc->char_dev.owner = rtc->owner; -+ class_dev->devt = MKDEV(MAJOR(rtc_devt), rtc->id); + -+ if (cdev_add(&rtc->char_dev, class_dev->devt, 1)) { ++ if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) { + cdev_del(&rtc->char_dev); -+ + dev_err(class_dev->dev, + "failed to add char device %d:%d\n", -+ MAJOR(class_dev->devt), -+ MINOR(class_dev->devt)); -+ -+ class_dev->devt = MKDEV(0, 0); ++ MAJOR(rtc_devt), rtc->id); + return -ENODEV; + } + -+ class_device_create_file(class_dev, &class_device_attr_dev); ++ rtc->rtc_dev = class_device_create(rtc_dev_class, NULL, ++ MKDEV(MAJOR(rtc_devt), rtc->id), ++ class_dev->dev, "rtc%d", rtc->id); ++ if (IS_ERR(rtc->rtc_dev)) { ++ dev_err(class_dev->dev, "cannot create rtc_dev device\n"); ++ err = PTR_ERR(rtc->rtc_dev); ++ goto err_cdev_del; ++ } + + dev_info(class_dev->dev, "rtc intf: dev (%d:%d)\n", -+ MAJOR(class_dev->devt), -+ MINOR(class_dev->devt)); -+ -+ kobject_uevent(&class_dev->kobj, KOBJ_ADD); ++ MAJOR(rtc->rtc_dev->devt), ++ MINOR(rtc->rtc_dev->devt)); + + return 0; ++ ++err_cdev_del: ++ ++ cdev_del(&rtc->char_dev); ++ return err; +} + +static void rtc_dev_remove_device(struct class_device *class_dev, @@ -2941,23 +3454,19 @@ +{ + struct rtc_device *rtc = to_rtc_device(class_dev); + -+ class_device_remove_file(class_dev, &class_device_attr_dev); -+ -+ if (MAJOR(class_dev->devt)) { ++ if (rtc->rtc_dev) { + dev_dbg(class_dev->dev, "removing char %d:%d\n", -+ MAJOR(class_dev->devt), -+ MINOR(class_dev->devt)); -+ cdev_del(&rtc->char_dev); -+ -+ kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); ++ MAJOR(rtc->rtc_dev->devt), ++ MINOR(rtc->rtc_dev->devt)); + -+ class_dev->devt = MKDEV(0, 0); ++ class_device_unregister(rtc->rtc_dev); ++ cdev_del(&rtc->char_dev); + } +} + +/* interface registration */ + -+struct class_interface rtc_dev_interface = { ++static struct class_interface rtc_dev_interface = { + .add = &rtc_dev_add_device, + .remove = &rtc_dev_remove_device, +}; @@ -2966,26 +3475,39 @@ +{ + int err; + -+ if ((err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc")) < 0) { ++ rtc_dev_class = class_create(THIS_MODULE, "rtc-dev"); ++ if (IS_ERR(rtc_dev_class)) ++ return PTR_ERR(rtc_dev_class); ++ ++ err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); ++ if (err < 0) { + printk(KERN_ERR "%s: failed to allocate char dev region\n", + __FILE__); -+ return err; ++ goto err_destroy_class; + } + -+ if ((err = rtc_interface_register(&rtc_dev_interface)) < 0) { ++ err = rtc_interface_register(&rtc_dev_interface); ++ if (err < 0) { + printk(KERN_ERR "%s: failed to register the interface\n", + __FILE__); -+ unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); -+ return err; ++ goto err_unregister_chrdev; + } + + return 0; ++ ++err_unregister_chrdev: ++ unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); ++ ++err_destroy_class: ++ class_destroy(rtc_dev_class); ++ ++ return err; +} + +static void __exit rtc_dev_exit(void) +{ + class_interface_unregister(&rtc_dev_interface); -+ ++ class_destroy(rtc_dev_class); + unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); +} + @@ -2996,7 +3518,7 @@ +MODULE_DESCRIPTION("RTC class dev interface"); +MODULE_LICENSE("GPL"); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-x1205.c 2006-02-21 00:36:43.000000000 +0100 ++++ linux-ixp4xx/drivers/rtc/rtc-x1205.c 2006-03-08 01:59:26.000000000 +0100 @@ -0,0 +1,619 @@ +/* + * An i2c driver for the Xicor/Intersil X1205 RTC @@ -3374,7 +3896,7 @@ + if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { + dev_err(&client->adapter->dev, + "%s: could not read register %x\n", -+ __FUNCTION__, probe_zero_pattern[i]); ++ __FUNCTION__, probe_zero_pattern[i]); + + return -EIO; + } @@ -3618,8 +4140,8 @@ +module_init(x1205_init); +module_exit(x1205_exit); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-test.c 2006-02-21 00:36:43.000000000 +0100 -@@ -0,0 +1,206 @@ ++++ linux-ixp4xx/drivers/rtc/rtc-test.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,205 @@ +/* + * An RTC test device/driver + * Copyright (C) 2005 Tower Technologies @@ -3636,8 +4158,7 @@ +#include <linux/rtc.h> +#include <linux/platform_device.h> + -+struct platform_device *test0 = NULL, *test1 = NULL; -+ ++static struct platform_device *test0 = NULL, *test1 = NULL; + +static int test_rtc_read_alarm(struct device *dev, + struct rtc_wkalrm *alrm) @@ -3827,7 +4348,7 @@ +module_init(test_init); +module_exit(test_exit); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-ds1672.c 2006-02-21 00:36:43.000000000 +0100 ++++ linux-ixp4xx/drivers/rtc/rtc-ds1672.c 2006-03-08 01:59:26.000000000 +0100 @@ -0,0 +1,233 @@ +/* + * An rtc/i2c driver for the Dallas DS1672 @@ -3877,11 +4398,11 @@ + { client->addr, I2C_M_RD, 4, buf }, /* read date */ + }; + -+ /* read date registers */ -+ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { -+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__); -+ return -EIO; -+ } ++ /* read date registers */ ++ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { ++ dev_err(&client->dev, "%s: read error\n", __FUNCTION__); ++ return -EIO; ++ } + + dev_dbg(&client->dev, + "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" @@ -4063,7 +4584,7 @@ +module_init(ds1672_init); +module_exit(ds1672_exit); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-pcf8563.c 2006-02-21 00:36:43.000000000 +0100 ++++ linux-ixp4xx/drivers/rtc/rtc-pcf8563.c 2006-03-08 01:59:26.000000000 +0100 @@ -0,0 +1,355 @@ +/* + * An I2C driver for the Philips PCF8563 RTC @@ -4421,7 +4942,7 @@ +module_init(pcf8563_init); +module_exit(pcf8563_exit); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-rtc/drivers/rtc/rtc-rs5c372.c 2006-02-21 00:36:43.000000000 +0100 ++++ linux-ixp4xx/drivers/rtc/rtc-rs5c372.c 2006-03-08 01:59:26.000000000 +0100 @@ -0,0 +1,295 @@ +/* + * An I2C driver for the Ricoh RS5C372 RTC @@ -4718,3 +5239,608 @@ +MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/rtc/rtc-ep93xx.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,163 @@ ++/* ++ * A driver for the RTC embedded in the Cirrus Logic EP93XX processors ++ * Copyright (c) 2006 Tower Technologies ++ * ++ * Author: Alessandro Zummo <a.zummo@towertech.it> ++ * ++ * 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. ++ */ ++ ++#include <linux/module.h> ++#include <linux/rtc.h> ++#include <linux/platform_device.h> ++#include <asm/hardware.h> ++ ++#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x)) ++#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000) ++#define EP93XX_RTC_LOAD EP93XX_RTC_REG(0x000C) ++#define EP93XX_RTC_SWCOMP EP93XX_RTC_REG(0x0108) ++ ++#define DRV_VERSION "0.2" ++ ++static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload, ++ unsigned short *delete) ++{ ++ unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP); ++ ++ if (preload) ++ *preload = comp & 0xffff; ++ ++ if (delete) ++ *delete = (comp >> 16) & 0x1f; ++ ++ return 0; ++} ++ ++static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) ++{ ++ unsigned long time = __raw_readl(EP93XX_RTC_DATA); ++ ++ rtc_time_to_tm(time, tm); ++ return 0; ++} ++ ++static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) ++{ ++ __raw_writel(secs + 1, EP93XX_RTC_LOAD); ++ return 0; ++} ++ ++static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm) ++{ ++ int err; ++ unsigned long secs; ++ ++ err = rtc_tm_to_time(tm, &secs); ++ if (err != 0) ++ return err; ++ ++ return ep93xx_rtc_set_mmss(dev, secs); ++} ++ ++static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) ++{ ++ unsigned short preload, delete; ++ ++ ep93xx_get_swcomp(dev, &preload, &delete); ++ ++ seq_printf(seq, "24hr\t\t: yes\n"); ++ seq_printf(seq, "preload\t\t: %d\n", preload); ++ seq_printf(seq, "delete\t\t: %d\n", delete); ++ ++ return 0; ++} ++ ++static struct rtc_class_ops ep93xx_rtc_ops = { ++ .read_time = ep93xx_rtc_read_time, ++ .set_time = ep93xx_rtc_set_time, ++ .set_mmss = ep93xx_rtc_set_mmss, ++ .proc = ep93xx_rtc_proc, ++}; ++ ++static ssize_t ep93xx_sysfs_show_comp_preload(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ unsigned short preload; ++ ++ ep93xx_get_swcomp(dev, &preload, NULL); ++ ++ return sprintf(buf, "%d\n", preload); ++} ++static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_sysfs_show_comp_preload, NULL); ++ ++static ssize_t ep93xx_sysfs_show_comp_delete(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ unsigned short delete; ++ ++ ep93xx_get_swcomp(dev, NULL, &delete); ++ ++ return sprintf(buf, "%d\n", delete); ++} ++static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL); ++ ++ ++static int __devinit ep93xx_rtc_probe(struct platform_device *dev) ++{ ++ struct rtc_device *rtc = rtc_device_register("ep93xx", ++ &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); ++ ++ if (IS_ERR(rtc)) { ++ dev_err(&dev->dev, "unable to register\n"); ++ return PTR_ERR(rtc); ++ } ++ ++ platform_set_drvdata(dev, rtc); ++ ++ device_create_file(&dev->dev, &dev_attr_comp_preload); ++ device_create_file(&dev->dev, &dev_attr_comp_delete); ++ ++ return 0; ++} ++ ++static int __devexit ep93xx_rtc_remove(struct platform_device *dev) ++{ ++ struct rtc_device *rtc = platform_get_drvdata(dev); ++ ++ if (rtc) ++ rtc_device_unregister(rtc); ++ ++ platform_set_drvdata(dev, NULL); ++ ++ return 0; ++} ++ ++static struct platform_driver ep93xx_rtc_platform_driver = { ++ .driver = { ++ .name = "ep93xx-rtc", ++ .owner = THIS_MODULE, ++ }, ++ .probe = ep93xx_rtc_probe, ++ .remove = __devexit_p(ep93xx_rtc_remove), ++}; ++ ++static int __init ep93xx_rtc_init(void) ++{ ++ return platform_driver_register(&ep93xx_rtc_platform_driver); ++} ++ ++static void __exit ep93xx_rtc_exit(void) ++{ ++ platform_driver_unregister(&ep93xx_rtc_platform_driver); ++} ++ ++MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); ++MODULE_DESCRIPTION("EP93XX RTC driver"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(DRV_VERSION); ++ ++module_init(ep93xx_rtc_init); ++module_exit(ep93xx_rtc_exit); +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/drivers/rtc/rtc-sa1100.c 2006-03-08 01:59:26.000000000 +0100 +@@ -0,0 +1,392 @@ ++/* ++ * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx ++ * ++ * Copyright (c) 2000 Nils Faerber ++ * ++ * Based on rtc.c by Paul Gortmaker ++ * ++ * Original Driver by Nils Faerber <nils@kernelconcepts.de> ++ * ++ * Modifications from: ++ * CIH <cih@coventive.com> ++ * Nicolas Pitre <nico@cam.org> ++ * Andrew Christian <andrew.christian@hp.com> ++ * ++ * Converted to the RTC subsystem and Driver Model ++ * by Richard Purdie <rpurdie@rpsys.net> ++ * ++ * 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 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. ++ */ ++ ++#include <linux/platform_device.h> ++#include <linux/module.h> ++#include <linux/rtc.h> ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/interrupt.h> ++#include <linux/string.h> ++#include <linux/pm.h> ++ ++#include <asm/bitops.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <asm/rtc.h> ++ ++#ifdef CONFIG_ARCH_PXA ++#include <asm/arch/pxa-regs.h> ++#endif ++ ++#define TIMER_FREQ CLOCK_TICK_RATE ++#define RTC_DEF_DIVIDER 32768 - 1 ++#define RTC_DEF_TRIM 0 ++ ++static unsigned long rtc_freq = 1024; ++static struct rtc_time rtc_alarm; ++static spinlock_t sa1100_rtc_lock = SPIN_LOCK_UNLOCKED; ++ ++static int rtc_update_alarm(struct rtc_time *alrm) ++{ ++ struct rtc_time alarm_tm, now_tm; ++ unsigned long now, time; ++ int ret; ++ ++ do { ++ now = RCNR; ++ rtc_time_to_tm(now, &now_tm); ++ rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); ++ ret = rtc_tm_to_time(&alarm_tm, &time); ++ if (ret != 0) ++ break; ++ ++ RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); ++ RTAR = time; ++ } while (now != RCNR); ++ ++ return ret; ++} ++ ++static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id, ++ struct pt_regs *regs) ++{ ++ struct platform_device *pdev = to_platform_device(dev_id); ++ struct rtc_device *rtc = platform_get_drvdata(pdev); ++ unsigned int rtsr; ++ unsigned long events = 0; ++ ++ spin_lock(&sa1100_rtc_lock); ++ ++ rtsr = RTSR; ++ /* clear interrupt sources */ ++ RTSR = 0; ++ RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); ++ ++ /* clear alarm interrupt if it has occurred */ ++ if (rtsr & RTSR_AL) ++ rtsr &= ~RTSR_ALE; ++ RTSR = rtsr & (RTSR_ALE | RTSR_HZE); ++ ++ /* update irq data & counter */ ++ if (rtsr & RTSR_AL) ++ events |= RTC_AF | RTC_IRQF; ++ if (rtsr & RTSR_HZ) ++ events |= RTC_UF | RTC_IRQF; ++ ++ rtc_update_irq(&rtc->class_dev, 1, events); ++ ++ if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) ++ rtc_update_alarm(&rtc_alarm); ++ ++ spin_unlock(&sa1100_rtc_lock); ++ ++ return IRQ_HANDLED; ++} ++ ++static int rtc_timer1_count; ++ ++static irqreturn_t timer1_interrupt(int irq, void *dev_id, ++ struct pt_regs *regs) ++{ ++ struct platform_device *pdev = to_platform_device(dev_id); ++ struct rtc_device *rtc = platform_get_drvdata(pdev); ++ ++ /* ++ * If we match for the first time, rtc_timer1_count will be 1. ++ * Otherwise, we wrapped around (very unlikely but ++ * still possible) so compute the amount of missed periods. ++ * The match reg is updated only when the data is actually retrieved ++ * to avoid unnecessary interrupts. ++ */ ++ OSSR = OSSR_M1; /* clear match on timer1 */ ++ ++ rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF); ++ ++ if (rtc_timer1_count == 1) ++ rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); ++ ++ return IRQ_HANDLED; ++} ++ ++static int sa1100_rtc_read_callback(struct device *dev, int data) ++{ ++ if (data & RTC_PF) { ++ /* interpolate missed periods and set match for the next */ ++ unsigned long period = TIMER_FREQ/rtc_freq; ++ unsigned long oscr = OSCR; ++ unsigned long osmr1 = OSMR1; ++ unsigned long missed = (oscr - osmr1)/period; ++ data += missed << 8; ++ OSSR = OSSR_M1; /* clear match on timer 1 */ ++ OSMR1 = osmr1 + (missed + 1)*period; ++ /* Ensure we didn't miss another match in the mean time. ++ * Here we compare (match - OSCR) 8 instead of 0 -- ++ * see comment in pxa_timer_interrupt() for explanation. ++ */ ++ while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) { ++ data += 0x100; ++ OSSR = OSSR_M1; /* clear match on timer 1 */ ++ OSMR1 = osmr1 + period; ++ } ++ } ++ return data; ++} ++ ++static int sa1100_rtc_open(struct device *dev) ++{ ++ int ret; ++ ++ ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, ++ "rtc 1Hz", dev); ++ if (ret) { ++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz); ++ goto fail_ui; ++ } ++ ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, ++ "rtc Alrm", dev); ++ if (ret) { ++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm); ++ goto fail_ai; ++ } ++ ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, ++ "rtc timer", dev); ++ if (ret) { ++ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1); ++ goto fail_pi; ++ } ++ return 0; ++ ++ fail_pi: ++ free_irq(IRQ_RTCAlrm, NULL); ++ fail_ai: ++ free_irq(IRQ_RTC1Hz, NULL); ++ fail_ui: ++ return ret; ++} ++ ++static void sa1100_rtc_release(struct device *dev) ++{ ++ spin_lock_irq(&sa1100_rtc_lock); ++ RTSR = 0; ++ OIER &= ~OIER_E1; ++ OSSR = OSSR_M1; ++ spin_unlock_irq(&sa1100_rtc_lock); ++ ++ free_irq(IRQ_OST1, dev); ++ free_irq(IRQ_RTCAlrm, dev); ++ free_irq(IRQ_RTC1Hz, dev); ++} ++ ++ ++static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, ++ unsigned long arg) ++{ ++ switch(cmd) { ++ case RTC_AIE_OFF: ++ spin_lock_irq(&sa1100_rtc_lock); ++ RTSR &= ~RTSR_ALE; ++ spin_unlock_irq(&sa1100_rtc_lock); ++ return 0; ++ case RTC_AIE_ON: ++ spin_lock_irq(&sa1100_rtc_lock); ++ RTSR |= RTSR_ALE; ++ spin_unlock_irq(&sa1100_rtc_lock); ++ return 0; ++ case RTC_UIE_OFF: ++ spin_lock_irq(&sa1100_rtc_lock); ++ RTSR &= ~RTSR_HZE; ++ spin_unlock_irq(&sa1100_rtc_lock); ++ return 0; ++ case RTC_UIE_ON: ++ spin_lock_irq(&sa1100_rtc_lock); ++ RTSR |= RTSR_HZE; ++ spin_unlock_irq(&sa1100_rtc_lock); ++ return 0; ++ case RTC_PIE_OFF: ++ spin_lock_irq(&sa1100_rtc_lock); ++ OIER &= ~OIER_E1; ++ spin_unlock_irq(&sa1100_rtc_lock); ++ return 0; ++ case RTC_PIE_ON: ++ if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE)) ++ return -EACCES; ++ spin_lock_irq(&sa1100_rtc_lock); ++ OSMR1 = TIMER_FREQ/rtc_freq + OSCR; ++ OIER |= OIER_E1; ++ rtc_timer1_count = 1; ++ spin_unlock_irq(&sa1100_rtc_lock); ++ return 0; ++ case RTC_IRQP_READ: ++ return put_user(rtc_freq, (unsigned long *)arg); ++ case RTC_IRQP_SET: ++ if (arg < 1 || arg > TIMER_FREQ) ++ return -EINVAL; ++ if ((arg > 64) && (!capable(CAP_SYS_RESOURCE))) ++ return -EACCES; ++ rtc_freq = arg; ++ return 0; ++ } ++ return -EINVAL; ++} ++ ++static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) ++{ ++ rtc_time_to_tm(RCNR, tm); ++ return 0; ++} ++ ++static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) ++{ ++ unsigned long time; ++ int ret; ++ ++ ret = rtc_tm_to_time(tm, &time); ++ if (ret == 0) ++ RCNR = time; ++ return ret; ++} ++ ++static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); ++ alrm->pending = RTSR & RTSR_AL ? 1 : 0; ++ return 0; ++} ++ ++static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ int ret; ++ ++ spin_lock_irq(&sa1100_rtc_lock); ++ ret = rtc_update_alarm(&alrm->time); ++ if (ret == 0) { ++ memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time)); ++ ++ if (alrm->enabled) ++ enable_irq_wake(IRQ_RTCAlrm); ++ else ++ disable_irq_wake(IRQ_RTCAlrm); ++ } ++ spin_unlock_irq(&sa1100_rtc_lock); ++ ++ return ret; ++} ++ ++static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) ++{ ++ seq_printf(seq, "trim/divider\t: 0x%08x\n", RTTR); ++ seq_printf(seq, "alarm_IRQ\t: %s\n", ++ (RTSR & RTSR_ALE) ? "yes" : "no" ); ++ seq_printf(seq, "update_IRQ\t: %s\n", ++ (RTSR & RTSR_HZE) ? "yes" : "no"); ++ seq_printf(seq, "periodic_IRQ\t: %s\n", ++ (OIER & OIER_E1) ? "yes" : "no"); ++ seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq); ++ ++ return 0; ++} ++ ++static struct rtc_class_ops sa1100_rtc_ops = { ++ .open = sa1100_rtc_open, ++ .read_callback = sa1100_rtc_read_callback, ++ .release = sa1100_rtc_release, ++ .ioctl = sa1100_rtc_ioctl, ++ .read_time = sa1100_rtc_read_time, ++ .set_time = sa1100_rtc_set_time, ++ .read_alarm = sa1100_rtc_read_alarm, ++ .set_alarm = sa1100_rtc_set_alarm, ++ .proc = sa1100_rtc_proc, ++}; ++ ++static int sa1100_rtc_probe(struct platform_device *pdev) ++{ ++ struct rtc_device *rtc; ++ ++ /* ++ * According to the manual we should be able to let RTTR be zero ++ * and then a default diviser for a 32.768KHz clock is used. ++ * Apparently this doesn't work, at least for my SA1110 rev 5. ++ * If the clock divider is uninitialized then reset it to the ++ * default value to get the 1Hz clock. ++ */ ++ if (RTTR == 0) { ++ RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); ++ printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n"); ++ /* The current RTC value probably doesn't make sense either */ ++ RCNR = 0; ++ } ++ ++ rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, ++ THIS_MODULE); ++ ++ if (IS_ERR(rtc)) { ++ dev_err(&pdev->dev, "Unable to register the RTC device\n"); ++ return PTR_ERR(rtc); ++ } ++ ++ platform_set_drvdata(pdev, rtc); ++ ++ dev_info(&pdev->dev, "SA11xx/PXA2xx RTC Registered\n"); ++ ++ return 0; ++} ++ ++static int sa1100_rtc_remove(struct platform_device *pdev) ++{ ++ struct rtc_device *rtc = platform_get_drvdata(pdev); ++ ++ if (rtc) ++ rtc_device_unregister(rtc); ++ ++ return 0; ++} ++ ++static struct platform_driver sa1100_rtc_driver = { ++ .probe = sa1100_rtc_probe, ++ .remove = sa1100_rtc_remove, ++ .driver = { ++ .name = "sa1100-rtc", ++ }, ++}; ++ ++static int __init sa1100_rtc_init(void) ++{ ++ return platform_driver_register(&sa1100_rtc_driver); ++} ++ ++static void __exit sa1100_rtc_exit(void) ++{ ++ platform_driver_unregister(&sa1100_rtc_driver); ++} ++ ++module_init(sa1100_rtc_init); ++module_exit(sa1100_rtc_exit); ++ ++MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); ++MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); ++MODULE_LICENSE("GPL"); +--- linux-ixp4xx.orig/arch/arm/mach-pxa/generic.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-pxa/generic.c 2006-03-08 01:59:26.000000000 +0100 +@@ -319,6 +319,11 @@ void __init pxa_set_ficp_info(struct pxa + pxaficp_device.dev.platform_data = info; + } + ++static struct platform_device pxartc_device = { ++ .name = "sa1100-rtc", ++ .id = -1, ++}; ++ + static struct platform_device *devices[] __initdata = { + &pxamci_device, + &udc_device, +@@ -329,6 +334,7 @@ static struct platform_device *devices[] + &pxaficp_device, + &i2c_device, + &i2s_device, ++ &pxartc_device, + }; + + static int __init pxa_init(void) +--- linux-ixp4xx.orig/arch/arm/mach-sa1100/generic.c 2006-03-08 01:59:09.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-sa1100/generic.c 2006-03-08 01:59:26.000000000 +0100 +@@ -324,6 +324,11 @@ void sa11x0_set_irda_data(struct irda_pl + sa11x0ir_device.dev.platform_data = irda; + } + ++static struct platform_device sa11x0rtc_device = { ++ .name = "sa1100-rtc", ++ .id = -1, ++}; ++ + static struct platform_device *sa11x0_devices[] __initdata = { + &sa11x0udc_device, + &sa11x0uart1_device, +@@ -333,6 +338,7 @@ static struct platform_device *sa11x0_de + &sa11x0pcmcia_device, + &sa11x0fb_device, + &sa11x0mtd_device, ++ &sa11x0rtc_device, + }; + + static int __init sa1100_init(void) diff --git a/packages/linux/ixp4xx-kernel/2.6.16/45-eeprom-new-notifier.patch b/packages/linux/ixp4xx-kernel/2.6.16/45-eeprom-new-notifier.patch new file mode 100644 index 0000000000..2de12021a5 --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/45-eeprom-new-notifier.patch @@ -0,0 +1,209 @@ +Add EEPROM notifiers + +These help board level code by allowing a callback when EEPROMs are +loaded, this permits system level configuration to be loaded from the +EEPROM. This is particularly useful when the ethernet MAC ids are +stored in EEPROM and when the ethernet hardware is generic (so it +has no board level knowledge), then the MACs can be loaded into +the 'maclist' code and read out by the ethernet config. + +Signed-off-by: John Bowler <jbowler@acm.org> + +--- + drivers/i2c/chips/eeprom.c | 63 ++++++++++++++++++++++++++------------- + include/linux/eeprom.h | 71 +++++++++++++++++++++++++++++++++++++++++++++ + include/linux/notifier.h | 3 + + 3 files changed, 116 insertions(+), 21 deletions(-) + +--- linux-ixp4xx.orig/drivers/i2c/chips/eeprom.c 2006-03-27 03:03:46.000000000 +0200 ++++ linux-ixp4xx/drivers/i2c/chips/eeprom.c 2006-03-27 03:03:47.000000000 +0200 +@@ -25,7 +25,6 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +- + #include <linux/kernel.h> + #include <linux/init.h> + #include <linux/module.h> +@@ -34,6 +33,8 @@ + #include <linux/jiffies.h> + #include <linux/i2c.h> + #include <linux/mutex.h> ++#include <linux/notifier.h> ++#include <linux/eeprom.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, +@@ -42,26 +43,7 @@ static unsigned short normal_i2c[] = { 0 + /* Insmod parameters */ + I2C_CLIENT_INSMOD_1(eeprom); + +- +-/* Size of EEPROM in bytes */ +-#define EEPROM_SIZE 256 +- +-/* possible types of eeprom devices */ +-enum eeprom_nature { +- UNKNOWN, +- VAIO, +-}; +- +-/* Each client has this additional data */ +-struct eeprom_data { +- struct i2c_client client; +- struct mutex update_lock; +- u8 valid; /* bitfield, bit!=0 if slice is valid */ +- unsigned long last_updated[8]; /* In jiffies, 8 slices */ +- u8 data[EEPROM_SIZE]; /* Register values */ +- enum eeprom_nature nature; +-}; +- ++static struct notifier_block *eeprom_chain; + + static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind); + static int eeprom_detach_client(struct i2c_client *client); +@@ -186,6 +168,7 @@ static int eeprom_detect(struct i2c_adap + data->valid = 0; + mutex_init(&data->update_lock); + data->nature = UNKNOWN; ++ data->attr = &eeprom_attr; + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -207,6 +190,9 @@ static int eeprom_detect(struct i2c_adap + /* create the sysfs eeprom file */ + sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr); + ++ /* call the notifier chain */ ++ notifier_call_chain(&eeprom_chain, EEPROM_REGISTER, data); ++ + return 0; + + exit_kfree: +@@ -228,6 +214,41 @@ static int eeprom_detach_client(struct i + return 0; + } + ++/** ++ * register_eeprom_notifier - register a 'user' of EEPROM devices. ++ * @nb: pointer to notifier info structure ++ * ++ * Registers a callback function to be called upon detection ++ * of an EEPROM device. Detection invokes the 'add' callback ++ * with the kobj of the mutex and a bin_attribute which allows ++ * read from the EEPROM. The intention is that the notifier ++ * will be able to read system configuration from the notifier. ++ * ++ * Only EEPROMs detected *after* the addition of the notifier ++ * are notified. I.e. EEPROMs already known to the system ++ * will not be notified - add the notifier from board level ++ * code! ++ */ ++int register_eeprom_notifier(struct notifier_block *nb) ++{ ++ return notifier_chain_register(&eeprom_chain, nb); ++} ++ ++/** ++ * unregister_eeprom_notifier - unregister a 'user' of EEPROM devices. ++ * @old: pointer to notifier info structure ++ * ++ * Removes a callback function from the list of 'users' to be ++ * notified upon detection of EEPROM devices. ++ */ ++int unregister_eeprom_notifier(struct notifier_block *nb) ++{ ++ return notifier_chain_unregister(&eeprom_chain, nb); ++} ++ ++EXPORT_SYMBOL_GPL(register_eeprom_notifier); ++EXPORT_SYMBOL_GPL(unregister_eeprom_notifier); ++ + static int __init eeprom_init(void) + { + return i2c_add_driver(&eeprom_driver); +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/include/linux/eeprom.h 2006-03-27 03:03:47.000000000 +0200 +@@ -0,0 +1,71 @@ ++#ifndef _LINUX_EEPROM_H ++#define _LINUX_EEPROM_H ++/* ++ * $Id: 45-eeprom-new-notifier.patch,v 1.2 2006/03/27 11:10:19 azummo Exp $ ++ * ++ * Copyright (C) 2006 John Bowler ++ */ ++ ++/* ++ * 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 __KERNEL__ ++#error This is a kernel header ++#endif ++ ++#include <linux/list.h> ++#include <linux/kobject.h> ++#include <linux/sysfs.h> ++ ++/* Size of EEPROM in bytes */ ++#define EEPROM_SIZE 256 ++ ++/* possible types of eeprom devices */ ++enum eeprom_nature { ++ UNKNOWN, ++ VAIO, ++}; ++ ++/* Each client has this additional data */ ++struct eeprom_data { ++ struct i2c_client client; ++ struct mutex update_lock; ++ u8 valid; /* bitfield, bit!=0 if slice is valid */ ++ unsigned long last_updated[8]; /* In jiffies, 8 slices */ ++ u8 data[EEPROM_SIZE]; /* Register values */ ++ enum eeprom_nature nature; ++ struct bin_attribute *attr; ++}; ++ ++/* ++ * This is very basic. ++ * ++ * If an EEPROM is detected on the I2C bus (this only works for ++ * I2C EEPROMs) the eeprom_notifier::add method is called with ++ * both the I2C information and the kobject for the sysfs ++ * device which has been registers. It is then possible to ++ * read from the device via the bin_attribute::read method ++ * to extract configuration information. ++ * ++ * Register the notifier in the board level code, there is no ++ * need to unregister it but you can if you want (it will save ++ * a little bit or kernel memory to do so). ++ */ ++ ++extern int register_eeprom_notifier(struct notifier_block *nb); ++extern int unregister_eeprom_notifier(struct notifier_block *nb); ++ ++#endif /* _LINUX_EEPROM_H */ +--- linux-ixp4xx.orig/include/linux/notifier.h 2006-03-27 01:33:10.000000000 +0200 ++++ linux-ixp4xx/include/linux/notifier.h 2006-03-27 03:03:47.000000000 +0200 +@@ -72,5 +72,8 @@ extern int notifier_call_chain(struct no + #define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */ + #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ + ++/* eeprom notifier chain */ ++#define EEPROM_REGISTER 0x0001 ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NOTIFIER_H */ diff --git a/packages/linux/ixp4xx-kernel/2.6.16/45-eeprom-notifier.patch b/packages/linux/ixp4xx-kernel/2.6.16/45-eeprom-notifier.patch deleted file mode 100644 index 0367477a48..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/45-eeprom-notifier.patch +++ /dev/null @@ -1,184 +0,0 @@ -Add EEPROM notifiers - -These help board level code by allowing a callback when EEPROMs are -loaded, this permits system level configuration to be loaded from the -EEPROM. This is particularly useful when the ethernet MAC ids are -stored in EEPROM and when the ethernet hardware is generic (so it -has no board level knowledge), then the MACs can be loaded into -the 'maclist' code and read out by the ethernet config. - -Signed-off-by: John Bowler <jbowler@acm.org> - ---- linux-2.6.15/drivers/i2c/chips/eeprom.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/drivers/i2c/chips/eeprom.c 1970-01-01 00:00:00.000000000 +0000 -@@ -25,7 +25,6 @@ - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -- - #include <linux/kernel.h> - #include <linux/init.h> - #include <linux/module.h> -@@ -33,6 +32,9 @@ - #include <linux/sched.h> - #include <linux/jiffies.h> - #include <linux/i2c.h> -+#include <linux/notifier.h> -+ -+#include <linux/eeprom.h> - - /* Addresses to scan */ - static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, -@@ -41,6 +43,9 @@ static unsigned short normal_i2c[] = { 0 - /* Insmod parameters */ - I2C_CLIENT_INSMOD_1(eeprom); - -+/* Notifier list */ -+static DECLARE_MUTEX(eeprom_notifier_mutex); -+static LIST_HEAD(eeprom_notifiers); - - /* Size of EEPROM in bytes */ - #define EEPROM_SIZE 256 -@@ -160,6 +165,7 @@ static int eeprom_detect(struct i2c_adap - struct i2c_client *new_client; - struct eeprom_data *data; - int err = 0; -+ struct list_head *this; - - /* There are three ways we can read the EEPROM data: - (1) I2C block reads (faster, but unsupported by most adapters) -@@ -196,7 +202,7 @@ static int eeprom_detect(struct i2c_adap - - /* Detect the Vaio nature of EEPROMs. - We use the "PCG-" prefix as the signature. */ -- if (address == 0x57) { -+ if (list_empty(&eeprom_notifiers) && address == 0x57) { - if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P' - && i2c_smbus_read_byte(new_client) == 'C' - && i2c_smbus_read_byte(new_client) == 'G' -@@ -210,6 +216,14 @@ static int eeprom_detect(struct i2c_adap - /* create the sysfs eeprom file */ - sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr); - -+ /* Call each notifier callback */ -+ down(&eeprom_notifier_mutex); -+ list_for_each(this, &eeprom_notifiers) { -+ struct eeprom_notifier *not = list_entry(this, struct eeprom_notifier, list); -+ not->add(address, kind, &new_client->dev.kobj, &eeprom_attr); -+ } -+ up(&eeprom_notifier_mutex); -+ - return 0; - - exit_kfree: -@@ -231,6 +245,51 @@ static int eeprom_detach_client(struct i - return 0; - } - -+/** -+ * register_eeprom_user - register a 'user' of EEPROM devices. -+ * @new: pointer to notifier info structure -+ * -+ * Registers a callback function to be called upon detection -+ * of an EEPROM device. Detection invokes the 'add' callback -+ * with the kobj of the mutex and a bin_attribute which allows -+ * read from the EEPROM. The intention is that the notifier -+ * will be able to read system configuration from the notifier. -+ * -+ * Only EEPROMs detected *after* the addition of the notifier -+ * are notified. I.e. EEPROMs already known to the system -+ * will not be notified - add the notifier from board level -+ * code! -+ */ -+void register_eeprom_user (struct eeprom_notifier *new) -+{ -+ down(&eeprom_notifier_mutex); -+ -+ list_add(&new->list, &eeprom_notifiers); -+ -+ up(&eeprom_notifier_mutex); -+} -+ -+/** -+ * unregister_eeprom_user - unregister a 'user' of EEPROM devices. -+ * @old: pointer to notifier info structure -+ * -+ * Removes a callback function from the list of 'users' to be -+ * notified upon detection of EEPROM devices. -+ */ -+void unregister_eeprom_user (struct eeprom_notifier *old) -+{ -+ down(&eeprom_notifier_mutex); -+ -+ list_del(&old->list); -+ -+ up(&eeprom_notifier_mutex); -+} -+ -+ -+EXPORT_SYMBOL(register_eeprom_user); -+EXPORT_SYMBOL(unregister_eeprom_user); -+ -+ - static int __init eeprom_init(void) - { - return i2c_add_driver(&eeprom_driver); ---- linux-2.6.15/include/linux/eeprom.h 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.15/include/linux/eeprom.h 1970-01-01 00:00:00.000000000 +0000 -@@ -0,0 +1,56 @@ -+#ifndef _LINUX_EEPROM_H -+#define _LINUX_EEPROM_H -+/* -+ * $Id: 45-eeprom-notifier.patch,v 1.1 2006/02/07 00:38:33 azummo Exp $ -+ * -+ * Copyright (C) 2006 John Bowler -+ */ -+ -+/* -+ * 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 __KERNEL__ -+#error This is a kernel header -+#endif -+ -+#include <linux/list.h> -+#include <linux/kobject.h> -+#include <linux/sysfs.h> -+ -+/* -+ * This is very basic. -+ * -+ * If an EEPROM is detected on the I2C bus (this only works for -+ * I2C EEPROMs) the eeprom_notifier::add method is called with -+ * both the I2C information and the kobject for the sysfs -+ * device which has been registers. It is then possible to -+ * read from the device via the bin_attribute::read method -+ * to extract configuration information. -+ * -+ * Register the notifier in the board level code, there is no -+ * need to unregister it but you can if you want (it will save -+ * a little bit or kernel memory to do so). -+ */ -+struct eeprom_notifier { -+ void (*add)(int address, int kind, struct kobject *kobj, -+ struct bin_attribute *eeprom_attr); -+ struct list_head list; -+}; -+ -+extern void register_eeprom_user (struct eeprom_notifier *new); -+extern void unregister_eeprom_user (struct eeprom_notifier *old); -+ -+#endif /* _LINUX_EEPROM_H */ diff --git a/packages/linux/ixp4xx-kernel/2.6.16/50-i2c-bus-ixp4xx-hwmon.patch b/packages/linux/ixp4xx-kernel/2.6.16/50-i2c-bus-ixp4xx-hwmon.patch deleted file mode 100644 index d7fb8e55dc..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/50-i2c-bus-ixp4xx-hwmon.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- - drivers/i2c/busses/i2c-ixp4xx.c | 1 + - 1 file changed, 1 insertion(+) - ---- linux-ixp4xx.orig/drivers/i2c/busses/i2c-ixp4xx.c 2006-02-11 15:18:29.000000000 +0100 -+++ linux-ixp4xx/drivers/i2c/busses/i2c-ixp4xx.c 2006-02-18 16:20:12.000000000 +0100 -@@ -126,6 +126,7 @@ static int ixp4xx_i2c_probe(struct platf - drv_data->algo_data.timeout = 100; - - drv_data->adapter.id = I2C_HW_B_IXP4XX; -+ drv_data->adapter.class = I2C_CLASS_HWMON; - strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, - I2C_NAME_SIZE); - drv_data->adapter.algo_data = &drv_data->algo_data; diff --git a/packages/linux/ixp4xx-kernel/2.6.16/70-artop-latency.patch b/packages/linux/ixp4xx-kernel/2.6.16/70-artop-latency.patch deleted file mode 100644 index ad3ad11999..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/70-artop-latency.patch +++ /dev/null @@ -1,27 +0,0 @@ -On some controllers the pci latency timer -default value does not allow burst mode. -This patch fixes the latency value if it -is <= 0x80. - -Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> - ---- - drivers/scsi/pata_artop.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- linux-ixp4xx.orig/drivers/scsi/pata_artop.c 2006-02-21 02:53:43.000000000 +0100 -+++ linux-ixp4xx/drivers/scsi/pata_artop.c 2006-02-21 02:54:01.000000000 +0100 -@@ -450,6 +450,13 @@ static int artop_init_one (struct pci_de - pci_read_config_byte(pdev, 0x49, ®); - pci_write_config_byte(pdev, 0x49, reg & ~ 0x30); - -+ /* PCI latency must be > 0x80 for burst mode, tweak it -+ * if required. -+ */ -+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, ®); -+ if (reg <= 0x80) -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x90); -+ - /* Enable IRQ output and burst mode */ - pci_read_config_byte(pdev, 0x4a, ®); - pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/75-dsmg600.patch b/packages/linux/ixp4xx-kernel/2.6.16/75-dsmg600.patch index 05d467d0be..3603bd3ca8 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/75-dsmg600.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/75-dsmg600.patch @@ -9,9 +9,9 @@ include/asm-arm/arch-ixp4xx/irqs.h | 10 ++ 8 files changed, 296 insertions(+) ---- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:29:02.000000000 +0100 -+++ linux-ixp4xx/arch/arm/mach-ixp4xx/Kconfig 2006-02-23 18:29:11.000000000 +0100 -@@ -85,6 +85,14 @@ config MACH_NAS100D +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Kconfig 2006-03-18 18:10:31.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Kconfig 2006-03-18 18:10:34.000000000 +0100 +@@ -83,6 +83,14 @@ config MACH_NAS100D NAS 100d device. For more information on this platform, see http://www.nslu2-linux.org/wiki/NAS100d/HomePage @@ -27,7 +27,7 @@ # Avila and IXDP share the same source for now. Will change in future # --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/arch/arm/mach-ixp4xx/dsmg600-pci.c 2006-02-23 18:29:11.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/dsmg600-pci.c 2006-03-18 18:10:34.000000000 +0100 @@ -0,0 +1,74 @@ +/* + * DSM-G600 board-level PCI initialization @@ -104,7 +104,7 @@ + +subsys_initcall(dsmg600_pci_init); --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/arch/arm/mach-ixp4xx/dsmg600-setup.c 2006-02-23 18:29:11.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/dsmg600-setup.c 2006-03-18 18:10:34.000000000 +0100 @@ -0,0 +1,139 @@ +/* + * DSM-G600 board-setup @@ -245,15 +245,15 @@ + .timer = &ixp4xx_timer, + .init_machine = dsmg600_init, +MACHINE_END ---- linux-ixp4xx.orig/arch/arm/tools/mach-types 2006-02-23 18:29:02.000000000 +0100 -+++ linux-ixp4xx/arch/arm/tools/mach-types 2006-02-23 18:29:39.000000000 +0100 +--- linux-ixp4xx.orig/arch/arm/tools/mach-types 2006-03-18 18:10:31.000000000 +0100 ++++ linux-ixp4xx/arch/arm/tools/mach-types 2006-03-18 18:10:34.000000000 +0100 @@ -969,3 +969,4 @@ mxc300_30ads MACH_MXC30030ADS MXC30030A fujitsu_wimaxsoc MACH_FUJITSU_WIMAXSOC FUJITSU_WIMAXSOC 956 dualpcmodem MACH_DUALPCMODEM DUALPCMODEM 957 gesbc9312 MACH_GESBC9312 GESBC9312 958 +dsmg600 MACH_DSMG600 DSMG600 964 --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/dsmg600.h 2006-02-23 18:29:11.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/dsmg600.h 2006-03-18 18:10:34.000000000 +0100 @@ -0,0 +1,62 @@ +/* + * DSM-G600 platform specific definitions @@ -317,16 +317,16 @@ +#define DSMG600_IRQ_RSTBTN IRQ_IXP4XX_GPIO3 + +#define DSMG600_GPIO_PWROFF DSMG600_GPIO2 /* power off */ ---- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Makefile 2006-02-23 18:29:02.000000000 +0100 -+++ linux-ixp4xx/arch/arm/mach-ixp4xx/Makefile 2006-02-23 18:29:11.000000000 +0100 +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Makefile 2006-03-18 18:10:31.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Makefile 2006-03-18 18:10:34.000000000 +0100 @@ -10,4 +10,5 @@ obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote- obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o +obj-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o dsmg600-setup.o ---- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-23 18:29:02.000000000 +0100 -+++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/hardware.h 2006-02-23 18:29:11.000000000 +0100 +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/hardware.h 2006-03-18 18:10:31.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/hardware.h 2006-03-18 18:10:34.000000000 +0100 @@ -46,5 +46,6 @@ extern unsigned int processor_id; #include "prpmc1100.h" #include "nslu2.h" @@ -334,8 +334,8 @@ +#include "dsmg600.h" #endif /* _ASM_ARCH_HARDWARE_H */ ---- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-23 18:29:02.000000000 +0100 -+++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/irqs.h 2006-02-23 18:29:11.000000000 +0100 +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/irqs.h 2006-03-18 18:10:31.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/irqs.h 2006-03-18 18:10:34.000000000 +0100 @@ -109,4 +109,14 @@ #define IRQ_NAS100D_PCI_INTD IRQ_IXP4XX_GPIO8 #define IRQ_NAS100D_PCI_INTE IRQ_IXP4XX_GPIO7 @@ -343,11 +343,11 @@ +/* + * D-Link DSM-G600 board IRQs + */ -+#define IRQ_DSMG600_PCI_INTA IRQ_IXP4XX_GPIO11 -+#define IRQ_DSMG600_PCI_INTB IRQ_IXP4XX_GPIO10 -+#define IRQ_DSMG600_PCI_INTC IRQ_IXP4XX_GPIO9 -+#define IRQ_DSMG600_PCI_INTD IRQ_IXP4XX_GPIO8 -+#define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7 -+#define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6 ++#define IRQ_DSMG600_PCI_INTA IRQ_IXP4XX_GPIO11 ++#define IRQ_DSMG600_PCI_INTB IRQ_IXP4XX_GPIO10 ++#define IRQ_DSMG600_PCI_INTC IRQ_IXP4XX_GPIO9 ++#define IRQ_DSMG600_PCI_INTD IRQ_IXP4XX_GPIO8 ++#define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7 ++#define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6 + #endif diff --git a/packages/linux/ixp4xx-kernel/2.6.16/82-nas100d-power.patch b/packages/linux/ixp4xx-kernel/2.6.16/82-nas100d-power.patch deleted file mode 100644 index 4ce02c907f..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/82-nas100d-power.patch +++ /dev/null @@ -1,15 +0,0 @@ - arch/arm/mach-ixp4xx/nas100d-power.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nas100d-power.c 2006-02-06 20:37:01.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nas100d-power.c 2006-02-06 22:34:52.000000000 +0100 -@@ -56,6 +56,9 @@ static int __init nas100d_power_init(voi - - static void __exit nas100d_power_exit(void) - { -+ if (!(machine_is_nas100d())) -+ return; -+ - free_irq(NAS100D_RB_IRQ, NULL); - } - diff --git a/packages/linux/ixp4xx-kernel/2.6.16/92-nas100d-mac.patch b/packages/linux/ixp4xx-kernel/2.6.16/92-nas100d-mac.patch new file mode 100644 index 0000000000..59715a024e --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/92-nas100d-mac.patch @@ -0,0 +1,85 @@ + arch/arm/mach-ixp4xx/nas100d-setup.c | 64 +++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-27 03:03:47.000000000 +0200 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-27 03:37:23.000000000 +0200 +@@ -15,6 +15,9 @@ + #include <linux/kernel.h> + #include <linux/serial.h> + #include <linux/serial_8250.h> ++#include <linux/mtd/mtd.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> + + #include <asm/mach-types.h> + #include <asm/mach/arch.h> +@@ -110,8 +113,69 @@ static void nas100d_power_off(void) + gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH); + } + ++/* ++ * When the RedBoot config partition is added the MAC address is read from ++ * it. ++ */ ++static struct sockaddr mac; ++ ++static void nas100d_flash_add(struct mtd_info *mtd) { ++ if (strcmp(mtd->name, "RedBoot config") == 0) { ++ size_t retlen; ++ int err; ++ /* the mac addr is at a known offset */ ++ err = mtd->read(mtd, 0x0FD8, 6, &retlen, (u8 *) &mac.sa_data); ++ if (err != 0 || retlen != 6) ++ printk(KERN_ERR "nas100d: mac addr read failed\n"); ++ else ++ printk(KERN_INFO ++ "nas100d: mac %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", ++ mac.sa_data[0], mac.sa_data[1], mac.sa_data[2], ++ mac.sa_data[3], mac.sa_data[4], mac.sa_data[5]); ++ } ++} ++ ++/* ++ * Nothing to do on remove at present. ++ */ ++static void nas100d_flash_remove(struct mtd_info *mtd) { ++} ++ ++static struct mtd_notifier nas100d_flash_notifier = { ++ .add = nas100d_flash_add, ++ .remove = nas100d_flash_remove, ++}; ++ ++static int nas100d_netdev_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = ptr; ++ ++ /* identify the ixp4xx eth, port 1 */ ++ if (dev->dev_addr[1] != 0x02 || dev->dev_addr[2] != 0xB3 ++ || dev->dev_addr[5] != 0x01) ++ return NOTIFY_DONE; ++ ++ if (event == NETDEV_REGISTER && is_valid_ether_addr(mac.sa_data)) { ++ mac.sa_family = dev->type; ++ dev_set_mac_address(dev, &mac); ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block nas100d_netdev_notifier = { ++ .notifier_call = nas100d_netdev_event, ++}; ++ + static void __init nas100d_init(void) + { ++ /* The flash has an ethernet MAC embedded in it which we need, ++ * that is all this notifier does. ++ */ ++ register_mtd_user(&nas100d_flash_notifier); ++ register_netdevice_notifier(&nas100d_netdev_notifier); ++ + ixp4xx_sys_init(); + + /* gpio 14 and 15 are _not_ clocks */ diff --git a/packages/linux/ixp4xx-kernel/2.6.16/92-nslu2-mac.patch b/packages/linux/ixp4xx-kernel/2.6.16/92-nslu2-mac.patch new file mode 100644 index 0000000000..31c5f04ebe --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/92-nslu2-mac.patch @@ -0,0 +1,88 @@ + arch/arm/mach-ixp4xx/nslu2-setup.c | 62 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) + +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-03-27 14:42:07.000000000 +0200 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-03-27 14:45:45.000000000 +0200 +@@ -16,6 +16,9 @@ + #include <linux/kernel.h> + #include <linux/serial.h> + #include <linux/serial_8250.h> ++#include <linux/mtd/mtd.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> + + #include <asm/mach-types.h> + #include <asm/mach/arch.h> +@@ -117,6 +120,59 @@ static void nslu2_power_off(void) + gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH); + } + ++/* ++ * When the RedBoot config partition is added the MAC address is read from ++ * it. ++ */ ++static struct sockaddr mac; ++ ++static void nslu2_flash_add(struct mtd_info *mtd) { ++ if (strcmp(mtd->name, "RedBoot config") == 0) { ++ size_t retlen; ++ int err; ++ /* the mac addr is at a known offset */ ++ err = mtd->read(mtd, 0x3FFD8, 6, &retlen, (u8 *) &mac.sa_data); ++ if (err != 0 || retlen != 6) ++ printk(KERN_ERR "nslu2: mac addr read failed\n"); ++ else ++ printk(KERN_INFO ++ "nslu2: mac %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", ++ mac.sa_data[0], mac.sa_data[1], mac.sa_data[2], ++ mac.sa_data[3], mac.sa_data[4], mac.sa_data[5]); ++ } ++} ++ ++static void nslu2_flash_remove(struct mtd_info *mtd) { ++} ++ ++static struct mtd_notifier nslu2_flash_notifier = { ++ .add = nslu2_flash_add, ++ .remove = nslu2_flash_remove, ++}; ++ ++ ++static int nslu2_netdev_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = ptr; ++ ++ /* identify the ixp4xx eth, port 1 */ ++ if (dev->dev_addr[1] != 0x02 || dev->dev_addr[2] != 0xB3 ++ || dev->dev_addr[5] != 0x01) ++ return NOTIFY_DONE; ++ ++ if (event == NETDEV_REGISTER && is_valid_ether_addr(mac.sa_data)) { ++ mac.sa_family = dev->type; ++ dev_set_mac_address(dev, &mac); ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block nslu2_netdev_notifier = { ++ .notifier_call = nslu2_netdev_event, ++}; ++ + static void __init nslu2_init(void) + { + /* The NSLU2 has a 33MHz crystal on board - 1.01% different +@@ -124,6 +180,12 @@ static void __init nslu2_init(void) + */ + ixp4xx_set_board_tick_rate(66000000); + ++ /* The flash has an ethernet MAC embedded in it which we need, ++ * that is all this notifier does. ++ */ ++ register_mtd_user(&nslu2_flash_notifier); ++ register_netdevice_notifier(&nslu2_netdev_notifier); ++ + ixp4xx_sys_init(); + + nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); diff --git a/packages/linux/ixp4xx-kernel/2.6.16/94-loft-setup.patch b/packages/linux/ixp4xx-kernel/2.6.16/94-loft-setup.patch index 62efa77495..6f82262967 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/94-loft-setup.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/94-loft-setup.patch @@ -1,20 +1,29 @@ --- - arch/arm/mach-ixp4xx/ixdp425-setup.c | 145 +++++++++++++++++++++++++++++++++-- - 1 file changed, 140 insertions(+), 5 deletions(-) + arch/arm/mach-ixp4xx/ixdp425-setup.c | 173 ++++++++++++++++++++++++++++++++--- + 1 file changed, 163 insertions(+), 10 deletions(-) ---- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-02-22 18:53:29.000000000 +0100 -+++ linux-ixp4xx/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-02-22 18:57:00.000000000 +0100 -@@ -15,7 +15,7 @@ - #include <linux/tty.h> +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-03-27 03:08:59.000000000 +0200 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-03-27 03:40:03.000000000 +0200 +@@ -11,20 +11,26 @@ + #include <linux/kernel.h> + #include <linux/init.h> + #include <linux/device.h> +-#include <linux/serial.h> +-#include <linux/tty.h> #include <linux/serial_8250.h> - #include <linux/slab.h> +-#include <linux/slab.h> - +-#include <asm/types.h> ++#include <linux/i2c.h> +#include <linux/eeprom.h> - #include <asm/types.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> #include <asm/setup.h> #include <asm/memory.h> -@@ -25,6 +25,14 @@ + #include <asm/hardware.h> + #include <asm/mach-types.h> +-#include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> @@ -29,7 +38,7 @@ static struct flash_platform_data ixdp425_flash_data = { .map_name = "cfi_probe", .width = 2, -@@ -176,22 +184,149 @@ MACHINE_START(AVILA, "Gateworks Avila Ne +@@ -176,22 +182,169 @@ MACHINE_START(AVILA, "Gateworks Avila Ne MACHINE_END #endif @@ -68,37 +77,56 @@ */ -#ifdef CONFIG_MACH_LOFT + -+#if defined(CONFIG_SENSORS_EEPROM) && defined(CONFIG_MACLIST) -+static void loft_eeprom_add(int address, int kind, struct kobject *kobj, -+ struct bin_attribute *eeprom_attr) { ++#if defined(CONFIG_SENSORS_EEPROM) ++static unsigned char loft_macs[12]; ++ ++static int loft_eeprom_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ struct eeprom_data *data = ptr; ++ + /* The MACs are the first 12 bytes in the eeprom at address 0x51 */ -+ if (address == 0x51) { -+ ssize_t retlen; -+ char data[12]; -+ -+ /* Two Macs, one at 0, the other at 6, maclist_add will -+ * complain if the ID is not a valid MAC. -+ */ -+ retlen = eeprom_attr->read(kobj, data, 0, sizeof data); -+ if (retlen >= 6) { -+ u8 mac[6]; -+ memcpy(mac, data+0, sizeof mac); -+ printk(KERN_INFO "LOFT MAC[0]: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ maclist_add(mac); -+ } -+ if (retlen >= 12) { -+ u8 mac[6]; -+ memcpy(mac, data+6, sizeof mac); -+ printk(KERN_INFO "LOFT MAC[1]: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", -+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -+ maclist_add(mac); -+ } ++ if (event == EEPROM_REGISTER && data->client.addr == 0x51) ++ data->attr->read(&data->client.dev.kobj, loft_macs, 0, 12); ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block loft_eeprom_notifier = { ++ .notifier_call = loft_eeprom_event, ++}; ++ ++static int loft_netdev_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = ptr; ++ unsigned char *hwaddr = NULL; ++ ++ /* identify the ixp4xx eth */ ++ if (dev->dev_addr[1] != 0x02 || dev->dev_addr[2] != 0xB3) ++ return NOTIFY_DONE; ++ ++ if (event != NETDEV_REGISTER) ++ return NOTIFY_DONE; ++ ++ /* identify the port */ ++ if (dev->dev_addr[5] == 0x01) ++ hwaddr = &loft_macs[0]; ++ else if (dev->dev_addr[5] == 0x02) ++ hwaddr = &loft_macs[6]; ++ ++ if (hwaddr && is_valid_ether_addr(hwaddr)) { ++ struct sockaddr addr; ++ addr.sa_family = dev->type; ++ memcpy(addr.sa_data, hwaddr, ETH_ALEN); ++ dev_set_mac_address(dev, &addr); + } ++ ++ return NOTIFY_DONE; +} + -+static struct eeprom_notifier loft_eeprom_notifier = { -+ .add = loft_eeprom_add ++static struct notifier_block loft_netdev_notifier = { ++ .notifier_call = loft_netdev_event, +}; +#endif + @@ -114,7 +142,8 @@ + * that is all this notifier does. + */ +#ifdef CONFIG_SENSORS_EEPROM -+ register_eeprom_user(&loft_eeprom_notifier); ++ register_eeprom_notifier(&loft_eeprom_notifier); ++ register_netdevice_notifier(&loft_netdev_notifier); +#endif +} + diff --git a/packages/linux/ixp4xx-kernel/2.6.16/94-nas100d-setup.patch b/packages/linux/ixp4xx-kernel/2.6.16/94-nas100d-setup.patch deleted file mode 100644 index cdca7d2766..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/94-nas100d-setup.patch +++ /dev/null @@ -1,73 +0,0 @@ -Include a fixup machine start function in nas100d-setup.c to handle -the command line and memory setup parameters which are not specifiable -in the boot loader. - -Signed-off-by: John Bowler <jbowler@acm.org> - - arch/arm/mach-ixp4xx/nas100d-setup.c | 43 +++++++++++++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - ---- linux-nslu2.orig/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-02-10 19:19:53.000000000 +0100 -+++ linux-nslu2/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-02-10 19:29:18.000000000 +0100 -@@ -17,6 +17,8 @@ - #include <linux/serial_8250.h> - #include <linux/mtd/mtd.h> - -+#include <asm/setup.h> -+#include <asm/memory.h> - #include <asm/mach-types.h> - #include <asm/mach/arch.h> - #include <asm/mach/flash.h> -@@ -161,11 +163,52 @@ static void __init nas100d_init(void) - platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices)); - } - -+/* -+ * NAS100D bootstrap may pass in parameters, but we zap the mem -+ * settings to be safe (the box always has 64MByte at 0). The -+ * passed in command line can override this default, we prepend -+ * to the config'ed default. -+ * -+ * NOTE: the startup sequence is: -+ * 1) Call the machine fixup -+ * 2) Parse the ATAG list, the ATAG_CMDLINE is copied in -+ * to default_command_line which is the value of *from -+ * 3) Parse the command line in *from (*not* -+ * default_command_line unless they are the same!) -+ * -+ * Setting mi->nr_banks causes (2) to 'squash' (set to ATAG_NONE) -+ * any ATAG_MEM tags, but mem= command line options cause nr_banks -+ * to be reset to 0 (on the first mem=) -+ */ -+static char nas100d_command_line[] __initdata = -+ "root=/dev/mtdblock2 rootfstype=jffs2 init=/linuxrc " -+ "rtc-pcf8563.probe=0,0x51 " -+ CONFIG_CMDLINE; -+ -+static void __init nas100d_fixup(struct machine_desc *desc, -+ struct tag *tags, char **cmdline, struct meminfo *mi) -+{ -+ /* The NAS100D has one bank of 64MByte memory. -+ * NOTE: setting nr_banks != 0 causes kernel/setup.c to remove -+ * the mem tags from the tag list. We need do nothing here! -+ */ -+ mi->nr_banks=1; -+ mi->bank[0].start = 0; -+ mi->bank[0].size = (64*1024*1024); -+ mi->bank[0].node = PHYS_TO_NID(0); -+ -+ /* A command line in the ATAG list will override this one, -+ * as is intended. -+ */ -+ strlcpy(*cmdline, nas100d_command_line, COMMAND_LINE_SIZE); -+} -+ - MACHINE_START(NAS100D, "Iomega NAS 100d") - /* Maintainer: www.nslu2-linux.org */ - .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, - .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, - .boot_params = 0x00000100, -+ .fixup = nas100d_fixup, - .map_io = ixp4xx_map_io, - .init_irq = ixp4xx_init_irq, - .timer = &ixp4xx_timer, diff --git a/packages/linux/ixp4xx-kernel/2.6.16/96-nas100d-leds.patch b/packages/linux/ixp4xx-kernel/2.6.16/96-nas100d-leds.patch index ceb4b8b2f8..60b6bbd4c9 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/96-nas100d-leds.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/96-nas100d-leds.patch @@ -6,17 +6,17 @@ Signed-off-by: John Bowler <jbowler@acm.org> arch/arm/mach-ixp4xx/nas100d-setup.c | 43 ++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) ---- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-02-21 01:40:40.000000000 +0100 -+++ linux-ixp4xx/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-02-21 01:53:48.000000000 +0100 -@@ -16,6 +16,7 @@ - #include <linux/serial.h> - #include <linux/serial_8250.h> +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-27 13:45:22.000000000 +0200 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-27 13:46:00.000000000 +0200 +@@ -18,6 +18,7 @@ #include <linux/mtd/mtd.h> + #include <linux/netdevice.h> + #include <linux/etherdevice.h> +#include <linux/leds.h> - #include <asm/setup.h> - #include <asm/memory.h> -@@ -42,6 +43,36 @@ static struct platform_device nas100d_fl + #include <asm/mach-types.h> + #include <asm/mach/arch.h> +@@ -41,6 +42,36 @@ static struct platform_device nas100d_fl .resource = &nas100d_flash_resource, }; @@ -35,7 +35,7 @@ Signed-off-by: John Bowler <jbowler@acm.org> + .flags = IXP4XX_GPIO_LOW, + }, + { -+ .name = "disk-1", /* yellow led */ ++ .name = "disk", /* yellow led */ + .start = 3, + .end = 3, + .flags = IXP4XX_GPIO_LOW, @@ -53,7 +53,7 @@ Signed-off-by: John Bowler <jbowler@acm.org> static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = { .sda_pin = NAS100D_SDA_PIN, .scl_pin = NAS100D_SCL_PIN, -@@ -100,7 +131,6 @@ static struct platform_device nas100d_ua +@@ -99,7 +130,6 @@ static struct platform_device nas100d_ua static struct platform_device *nas100d_devices[] __initdata = { &nas100d_i2c_controller, &nas100d_flash, @@ -61,7 +61,7 @@ Signed-off-by: John Bowler <jbowler@acm.org> }; static void nas100d_power_off(void) -@@ -160,7 +190,18 @@ static void __init nas100d_init(void) +@@ -187,7 +217,18 @@ static void __init nas100d_init(void) pm_power_off = nas100d_power_off; diff --git a/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch b/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch index 6b3b8d7d39..7890d392b0 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch +++ b/packages/linux/ixp4xx-kernel/2.6.16/96-nslu2-leds.patch @@ -8,9 +8,9 @@ Signed-off-by: John Bowler <jbowler@acm.org> --- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-21 02:54:05.000000000 +0100 +++ linux-ixp4xx/arch/arm/mach-ixp4xx/nslu2-setup.c 2006-02-21 02:54:05.000000000 +0100 @@ -17,6 +17,9 @@ - #include <linux/serial.h> - #include <linux/serial_8250.h> #include <linux/mtd/mtd.h> + #include <linux/netdevice.h> + #include <linux/etherdevice.h> +#ifdef CONFIG_LEDS_CLASS +#include <linux/leds.h> +#endif diff --git a/packages/linux/ixp4xx-kernel/2.6.16/defconfig b/packages/linux/ixp4xx-kernel/2.6.16/defconfig index 8548ed54b0..1b190e290d 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/defconfig +++ b/packages/linux/ixp4xx-kernel/2.6.16/defconfig @@ -593,13 +593,13 @@ CONFIG_ATA_OVER_ETH=m # SCSI device support # # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=m +CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) # -CONFIG_BLK_DEV_SD=m +CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m # CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=m @@ -637,7 +637,7 @@ CONFIG_ISCSI_TCP=m # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -CONFIG_SCSI_SATA=m +CONFIG_SCSI_SATA=y # CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set # CONFIG_SCSI_ATA_PIIX is not set @@ -655,7 +655,7 @@ CONFIG_SCSI_SATA=m # CONFIG_SCSI_SATA_VITESSE is not set # CONFIG_SCSI_PATA_ALI is not set # CONFIG_SCSI_PATA_AMD is not set -CONFIG_SCSI_PATA_ARTOP=m +CONFIG_SCSI_PATA_ARTOP=y # CONFIG_SCSI_PATA_ATIIXP is not set # CONFIG_SCSI_PATA_CMD64X is not set # CONFIG_SCSI_PATA_CS5520 is not set @@ -686,7 +686,7 @@ CONFIG_SCSI_PATA_ARTOP=m # CONFIG_SCSI_PATA_TRIFLEX is not set # CONFIG_SCSI_PATA_VIA is not set # CONFIG_SCSI_PATA_WINBOND is not set -CONFIG_SCSI_PATA_IXP4XX=m +CONFIG_SCSI_PATA_IXP4XX=y # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set @@ -1024,7 +1024,6 @@ CONFIG_I2C_IXP4XX=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -1100,6 +1099,7 @@ CONFIG_HWMON=m # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT8231 is not set @@ -1302,14 +1302,14 @@ CONFIG_USB_DEVICEFS=y # # USB Host Controller Drivers # -CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y # CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=m +CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set # @@ -1326,7 +1326,7 @@ CONFIG_USB_PRINTER=m # # may also be needed; see USB_STORAGE Help for more information # -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 @@ -1484,6 +1484,7 @@ CONFIG_USB_EZUSB=y # # Real Time Clock # +CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" diff --git a/packages/linux/ixp4xx-kernel/2.6.16/linux-2.6.16-i2c.patch b/packages/linux/ixp4xx-kernel/2.6.16/linux-2.6.16-i2c.patch new file mode 100644 index 0000000000..86c88c3746 --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/linux-2.6.16-i2c.patch @@ -0,0 +1,13671 @@ +--- linux-2.6.16.orig/include/linux/hwmon-sysfs.h 2006-03-22 17:06:11.000000000 +0100 ++++ linux-2.6.16/include/linux/hwmon-sysfs.h 2006-03-22 17:06:15.000000000 +0100 +@@ -27,11 +27,13 @@ + #define to_sensor_dev_attr(_dev_attr) \ + container_of(_dev_attr, struct sensor_device_attribute, dev_attr) + +-#define SENSOR_DEVICE_ATTR(_name,_mode,_show,_store,_index) \ +-struct sensor_device_attribute sensor_dev_attr_##_name = { \ +- .dev_attr = __ATTR(_name,_mode,_show,_store), \ +- .index = _index, \ +-} ++#define SENSOR_ATTR(_name, _mode, _show, _store, _index) \ ++ { .dev_attr = __ATTR(_name, _mode, _show, _store), \ ++ .index = _index } ++ ++#define SENSOR_DEVICE_ATTR(_name, _mode, _show, _store, _index) \ ++struct sensor_device_attribute sensor_dev_attr_##_name \ ++ = SENSOR_ATTR(_name, _mode, _show, _store, _index) + + struct sensor_device_attribute_2 { + struct device_attribute dev_attr; +@@ -41,11 +43,13 @@ + #define to_sensor_dev_attr_2(_dev_attr) \ + container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr) + ++#define SENSOR_ATTR_2(_name, _mode, _show, _store, _nr, _index) \ ++ { .dev_attr = __ATTR(_name, _mode, _show, _store), \ ++ .index = _index, \ ++ .nr = _nr } ++ + #define SENSOR_DEVICE_ATTR_2(_name,_mode,_show,_store,_nr,_index) \ +-struct sensor_device_attribute_2 sensor_dev_attr_##_name = { \ +- .dev_attr = __ATTR(_name,_mode,_show,_store), \ +- .index = _index, \ +- .nr = _nr, \ +-} ++struct sensor_device_attribute_2 sensor_dev_attr_##_name \ ++ = SENSOR_ATTR_2(_name, _mode, _show, _store, _nr, _index) + + #endif /* _LINUX_HWMON_SYSFS_H */ +--- linux-2.6.16.orig/drivers/hwmon/pc87360.c 2006-03-22 17:06:11.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/pc87360.c 2006-03-22 17:06:15.000000000 +0100 +@@ -43,6 +43,7 @@ + #include <linux/hwmon-sysfs.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + static u8 devid; +@@ -183,8 +184,8 @@ + struct pc87360_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; +- struct semaphore update_lock; ++ struct mutex lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -283,7 +284,7 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long fan_min = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index])); + + /* If it wouldn't fit, change clock divisor */ +@@ -300,23 +301,31 @@ + /* Write new divider, preserve alarm bits */ + pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index), + data->fan_status[attr->index] & 0xF9); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } + +-#define show_and_set_fan(offset) \ +-static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ +- show_fan_input, NULL, offset-1); \ +-static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IWUSR | S_IRUGO, \ +- show_fan_min, set_fan_min, offset-1); \ +-static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ +- show_fan_div, NULL, offset-1); \ +-static SENSOR_DEVICE_ATTR(fan##offset##_status, S_IRUGO, \ +- show_fan_status, NULL, offset-1); +-show_and_set_fan(1) +-show_and_set_fan(2) +-show_and_set_fan(3) ++static struct sensor_device_attribute fan_input[] = { ++ SENSOR_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0), ++ SENSOR_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1), ++ SENSOR_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2), ++}; ++static struct sensor_device_attribute fan_status[] = { ++ SENSOR_ATTR(fan1_status, S_IRUGO, show_fan_status, NULL, 0), ++ SENSOR_ATTR(fan2_status, S_IRUGO, show_fan_status, NULL, 1), ++ SENSOR_ATTR(fan3_status, S_IRUGO, show_fan_status, NULL, 2), ++}; ++static struct sensor_device_attribute fan_div[] = { ++ SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), ++ SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), ++ SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2), ++}; ++static struct sensor_device_attribute fan_min[] = { ++ SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 0), ++ SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 1), ++ SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 2), ++}; + + static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf) + { +@@ -335,21 +344,20 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm[attr->index] = PWM_TO_REG(val, + FAN_CONFIG_INVERT(data->fan_conf, attr->index)); + pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(attr->index), + data->pwm[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +-#define show_and_set_pwm(offset) \ +-static SENSOR_DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \ +- show_pwm, set_pwm, offset-1); +-show_and_set_pwm(1) +-show_and_set_pwm(2) +-show_and_set_pwm(3) ++static struct sensor_device_attribute pwm[] = { ++ SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0), ++ SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1), ++ SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2), ++}; + + static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf) + { +@@ -386,11 +394,11 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); + pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MIN, + data->in_min[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf, +@@ -401,35 +409,67 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[attr->index] = IN_TO_REG(val, + data->in_vref); + pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MAX, + data->in_max[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +-#define show_and_set_in(offset) \ +-static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ +- show_in_input, NULL, offset); \ +-static SENSOR_DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \ +- show_in_min, set_in_min, offset); \ +-static SENSOR_DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \ +- show_in_max, set_in_max, offset); \ +-static SENSOR_DEVICE_ATTR(in##offset##_status, S_IRUGO, \ +- show_in_status, NULL, offset); +-show_and_set_in(0) +-show_and_set_in(1) +-show_and_set_in(2) +-show_and_set_in(3) +-show_and_set_in(4) +-show_and_set_in(5) +-show_and_set_in(6) +-show_and_set_in(7) +-show_and_set_in(8) +-show_and_set_in(9) +-show_and_set_in(10) ++static struct sensor_device_attribute in_input[] = { ++ SENSOR_ATTR(in0_input, S_IRUGO, show_in_input, NULL, 0), ++ SENSOR_ATTR(in1_input, S_IRUGO, show_in_input, NULL, 1), ++ SENSOR_ATTR(in2_input, S_IRUGO, show_in_input, NULL, 2), ++ SENSOR_ATTR(in3_input, S_IRUGO, show_in_input, NULL, 3), ++ SENSOR_ATTR(in4_input, S_IRUGO, show_in_input, NULL, 4), ++ SENSOR_ATTR(in5_input, S_IRUGO, show_in_input, NULL, 5), ++ SENSOR_ATTR(in6_input, S_IRUGO, show_in_input, NULL, 6), ++ SENSOR_ATTR(in7_input, S_IRUGO, show_in_input, NULL, 7), ++ SENSOR_ATTR(in8_input, S_IRUGO, show_in_input, NULL, 8), ++ SENSOR_ATTR(in9_input, S_IRUGO, show_in_input, NULL, 9), ++ SENSOR_ATTR(in10_input, S_IRUGO, show_in_input, NULL, 10), ++}; ++static struct sensor_device_attribute in_status[] = { ++ SENSOR_ATTR(in0_status, S_IRUGO, show_in_status, NULL, 0), ++ SENSOR_ATTR(in1_status, S_IRUGO, show_in_status, NULL, 1), ++ SENSOR_ATTR(in2_status, S_IRUGO, show_in_status, NULL, 2), ++ SENSOR_ATTR(in3_status, S_IRUGO, show_in_status, NULL, 3), ++ SENSOR_ATTR(in4_status, S_IRUGO, show_in_status, NULL, 4), ++ SENSOR_ATTR(in5_status, S_IRUGO, show_in_status, NULL, 5), ++ SENSOR_ATTR(in6_status, S_IRUGO, show_in_status, NULL, 6), ++ SENSOR_ATTR(in7_status, S_IRUGO, show_in_status, NULL, 7), ++ SENSOR_ATTR(in8_status, S_IRUGO, show_in_status, NULL, 8), ++ SENSOR_ATTR(in9_status, S_IRUGO, show_in_status, NULL, 9), ++ SENSOR_ATTR(in10_status, S_IRUGO, show_in_status, NULL, 10), ++}; ++static struct sensor_device_attribute in_min[] = { ++ SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 0), ++ SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 1), ++ SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 2), ++ SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 3), ++ SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 4), ++ SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 5), ++ SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 6), ++ SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 7), ++ SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 8), ++ SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 9), ++ SENSOR_ATTR(in10_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 10), ++}; ++static struct sensor_device_attribute in_max[] = { ++ SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 0), ++ SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 1), ++ SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 2), ++ SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 3), ++ SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 4), ++ SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 5), ++ SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 6), ++ SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 7), ++ SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 8), ++ SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 9), ++ SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10), ++}; + + static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf) + { +@@ -473,11 +513,11 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); + pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MIN, + data->in_min[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf, +@@ -488,11 +528,11 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[attr->index] = IN_TO_REG(val, data->in_vref); + pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MAX, + data->in_max[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf, +@@ -503,28 +543,51 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref); + pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_CRIT, + data->in_crit[attr->index-11]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +-#define show_and_set_therm(offset) \ +-static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ +- show_therm_input, NULL, 11+offset-4); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \ +- show_therm_min, set_therm_min, 11+offset-4); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \ +- show_therm_max, set_therm_max, 11+offset-4); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \ +- show_therm_crit, set_therm_crit, 11+offset-4); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_status, S_IRUGO, \ +- show_therm_status, NULL, 11+offset-4); +-show_and_set_therm(4) +-show_and_set_therm(5) +-show_and_set_therm(6) ++/* the +11 term below reflects the fact that VLM units 11,12,13 are ++ used in the chip to measure voltage across the thermistors ++*/ ++static struct sensor_device_attribute therm_input[] = { ++ SENSOR_ATTR(temp4_input, S_IRUGO, show_therm_input, NULL, 0+11), ++ SENSOR_ATTR(temp5_input, S_IRUGO, show_therm_input, NULL, 1+11), ++ SENSOR_ATTR(temp6_input, S_IRUGO, show_therm_input, NULL, 2+11), ++}; ++static struct sensor_device_attribute therm_status[] = { ++ SENSOR_ATTR(temp4_status, S_IRUGO, show_therm_status, NULL, 0+11), ++ SENSOR_ATTR(temp5_status, S_IRUGO, show_therm_status, NULL, 1+11), ++ SENSOR_ATTR(temp6_status, S_IRUGO, show_therm_status, NULL, 2+11), ++}; ++static struct sensor_device_attribute therm_min[] = { ++ SENSOR_ATTR(temp4_min, S_IRUGO | S_IWUSR, ++ show_therm_min, set_therm_min, 0+11), ++ SENSOR_ATTR(temp5_min, S_IRUGO | S_IWUSR, ++ show_therm_min, set_therm_min, 1+11), ++ SENSOR_ATTR(temp6_min, S_IRUGO | S_IWUSR, ++ show_therm_min, set_therm_min, 2+11), ++}; ++static struct sensor_device_attribute therm_max[] = { ++ SENSOR_ATTR(temp4_max, S_IRUGO | S_IWUSR, ++ show_therm_max, set_therm_max, 0+11), ++ SENSOR_ATTR(temp5_max, S_IRUGO | S_IWUSR, ++ show_therm_max, set_therm_max, 1+11), ++ SENSOR_ATTR(temp6_max, S_IRUGO | S_IWUSR, ++ show_therm_max, set_therm_max, 2+11), ++}; ++static struct sensor_device_attribute therm_crit[] = { ++ SENSOR_ATTR(temp4_crit, S_IRUGO | S_IWUSR, ++ show_therm_crit, set_therm_crit, 0+11), ++ SENSOR_ATTR(temp5_crit, S_IRUGO | S_IWUSR, ++ show_therm_crit, set_therm_crit, 1+11), ++ SENSOR_ATTR(temp6_crit, S_IRUGO | S_IWUSR, ++ show_therm_crit, set_therm_crit, 2+11), ++}; + + static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) + { +@@ -592,11 +655,11 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_min[attr->index] = TEMP_TO_REG(val); + pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MIN, + data->temp_min[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, +@@ -607,11 +670,11 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[attr->index] = TEMP_TO_REG(val); + pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MAX, + data->temp_max[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf, +@@ -622,28 +685,48 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_crit[attr->index] = TEMP_TO_REG(val); + pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_CRIT, + data->temp_crit[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +-#define show_and_set_temp(offset) \ +-static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ +- show_temp_input, NULL, offset-1); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \ +- show_temp_min, set_temp_min, offset-1); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \ +- show_temp_max, set_temp_max, offset-1); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \ +- show_temp_crit, set_temp_crit, offset-1); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_status, S_IRUGO, \ +- show_temp_status, NULL, offset-1); +-show_and_set_temp(1) +-show_and_set_temp(2) +-show_and_set_temp(3) ++static struct sensor_device_attribute temp_input[] = { ++ SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0), ++ SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1), ++ SENSOR_ATTR(temp3_input, S_IRUGO, show_temp_input, NULL, 2), ++}; ++static struct sensor_device_attribute temp_status[] = { ++ SENSOR_ATTR(temp1_status, S_IRUGO, show_temp_status, NULL, 0), ++ SENSOR_ATTR(temp2_status, S_IRUGO, show_temp_status, NULL, 1), ++ SENSOR_ATTR(temp3_status, S_IRUGO, show_temp_status, NULL, 2), ++}; ++static struct sensor_device_attribute temp_min[] = { ++ SENSOR_ATTR(temp1_min, S_IRUGO | S_IWUSR, ++ show_temp_min, set_temp_min, 0), ++ SENSOR_ATTR(temp2_min, S_IRUGO | S_IWUSR, ++ show_temp_min, set_temp_min, 1), ++ SENSOR_ATTR(temp3_min, S_IRUGO | S_IWUSR, ++ show_temp_min, set_temp_min, 2), ++}; ++static struct sensor_device_attribute temp_max[] = { ++ SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, ++ show_temp_max, set_temp_max, 0), ++ SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, ++ show_temp_max, set_temp_max, 1), ++ SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, ++ show_temp_max, set_temp_max, 2), ++}; ++static struct sensor_device_attribute temp_crit[] = { ++ SENSOR_ATTR(temp1_crit, S_IRUGO | S_IWUSR, ++ show_temp_crit, set_temp_crit, 0), ++ SENSOR_ATTR(temp2_crit, S_IRUGO | S_IWUSR, ++ show_temp_crit, set_temp_crit, 1), ++ SENSOR_ATTR(temp3_crit, S_IRUGO | S_IWUSR, ++ show_temp_crit, set_temp_crit, 2), ++}; + + static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf) + { +@@ -749,22 +832,24 @@ + static int pc87360_detect(struct i2c_adapter *adapter) + { + int i; +- struct i2c_client *new_client; ++ struct i2c_client *client; + struct pc87360_data *data; + int err = 0; + const char *name = "pc87360"; + int use_thermistors = 0; ++ struct device *dev; + + if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) + return -ENOMEM; + +- new_client = &data->client; +- i2c_set_clientdata(new_client, data); +- new_client->addr = address; +- init_MUTEX(&data->lock); +- new_client->adapter = adapter; +- new_client->driver = &pc87360_driver; +- new_client->flags = 0; ++ client = &data->client; ++ dev = &client->dev; ++ i2c_set_clientdata(client, data); ++ client->addr = address; ++ mutex_init(&data->lock); ++ client->adapter = adapter; ++ client->driver = &pc87360_driver; ++ client->flags = 0; + + data->fannr = 2; + data->innr = 0; +@@ -792,15 +877,15 @@ + break; + } + +- strcpy(new_client->name, name); ++ strlcpy(client->name, name, sizeof(client->name)); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + for (i = 0; i < 3; i++) { + if (((data->address[i] = extra_isa[i])) + && !request_region(extra_isa[i], PC87360_EXTENT, + pc87360_driver.driver.name)) { +- dev_err(&new_client->dev, "Region 0x%x-0x%x already " ++ dev_err(&client->dev, "Region 0x%x-0x%x already " + "in use!\n", extra_isa[i], + extra_isa[i]+PC87360_EXTENT-1); + for (i--; i >= 0; i--) +@@ -814,7 +899,7 @@ + if (data->fannr) + data->fan_conf = confreg[0] | (confreg[1] << 8); + +- if ((err = i2c_attach_client(new_client))) ++ if ((err = i2c_attach_client(client))) + goto ERROR2; + + /* Use the correct reference voltage +@@ -828,7 +913,7 @@ + PC87365_REG_TEMP_CONFIG); + } + data->in_vref = (i&0x02) ? 3025 : 2966; +- dev_dbg(&new_client->dev, "Using %s reference voltage\n", ++ dev_dbg(&client->dev, "Using %s reference voltage\n", + (i&0x02) ? "external" : "internal"); + + data->vid_conf = confreg[3]; +@@ -847,154 +932,64 @@ + if (devid == 0xe9 && data->address[1]) /* PC87366 */ + use_thermistors = confreg[2] & 0x40; + +- pc87360_init_client(new_client, use_thermistors); ++ pc87360_init_client(client, use_thermistors); + } + + /* Register sysfs hooks */ +- data->class_dev = hwmon_device_register(&new_client->dev); ++ data->class_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto ERROR3; + } + + if (data->innr) { +- device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in9_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in10_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in8_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in9_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in10_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in8_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in9_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in10_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in0_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in1_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in2_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in3_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in4_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in5_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in6_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in7_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in8_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in9_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_in10_status.dev_attr); +- +- device_create_file(&new_client->dev, &dev_attr_cpu0_vid); +- device_create_file(&new_client->dev, &dev_attr_vrm); +- device_create_file(&new_client->dev, &dev_attr_alarms_in); ++ for (i = 0; i < 11; i++) { ++ device_create_file(dev, &in_input[i].dev_attr); ++ device_create_file(dev, &in_min[i].dev_attr); ++ device_create_file(dev, &in_max[i].dev_attr); ++ device_create_file(dev, &in_status[i].dev_attr); ++ } ++ device_create_file(dev, &dev_attr_cpu0_vid); ++ device_create_file(dev, &dev_attr_vrm); ++ device_create_file(dev, &dev_attr_alarms_in); + } + + if (data->tempnr) { +- device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp2_crit.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp1_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp2_status.dev_attr); +- +- device_create_file(&new_client->dev, &dev_attr_alarms_temp); +- } +- if (data->tempnr == 3) { +- device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp3_status.dev_attr); ++ for (i = 0; i < data->tempnr; i++) { ++ device_create_file(dev, &temp_input[i].dev_attr); ++ device_create_file(dev, &temp_min[i].dev_attr); ++ device_create_file(dev, &temp_max[i].dev_attr); ++ device_create_file(dev, &temp_crit[i].dev_attr); ++ device_create_file(dev, &temp_status[i].dev_attr); ++ } ++ device_create_file(dev, &dev_attr_alarms_temp); + } ++ + if (data->innr == 14) { +- device_create_file(&new_client->dev, &sensor_dev_attr_temp4_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp5_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp6_input.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp4_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp5_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp6_min.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp4_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp5_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp6_max.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp4_crit.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp5_crit.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp6_crit.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp4_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp5_status.dev_attr); +- device_create_file(&new_client->dev, &sensor_dev_attr_temp6_status.dev_attr); +- } +- +- if (data->fannr) { +- if (FAN_CONFIG_MONITOR(data->fan_conf, 0)) { +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan1_input.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan1_min.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan1_div.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan1_status.dev_attr); +- } +- +- if (FAN_CONFIG_MONITOR(data->fan_conf, 1)) { +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan2_input.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan2_min.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan2_div.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan2_status.dev_attr); +- } +- +- if (FAN_CONFIG_CONTROL(data->fan_conf, 0)) +- device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr); +- if (FAN_CONFIG_CONTROL(data->fan_conf, 1)) +- device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr); +- } +- if (data->fannr == 3) { +- if (FAN_CONFIG_MONITOR(data->fan_conf, 2)) { +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan3_input.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan3_min.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan3_div.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_fan3_status.dev_attr); ++ for (i = 0; i < 3; i++) { ++ device_create_file(dev, &therm_input[i].dev_attr); ++ device_create_file(dev, &therm_min[i].dev_attr); ++ device_create_file(dev, &therm_max[i].dev_attr); ++ device_create_file(dev, &therm_crit[i].dev_attr); ++ device_create_file(dev, &therm_status[i].dev_attr); + } ++ } + +- if (FAN_CONFIG_CONTROL(data->fan_conf, 2)) +- device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr); ++ for (i = 0; i < data->fannr; i++) { ++ if (FAN_CONFIG_MONITOR(data->fan_conf, i)) { ++ device_create_file(dev, &fan_input[i].dev_attr); ++ device_create_file(dev, &fan_min[i].dev_attr); ++ device_create_file(dev, &fan_div[i].dev_attr); ++ device_create_file(dev, &fan_status[i].dev_attr); ++ } ++ if (FAN_CONFIG_CONTROL(data->fan_conf, i)) ++ device_create_file(dev, &pwm[i].dev_attr); + } + + return 0; + + ERROR3: +- i2c_detach_client(new_client); ++ i2c_detach_client(client); + ERROR2: + for (i = 0; i < 3; i++) { + if (data->address[i]) { +@@ -1033,11 +1028,11 @@ + { + int res; + +- down(&(data->lock)); ++ mutex_lock(&(data->lock)); + if (bank != NO_BANK) + outb_p(bank, data->address[ldi] + PC87365_REG_BANK); + res = inb_p(data->address[ldi] + reg); +- up(&(data->lock)); ++ mutex_unlock(&(data->lock)); + + return res; + } +@@ -1045,11 +1040,11 @@ + static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, + u8 reg, u8 value) + { +- down(&(data->lock)); ++ mutex_lock(&(data->lock)); + if (bank != NO_BANK) + outb_p(bank, data->address[ldi] + PC87365_REG_BANK); + outb_p(value, data->address[ldi] + reg); +- up(&(data->lock)); ++ mutex_unlock(&(data->lock)); + } + + static void pc87360_init_client(struct i2c_client *client, int use_thermistors) +@@ -1071,7 +1066,7 @@ + } + + nr = data->innr < 11 ? data->innr : 11; +- for (i=0; i<nr; i++) { ++ for (i = 0; i < nr; i++) { + if (init >= init_in[i]) { + /* Forcibly enable voltage channel */ + reg = pc87360_read_value(data, LD_IN, i, +@@ -1088,14 +1083,14 @@ + + /* We can't blindly trust the Super-I/O space configuration bit, + most BIOS won't set it properly */ +- for (i=11; i<data->innr; i++) { ++ for (i = 11; i < data->innr; i++) { + reg = pc87360_read_value(data, LD_IN, i, + PC87365_REG_TEMP_STATUS); + use_thermistors = use_thermistors || (reg & 0x01); + } + + i = use_thermistors ? 2 : 0; +- for (; i<data->tempnr; i++) { ++ for (; i < data->tempnr; i++) { + if (init >= init_temp[i]) { + /* Forcibly enable temperature channel */ + reg = pc87360_read_value(data, LD_TEMP, i, +@@ -1111,7 +1106,7 @@ + } + + if (use_thermistors) { +- for (i=11; i<data->innr; i++) { ++ for (i = 11; i < data->innr; i++) { + if (init >= init_in[i]) { + /* The pin may already be used by thermal + diodes */ +@@ -1221,7 +1216,7 @@ + struct pc87360_data *data = i2c_get_clientdata(client); + u8 i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + dev_dbg(&client->dev, "Data update\n"); +@@ -1321,7 +1316,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/f71805f.c 2006-03-22 17:06:11.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/f71805f.c 2006-03-22 17:06:16.000000000 +0100 +@@ -30,6 +30,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-sysfs.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + static struct platform_device *pdev; +@@ -98,10 +99,6 @@ + #define ADDR_REG_OFFSET 0 + #define DATA_REG_OFFSET 1 + +-static struct resource f71805f_resource __initdata = { +- .flags = IORESOURCE_IO, +-}; +- + /* + * Registers + */ +@@ -131,10 +128,10 @@ + struct f71805f_data { + unsigned short addr; + const char *name; +- struct semaphore lock; ++ struct mutex lock; + struct class_device *class_dev; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long last_limits; /* In jiffies */ +@@ -150,7 +147,7 @@ + u8 temp_high[3]; + u8 temp_hyst[3]; + u8 temp_mode; +- u8 alarms[3]; ++ unsigned long alarms; + }; + + static inline long in_from_reg(u8 reg) +@@ -224,20 +221,20 @@ + { + u8 val; + +- down(&data->lock); ++ mutex_lock(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + val = inb(data->addr + DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + + return val; + } + + static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) + { +- down(&data->lock); ++ mutex_lock(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + outb(val, data->addr + DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + } + + /* It is important to read the MSB first, because doing so latches the +@@ -246,24 +243,24 @@ + { + u16 val; + +- down(&data->lock); ++ mutex_lock(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + val = inb(data->addr + DATA_REG_OFFSET) << 8; + outb(++reg, data->addr + ADDR_REG_OFFSET); + val |= inb(data->addr + DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + + return val; + } + + static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) + { +- down(&data->lock); ++ mutex_lock(&data->lock); + outb(reg, data->addr + ADDR_REG_OFFSET); + outb(val >> 8, data->addr + DATA_REG_OFFSET); + outb(++reg, data->addr + ADDR_REG_OFFSET); + outb(val & 0xff, data->addr + DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + } + + static struct f71805f_data *f71805f_update_device(struct device *dev) +@@ -271,7 +268,7 @@ + struct f71805f_data *data = dev_get_drvdata(dev); + int nr; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + /* Limit registers cache is refreshed after 60 seconds */ + if (time_after(jiffies, data->last_updated + 60 * HZ) +@@ -314,16 +311,15 @@ + data->temp[nr] = f71805f_read8(data, + F71805F_REG_TEMP(nr)); + } +- for (nr = 0; nr < 3; nr++) { +- data->alarms[nr] = f71805f_read8(data, +- F71805F_REG_STATUS(nr)); +- } ++ data->alarms = f71805f_read8(data, F71805F_REG_STATUS(0)) ++ + (f71805f_read8(data, F71805F_REG_STATUS(1)) << 8) ++ + (f71805f_read8(data, F71805F_REG_STATUS(2)) << 16); + + data->last_updated = jiffies; + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +@@ -362,10 +358,10 @@ + struct f71805f_data *data = dev_get_drvdata(dev); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_high[0] = in0_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -376,18 +372,14 @@ + struct f71805f_data *data = dev_get_drvdata(dev); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_low[0] = in0_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } + +-static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL); +-static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max); +-static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min); +- + static ssize_t show_in(struct device *dev, struct device_attribute *devattr, + char *buf) + { +@@ -426,10 +418,10 @@ + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_high[nr] = in_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -442,31 +434,14 @@ + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_low[nr] = in_to_reg(val); + f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } + +-#define sysfs_in(offset) \ +-static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ +- show_in, NULL, offset); \ +-static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ +- show_in_max, set_in_max, offset); \ +-static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ +- show_in_min, set_in_min, offset) +- +-sysfs_in(1); +-sysfs_in(2); +-sysfs_in(3); +-sysfs_in(4); +-sysfs_in(5); +-sysfs_in(6); +-sysfs_in(7); +-sysfs_in(8); +- + static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) + { +@@ -495,24 +470,14 @@ + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_low[nr] = fan_to_reg(val); + f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } + +-#define sysfs_fan(offset) \ +-static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ +- show_fan, NULL, offset - 1); \ +-static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ +- show_fan_min, set_fan_min, offset - 1) +- +-sysfs_fan(1); +-sysfs_fan(2); +-sysfs_fan(3); +- + static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, + char *buf) + { +@@ -562,10 +527,10 @@ + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_high[nr] = temp_to_reg(val); + f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -578,35 +543,20 @@ + int nr = attr->index; + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_hyst[nr] = temp_to_reg(val); + f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } + +-#define sysfs_temp(offset) \ +-static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ +- show_temp, NULL, offset - 1); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ +- show_temp_max, set_temp_max, offset - 1); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ +- show_temp_hyst, set_temp_hyst, offset - 1); \ +-static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO, \ +- show_temp_type, NULL, offset - 1) +- +-sysfs_temp(1); +-sysfs_temp(2); +-sysfs_temp(3); +- + static ssize_t show_alarms_in(struct device *dev, struct device_attribute + *devattr, char *buf) + { + struct f71805f_data *data = f71805f_update_device(dev); + +- return sprintf(buf, "%d\n", data->alarms[0] | +- ((data->alarms[1] & 0x01) << 8)); ++ return sprintf(buf, "%lu\n", data->alarms & 0x1ff); + } + + static ssize_t show_alarms_fan(struct device *dev, struct device_attribute +@@ -614,7 +564,7 @@ + { + struct f71805f_data *data = f71805f_update_device(dev); + +- return sprintf(buf, "%d\n", data->alarms[2] & 0x07); ++ return sprintf(buf, "%lu\n", (data->alarms >> 16) & 0x07); + } + + static ssize_t show_alarms_temp(struct device *dev, struct device_attribute +@@ -622,12 +572,18 @@ + { + struct f71805f_data *data = f71805f_update_device(dev); + +- return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07); ++ return sprintf(buf, "%lu\n", (data->alarms >> 11) & 0x07); + } + +-static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL); +-static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL); +-static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL); ++static ssize_t show_alarm(struct device *dev, struct device_attribute ++ *devattr, char *buf) ++{ ++ struct f71805f_data *data = f71805f_update_device(dev); ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ int nr = attr->index; ++ ++ return sprintf(buf, "%lu\n", (data->alarms >> nr) & 1); ++} + + static ssize_t show_name(struct device *dev, struct device_attribute + *devattr, char *buf) +@@ -637,7 +593,104 @@ + return sprintf(buf, "%s\n", data->name); + } + +-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); ++static struct device_attribute f71805f_dev_attr[] = { ++ __ATTR(in0_input, S_IRUGO, show_in0, NULL), ++ __ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max), ++ __ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min), ++ __ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL), ++ __ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL), ++ __ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL), ++ __ATTR(name, S_IRUGO, show_name, NULL), ++}; ++ ++static struct sensor_device_attribute f71805f_sensor_attr[] = { ++ SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0), ++ SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), ++ SENSOR_ATTR(in1_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 1), ++ SENSOR_ATTR(in1_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 1), ++ SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1), ++ SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), ++ SENSOR_ATTR(in2_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 2), ++ SENSOR_ATTR(in2_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 2), ++ SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2), ++ SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), ++ SENSOR_ATTR(in3_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 3), ++ SENSOR_ATTR(in3_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 3), ++ SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3), ++ SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), ++ SENSOR_ATTR(in4_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 4), ++ SENSOR_ATTR(in4_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 4), ++ SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4), ++ SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), ++ SENSOR_ATTR(in5_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 5), ++ SENSOR_ATTR(in5_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 5), ++ SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5), ++ SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), ++ SENSOR_ATTR(in6_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 6), ++ SENSOR_ATTR(in6_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 6), ++ SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6), ++ SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), ++ SENSOR_ATTR(in7_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 7), ++ SENSOR_ATTR(in7_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 7), ++ SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7), ++ SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), ++ SENSOR_ATTR(in8_max, S_IRUGO | S_IWUSR, ++ show_in_max, set_in_max, 8), ++ SENSOR_ATTR(in8_min, S_IRUGO | S_IWUSR, ++ show_in_min, set_in_min, 8), ++ SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8), ++ ++ SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0), ++ SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, ++ show_temp_max, set_temp_max, 0), ++ SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, ++ show_temp_hyst, set_temp_hyst, 0), ++ SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), ++ SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11), ++ SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1), ++ SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, ++ show_temp_max, set_temp_max, 1), ++ SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, ++ show_temp_hyst, set_temp_hyst, 1), ++ SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), ++ SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12), ++ SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2), ++ SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, ++ show_temp_max, set_temp_max, 2), ++ SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, ++ show_temp_hyst, set_temp_hyst, 2), ++ SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), ++ SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), ++}; ++ ++static struct sensor_device_attribute f71805f_fan_attr[] = { ++ SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), ++ SENSOR_ATTR(fan1_min, S_IRUGO | S_IWUSR, ++ show_fan_min, set_fan_min, 0), ++ SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 16), ++ SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), ++ SENSOR_ATTR(fan2_min, S_IRUGO | S_IWUSR, ++ show_fan_min, set_fan_min, 1), ++ SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 17), ++ SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), ++ SENSOR_ATTR(fan3_min, S_IRUGO | S_IWUSR, ++ show_fan_min, set_fan_min, 2), ++ SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 18), ++}; + + /* + * Device registration and initialization +@@ -668,7 +721,7 @@ + { + struct f71805f_data *data; + struct resource *res; +- int err; ++ int i, err; + + if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { + err = -ENOMEM; +@@ -678,9 +731,9 @@ + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + data->addr = res->start; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + data->name = "f71805f"; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + platform_set_drvdata(pdev, data); + +@@ -695,76 +748,31 @@ + f71805f_init_device(data); + + /* Register sysfs interface files */ +- device_create_file(&pdev->dev, &dev_attr_in0_input); +- device_create_file(&pdev->dev, &dev_attr_in0_max); +- device_create_file(&pdev->dev, &dev_attr_in0_min); +- device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr); +- if (data->fan_enabled & (1 << 0)) { +- device_create_file(&pdev->dev, +- &sensor_dev_attr_fan1_input.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_fan1_min.dev_attr); +- } +- if (data->fan_enabled & (1 << 1)) { +- device_create_file(&pdev->dev, +- &sensor_dev_attr_fan2_input.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_fan2_min.dev_attr); +- } +- if (data->fan_enabled & (1 << 2)) { +- device_create_file(&pdev->dev, +- &sensor_dev_attr_fan3_input.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_fan3_min.dev_attr); +- } +- device_create_file(&pdev->dev, +- &sensor_dev_attr_temp1_input.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_temp2_input.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_temp3_input.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_temp1_max_hyst.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_temp2_max_hyst.dev_attr); +- device_create_file(&pdev->dev, +- &sensor_dev_attr_temp3_max_hyst.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr); +- device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr); +- device_create_file(&pdev->dev, &dev_attr_alarms_in); +- device_create_file(&pdev->dev, &dev_attr_alarms_fan); +- device_create_file(&pdev->dev, &dev_attr_alarms_temp); +- device_create_file(&pdev->dev, &dev_attr_name); ++ for (i = 0; i < ARRAY_SIZE(f71805f_dev_attr); i++) { ++ err = device_create_file(&pdev->dev, &f71805f_dev_attr[i]); ++ if (err) ++ goto exit_class; ++ } ++ for (i = 0; i < ARRAY_SIZE(f71805f_sensor_attr); i++) { ++ err = device_create_file(&pdev->dev, ++ &f71805f_sensor_attr[i].dev_attr); ++ if (err) ++ goto exit_class; ++ } ++ for (i = 0; i < ARRAY_SIZE(f71805f_fan_attr); i++) { ++ if (!(data->fan_enabled & (1 << (i / 3)))) ++ continue; ++ err = device_create_file(&pdev->dev, ++ &f71805f_fan_attr[i].dev_attr); ++ if (err) ++ goto exit_class; ++ } + + return 0; + ++exit_class: ++ dev_err(&pdev->dev, "Sysfs interface creation failed\n"); ++ hwmon_device_unregister(data->class_dev); + exit_free: + kfree(data); + exit: +@@ -793,6 +801,11 @@ + + static int __init f71805f_device_add(unsigned short address) + { ++ struct resource res = { ++ .start = address, ++ .end = address + REGION_LENGTH - 1, ++ .flags = IORESOURCE_IO, ++ }; + int err; + + pdev = platform_device_alloc(DRVNAME, address); +@@ -802,10 +815,8 @@ + goto exit; + } + +- f71805f_resource.start = address; +- f71805f_resource.end = address + REGION_LENGTH - 1; +- f71805f_resource.name = pdev->name; +- err = platform_device_add_resources(pdev, &f71805f_resource, 1); ++ res.name = pdev->name; ++ err = platform_device_add_resources(pdev, &res, 1); + if (err) { + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-ali1535.c 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-ali1535.c 2006-03-22 17:06:16.000000000 +0100 +@@ -63,7 +63,6 @@ + #include <linux/i2c.h> + #include <linux/init.h> + #include <asm/io.h> +-#include <asm/semaphore.h> + + + /* ALI1535 SMBus address offsets */ +@@ -136,7 +135,6 @@ + + static struct pci_driver ali1535_driver; + static unsigned short ali1535_smba; +-static DECLARE_MUTEX(i2c_ali1535_sem); + + /* Detect whether a ALI1535 can be found, and initialize it, where necessary. + Note the differences between kernels with the old PCI BIOS interface and +@@ -345,7 +343,6 @@ + int timeout; + s32 result = 0; + +- down(&i2c_ali1535_sem); + /* make sure SMBus is idle */ + temp = inb_p(SMBHSTSTS); + for (timeout = 0; +@@ -460,7 +457,6 @@ + break; + } + EXIT: +- up(&i2c_ali1535_sem); + return result; + } + +@@ -479,7 +475,7 @@ + + static struct i2c_adapter ali1535_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/chips/ds1374.c 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/chips/ds1374.c 2006-03-22 17:06:14.000000000 +0100 +@@ -26,6 +26,7 @@ + #include <linux/i2c.h> + #include <linux/rtc.h> + #include <linux/bcd.h> ++#include <linux/mutex.h> + + #define DS1374_REG_TOD0 0x00 + #define DS1374_REG_TOD1 0x01 +@@ -41,7 +42,7 @@ + + #define DS1374_DRV_NAME "ds1374" + +-static DECLARE_MUTEX(ds1374_mutex); ++static DEFINE_MUTEX(ds1374_mutex); + + static struct i2c_driver ds1374_driver; + static struct i2c_client *save_client; +@@ -114,7 +115,7 @@ + ulong t1, t2; + int limit = 10; /* arbitrary retry limit */ + +- down(&ds1374_mutex); ++ mutex_lock(&ds1374_mutex); + + /* + * Since the reads are being performed one byte at a time using +@@ -127,7 +128,7 @@ + t2 = ds1374_read_rtc(); + } while (t1 != t2 && limit--); + +- up(&ds1374_mutex); ++ mutex_unlock(&ds1374_mutex); + + if (t1 != t2) { + dev_warn(&save_client->dev, +@@ -145,7 +146,7 @@ + + t1 = *(ulong *) arg; + +- down(&ds1374_mutex); ++ mutex_lock(&ds1374_mutex); + + /* + * Since the writes are being performed one byte at a time using +@@ -158,7 +159,7 @@ + t2 = ds1374_read_rtc(); + } while (t1 != t2 && limit--); + +- up(&ds1374_mutex); ++ mutex_unlock(&ds1374_mutex); + + if (t1 != t2) + dev_warn(&save_client->dev, +--- linux-2.6.16.orig/drivers/i2c/chips/m41t00.c 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/chips/m41t00.c 2006-03-22 17:06:14.000000000 +0100 +@@ -24,13 +24,14 @@ + #include <linux/i2c.h> + #include <linux/rtc.h> + #include <linux/bcd.h> ++#include <linux/mutex.h> + + #include <asm/time.h> + #include <asm/rtc.h> + + #define M41T00_DRV_NAME "m41t00" + +-static DECLARE_MUTEX(m41t00_mutex); ++static DEFINE_MUTEX(m41t00_mutex); + + static struct i2c_driver m41t00_driver; + static struct i2c_client *save_client; +@@ -54,7 +55,7 @@ + sec = min = hour = day = mon = year = 0; + sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; + +- down(&m41t00_mutex); ++ mutex_lock(&m41t00_mutex); + do { + if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) + && ((min = i2c_smbus_read_byte_data(save_client, 1)) +@@ -80,7 +81,7 @@ + mon1 = mon; + year1 = year; + } while (--limit > 0); +- up(&m41t00_mutex); ++ mutex_unlock(&m41t00_mutex); + + if (limit == 0) { + dev_warn(&save_client->dev, +@@ -125,7 +126,7 @@ + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + +- down(&m41t00_mutex); ++ mutex_lock(&m41t00_mutex); + if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) + || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) + < 0) +@@ -140,7 +141,7 @@ + + dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); + +- up(&m41t00_mutex); ++ mutex_unlock(&m41t00_mutex); + return; + } + +--- linux-2.6.16.orig/drivers/i2c/i2c-core.c 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/i2c-core.c 2006-03-22 17:06:21.000000000 +0100 +@@ -31,14 +31,17 @@ + #include <linux/idr.h> + #include <linux/seq_file.h> + #include <linux/platform_device.h> ++#include <linux/mutex.h> + #include <asm/uaccess.h> + + + static LIST_HEAD(adapters); + static LIST_HEAD(drivers); +-static DECLARE_MUTEX(core_lists); ++static DEFINE_MUTEX(core_lists); + static DEFINE_IDR(i2c_adapter_idr); + ++static void i2c_notify(struct i2c_adapter *adap, struct i2c_driver *driver); ++ + /* match always succeeds, as we want the probe() to tell if we really accept this match */ + static int i2c_device_match(struct device *dev, struct device_driver *drv) + { +@@ -153,7 +156,7 @@ + struct list_head *item; + struct i2c_driver *driver; + +- down(&core_lists); ++ mutex_lock(&core_lists); + + if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) { + res = -ENOMEM; +@@ -168,8 +171,8 @@ + } + + adap->nr = id & MAX_ID_MASK; +- init_MUTEX(&adap->bus_lock); +- init_MUTEX(&adap->clist_lock); ++ mutex_init(&adap->bus_lock); ++ mutex_init(&adap->clist_lock); + list_add_tail(&adap->list,&adapters); + INIT_LIST_HEAD(&adap->clients); + +@@ -197,13 +200,11 @@ + /* inform drivers of new adapters */ + list_for_each(item,&drivers) { + driver = list_entry(item, struct i2c_driver, list); +- if (driver->attach_adapter) +- /* We ignore the return code; if it fails, too bad */ +- driver->attach_adapter(adap); ++ i2c_notify(adap, driver); + } + + out_unlock: +- up(&core_lists); ++ mutex_unlock(&core_lists); + return res; + } + +@@ -216,7 +217,7 @@ + struct i2c_client *client; + int res = 0; + +- down(&core_lists); ++ mutex_lock(&core_lists); + + /* First make sure that this adapter was ever added */ + list_for_each_entry(adap_from_list, &adapters, list) { +@@ -272,7 +273,7 @@ + dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); + + out_unlock: +- up(&core_lists); ++ mutex_unlock(&core_lists); + return res; + } + +@@ -287,9 +288,7 @@ + { + struct list_head *item; + struct i2c_adapter *adapter; +- int res = 0; +- +- down(&core_lists); ++ int res; + + /* add the driver to the list of i2c drivers in the driver core */ + driver->driver.owner = owner; +@@ -297,22 +296,21 @@ + + res = driver_register(&driver->driver); + if (res) +- goto out_unlock; ++ return res; + ++ mutex_lock(&core_lists); ++ + list_add_tail(&driver->list,&drivers); + pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); + + /* now look for instances of driver on our adapters */ +- if (driver->attach_adapter) { +- list_for_each(item,&adapters) { +- adapter = list_entry(item, struct i2c_adapter, list); +- driver->attach_adapter(adapter); +- } ++ list_for_each(item, &adapters) { ++ adapter = list_entry(item, struct i2c_adapter, list); ++ i2c_notify(adapter, driver); + } + +- out_unlock: +- up(&core_lists); +- return res; ++ mutex_unlock(&core_lists); ++ return 0; + } + EXPORT_SYMBOL(i2c_register_driver); + +@@ -324,7 +322,7 @@ + + int res = 0; + +- down(&core_lists); ++ mutex_lock(&core_lists); + + /* Have a look at each adapter, if clients of this driver are still + * attached. If so, detach them to be able to kill the driver +@@ -363,7 +361,7 @@ + pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); + + out_unlock: +- up(&core_lists); ++ mutex_unlock(&core_lists); + return 0; + } + +@@ -384,9 +382,9 @@ + { + int rval; + +- down(&adapter->clist_lock); ++ mutex_lock(&adapter->clist_lock); + rval = __i2c_check_addr(adapter, addr); +- up(&adapter->clist_lock); ++ mutex_unlock(&adapter->clist_lock); + + return rval; + } +@@ -395,13 +393,13 @@ + { + struct i2c_adapter *adapter = client->adapter; + +- down(&adapter->clist_lock); ++ mutex_lock(&adapter->clist_lock); + if (__i2c_check_addr(client->adapter, client->addr)) { +- up(&adapter->clist_lock); ++ mutex_unlock(&adapter->clist_lock); + return -EBUSY; + } + list_add_tail(&client->list,&adapter->clients); +- up(&adapter->clist_lock); ++ mutex_unlock(&adapter->clist_lock); + + if (adapter->client_register) { + if (adapter->client_register(client)) { +@@ -450,12 +448,12 @@ + } + } + +- down(&adapter->clist_lock); ++ mutex_lock(&adapter->clist_lock); + list_del(&client->list); + init_completion(&client->released); + device_remove_file(&client->dev, &dev_attr_client_name); + device_unregister(&client->dev); +- up(&adapter->clist_lock); ++ mutex_unlock(&adapter->clist_lock); + wait_for_completion(&client->released); + + out: +@@ -513,19 +511,19 @@ + struct list_head *item; + struct i2c_client *client; + +- down(&adap->clist_lock); ++ mutex_lock(&adap->clist_lock); + list_for_each(item,&adap->clients) { + client = list_entry(item, struct i2c_client, list); + if (!try_module_get(client->driver->driver.owner)) + continue; + if (NULL != client->driver->command) { +- up(&adap->clist_lock); ++ mutex_unlock(&adap->clist_lock); + client->driver->command(client,cmd,arg); +- down(&adap->clist_lock); ++ mutex_lock(&adap->clist_lock); + } + module_put(client->driver->driver.owner); + } +- up(&adap->clist_lock); ++ mutex_unlock(&adap->clist_lock); + } + + static int __init i2c_init(void) +@@ -569,9 +567,9 @@ + } + #endif + +- down(&adap->bus_lock); ++ mutex_lock(&adap->bus_lock); + ret = adap->algo->master_xfer(adap,msgs,num); +- up(&adap->bus_lock); ++ mutex_unlock(&adap->bus_lock); + + return ret; + } else { +@@ -775,16 +773,53 @@ + return 0; + } + ++/* For explicitely attaching a driver to a given device */ ++int i2c_probe_device(struct i2c_adapter *adapter, int driver_id, ++ int addr, int kind) ++{ ++ struct list_head *item; ++ struct i2c_driver *driver = NULL; ++ ++ /* There's no way to probe addresses on this adapter... */ ++ if (kind < 0 && !i2c_check_functionality(adapter, ++ I2C_FUNC_SMBUS_QUICK)) ++ return -EINVAL; ++ ++ mutex_lock(&core_lists); ++ list_for_each(item, &drivers) { ++ driver = list_entry(item, struct i2c_driver, list); ++ if (driver->id == driver_id) ++ break; ++ } ++ mutex_unlock(&core_lists); ++ if (!item) ++ return -ENOENT; ++ ++ return i2c_probe_address(adapter, addr, kind, driver->detect_client); ++} ++ ++static void i2c_notify(struct i2c_adapter *adap, struct i2c_driver *driver) ++{ ++ if (driver->attach_adapter) ++ driver->attach_adapter(adap); ++ ++ /* Probe devices if the driver provided the necessary information ++ (detect_client and address_data) */ ++ if (driver->detect_client && driver->address_data && ++ (driver->class & adap->class)) ++ i2c_probe(adap, driver->address_data, driver->detect_client); ++} ++ + struct i2c_adapter* i2c_get_adapter(int id) + { + struct i2c_adapter *adapter; + +- down(&core_lists); ++ mutex_lock(&core_lists); + adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); + if (adapter && !try_module_get(adapter->owner)) + adapter = NULL; + +- up(&core_lists); ++ mutex_unlock(&core_lists); + return adapter; + } + +@@ -919,12 +954,11 @@ + u8 length, u8 *values) + { + union i2c_smbus_data data; +- int i; ++ + if (length > I2C_SMBUS_BLOCK_MAX) + length = I2C_SMBUS_BLOCK_MAX; +- for (i = 1; i <= length; i++) +- data.block[i] = values[i-1]; + data.block[0] = length; ++ memcpy(&data.block[1], values, length); + return i2c_smbus_xfer(client->adapter,client->addr,client->flags, + I2C_SMBUS_WRITE,command, + I2C_SMBUS_BLOCK_DATA,&data); +@@ -934,16 +968,14 @@ + s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values) + { + union i2c_smbus_data data; +- int i; ++ + if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, + I2C_SMBUS_READ,command, + I2C_SMBUS_I2C_BLOCK_DATA,&data)) + return -1; +- else { +- for (i = 1; i <= data.block[0]; i++) +- values[i-1] = data.block[i]; +- return data.block[0]; +- } ++ ++ memcpy(values, &data.block[1], data.block[0]); ++ return data.block[0]; + } + + s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, +@@ -1118,10 +1150,10 @@ + flags &= I2C_M_TEN | I2C_CLIENT_PEC; + + if (adapter->algo->smbus_xfer) { +- down(&adapter->bus_lock); ++ mutex_lock(&adapter->bus_lock); + res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, + command,size,data); +- up(&adapter->bus_lock); ++ mutex_unlock(&adapter->bus_lock); + } else + res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, + command,size,data); +@@ -1153,6 +1185,7 @@ + EXPORT_SYMBOL(i2c_get_adapter); + EXPORT_SYMBOL(i2c_put_adapter); + EXPORT_SYMBOL(i2c_probe); ++EXPORT_SYMBOL(i2c_probe_device); + + EXPORT_SYMBOL(i2c_smbus_xfer); + EXPORT_SYMBOL(i2c_smbus_write_quick); +--- linux-2.6.16.orig/drivers/i2c/busses/scx200_acb.c 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/scx200_acb.c 2006-03-22 17:06:16.000000000 +0100 +@@ -1,27 +1,26 @@ +-/* linux/drivers/i2c/scx200_acb.c +- ++/* + Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> + + National Semiconductor SCx200 ACCESS.bus support +- ++ Also supports the AMD CS5535 and AMD CS5536 ++ + Based on i2c-keywest.c which is: + Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> + Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> +- ++ + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +- + */ + + #include <linux/module.h> +@@ -32,7 +31,9 @@ + #include <linux/smp_lock.h> + #include <linux/pci.h> + #include <linux/delay.h> ++#include <linux/mutex.h> + #include <asm/io.h> ++#include <asm/msr.h> + + #include <linux/scx200.h> + +@@ -47,16 +48,7 @@ + module_param_array(base, int, NULL, 0); + MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers"); + +-#ifdef DEBUG +-#define DBG(x...) printk(KERN_DEBUG NAME ": " x) +-#else +-#define DBG(x...) +-#endif +- +-/* The hardware supports interrupt driven mode too, but I haven't +- implemented that. */ +-#define POLLED_MODE 1 +-#define POLL_TIMEOUT (HZ) ++#define POLL_TIMEOUT (HZ/5) + + enum scx200_acb_state { + state_idle, +@@ -79,12 +71,11 @@ + }; + + /* Physical interface */ +-struct scx200_acb_iface +-{ ++struct scx200_acb_iface { + struct scx200_acb_iface *next; + struct i2c_adapter adapter; + unsigned base; +- struct semaphore sem; ++ struct mutex mutex; + + /* State machine data */ + enum scx200_acb_state state; +@@ -100,7 +91,7 @@ + #define ACBSDA (iface->base + 0) + #define ACBST (iface->base + 1) + #define ACBST_SDAST 0x40 /* SDA Status */ +-#define ACBST_BER 0x20 ++#define ACBST_BER 0x20 + #define ACBST_NEGACK 0x10 /* Negative Acknowledge */ + #define ACBST_STASTR 0x08 /* Stall After Start */ + #define ACBST_MASTER 0x02 +@@ -109,9 +100,9 @@ + #define ACBCTL1 (iface->base + 3) + #define ACBCTL1_STASTRE 0x80 + #define ACBCTL1_NMINTE 0x40 +-#define ACBCTL1_ACK 0x10 +-#define ACBCTL1_STOP 0x02 +-#define ACBCTL1_START 0x01 ++#define ACBCTL1_ACK 0x10 ++#define ACBCTL1_STOP 0x02 ++#define ACBCTL1_START 0x01 + #define ACBADDR (iface->base + 4) + #define ACBCTL2 (iface->base + 5) + #define ACBCTL2_ENABLE 0x01 +@@ -122,8 +113,8 @@ + { + const char *errmsg; + +- DBG("state %s, status = 0x%02x\n", +- scx200_acb_state_name[iface->state], status); ++ dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n", ++ scx200_acb_state_name[iface->state], status); + + if (status & ACBST_BER) { + errmsg = "bus error"; +@@ -133,8 +124,17 @@ + errmsg = "not master"; + goto error; + } +- if (status & ACBST_NEGACK) +- goto negack; ++ if (status & ACBST_NEGACK) { ++ dev_dbg(&iface->adapter.dev, "negative ack in state %s\n", ++ scx200_acb_state_name[iface->state]); ++ ++ iface->state = state_idle; ++ iface->result = -ENXIO; ++ ++ outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); ++ outb(ACBST_STASTR | ACBST_NEGACK, ACBST); ++ return; ++ } + + switch (iface->state) { + case state_idle: +@@ -160,10 +160,10 @@ + case state_repeat_start: + outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1); + /* fallthrough */ +- ++ + case state_quick: + if (iface->address_byte & 1) { +- if (iface->len == 1) ++ if (iface->len == 1) + outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1); + else + outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1); +@@ -202,26 +202,15 @@ + outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); + break; + } +- ++ + outb(*iface->ptr++, ACBSDA); + --iface->len; +- ++ + break; + } + + return; + +- negack: +- DBG("negative acknowledge in state %s\n", +- scx200_acb_state_name[iface->state]); +- +- iface->state = state_idle; +- iface->result = -ENXIO; +- +- outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); +- outb(ACBST_STASTR | ACBST_NEGACK, ACBST); +- return; +- + error: + dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg, + scx200_acb_state_name[iface->state]); +@@ -231,20 +220,9 @@ + iface->needs_reset = 1; + } + +-static void scx200_acb_timeout(struct scx200_acb_iface *iface) +-{ +- dev_err(&iface->adapter.dev, "timeout in state %s\n", +- scx200_acb_state_name[iface->state]); +- +- iface->state = state_idle; +- iface->result = -EIO; +- iface->needs_reset = 1; +-} +- +-#ifdef POLLED_MODE + static void scx200_acb_poll(struct scx200_acb_iface *iface) + { +- u8 status = 0; ++ u8 status; + unsigned long timeout; + + timeout = jiffies + POLL_TIMEOUT; +@@ -254,17 +232,21 @@ + scx200_acb_machine(iface, status); + return; + } +- msleep(10); ++ yield(); + } + +- scx200_acb_timeout(iface); ++ dev_err(&iface->adapter.dev, "timeout in state %s\n", ++ scx200_acb_state_name[iface->state]); ++ ++ iface->state = state_idle; ++ iface->result = -EIO; ++ iface->needs_reset = 1; + } +-#endif /* POLLED_MODE */ + + static void scx200_acb_reset(struct scx200_acb_iface *iface) + { + /* Disable the ACCESS.bus device and Configure the SCL +- frequency: 16 clock cycles */ ++ frequency: 16 clock cycles */ + outb(0x70, ACBCTL2); + /* Polling mode */ + outb(0, ACBCTL1); +@@ -283,9 +265,9 @@ + } + + static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, +- u16 address, unsigned short flags, +- char rw, u8 command, int size, +- union i2c_smbus_data *data) ++ u16 address, unsigned short flags, ++ char rw, u8 command, int size, ++ union i2c_smbus_data *data) + { + struct scx200_acb_iface *iface = i2c_get_adapdata(adapter); + int len; +@@ -295,53 +277,47 @@ + + switch (size) { + case I2C_SMBUS_QUICK: +- len = 0; +- buffer = NULL; +- break; ++ len = 0; ++ buffer = NULL; ++ break; ++ + case I2C_SMBUS_BYTE: +- if (rw == I2C_SMBUS_READ) { +- len = 1; +- buffer = &data->byte; +- } else { +- len = 1; +- buffer = &command; +- } +- break; ++ len = 1; ++ buffer = rw ? &data->byte : &command; ++ break; ++ + case I2C_SMBUS_BYTE_DATA: +- len = 1; +- buffer = &data->byte; +- break; ++ len = 1; ++ buffer = &data->byte; ++ break; ++ + case I2C_SMBUS_WORD_DATA: + len = 2; +- cur_word = cpu_to_le16(data->word); +- buffer = (u8 *)&cur_word; ++ cur_word = cpu_to_le16(data->word); ++ buffer = (u8 *)&cur_word; + break; ++ + case I2C_SMBUS_BLOCK_DATA: +- len = data->block[0]; +- buffer = &data->block[1]; ++ len = data->block[0]; ++ buffer = &data->block[1]; + break; ++ + default: +- return -EINVAL; ++ return -EINVAL; + } + +- DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n", +- size, address, command, len, rw == I2C_SMBUS_READ); ++ dev_dbg(&adapter->dev, ++ "size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n", ++ size, address, command, len, rw); + + if (!len && rw == I2C_SMBUS_READ) { +- dev_warn(&adapter->dev, "zero length read\n"); ++ dev_dbg(&adapter->dev, "zero length read\n"); + return -EINVAL; + } + +- if (len && !buffer) { +- dev_warn(&adapter->dev, "nonzero length but no buffer\n"); +- return -EFAULT; +- } +- +- down(&iface->sem); ++ mutex_lock(&iface->mutex); + +- iface->address_byte = address<<1; +- if (rw == I2C_SMBUS_READ) +- iface->address_byte |= 1; ++ iface->address_byte = (address << 1) | rw; + iface->command = command; + iface->ptr = buffer; + iface->len = len; +@@ -355,25 +331,21 @@ + else + iface->state = state_address; + +-#ifdef POLLED_MODE + while (iface->state != state_idle) + scx200_acb_poll(iface); +-#else /* POLLED_MODE */ +-#error Interrupt driven mode not implemented +-#endif /* POLLED_MODE */ + + if (iface->needs_reset) + scx200_acb_reset(iface); + + rc = iface->result; + +- up(&iface->sem); ++ mutex_unlock(&iface->mutex); + + if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ) +- data->word = le16_to_cpu(cur_word); ++ data->word = le16_to_cpu(cur_word); + + #ifdef DEBUG +- DBG(": transfer done, result: %d", rc); ++ dev_dbg(&adapter->dev, "transfer done, result: %d", rc); + if (buffer) { + int i; + printk(" data:"); +@@ -400,17 +372,18 @@ + }; + + static struct scx200_acb_iface *scx200_acb_list; ++static DECLARE_MUTEX(scx200_acb_list_mutex); + + static int scx200_acb_probe(struct scx200_acb_iface *iface) + { + u8 val; + + /* Disable the ACCESS.bus device and Configure the SCL +- frequency: 16 clock cycles */ ++ frequency: 16 clock cycles */ + outb(0x70, ACBCTL2); + + if (inb(ACBCTL2) != 0x70) { +- DBG("ACBCTL2 readback failed\n"); ++ pr_debug(NAME ": ACBCTL2 readback failed\n"); + return -ENXIO; + } + +@@ -418,7 +391,8 @@ + + val = inb(ACBCTL1); + if (val) { +- DBG("disabled, but ACBCTL1=0x%02x\n", val); ++ pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n", ++ val); + return -ENXIO; + } + +@@ -428,18 +402,19 @@ + + val = inb(ACBCTL1); + if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) { +- DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val); ++ pr_debug(NAME ": enabled, but NMINTE won't be set, " ++ "ACBCTL1=0x%02x\n", val); + return -ENXIO; + } + + return 0; + } + +-static int __init scx200_acb_create(int base, int index) ++static int __init scx200_acb_create(const char *text, int base, int index) + { + struct scx200_acb_iface *iface; + struct i2c_adapter *adapter; +- int rc = 0; ++ int rc; + char description[64]; + + iface = kzalloc(sizeof(*iface), GFP_KERNEL); +@@ -451,50 +426,51 @@ + + adapter = &iface->adapter; + i2c_set_adapdata(adapter, iface); +- snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index); ++ snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index); + adapter->owner = THIS_MODULE; + adapter->id = I2C_HW_SMBUS_SCX200; + adapter->algo = &scx200_acb_algorithm; +- adapter->class = I2C_CLASS_HWMON; ++ adapter->class = I2C_CLASS_HWMON | I2C_CLASS_DATA; ++ ++ mutex_init(&iface->mutex); + +- init_MUTEX(&iface->sem); ++ snprintf(description, sizeof(description), "%s ACCESS.bus [%s]", ++ text, adapter->name); + +- snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name); + if (request_region(base, 8, description) == 0) { +- dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n", ++ printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", + base, base + 8-1); + rc = -EBUSY; +- goto errout; ++ goto errout_free; + } + iface->base = base; + + rc = scx200_acb_probe(iface); + if (rc) { +- dev_warn(&adapter->dev, "probe failed\n"); +- goto errout; ++ printk(KERN_WARNING NAME ": probe failed\n"); ++ goto errout_release; + } + + scx200_acb_reset(iface); + + if (i2c_add_adapter(adapter) < 0) { +- dev_err(&adapter->dev, "failed to register\n"); ++ printk(KERN_ERR NAME ": failed to register\n"); + rc = -ENODEV; +- goto errout; ++ goto errout_release; + } + +- lock_kernel(); ++ down(&scx200_acb_list_mutex); + iface->next = scx200_acb_list; + scx200_acb_list = iface; +- unlock_kernel(); ++ up(&scx200_acb_list_mutex); + + return 0; + ++ errout_release: ++ release_region(iface->base, 8); ++ errout_free: ++ kfree(iface); + errout: +- if (iface) { +- if (iface->base) +- release_region(iface->base, 8); +- kfree(iface); +- } + return rc; + } + +@@ -504,50 +480,69 @@ + { }, + }; + ++static struct pci_device_id divil_pci[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, ++ { } /* NULL entry */ ++}; ++ ++#define MSR_LBAR_SMB 0x5140000B ++ ++static int scx200_add_cs553x(void) ++{ ++ u32 low, hi; ++ u32 smb_base; ++ ++ /* Grab & reserve the SMB I/O range */ ++ rdmsr(MSR_LBAR_SMB, low, hi); ++ ++ /* Check the IO mask and whether SMB is enabled */ ++ if (hi != 0x0000F001) { ++ printk(KERN_WARNING NAME ": SMBus not enabled\n"); ++ return -ENODEV; ++ } ++ ++ /* SMBus IO size is 8 bytes */ ++ smb_base = low & 0x0000FFF8; ++ ++ return scx200_acb_create("CS5535", smb_base, 0); ++} ++ + static int __init scx200_acb_init(void) + { + int i; +- int rc; ++ int rc = -ENODEV; + + pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); + + /* Verify that this really is a SCx200 processor */ +- if (pci_dev_present(scx200) == 0) +- return -ENODEV; ++ if (pci_dev_present(scx200)) { ++ for (i = 0; i < MAX_DEVICES; ++i) { ++ if (base[i] > 0) ++ rc = scx200_acb_create("SCx200", base[i], i); ++ } ++ } else if (pci_dev_present(divil_pci)) ++ rc = scx200_add_cs553x(); + +- rc = -ENXIO; +- for (i = 0; i < MAX_DEVICES; ++i) { +- if (base[i] > 0) +- rc = scx200_acb_create(base[i], i); +- } +- if (scx200_acb_list) +- return 0; + return rc; + } + + static void __exit scx200_acb_cleanup(void) + { + struct scx200_acb_iface *iface; +- lock_kernel(); ++ ++ down(&scx200_acb_list_mutex); + while ((iface = scx200_acb_list) != NULL) { + scx200_acb_list = iface->next; +- unlock_kernel(); ++ up(&scx200_acb_list_mutex); + + i2c_del_adapter(&iface->adapter); + release_region(iface->base, 8); + kfree(iface); +- lock_kernel(); ++ down(&scx200_acb_list_mutex); + } +- unlock_kernel(); ++ up(&scx200_acb_list_mutex); + } + + module_init(scx200_acb_init); + module_exit(scx200_acb_cleanup); +- +-/* +- Local variables: +- compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules" +- c-basic-offset: 8 +- End: +-*/ +- +--- linux-2.6.16.orig/Documentation/i2c/busses/scx200_acb 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/Documentation/i2c/busses/scx200_acb 2006-03-22 17:06:15.000000000 +0100 +@@ -6,9 +6,10 @@ + ----------------- + + * base: int +- Base addresses for the ACCESS.bus controllers ++ Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices + + Description + ----------- + +-Enable the use of the ACCESS.bus controllers of a SCx200 processor. ++Enable the use of the ACCESS.bus controller on the Geode SCx200 and ++SC1100 processors and the CS5535 and CS5536 Geode companion devices. +--- linux-2.6.16.orig/drivers/i2c/busses/Kconfig 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/Kconfig 2006-03-22 17:06:16.000000000 +0100 +@@ -163,17 +163,22 @@ + I2C bus. + + config I2C_PIIX4 +- tristate "Intel PIIX4" ++ tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" + depends on I2C && PCI + help + If you say yes to this option, support will be included for the Intel + PIIX4 family of mainboard I2C interfaces. Specifically, the following +- versions of the chipset are supported: ++ versions of the chipset are supported (note that Serverworks is part ++ of Broadcom): + Intel PIIX4 + Intel 440MX ++ ATI IXP200 ++ ATI IXP300 ++ ATI IXP400 + Serverworks OSB4 + Serverworks CSB5 + Serverworks CSB6 ++ Serverworks HT-1000 + SMSC Victory66 + + This driver can also be built as a module. If so, the module +@@ -284,7 +289,10 @@ + This driver is a replacement for (and was inspired by) an older + driver named i2c-philips-par. The new driver supports more devices, + and makes it easier to add support for new devices. +- ++ ++ An adapter type parameter is now mandatory. Please read the file ++ Documentation/i2c/busses/i2c-parport for details. ++ + Another driver exists, named i2c-parport-light, which doesn't depend + on the parport driver. This is meant for embedded systems. Don't say + Y here if you intend to say Y or M there. +@@ -389,10 +397,11 @@ + also be specified with a module parameter. + + config SCx200_ACB +- tristate "NatSemi SCx200 ACCESS.bus" +- depends on I2C && PCI ++ tristate "Geode ACCESS.bus support" ++ depends on X86_32 && I2C && PCI + help +- Enable the use of the ACCESS.bus controllers of a SCx200 processor. ++ Enable the use of the ACCESS.bus controllers on the Geode SCx200 and ++ SC1100 processors and the CS5535 and CS5536 Geode companion devices. + + If you don't know what to do here, say N. + +--- linux-2.6.16.orig/drivers/hwmon/w83792d.c 2006-03-22 17:06:10.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/w83792d.c 2006-03-22 17:06:16.000000000 +0100 +@@ -43,6 +43,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-sysfs.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +@@ -271,7 +272,7 @@ + struct class_device *class_dev; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -300,7 +301,6 @@ + u8 sf2_levels[3][4]; /* Smart FanII: Fan1,2,3 duty cycle levels */ + }; + +-static int w83792d_attach_adapter(struct i2c_adapter *adapter); + static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); + static int w83792d_detach_client(struct i2c_client *client); + static struct w83792d_data *w83792d_update_device(struct device *dev); +@@ -315,7 +315,9 @@ + .driver = { + .name = "w83792d", + }, +- .attach_adapter = w83792d_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = w83792d_detect, + .detach_client = w83792d_detach_client, + }; + +@@ -382,30 +384,40 @@ + store_in_reg(MIN, min); + store_in_reg(MAX, max); + +-#define sysfs_in_reg(offset) \ +-static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \ +- NULL, offset); \ +-static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ +- show_in_min, store_in_min, offset); \ +-static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ +- show_in_max, store_in_max, offset); +- +-sysfs_in_reg(0); +-sysfs_in_reg(1); +-sysfs_in_reg(2); +-sysfs_in_reg(3); +-sysfs_in_reg(4); +-sysfs_in_reg(5); +-sysfs_in_reg(6); +-sysfs_in_reg(7); +-sysfs_in_reg(8); +- +-#define device_create_file_in(client, offset) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_in##offset##_input.dev_attr); \ +-device_create_file(&client->dev, &sensor_dev_attr_in##offset##_max.dev_attr); \ +-device_create_file(&client->dev, &sensor_dev_attr_in##offset##_min.dev_attr); \ +-} while (0) ++static struct sensor_device_attribute sda_in_input[] = { ++ SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), ++ SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), ++ SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), ++ SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), ++ SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), ++ SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), ++ SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), ++ SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), ++ SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), ++}; ++static struct sensor_device_attribute sda_in_min[] = { ++ SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), ++ SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), ++ SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), ++ SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), ++ SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), ++ SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), ++ SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), ++ SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), ++ SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), ++}; ++static struct sensor_device_attribute sda_in_max[] = { ++ SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), ++ SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), ++ SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), ++ SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), ++ SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), ++ SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), ++ SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), ++ SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), ++ SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), ++}; ++ + + #define show_fan_reg(reg) \ + static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ +@@ -486,28 +498,33 @@ + return count; + } + +-#define sysfs_fan(offset) \ +-static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \ +- offset); \ +-static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ +- show_fan_div, store_fan_div, offset); \ +-static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ +- show_fan_min, store_fan_min, offset); +- +-sysfs_fan(1); +-sysfs_fan(2); +-sysfs_fan(3); +-sysfs_fan(4); +-sysfs_fan(5); +-sysfs_fan(6); +-sysfs_fan(7); +- +-#define device_create_file_fan(client, offset) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_input.dev_attr); \ +-device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_div.dev_attr); \ +-device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_min.dev_attr); \ +-} while (0) ++static struct sensor_device_attribute sda_fan_input[] = { ++ SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 1), ++ SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 2), ++ SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 3), ++ SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 4), ++ SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 5), ++ SENSOR_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 6), ++ SENSOR_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 7), ++}; ++static struct sensor_device_attribute sda_fan_min[] = { ++ SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 1), ++ SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 2), ++ SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 3), ++ SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 4), ++ SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 5), ++ SENSOR_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 6), ++ SENSOR_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 7), ++}; ++static struct sensor_device_attribute sda_fan_div[] = { ++ SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 1), ++ SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 2), ++ SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 3), ++ SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 4), ++ SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 5), ++ SENSOR_ATTR(fan6_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 6), ++ SENSOR_ATTR(fan7_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 7), ++}; + + + /* read/write the temperature1, includes measured value and limits */ +@@ -539,21 +556,6 @@ + return count; + } + +- +-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0); +-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1, +- store_temp1, 1); +-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1, +- store_temp1, 2); +- +-#define device_create_file_temp1(client) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); \ +-device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); \ +-device_create_file(&client->dev, &sensor_dev_attr_temp1_max_hyst.dev_attr); \ +-} while (0) +- +- + /* read/write the temperature2-3, includes measured value and limits */ + + static ssize_t show_temp23(struct device *dev, struct device_attribute *attr, +@@ -590,25 +592,23 @@ + return count; + } + +-#define sysfs_temp23(name,idx) \ +-static SENSOR_DEVICE_ATTR_2(name##_input, S_IRUGO, show_temp23, NULL, \ +- idx, 0); \ +-static SENSOR_DEVICE_ATTR_2(name##_max, S_IRUGO | S_IWUSR, \ +- show_temp23, store_temp23, idx, 2); \ +-static SENSOR_DEVICE_ATTR_2(name##_max_hyst, S_IRUGO | S_IWUSR, \ +- show_temp23, store_temp23, idx, 4); +- +-sysfs_temp23(temp2,0) +-sysfs_temp23(temp3,1) +- +-#define device_create_file_temp_add(client, offset) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_input.dev_attr); \ +-device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_max.dev_attr); \ +-device_create_file(&client->dev, \ +-&sensor_dev_attr_temp##offset##_max_hyst.dev_attr); \ +-} while (0) ++static struct sensor_device_attribute_2 sda_temp_input[] = { ++ SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0), ++ SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0), ++ SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0), ++}; ++ ++static struct sensor_device_attribute_2 sda_temp_max[] = { ++ SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 1), ++ SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 2), ++ SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 2), ++}; + ++static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { ++ SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 2), ++ SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 4), ++ SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 4), ++}; + + /* get reatime status of all sensors items: voltage, temp, fan */ + static ssize_t +@@ -620,10 +620,6 @@ + + static + DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); +-#define device_create_file_alarms(client) \ +-device_create_file(&client->dev, &dev_attr_alarms); +- +- + + static ssize_t + show_pwm(struct device *dev, struct device_attribute *attr, +@@ -711,26 +707,19 @@ + return count; + } + +-#define sysfs_pwm(offset) \ +-static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ +- show_pwm, store_pwm, offset); \ +-static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ +- show_pwmenable, store_pwmenable, offset); \ +- +-sysfs_pwm(1); +-sysfs_pwm(2); +-sysfs_pwm(3); +- +- +-#define device_create_file_pwm(client, offset) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_pwm##offset.dev_attr); \ +-} while (0) +- +-#define device_create_file_pwmenable(client, offset) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_enable.dev_attr); \ +-} while (0) ++static struct sensor_device_attribute sda_pwm[] = { ++ SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), ++ SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), ++ SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3), ++}; ++static struct sensor_device_attribute sda_pwm_enable[] = { ++ SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, ++ show_pwmenable, store_pwmenable, 1), ++ SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, ++ show_pwmenable, store_pwmenable, 2), ++ SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, ++ show_pwmenable, store_pwmenable, 3), ++}; + + + static ssize_t +@@ -764,18 +753,14 @@ + return count; + } + +-#define sysfs_pwm_mode(offset) \ +-static SENSOR_DEVICE_ATTR(pwm##offset##_mode, S_IRUGO | S_IWUSR, \ +- show_pwm_mode, store_pwm_mode, offset); +- +-sysfs_pwm_mode(1); +-sysfs_pwm_mode(2); +-sysfs_pwm_mode(3); +- +-#define device_create_file_pwm_mode(client, offset) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_mode.dev_attr); \ +-} while (0) ++static struct sensor_device_attribute sda_pwm_mode[] = { ++ SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, ++ show_pwm_mode, store_pwm_mode, 1), ++ SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, ++ show_pwm_mode, store_pwm_mode, 2), ++ SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, ++ show_pwm_mode, store_pwm_mode, 3), ++}; + + + static ssize_t +@@ -788,12 +773,6 @@ + + static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); + +-#define device_create_file_chassis(client) \ +-do { \ +-device_create_file(&client->dev, &dev_attr_chassis); \ +-} while (0) +- +- + static ssize_t + show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) + { +@@ -824,13 +803,6 @@ + static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, + show_chassis_clear, store_chassis_clear); + +-#define device_create_file_chassis_clear(client) \ +-do { \ +-device_create_file(&client->dev, &dev_attr_chassis_clear); \ +-} while (0) +- +- +- + /* For Smart Fan I / Thermal Cruise */ + static ssize_t + show_thermal_cruise(struct device *dev, struct device_attribute *attr, +@@ -864,20 +836,14 @@ + return count; + } + +-#define sysfs_thermal_cruise(offset) \ +-static SENSOR_DEVICE_ATTR(thermal_cruise##offset, S_IRUGO | S_IWUSR, \ +- show_thermal_cruise, store_thermal_cruise, offset); +- +-sysfs_thermal_cruise(1); +-sysfs_thermal_cruise(2); +-sysfs_thermal_cruise(3); +- +-#define device_create_file_thermal_cruise(client, offset) \ +-do { \ +-device_create_file(&client->dev, \ +-&sensor_dev_attr_thermal_cruise##offset.dev_attr); \ +-} while (0) +- ++static struct sensor_device_attribute sda_thermal_cruise[] = { ++ SENSOR_ATTR(thermal_cruise1, S_IWUSR | S_IRUGO, ++ show_thermal_cruise, store_thermal_cruise, 1), ++ SENSOR_ATTR(thermal_cruise2, S_IWUSR | S_IRUGO, ++ show_thermal_cruise, store_thermal_cruise, 2), ++ SENSOR_ATTR(thermal_cruise3, S_IWUSR | S_IRUGO, ++ show_thermal_cruise, store_thermal_cruise, 3), ++}; + + /* For Smart Fan I/Thermal Cruise and Smart Fan II */ + static ssize_t +@@ -916,19 +882,14 @@ + return count; + } + +-#define sysfs_tolerance(offset) \ +-static SENSOR_DEVICE_ATTR(tolerance##offset, S_IRUGO | S_IWUSR, \ +- show_tolerance, store_tolerance, offset); +- +-sysfs_tolerance(1); +-sysfs_tolerance(2); +-sysfs_tolerance(3); +- +-#define device_create_file_tolerance(client, offset) \ +-do { \ +-device_create_file(&client->dev, &sensor_dev_attr_tolerance##offset.dev_attr); \ +-} while (0) +- ++static struct sensor_device_attribute sda_tolerance[] = { ++ SENSOR_ATTR(tolerance1, S_IWUSR | S_IRUGO, ++ show_tolerance, store_tolerance, 1), ++ SENSOR_ATTR(tolerance2, S_IWUSR | S_IRUGO, ++ show_tolerance, store_tolerance, 2), ++ SENSOR_ATTR(tolerance3, S_IWUSR | S_IRUGO, ++ show_tolerance, store_tolerance, 3), ++}; + + /* For Smart Fan II */ + static ssize_t +@@ -964,28 +925,34 @@ + return count; + } + +-#define sysfs_sf2_point(offset, index) \ +-static SENSOR_DEVICE_ATTR_2(sf2_point##offset##_fan##index, S_IRUGO | S_IWUSR, \ +- show_sf2_point, store_sf2_point, offset, index); +- +-sysfs_sf2_point(1, 1); /* Fan1 */ +-sysfs_sf2_point(2, 1); /* Fan1 */ +-sysfs_sf2_point(3, 1); /* Fan1 */ +-sysfs_sf2_point(4, 1); /* Fan1 */ +-sysfs_sf2_point(1, 2); /* Fan2 */ +-sysfs_sf2_point(2, 2); /* Fan2 */ +-sysfs_sf2_point(3, 2); /* Fan2 */ +-sysfs_sf2_point(4, 2); /* Fan2 */ +-sysfs_sf2_point(1, 3); /* Fan3 */ +-sysfs_sf2_point(2, 3); /* Fan3 */ +-sysfs_sf2_point(3, 3); /* Fan3 */ +-sysfs_sf2_point(4, 3); /* Fan3 */ +- +-#define device_create_file_sf2_point(client, offset, index) \ +-do { \ +-device_create_file(&client->dev, \ +-&sensor_dev_attr_sf2_point##offset##_fan##index.dev_attr); \ +-} while (0) ++static struct sensor_device_attribute_2 sda_sf2_point[] = { ++ SENSOR_ATTR_2(sf2_point1_fan1, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 1, 1), ++ SENSOR_ATTR_2(sf2_point2_fan1, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 2, 1), ++ SENSOR_ATTR_2(sf2_point3_fan1, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 3, 1), ++ SENSOR_ATTR_2(sf2_point4_fan1, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 4, 1), ++ ++ SENSOR_ATTR_2(sf2_point1_fan2, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 1, 2), ++ SENSOR_ATTR_2(sf2_point2_fan2, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 2, 2), ++ SENSOR_ATTR_2(sf2_point3_fan2, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 3, 2), ++ SENSOR_ATTR_2(sf2_point4_fan2, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 4, 2), ++ ++ SENSOR_ATTR_2(sf2_point1_fan3, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 1, 3), ++ SENSOR_ATTR_2(sf2_point2_fan3, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 2, 3), ++ SENSOR_ATTR_2(sf2_point3_fan3, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 3, 3), ++ SENSOR_ATTR_2(sf2_point4_fan3, S_IRUGO | S_IWUSR, ++ show_sf2_point, store_sf2_point, 4, 3), ++}; + + + static ssize_t +@@ -1026,39 +993,28 @@ + return count; + } + +-#define sysfs_sf2_level(offset, index) \ +-static SENSOR_DEVICE_ATTR_2(sf2_level##offset##_fan##index, S_IRUGO | S_IWUSR, \ +- show_sf2_level, store_sf2_level, offset, index); +- +-sysfs_sf2_level(1, 1); /* Fan1 */ +-sysfs_sf2_level(2, 1); /* Fan1 */ +-sysfs_sf2_level(3, 1); /* Fan1 */ +-sysfs_sf2_level(1, 2); /* Fan2 */ +-sysfs_sf2_level(2, 2); /* Fan2 */ +-sysfs_sf2_level(3, 2); /* Fan2 */ +-sysfs_sf2_level(1, 3); /* Fan3 */ +-sysfs_sf2_level(2, 3); /* Fan3 */ +-sysfs_sf2_level(3, 3); /* Fan3 */ +- +-#define device_create_file_sf2_level(client, offset, index) \ +-do { \ +-device_create_file(&client->dev, \ +-&sensor_dev_attr_sf2_level##offset##_fan##index.dev_attr); \ +-} while (0) +- +- +-/* This function is called when: +- * w83792d_driver is inserted (when this module is loaded), for each +- available adapter +- * when a new adapter is inserted (and w83792d_driver is still present) */ +-static int +-w83792d_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, w83792d_detect); +-} +- ++static struct sensor_device_attribute_2 sda_sf2_level[] = { ++ SENSOR_ATTR_2(sf2_level1_fan1, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 1, 1), ++ SENSOR_ATTR_2(sf2_level2_fan1, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 2, 1), ++ SENSOR_ATTR_2(sf2_level3_fan1, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 3, 1), ++ ++ SENSOR_ATTR_2(sf2_level1_fan2, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 1, 2), ++ SENSOR_ATTR_2(sf2_level2_fan2, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 2, 2), ++ SENSOR_ATTR_2(sf2_level3_fan2, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 3, 2), ++ ++ SENSOR_ATTR_2(sf2_level1_fan3, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 1, 3), ++ SENSOR_ATTR_2(sf2_level2_fan3, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 2, 3), ++ SENSOR_ATTR_2(sf2_level3_fan3, S_IRUGO | S_IWUSR, ++ show_sf2_level, store_sf2_level, 3, 3), ++}; + + static int + w83792d_create_subclient(struct i2c_adapter *adapter, +@@ -1147,12 +1103,19 @@ + return err; + } + ++static void device_create_file_fan(struct device *dev, int i) ++{ ++ device_create_file(dev, &sda_fan_input[i].dev_attr); ++ device_create_file(dev, &sda_fan_div[i].dev_attr); ++ device_create_file(dev, &sda_fan_min[i].dev_attr); ++} + + static int + w83792d_detect(struct i2c_adapter *adapter, int address, int kind) + { + int i = 0, val1 = 0, val2; +- struct i2c_client *new_client; ++ struct i2c_client *client; ++ struct device *dev; + struct w83792d_data *data; + int err = 0; + const char *client_name = ""; +@@ -1170,12 +1133,13 @@ + goto ERROR0; + } + +- new_client = &data->client; +- i2c_set_clientdata(new_client, data); +- new_client->addr = address; +- new_client->adapter = adapter; +- new_client->driver = &w83792d_driver; +- new_client->flags = 0; ++ client = &data->client; ++ dev = &client->dev; ++ i2c_set_clientdata(client, data); ++ client->addr = address; ++ client->adapter = adapter; ++ client->driver = &w83792d_driver; ++ client->flags = 0; + + /* Now, we do the remaining detection. */ + +@@ -1184,50 +1148,49 @@ + force_*=... parameter, and the Winbond will be reset to the right + bank. */ + if (kind < 0) { +- if (w83792d_read_value(new_client, W83792D_REG_CONFIG) & 0x80) { +- dev_warn(&new_client->dev, "Detection failed at step " +- "3\n"); ++ if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) { ++ dev_dbg(dev, "Detection failed at step 1\n"); + goto ERROR1; + } +- val1 = w83792d_read_value(new_client, W83792D_REG_BANK); +- val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN); ++ val1 = w83792d_read_value(client, W83792D_REG_BANK); ++ val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); + /* Check for Winbond ID if in bank 0 */ + if (!(val1 & 0x07)) { /* is Bank0 */ + if (((!(val1 & 0x80)) && (val2 != 0xa3)) || + ((val1 & 0x80) && (val2 != 0x5c))) { ++ dev_dbg(dev, "Detection failed at step 2\n"); + goto ERROR1; + } + } + /* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR + should match */ +- if (w83792d_read_value(new_client, ++ if (w83792d_read_value(client, + W83792D_REG_I2C_ADDR) != address) { +- dev_warn(&new_client->dev, "Detection failed " +- "at step 5\n"); ++ dev_dbg(dev, "Detection failed at step 3\n"); + goto ERROR1; + } + } + + /* We have either had a force parameter, or we have already detected the + Winbond. Put it now into bank 0 and Vendor ID High Byte */ +- w83792d_write_value(new_client, ++ w83792d_write_value(client, + W83792D_REG_BANK, +- (w83792d_read_value(new_client, ++ (w83792d_read_value(client, + W83792D_REG_BANK) & 0x78) | 0x80); + + /* Determine the chip type. */ + if (kind <= 0) { + /* get vendor ID */ +- val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN); ++ val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); + if (val2 != 0x5c) { /* the vendor is NOT Winbond */ + goto ERROR1; + } +- val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID); ++ val1 = w83792d_read_value(client, W83792D_REG_WCHIPID); + if (val1 == 0x7a) { + kind = w83792d; + } else { + if (kind == 0) +- dev_warn(&new_client->dev, ++ dev_warn(dev, + "w83792d: Ignoring 'force' parameter for" + " unknown chip at adapter %d, address" + " 0x%02x\n", i2c_adapter_id(adapter), +@@ -1239,120 +1202,86 @@ + if (kind == w83792d) { + client_name = "w83792d"; + } else { +- dev_err(&new_client->dev, "w83792d: Internal error: unknown" ++ dev_err(dev, "w83792d: Internal error: unknown" + " kind (%d)?!?", kind); + goto ERROR1; + } + + /* Fill in the remaining client fields and put into the global list */ +- strlcpy(new_client->name, client_name, I2C_NAME_SIZE); ++ strlcpy(client->name, client_name, I2C_NAME_SIZE); + data->type = kind; + + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ +- if ((err = i2c_attach_client(new_client))) ++ if ((err = i2c_attach_client(client))) + goto ERROR1; + + if ((err = w83792d_detect_subclients(adapter, address, +- kind, new_client))) ++ kind, client))) + goto ERROR2; + + /* Initialize the chip */ +- w83792d_init_client(new_client); ++ w83792d_init_client(client); + + /* A few vars need to be filled upon startup */ + for (i = 0; i < 7; i++) { +- data->fan_min[i] = w83792d_read_value(new_client, ++ data->fan_min[i] = w83792d_read_value(client, + W83792D_REG_FAN_MIN[i]); + } + + /* Register sysfs hooks */ +- data->class_dev = hwmon_device_register(&new_client->dev); ++ data->class_dev = hwmon_device_register(dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto ERROR3; + } +- device_create_file_in(new_client, 0); +- device_create_file_in(new_client, 1); +- device_create_file_in(new_client, 2); +- device_create_file_in(new_client, 3); +- device_create_file_in(new_client, 4); +- device_create_file_in(new_client, 5); +- device_create_file_in(new_client, 6); +- device_create_file_in(new_client, 7); +- device_create_file_in(new_client, 8); +- +- device_create_file_fan(new_client, 1); +- device_create_file_fan(new_client, 2); +- device_create_file_fan(new_client, 3); ++ for (i = 0; i < 9; i++) { ++ device_create_file(dev, &sda_in_input[i].dev_attr); ++ device_create_file(dev, &sda_in_max[i].dev_attr); ++ device_create_file(dev, &sda_in_min[i].dev_attr); ++ } ++ for (i = 0; i < 3; i++) ++ device_create_file_fan(dev, i); + + /* Read GPIO enable register to check if pins for fan 4,5 are used as + GPIO */ +- val1 = w83792d_read_value(new_client, W83792D_REG_GPIO_EN); ++ val1 = w83792d_read_value(client, W83792D_REG_GPIO_EN); + if (!(val1 & 0x40)) +- device_create_file_fan(new_client, 4); ++ device_create_file_fan(dev, 3); + if (!(val1 & 0x20)) +- device_create_file_fan(new_client, 5); ++ device_create_file_fan(dev, 4); + +- val1 = w83792d_read_value(new_client, W83792D_REG_PIN); ++ val1 = w83792d_read_value(client, W83792D_REG_PIN); + if (val1 & 0x40) +- device_create_file_fan(new_client, 6); ++ device_create_file_fan(dev, 5); + if (val1 & 0x04) +- device_create_file_fan(new_client, 7); ++ device_create_file_fan(dev, 6); ++ ++ for (i = 0; i < 3; i++) { ++ device_create_file(dev, &sda_temp_input[i].dev_attr); ++ device_create_file(dev, &sda_temp_max[i].dev_attr); ++ device_create_file(dev, &sda_temp_max_hyst[i].dev_attr); ++ device_create_file(dev, &sda_thermal_cruise[i].dev_attr); ++ device_create_file(dev, &sda_tolerance[i].dev_attr); ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(sda_pwm); i++) { ++ device_create_file(dev, &sda_pwm[i].dev_attr); ++ device_create_file(dev, &sda_pwm_enable[i].dev_attr); ++ device_create_file(dev, &sda_pwm_mode[i].dev_attr); ++ } ++ ++ device_create_file(dev, &dev_attr_alarms); ++ device_create_file(dev, &dev_attr_chassis); ++ device_create_file(dev, &dev_attr_chassis_clear); ++ ++ for (i = 0; i < ARRAY_SIZE(sda_sf2_point); i++) ++ device_create_file(dev, &sda_sf2_point[i].dev_attr); + +- device_create_file_temp1(new_client); /* Temp1 */ +- device_create_file_temp_add(new_client, 2); /* Temp2 */ +- device_create_file_temp_add(new_client, 3); /* Temp3 */ +- +- device_create_file_alarms(new_client); +- +- device_create_file_pwm(new_client, 1); +- device_create_file_pwm(new_client, 2); +- device_create_file_pwm(new_client, 3); +- +- device_create_file_pwmenable(new_client, 1); +- device_create_file_pwmenable(new_client, 2); +- device_create_file_pwmenable(new_client, 3); +- +- device_create_file_pwm_mode(new_client, 1); +- device_create_file_pwm_mode(new_client, 2); +- device_create_file_pwm_mode(new_client, 3); +- +- device_create_file_chassis(new_client); +- device_create_file_chassis_clear(new_client); +- +- device_create_file_thermal_cruise(new_client, 1); +- device_create_file_thermal_cruise(new_client, 2); +- device_create_file_thermal_cruise(new_client, 3); +- +- device_create_file_tolerance(new_client, 1); +- device_create_file_tolerance(new_client, 2); +- device_create_file_tolerance(new_client, 3); +- +- device_create_file_sf2_point(new_client, 1, 1); /* Fan1 */ +- device_create_file_sf2_point(new_client, 2, 1); /* Fan1 */ +- device_create_file_sf2_point(new_client, 3, 1); /* Fan1 */ +- device_create_file_sf2_point(new_client, 4, 1); /* Fan1 */ +- device_create_file_sf2_point(new_client, 1, 2); /* Fan2 */ +- device_create_file_sf2_point(new_client, 2, 2); /* Fan2 */ +- device_create_file_sf2_point(new_client, 3, 2); /* Fan2 */ +- device_create_file_sf2_point(new_client, 4, 2); /* Fan2 */ +- device_create_file_sf2_point(new_client, 1, 3); /* Fan3 */ +- device_create_file_sf2_point(new_client, 2, 3); /* Fan3 */ +- device_create_file_sf2_point(new_client, 3, 3); /* Fan3 */ +- device_create_file_sf2_point(new_client, 4, 3); /* Fan3 */ +- +- device_create_file_sf2_level(new_client, 1, 1); /* Fan1 */ +- device_create_file_sf2_level(new_client, 2, 1); /* Fan1 */ +- device_create_file_sf2_level(new_client, 3, 1); /* Fan1 */ +- device_create_file_sf2_level(new_client, 1, 2); /* Fan2 */ +- device_create_file_sf2_level(new_client, 2, 2); /* Fan2 */ +- device_create_file_sf2_level(new_client, 3, 2); /* Fan2 */ +- device_create_file_sf2_level(new_client, 1, 3); /* Fan3 */ +- device_create_file_sf2_level(new_client, 2, 3); /* Fan3 */ +- device_create_file_sf2_level(new_client, 3, 3); /* Fan3 */ ++ for (i = 0; i < ARRAY_SIZE(sda_sf2_level); i++) ++ device_create_file(dev, &sda_sf2_level[i].dev_attr); + + return 0; + +@@ -1366,7 +1295,7 @@ + kfree(data->lm75[1]); + } + ERROR2: +- i2c_detach_client(new_client); ++ i2c_detach_client(client); + ERROR1: + kfree(data); + ERROR0: +@@ -1434,7 +1363,7 @@ + int i, j; + u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after + (jiffies - data->last_updated, (unsigned long) (HZ * 3)) +@@ -1545,7 +1474,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + #ifdef DEBUG + w83792d_print_debug(data, dev); +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-amd756-s4882.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-amd756-s4882.c 2006-03-22 17:06:15.000000000 +0100 +@@ -38,6 +38,7 @@ + #include <linux/slab.h> + #include <linux/init.h> + #include <linux/i2c.h> ++#include <linux/mutex.h> + + extern struct i2c_adapter amd756_smbus; + +@@ -45,7 +46,7 @@ + static struct i2c_algorithm *s4882_algo; + + /* Wrapper access functions for multiplexed SMBus */ +-static struct semaphore amd756_lock; ++static DEFINE_MUTEX(amd756_lock); + + static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr, + unsigned short flags, char read_write, +@@ -59,12 +60,12 @@ + || addr == 0x18) + return -1; + +- down(&amd756_lock); ++ mutex_lock(&amd756_lock); + + error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write, + command, size, data); + +- up(&amd756_lock); ++ mutex_unlock(&amd756_lock); + + return error; + } +@@ -87,7 +88,7 @@ + if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30) + return -1; + +- down(&amd756_lock); ++ mutex_lock(&amd756_lock); + + if (last_channels != channels) { + union i2c_smbus_data mplxdata; +@@ -105,7 +106,7 @@ + command, size, data); + + UNLOCK: +- up(&amd756_lock); ++ mutex_unlock(&amd756_lock); + return error; + } + +@@ -166,8 +167,6 @@ + } + + printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n"); +- init_MUTEX(&amd756_lock); +- + /* Define the 5 virtual adapters and algorithms structures */ + if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter), + GFP_KERNEL))) { +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-isa.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-isa.c 2006-03-22 17:06:15.000000000 +0100 +@@ -125,7 +125,7 @@ + + static int __init i2c_isa_init(void) + { +- init_MUTEX(&isa_adapter.clist_lock); ++ mutex_init(&isa_adapter.clist_lock); + INIT_LIST_HEAD(&isa_adapter.clients); + + isa_adapter.nr = ANY_I2C_ISA_BUS; +--- linux-2.6.16.orig/drivers/i2c/chips/eeprom.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/chips/eeprom.c 2006-03-22 17:06:16.000000000 +0100 +@@ -33,6 +33,7 @@ + #include <linux/sched.h> + #include <linux/jiffies.h> + #include <linux/i2c.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, +@@ -54,7 +55,7 @@ + /* Each client has this additional data */ + struct eeprom_data { + struct i2c_client client; +- struct semaphore update_lock; ++ struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[8]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +@@ -62,7 +63,6 @@ + }; + + +-static int eeprom_attach_adapter(struct i2c_adapter *adapter); + static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind); + static int eeprom_detach_client(struct i2c_client *client); + +@@ -72,7 +72,9 @@ + .name = "eeprom", + }, + .id = I2C_DRIVERID_EEPROM, +- .attach_adapter = eeprom_attach_adapter, ++ .class = I2C_CLASS_DATA, ++ .address_data = &addr_data, ++ .detect_client = eeprom_detect, + .detach_client = eeprom_detach_client, + }; + +@@ -81,7 +83,7 @@ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { +@@ -107,7 +109,7 @@ + data->valid |= (1 << slice); + } + exit: +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + + static ssize_t eeprom_read(struct kobject *kobj, char *buf, loff_t off, size_t count) +@@ -149,11 +151,6 @@ + .read = eeprom_read, + }; + +-static int eeprom_attach_adapter(struct i2c_adapter *adapter) +-{ +- return i2c_probe(adapter, &addr_data, eeprom_detect); +-} +- + /* This function is called by i2c_probe */ + static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) + { +@@ -187,7 +184,7 @@ + /* Fill in the remaining client fields */ + strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + data->nature = UNKNOWN; + + /* Tell the I2C layer a new client has arrived */ +--- linux-2.6.16.orig/drivers/i2c/chips/max6875.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/chips/max6875.c 2006-03-22 17:06:15.000000000 +0100 +@@ -31,7 +31,7 @@ + #include <linux/module.h> + #include <linux/slab.h> + #include <linux/i2c.h> +-#include <asm/semaphore.h> ++#include <linux/mutex.h> + + /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ + static unsigned short normal_i2c[] = {I2C_CLIENT_END}; +@@ -54,7 +54,7 @@ + /* Each client has this additional data */ + struct max6875_data { + struct i2c_client client; +- struct semaphore update_lock; ++ struct mutex update_lock; + + u32 valid; + u8 data[USER_EEPROM_SIZE]; +@@ -83,7 +83,7 @@ + if (slice >= USER_EEPROM_SLICES) + return; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + buf = &data->data[slice << SLICE_BITS]; + +@@ -122,7 +122,7 @@ + data->valid |= (1 << slice); + } + exit_up: +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + + static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off, +@@ -196,7 +196,7 @@ + real_client->driver = &max6875_driver; + real_client->flags = 0; + strlcpy(real_client->name, "max6875", I2C_NAME_SIZE); +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Init fake client data */ + /* set the client data to the i2c_client so that it will get freed */ +--- linux-2.6.16.orig/drivers/i2c/chips/pcf8591.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/chips/pcf8591.c 2006-03-22 17:06:15.000000000 +0100 +@@ -24,6 +24,7 @@ + #include <linux/init.h> + #include <linux/slab.h> + #include <linux/i2c.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, +@@ -74,7 +75,7 @@ + + struct pcf8591_data { + struct i2c_client client; +- struct semaphore update_lock; ++ struct mutex update_lock; + + u8 control; + u8 aout; +@@ -144,13 +145,13 @@ + struct pcf8591_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + if (val) + data->control |= PCF8591_CONTROL_AOEF; + else + data->control &= ~PCF8591_CONTROL_AOEF; + i2c_smbus_write_byte(client, data->control); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -200,7 +201,7 @@ + /* Fill in the remaining client fields and put it into the global + list */ + strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE); +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -265,7 +266,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct pcf8591_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) { + data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK) +@@ -278,7 +279,7 @@ + } + value = i2c_smbus_read_byte(client); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + if ((channel == 2 && input_mode == 2) || + (channel != 3 && (input_mode == 1 || input_mode == 3))) +--- linux-2.6.16.orig/drivers/i2c/chips/tps65010.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/chips/tps65010.c 2006-03-22 17:06:15.000000000 +0100 +@@ -32,6 +32,7 @@ + #include <linux/suspend.h> + #include <linux/debugfs.h> + #include <linux/seq_file.h> ++#include <linux/mutex.h> + + #include <asm/irq.h> + #include <asm/mach-types.h> +@@ -81,7 +82,7 @@ + + struct tps65010 { + struct i2c_client client; +- struct semaphore lock; ++ struct mutex lock; + int irq; + struct work_struct work; + struct dentry *file; +@@ -218,7 +219,7 @@ + seq_printf(s, "driver %s\nversion %s\nchip %s\n\n", + DRIVER_NAME, DRIVER_VERSION, chip); + +- down(&tps->lock); ++ mutex_lock(&tps->lock); + + /* FIXME how can we tell whether a battery is present? + * likely involves a charge gauging chip (like BQ26501). +@@ -300,7 +301,7 @@ + (v2 & (1 << (4 + i))) ? "rising" : "falling"); + } + +- up(&tps->lock); ++ mutex_unlock(&tps->lock); + return 0; + } + +@@ -416,7 +417,7 @@ + { + struct tps65010 *tps = _tps; + +- down(&tps->lock); ++ mutex_lock(&tps->lock); + + tps65010_interrupt(tps); + +@@ -444,7 +445,7 @@ + if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags)) + enable_irq(tps->irq); + +- up(&tps->lock); ++ mutex_unlock(&tps->lock); + } + + static irqreturn_t tps65010_irq(int irq, void *_tps, struct pt_regs *regs) +@@ -505,7 +506,7 @@ + if (!tps) + return 0; + +- init_MUTEX(&tps->lock); ++ mutex_init(&tps->lock); + INIT_WORK(&tps->work, tps65010_work, tps); + tps->irq = -1; + tps->client.addr = address; +@@ -695,7 +696,7 @@ + if ((gpio < GPIO1) || (gpio > GPIO4)) + return -EINVAL; + +- down(&the_tps->lock); ++ mutex_lock(&the_tps->lock); + + defgpio = i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO); + +@@ -720,7 +721,7 @@ + gpio, value ? "high" : "low", + i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO)); + +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + return status; + } + EXPORT_SYMBOL(tps65010_set_gpio_out_value); +@@ -745,7 +746,7 @@ + led = LED2; + } + +- down(&the_tps->lock); ++ mutex_lock(&the_tps->lock); + + pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led, + i2c_smbus_read_byte_data(&the_tps->client, +@@ -771,7 +772,7 @@ + default: + printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n", + DRIVER_NAME); +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + return -EINVAL; + } + +@@ -781,7 +782,7 @@ + if (status != 0) { + printk(KERN_ERR "%s: Failed to write led%i_on register\n", + DRIVER_NAME, led); +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + return status; + } + +@@ -794,7 +795,7 @@ + if (status != 0) { + printk(KERN_ERR "%s: Failed to write led%i_per register\n", + DRIVER_NAME, led); +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + return status; + } + +@@ -802,7 +803,7 @@ + i2c_smbus_read_byte_data(&the_tps->client, + TPS_LED1_PER + offs)); + +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + + return status; + } +@@ -820,7 +821,7 @@ + if (!the_tps) + return -ENODEV; + +- down(&the_tps->lock); ++ mutex_lock(&the_tps->lock); + + vdcdc2 = i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC2); + vdcdc2 &= ~(1 << 1); +@@ -831,7 +832,7 @@ + + pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off"); + +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + return status; + } + EXPORT_SYMBOL(tps65010_set_vib); +@@ -848,7 +849,7 @@ + if (!the_tps) + return -ENODEV; + +- down(&the_tps->lock); ++ mutex_lock(&the_tps->lock); + + pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME, + mode ? "enable" : "disable", +@@ -876,7 +877,7 @@ + pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, + i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1)); + +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + + return status; + } +@@ -894,7 +895,7 @@ + if (!the_tps) + return -ENODEV; + +- down(&the_tps->lock); ++ mutex_lock(&the_tps->lock); + + pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, + i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1)); +@@ -909,7 +910,7 @@ + pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, + i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1)); + +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + + return status; + } +@@ -931,7 +932,7 @@ + if (!the_tps || the_tps->por) + return -ENODEV; + +- down(&the_tps->lock); ++ mutex_lock(&the_tps->lock); + + pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n", + DRIVER_NAME, +@@ -959,7 +960,7 @@ + if (status != 0) { + printk(KERN_ERR "%s: Failed to write chconfig register\n", + DRIVER_NAME); +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + return status; + } + +@@ -977,7 +978,7 @@ + pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, + i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1)); + +- up(&the_tps->lock); ++ mutex_unlock(&the_tps->lock); + + return status; + } +--- linux-2.6.16.orig/include/linux/i2c.h 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/include/linux/i2c.h 2006-03-22 17:06:21.000000000 +0100 +@@ -32,7 +32,7 @@ + #include <linux/mod_devicetable.h> + #include <linux/device.h> /* for struct device */ + #include <linux/sched.h> /* for completion */ +-#include <asm/semaphore.h> ++#include <linux/mutex.h> + + /* --- For i2c-isa ---------------------------------------------------- */ + +@@ -48,6 +48,7 @@ + struct i2c_adapter; + struct i2c_client; + struct i2c_driver; ++struct i2c_client_address_data; + union i2c_smbus_data; + + /* +@@ -116,6 +117,7 @@ + struct i2c_driver { + int id; + unsigned int class; ++ struct i2c_client_address_data *address_data; + + /* Notifies the driver that a new bus has appeared. This routine + * can be used by the driver to test if the bus meets its conditions +@@ -133,6 +135,15 @@ + */ + int (*detach_client)(struct i2c_client *); + ++ /* Requests that the driver validate an address on a bus and attach a ++ * new client. If this routine is supplied, it will be called for ++ * each device on new buses that appear, provided the bus class ++ * matches the class field and devices exist at the addresses listed ++ * in the address_data field. For most drivers, this mechanism can ++ * be used instead of an attach_adapter routine. ++ */ ++ int (*detect_client)(struct i2c_adapter *, int addr, int kind); ++ + /* a ioctl like command that can be used to perform specific functions + * with the device. + */ +@@ -225,8 +236,8 @@ + int (*client_unregister)(struct i2c_client *); + + /* data fields that are valid for all devices */ +- struct semaphore bus_lock; +- struct semaphore clist_lock; ++ struct mutex bus_lock; ++ struct mutex clist_lock; + + int timeout; + int retries; +@@ -262,7 +273,7 @@ + #define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ + #define I2C_CLASS_TV_ANALOG (1<<1) /* bttv + friends */ + #define I2C_CLASS_TV_DIGITAL (1<<2) /* dvb cards */ +-#define I2C_CLASS_DDC (1<<3) /* i2c-matroxfb ? */ ++#define I2C_CLASS_DATA (1<<3) /* data storage */ + #define I2C_CLASS_CAM_ANALOG (1<<4) /* camera with analog CCD */ + #define I2C_CLASS_CAM_DIGITAL (1<<5) /* most webcams */ + #define I2C_CLASS_SOUND (1<<6) /* sound devices */ +@@ -329,6 +340,10 @@ + struct i2c_client_address_data *address_data, + int (*found_proc) (struct i2c_adapter *, int, int)); + ++/* Direct chip probing function to create clients by address */ ++extern int i2c_probe_device(struct i2c_adapter *adapter, int driver_id, ++ int addr, int kind); ++ + /* An ioctl like call to set div. parameters of the adapter. + */ + extern int i2c_control(struct i2c_client *,unsigned int, unsigned long); +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-pxa.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-pxa.c 2006-03-22 17:06:15.000000000 +0100 +@@ -647,7 +647,7 @@ + } + + /* +- * We are protected by the adapter bus semaphore. ++ * We are protected by the adapter bus mutex. + */ + static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num) + { +--- linux-2.6.16.orig/drivers/hwmon/adm1021.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/adm1021.c 2006-03-22 17:06:16.000000000 +0100 +@@ -26,6 +26,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + + /* Addresses to scan */ +@@ -92,7 +93,7 @@ + struct class_device *class_dev; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -111,7 +112,6 @@ + u8 remote_temp_offset_prec; + }; + +-static int adm1021_attach_adapter(struct i2c_adapter *adapter); + static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); + static void adm1021_init_client(struct i2c_client *client); + static int adm1021_detach_client(struct i2c_client *client); +@@ -130,7 +130,9 @@ + .name = "adm1021", + }, + .id = I2C_DRIVERID_ADM1021, +- .attach_adapter = adm1021_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = adm1021_detect, + .detach_client = adm1021_detach_client, + }; + +@@ -162,10 +164,10 @@ + struct adm1021_data *data = i2c_get_clientdata(client); \ + int temp = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = TEMP_TO_REG(temp); \ + adm1021_write_value(client, reg, data->value); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + set(temp_max, ADM1021_REG_TOS_W); +@@ -182,13 +184,6 @@ + static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + + +-static int adm1021_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, adm1021_detect); +-} +- + static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) + { + int i; +@@ -275,7 +270,7 @@ + strlcpy(new_client->name, type_name, I2C_NAME_SIZE); + data->type = kind; + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -351,7 +346,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct adm1021_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -375,7 +370,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/adm1025.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/adm1025.c 2006-03-22 17:06:16.000000000 +0100 +@@ -53,6 +53,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* + * Addresses to scan +@@ -107,7 +108,6 @@ + * Functions declaration + */ + +-static int adm1025_attach_adapter(struct i2c_adapter *adapter); + static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind); + static void adm1025_init_client(struct i2c_client *client); + static int adm1025_detach_client(struct i2c_client *client); +@@ -122,7 +122,9 @@ + .name = "adm1025", + }, + .id = I2C_DRIVERID_ADM1025, +- .attach_adapter = adm1025_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = adm1025_detect, + .detach_client = adm1025_detach_client, + }; + +@@ -133,7 +135,7 @@ + struct adm1025_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -207,11 +209,11 @@ + struct adm1025_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->in_min[offset] = IN_TO_REG(val, in_scale[offset]); \ + i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MIN(offset), \ + data->in_min[offset]); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } \ + static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \ +@@ -221,11 +223,11 @@ + struct adm1025_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->in_max[offset] = IN_TO_REG(val, in_scale[offset]); \ + i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(offset), \ + data->in_max[offset]); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } \ + static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \ +@@ -247,11 +249,11 @@ + struct adm1025_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->temp_min[offset-1] = TEMP_TO_REG(val); \ + i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_LOW(offset-1), \ + data->temp_min[offset-1]); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } \ + static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \ +@@ -261,11 +263,11 @@ + struct adm1025_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->temp_max[offset-1] = TEMP_TO_REG(val); \ + i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_HIGH(offset-1), \ + data->temp_max[offset-1]); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } \ + static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \ +@@ -307,13 +309,6 @@ + * Real code + */ + +-static int adm1025_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, adm1025_detect); +-} +- + /* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. +@@ -404,7 +399,7 @@ + /* We can fill in the remaining client fields */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -523,7 +518,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct adm1025_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + int i; +@@ -558,7 +553,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/adm1026.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/adm1026.c 2006-03-22 17:06:21.000000000 +0100 +@@ -32,6 +32,7 @@ + #include <linux/hwmon-sysfs.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +@@ -260,10 +261,10 @@ + struct adm1026_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + int valid; /* !=0 if following fields are valid */ + unsigned long last_reading; /* In jiffies */ + unsigned long last_config; /* In jiffies */ +@@ -294,13 +295,11 @@ + u8 config3; /* Register value */ + }; + +-static int adm1026_attach_adapter(struct i2c_adapter *adapter); + static int adm1026_detect(struct i2c_adapter *adapter, int address, + int kind); + static int adm1026_detach_client(struct i2c_client *client); +-static int adm1026_read_value(struct i2c_client *client, u8 register); +-static int adm1026_write_value(struct i2c_client *client, u8 register, +- int value); ++static int adm1026_read_value(struct i2c_client *client, u8 reg); ++static int adm1026_write_value(struct i2c_client *client, u8 reg, int value); + static void adm1026_print_gpio(struct i2c_client *client); + static void adm1026_fixup_gpio(struct i2c_client *client); + static struct adm1026_data *adm1026_update_device(struct device *dev); +@@ -311,18 +310,12 @@ + .driver = { + .name = "adm1026", + }, +- .attach_adapter = adm1026_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = adm1026_detect, + .detach_client = adm1026_detach_client, + }; + +-static int adm1026_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) { +- return 0; +- } +- return i2c_probe(adapter, &addr_data, adm1026_detect); +-} +- + static int adm1026_detach_client(struct i2c_client *client) + { + struct adm1026_data *data = i2c_get_clientdata(client); +@@ -575,7 +568,7 @@ + int i; + long value, alarms, gpio; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + if (!data->valid + || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) { + /* Things that change quickly */ +@@ -710,7 +703,7 @@ + dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n"); + data->vid = (data->gpio >> 11) & 0x1f; + data->valid = 1; +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return data; + } + +@@ -739,10 +732,10 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = INS_TO_REG(nr, val); + adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, +@@ -762,10 +755,10 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = INS_TO_REG(nr, val); + adm1026_write_value(client, ADM1026_REG_IN_MAX[nr], data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -813,10 +806,10 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET); + adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf) +@@ -831,10 +824,10 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET); + adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -874,11 +867,11 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]); + adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr), + data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -939,7 +932,7 @@ + if (new_div == 0) { + return -EINVAL; + } +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + orig_div = data->fan_div[nr]; + data->fan_div[nr] = DIV_FROM_REG(new_div); + +@@ -958,7 +951,7 @@ + if (data->fan_div[nr] != orig_div) { + fixup_fan_min(dev,nr,orig_div); + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1001,11 +994,11 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_min[nr] = TEMP_TO_REG(val); + adm1026_write_value(client, ADM1026_REG_TEMP_MIN[nr], + data->temp_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, +@@ -1025,11 +1018,11 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[nr] = TEMP_TO_REG(val); + adm1026_write_value(client, ADM1026_REG_TEMP_MAX[nr], + data->temp_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1064,11 +1057,11 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_offset[nr] = TEMP_TO_REG(val); + adm1026_write_value(client, ADM1026_REG_TEMP_OFFSET[nr], + data->temp_offset[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1115,11 +1108,11 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_tmin[nr] = TEMP_TO_REG(val); + adm1026_write_value(client, ADM1026_REG_TEMP_TMIN[nr], + data->temp_tmin[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1150,11 +1143,11 @@ + int val = simple_strtol(buf, NULL, 10); + + if ((val == 1) || (val==0)) { +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4); + adm1026_write_value(client, ADM1026_REG_CONFIG1, + data->config1); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + return count; + } +@@ -1184,11 +1177,11 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_crit[nr] = TEMP_TO_REG(val); + adm1026_write_value(client, ADM1026_REG_TEMP_THERM[nr], + data->temp_crit[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1212,10 +1205,10 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->analog_out = DAC_TO_REG(val); + adm1026_write_value(client, ADM1026_REG_DAC, data->analog_out); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1267,7 +1260,7 @@ + int val = simple_strtol(buf, NULL, 10); + unsigned long mask; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->alarm_mask = val & 0x7fffffff; + mask = data->alarm_mask + | (data->gpio_mask & 0x10000 ? 0x80000000 : 0); +@@ -1282,7 +1275,7 @@ + mask >>= 8; + adm1026_write_value(client, ADM1026_REG_MASK4, + mask & 0xff); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1303,7 +1296,7 @@ + int val = simple_strtol(buf, NULL, 10); + long gpio; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->gpio = val & 0x1ffff; + gpio = data->gpio; + adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7,gpio & 0xff); +@@ -1311,7 +1304,7 @@ + adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_8_15,gpio & 0xff); + gpio = ((gpio >> 1) & 0x80) | (data->alarms >> 24 & 0x7f); + adm1026_write_value(client, ADM1026_REG_STATUS4,gpio & 0xff); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1331,7 +1324,7 @@ + int val = simple_strtol(buf, NULL, 10); + long mask; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->gpio_mask = val & 0x1ffff; + mask = data->gpio_mask; + adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7,mask & 0xff); +@@ -1339,7 +1332,7 @@ + adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15,mask & 0xff); + mask = ((mask >> 1) & 0x80) | (data->alarm_mask >> 24 & 0x7f); + adm1026_write_value(client, ADM1026_REG_MASK1,mask & 0xff); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -1359,10 +1352,10 @@ + if (data->pwm1.enable == 1) { + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm1.pwm = PWM_TO_REG(val); + adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + return count; + } +@@ -1378,14 +1371,14 @@ + struct adm1026_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255); + if (data->pwm1.enable == 2) { /* apply immediately */ + data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) | + PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); + adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf) +@@ -1406,7 +1399,7 @@ + int old_enable; + + if ((val >= 0) && (val < 3)) { +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + old_enable = data->pwm1.enable; + data->pwm1.enable = val; + data->config1 = (data->config1 & ~CFG1_PWM_AFC) +@@ -1424,7 +1417,7 @@ + adm1026_write_value(client, ADM1026_REG_PWM, + data->pwm1.pwm); + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + return count; + } +@@ -1541,7 +1534,7 @@ + /* Fill in the remaining client fields */ + data->type = kind; + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +--- linux-2.6.16.orig/drivers/hwmon/adm1031.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/adm1031.c 2006-03-22 17:06:16.000000000 +0100 +@@ -28,6 +28,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Following macros takes channel parameter starting from 0 to 2 */ + #define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr)) +@@ -70,7 +71,7 @@ + struct adm1031_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + int chip_type; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ +@@ -97,7 +98,6 @@ + s8 temp_crit[3]; + }; + +-static int adm1031_attach_adapter(struct i2c_adapter *adapter); + static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind); + static void adm1031_init_client(struct i2c_client *client); + static int adm1031_detach_client(struct i2c_client *client); +@@ -108,7 +108,9 @@ + .driver = { + .name = "adm1031", + }, +- .attach_adapter = adm1031_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = adm1031_detect, + .detach_client = adm1031_detach_client, + }; + +@@ -262,10 +264,10 @@ + + old_fan_mode = data->conf1; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®))) { +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return ret; + } + if (((data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1)) & ADM1031_CONF1_AUTO_MODE) ^ +@@ -288,7 +290,7 @@ + } + data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1); + adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -329,11 +331,11 @@ + struct adm1031_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); + adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), + data->auto_temp[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_auto_temp_max(struct device *dev, char *buf, int nr) +@@ -349,11 +351,11 @@ + struct adm1031_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]); + adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), + data->temp_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -405,11 +407,11 @@ + int val = simple_strtol(buf, NULL, 10); + int reg; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) && + (((val>>4) & 0xf) != 5)) { + /* In automatic mode, the only PWM accepted is 33% */ +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + data->pwm[nr] = PWM_TO_REG(val); +@@ -417,7 +419,7 @@ + adm1031_write_value(client, ADM1031_REG_PWM, + nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf) + : (data->pwm[nr] & 0xf) | (reg & 0xf0)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -511,7 +513,7 @@ + struct adm1031_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + if (val) { + data->fan_min[nr] = + FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr])); +@@ -519,7 +521,7 @@ + data->fan_min[nr] = 0xff; + } + adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t +@@ -540,7 +542,7 @@ + if (tmp == 0xff) + return -EINVAL; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + old_div = FAN_DIV_FROM_REG(data->fan_div[nr]); + data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]); + new_min = data->fan_min[nr] * old_div / +@@ -553,7 +555,7 @@ + data->fan_div[nr]); + adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), + data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -627,11 +629,11 @@ + + val = simple_strtol(buf, NULL, 10); + val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_min[nr] = TEMP_TO_REG(val); + adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr), + data->temp_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t +@@ -643,11 +645,11 @@ + + val = simple_strtol(buf, NULL, 10); + val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[nr] = TEMP_TO_REG(val); + adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr), + data->temp_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t +@@ -659,11 +661,11 @@ + + val = simple_strtol(buf, NULL, 10); + val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_crit[nr] = TEMP_TO_REG(val); + adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr), + data->temp_crit[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -722,13 +724,6 @@ + static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + + +-static int adm1031_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, adm1031_detect); +-} +- + /* This function is called by i2c_probe */ + static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) + { +@@ -778,7 +773,7 @@ + + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -891,7 +886,7 @@ + struct adm1031_data *data = i2c_get_clientdata(client); + int chan; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -965,7 +960,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/adm9240.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/adm9240.c 2006-03-22 17:06:16.000000000 +0100 +@@ -49,6 +49,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, +@@ -129,7 +130,6 @@ + return SCALE(reg, 1250, 255); + } + +-static int adm9240_attach_adapter(struct i2c_adapter *adapter); + static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind); + static void adm9240_init_client(struct i2c_client *client); + static int adm9240_detach_client(struct i2c_client *client); +@@ -141,7 +141,9 @@ + .name = "adm9240", + }, + .id = I2C_DRIVERID_ADM9240, +- .attach_adapter = adm9240_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = adm9240_detect, + .detach_client = adm9240_detach_client, + }; + +@@ -150,7 +152,7 @@ + enum chips type; + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; + unsigned long last_updated_measure; + unsigned long last_updated_config; +@@ -195,11 +197,11 @@ + struct adm9240_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[attr->index] = TEMP_TO_REG(val); + i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index), + data->temp_max[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -246,11 +248,11 @@ + struct adm9240_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[attr->index] = IN_TO_REG(val, attr->index); + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index), + data->in_min[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -263,11 +265,11 @@ + struct adm9240_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[attr->index] = IN_TO_REG(val, attr->index); + i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index), + data->in_max[attr->index]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -350,7 +352,7 @@ + int nr = attr->index; + u8 new_div; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (!val) { + data->fan_min[nr] = 255; +@@ -390,7 +392,7 @@ + i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(nr), + data->fan_min[nr]); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -439,10 +441,10 @@ + struct adm9240_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->aout = AOUT_TO_REG(val); + i2c_smbus_write_byte_data(client, ADM9240_REG_ANALOG_OUT, data->aout); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); +@@ -539,7 +541,7 @@ + /* fill in the remaining client fields and attach */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->type = kind; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + if ((err = i2c_attach_client(new_client))) + goto exit_free; +@@ -621,13 +623,6 @@ + return err; + } + +-static int adm9240_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, adm9240_detect); +-} +- + static int adm9240_detach_client(struct i2c_client *client) + { + struct adm9240_data *data = i2c_get_clientdata(client); +@@ -691,7 +686,7 @@ + struct adm9240_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + /* minimum measurement cycle: 1.75 seconds */ + if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4)) +@@ -771,7 +766,7 @@ + data->last_updated_config = jiffies; + data->valid = 1; + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return data; + } + +--- linux-2.6.16.orig/drivers/hwmon/asb100.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/asb100.c 2006-03-22 17:06:16.000000000 +0100 +@@ -44,6 +44,7 @@ + #include <linux/err.h> + #include <linux/init.h> + #include <linux/jiffies.h> ++#include <linux/mutex.h> + #include "lm75.h" + + /* +@@ -182,10 +183,10 @@ + struct asb100_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + unsigned long last_updated; /* In jiffies */ + + /* array of 2 pointers to subclients */ +@@ -210,7 +211,6 @@ + static int asb100_read_value(struct i2c_client *client, u16 reg); + static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val); + +-static int asb100_attach_adapter(struct i2c_adapter *adapter); + static int asb100_detect(struct i2c_adapter *adapter, int address, int kind); + static int asb100_detach_client(struct i2c_client *client); + static struct asb100_data *asb100_update_device(struct device *dev); +@@ -221,7 +221,9 @@ + .name = "asb100", + }, + .id = I2C_DRIVERID_ASB100, +- .attach_adapter = asb100_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = asb100_detect, + .detach_client = asb100_detach_client, + }; + +@@ -245,11 +247,11 @@ + struct asb100_data *data = i2c_get_clientdata(client); \ + unsigned long val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->in_##reg[nr] = IN_TO_REG(val); \ + asb100_write_value(client, ASB100_REG_IN_##REG(nr), \ + data->in_##reg[nr]); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + +@@ -331,10 +333,10 @@ + struct asb100_data *data = i2c_get_clientdata(client); + u32 val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); + asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -351,7 +353,7 @@ + unsigned long val = simple_strtoul(buf, NULL, 10); + int reg; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + min = FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); +@@ -381,7 +383,7 @@ + FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -461,7 +463,7 @@ + struct asb100_data *data = i2c_get_clientdata(client); \ + unsigned long val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + switch (nr) { \ + case 1: case 2: \ + data->reg[nr] = LM75_TEMP_TO_REG(val); \ +@@ -472,7 +474,7 @@ + } \ + asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \ + data->reg[nr]); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + +@@ -574,11 +576,11 @@ + struct asb100_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm &= 0x80; /* keep the enable bit */ + data->pwm |= (0x0f & ASB100_PWM_TO_REG(val)); + asb100_write_value(client, ASB100_REG_PWM1, data->pwm); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -595,11 +597,11 @@ + struct asb100_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm &= 0x0f; /* keep the duty cycle bits */ + data->pwm |= (val ? 0x80 : 0x00); + asb100_write_value(client, ASB100_REG_PWM1, data->pwm); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -611,18 +613,6 @@ + device_create_file(&new_client->dev, &dev_attr_pwm1_enable); \ + } while (0) + +-/* This function is called when: +- asb100_driver is inserted (when this module is loaded), for each +- available adapter +- when a new adapter is inserted (and asb100_driver is still present) +- */ +-static int asb100_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, asb100_detect); +-} +- + static int asb100_detect_subclients(struct i2c_adapter *adapter, int address, + int kind, struct i2c_client *new_client) + { +@@ -729,7 +719,7 @@ + } + + new_client = &data->client; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; +@@ -789,7 +779,7 @@ + data->type = kind; + + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -885,7 +875,7 @@ + struct i2c_client *cl; + int res, bank; + +- down(&data->lock); ++ mutex_lock(&data->lock); + + bank = (reg >> 8) & 0x0f; + if (bank > 2) +@@ -919,7 +909,7 @@ + if (bank > 2) + i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0); + +- up(&data->lock); ++ mutex_unlock(&data->lock); + + return res; + } +@@ -930,7 +920,7 @@ + struct i2c_client *cl; + int bank; + +- down(&data->lock); ++ mutex_lock(&data->lock); + + bank = (reg >> 8) & 0x0f; + if (bank > 2) +@@ -960,7 +950,7 @@ + if (bank > 2) + i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0); + +- up(&data->lock); ++ mutex_unlock(&data->lock); + } + + static void asb100_init_client(struct i2c_client *client) +@@ -984,7 +974,7 @@ + struct asb100_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -1042,7 +1032,7 @@ + dev_dbg(&client->dev, "... device update complete\n"); + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/atxp1.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/atxp1.c 2006-03-22 17:06:16.000000000 +0100 +@@ -26,6 +26,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); +@@ -44,7 +45,6 @@ + + I2C_CLIENT_INSMOD_1(atxp1); + +-static int atxp1_attach_adapter(struct i2c_adapter * adapter); + static int atxp1_detach_client(struct i2c_client * client); + static struct atxp1_data * atxp1_update_device(struct device *dev); + static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); +@@ -53,14 +53,16 @@ + .driver = { + .name = "atxp1", + }, +- .attach_adapter = atxp1_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = atxp1_detect, + .detach_client = atxp1_detach_client, + }; + + struct atxp1_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + unsigned long last_updated; + u8 valid; + struct { +@@ -80,7 +82,7 @@ + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + +@@ -93,7 +95,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return(data); + } +@@ -251,13 +253,6 @@ + static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2); + + +-static int atxp1_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, &atxp1_detect); +-}; +- + static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) + { + struct i2c_client * new_client; +@@ -309,7 +304,7 @@ + + data->valid = 0; + +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + err = i2c_attach_client(new_client); + +--- linux-2.6.16.orig/drivers/hwmon/ds1621.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/ds1621.c 2006-03-22 17:06:16.000000000 +0100 +@@ -28,6 +28,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include "lm75.h" + + /* Addresses to scan */ +@@ -72,7 +73,7 @@ + struct ds1621_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -80,7 +81,6 @@ + u8 conf; /* Register encoding, combined */ + }; + +-static int ds1621_attach_adapter(struct i2c_adapter *adapter); + static int ds1621_detect(struct i2c_adapter *adapter, int address, + int kind); + static void ds1621_init_client(struct i2c_client *client); +@@ -93,7 +93,9 @@ + .name = "ds1621", + }, + .id = I2C_DRIVERID_DS1621, +- .attach_adapter = ds1621_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = ds1621_detect, + .detach_client = ds1621_detach_client, + }; + +@@ -156,10 +158,10 @@ + struct ds1621_data *data = ds1621_update_client(dev); \ + u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = val; \ + ds1621_write_value(client, reg, data->value); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + +@@ -178,13 +180,6 @@ + static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); + + +-static int ds1621_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, ds1621_detect); +-} +- + /* This function is called by i2c_probe */ + static int ds1621_detect(struct i2c_adapter *adapter, int address, + int kind) +@@ -242,7 +237,7 @@ + /* Fill in remaining client fields and put it into the global list */ + strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -297,7 +292,7 @@ + struct ds1621_data *data = i2c_get_clientdata(client); + u8 new_conf; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -327,7 +322,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/fscher.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/fscher.c 2006-03-22 17:06:16.000000000 +0100 +@@ -33,6 +33,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* + * Addresses to scan +@@ -104,7 +105,6 @@ + * Functions declaration + */ + +-static int fscher_attach_adapter(struct i2c_adapter *adapter); + static int fscher_detect(struct i2c_adapter *adapter, int address, int kind); + static int fscher_detach_client(struct i2c_client *client); + static struct fscher_data *fscher_update_device(struct device *dev); +@@ -122,7 +122,9 @@ + .name = "fscher", + }, + .id = I2C_DRIVERID_FSCHER, +- .attach_adapter = fscher_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = fscher_detect, + .detach_client = fscher_detach_client, + }; + +@@ -133,7 +135,7 @@ + struct fscher_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -284,13 +286,6 @@ + * Real code + */ + +-static int fscher_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, fscher_detect); +-} +- + static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) + { + struct i2c_client *new_client; +@@ -332,7 +327,7 @@ + * global list */ + strlcpy(new_client->name, "fscher", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -417,7 +412,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct fscher_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { + +@@ -457,7 +452,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +@@ -472,10 +467,10 @@ + /* bits 0..1, 3..7 reserved => mask with 0x04 */ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0x04; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_status[FAN_INDEX_FROM_NUM(nr)] &= ~v; + fscher_write_value(client, reg, v); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -490,10 +485,10 @@ + { + unsigned long v = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v; + fscher_write_value(client, reg, data->fan_min[FAN_INDEX_FROM_NUM(nr)]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -518,14 +513,14 @@ + return -EINVAL; + } + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + /* bits 2..7 reserved => mask with 0x03 */ + data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] &= ~0x03; + data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] |= v; + + fscher_write_value(client, reg, data->fan_ripple[FAN_INDEX_FROM_NUM(nr)]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -552,10 +547,10 @@ + /* bits 2..7 reserved, 0 read only => mask with 0x02 */ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v; + fscher_write_value(client, reg, v); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -609,10 +604,10 @@ + /* bits 1..7 reserved => mask with 0x01 */ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->global_control &= ~v; + fscher_write_value(client, reg, v); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -631,11 +626,11 @@ + /* bits 0..3 reserved => mask with 0xf0 */ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->watchdog[2] &= ~0xf0; + data->watchdog[2] |= v; + fscher_write_value(client, reg, data->watchdog[2]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -651,10 +646,10 @@ + /* bits 0, 2..7 reserved => mask with 0x02 */ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->watchdog[1] &= ~v; + fscher_write_value(client, reg, v); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -669,10 +664,10 @@ + { + unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->watchdog[0] = v; + fscher_write_value(client, reg, data->watchdog[0]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +--- linux-2.6.16.orig/drivers/hwmon/fscpos.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/fscpos.c 2006-03-22 17:06:16.000000000 +0100 +@@ -37,6 +37,7 @@ + #include <linux/init.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* + * Addresses to scan +@@ -85,12 +86,11 @@ + /* + * Functions declaration + */ +-static int fscpos_attach_adapter(struct i2c_adapter *adapter); + static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind); + static int fscpos_detach_client(struct i2c_client *client); + +-static int fscpos_read_value(struct i2c_client *client, u8 register); +-static int fscpos_write_value(struct i2c_client *client, u8 register, u8 value); ++static int fscpos_read_value(struct i2c_client *client, u8 reg); ++static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value); + static struct fscpos_data *fscpos_update_device(struct device *dev); + static void fscpos_init_client(struct i2c_client *client); + +@@ -104,7 +104,9 @@ + .name = "fscpos", + }, + .id = I2C_DRIVERID_FSCPOS, +- .attach_adapter = fscpos_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = fscpos_detect, + .detach_client = fscpos_detach_client, + }; + +@@ -114,7 +116,7 @@ + struct fscpos_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* 0 until following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -208,13 +210,13 @@ + return -EINVAL; + } + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + /* bits 2..7 reserved => mask with 0x03 */ + data->fan_ripple[nr - 1] &= ~0x03; + data->fan_ripple[nr - 1] |= v; + + fscpos_write_value(client, reg, data->fan_ripple[nr - 1]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -232,10 +234,10 @@ + if (v < 0) v = 0; + if (v > 255) v = 255; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm[nr - 1] = v; + fscpos_write_value(client, reg, data->pwm[nr - 1]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -278,11 +280,11 @@ + /* bits 0..3 reserved => mask with 0xf0 */ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->wdog_control &= ~0xf0; + data->wdog_control |= v; + fscpos_write_value(client, reg, data->wdog_control); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -304,10 +306,10 @@ + return -EINVAL; + } + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->wdog_state &= ~v; + fscpos_write_value(client, reg, v); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -321,10 +323,10 @@ + { + unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->wdog_preset = v; + fscpos_write_value(client, reg, data->wdog_preset); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -431,13 +433,6 @@ + static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL); + static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL); + +-static int fscpos_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, fscpos_detect); +-} +- + static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) + { + struct i2c_client *new_client; +@@ -483,7 +478,7 @@ + strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE); + + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -579,7 +574,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct fscpos_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { + int i; +@@ -625,7 +620,7 @@ + data->last_updated = jiffies; + data->valid = 1; + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return data; + } + +--- linux-2.6.16.orig/drivers/hwmon/gl518sm.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/gl518sm.c 2006-03-22 17:06:16.000000000 +0100 +@@ -43,6 +43,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +@@ -120,7 +121,7 @@ + struct class_device *class_dev; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -141,7 +142,6 @@ + u8 beep_enable; /* Boolean */ + }; + +-static int gl518_attach_adapter(struct i2c_adapter *adapter); + static int gl518_detect(struct i2c_adapter *adapter, int address, int kind); + static void gl518_init_client(struct i2c_client *client); + static int gl518_detach_client(struct i2c_client *client); +@@ -155,7 +155,9 @@ + .name = "gl518sm", + }, + .id = I2C_DRIVERID_GL518, +- .attach_adapter = gl518_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = gl518_detect, + .detach_client = gl518_detach_client, + }; + +@@ -212,10 +214,10 @@ + struct gl518_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = type##_TO_REG(val); \ + gl518_write_value(client, reg, data->value); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + +@@ -228,12 +230,12 @@ + int regvalue; \ + unsigned long val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + regvalue = gl518_read_value(client, reg); \ + data->value = type##_TO_REG(val); \ + regvalue = (regvalue & ~mask) | (data->value << shift); \ + gl518_write_value(client, reg, regvalue); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + +@@ -265,7 +267,7 @@ + int regvalue; + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT); + data->fan_min[0] = FAN_TO_REG(val, + DIV_FROM_REG(data->fan_div[0])); +@@ -280,7 +282,7 @@ + data->beep_mask &= data->alarm_mask; + gl518_write_value(client, GL518_REG_ALARM, data->beep_mask); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -291,7 +293,7 @@ + int regvalue; + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT); + data->fan_min[1] = FAN_TO_REG(val, + DIV_FROM_REG(data->fan_div[1])); +@@ -306,7 +308,7 @@ + data->beep_mask &= data->alarm_mask; + gl518_write_value(client, GL518_REG_ALARM, data->beep_mask); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -343,13 +345,6 @@ + * Real code + */ + +-static int gl518_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, gl518_detect); +-} +- + static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) + { + int i; +@@ -407,7 +402,7 @@ + strlcpy(new_client->name, "gl518sm", I2C_NAME_SIZE); + data->type = kind; + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -525,7 +520,7 @@ + struct gl518_data *data = i2c_get_clientdata(client); + int val; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -586,7 +581,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/gl520sm.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/gl520sm.c 2006-03-22 17:06:16.000000000 +0100 +@@ -29,6 +29,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Type of the extra sensor */ + static unsigned short extra_sensor_type; +@@ -99,7 +100,6 @@ + * Function declarations + */ + +-static int gl520_attach_adapter(struct i2c_adapter *adapter); + static int gl520_detect(struct i2c_adapter *adapter, int address, int kind); + static void gl520_init_client(struct i2c_client *client); + static int gl520_detach_client(struct i2c_client *client); +@@ -113,7 +113,9 @@ + .name = "gl520sm", + }, + .id = I2C_DRIVERID_GL520, +- .attach_adapter = gl520_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = gl520_detect, + .detach_client = gl520_detach_client, + }; + +@@ -121,7 +123,7 @@ + struct gl520_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until the following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -303,7 +305,7 @@ + long v = simple_strtol(buf, NULL, 10); + u8 r; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (n == 0) + r = VDD_TO_REG(v); +@@ -317,7 +319,7 @@ + else + gl520_write_value(client, reg, r); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -331,7 +333,7 @@ + else + r = IN_TO_REG(v); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + data->in_max[n] = r; + +@@ -340,7 +342,7 @@ + else + gl520_write_value(client, reg, r); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -373,7 +375,7 @@ + unsigned long v = simple_strtoul(buf, NULL, 10); + u8 r; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + r = FAN_TO_REG(v, data->fan_div[n - 1]); + data->fan_min[n - 1] = r; + +@@ -390,7 +392,7 @@ + data->beep_mask &= data->alarm_mask; + gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -409,7 +411,7 @@ + return -EINVAL; + } + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_div[n - 1] = r; + + if (n == 1) +@@ -417,7 +419,7 @@ + else + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4)); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -425,10 +427,10 @@ + { + u8 r = simple_strtoul(buf, NULL, 10)?1:0; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_off = r; + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x0c) | (r << 2)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -454,10 +456,10 @@ + { + long v = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[n - 1] = TEMP_TO_REG(v);; + gl520_write_value(client, reg, data->temp_max[n - 1]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -465,10 +467,10 @@ + { + long v = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max_hyst[n - 1] = TEMP_TO_REG(v); + gl520_write_value(client, reg, data->temp_max_hyst[n - 1]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -491,10 +493,10 @@ + { + u8 r = simple_strtoul(buf, NULL, 10)?0:1; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->beep_enable = !r; + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x04) | (r << 2)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -502,11 +504,11 @@ + { + u8 r = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + r &= data->alarm_mask; + data->beep_mask = r; + gl520_write_value(client, reg, r); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -515,13 +517,6 @@ + * Real code + */ + +-static int gl520_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, gl520_detect); +-} +- + static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) + { + struct i2c_client *new_client; +@@ -561,7 +556,7 @@ + /* Fill in the remaining client fields */ + strlcpy(new_client->name, "gl520sm", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -685,7 +680,7 @@ + struct gl520_data *data = i2c_get_clientdata(client); + int val; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { + +@@ -750,7 +745,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/hdaps.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/hdaps.c 2006-03-22 17:06:15.000000000 +0100 +@@ -33,6 +33,7 @@ + #include <linux/module.h> + #include <linux/timer.h> + #include <linux/dmi.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + #define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ +@@ -70,10 +71,10 @@ + static int rest_x; + static int rest_y; + +-static DECLARE_MUTEX(hdaps_sem); ++static DEFINE_MUTEX(hdaps_mutex); + + /* +- * __get_latch - Get the value from a given port. Callers must hold hdaps_sem. ++ * __get_latch - Get the value from a given port. Callers must hold hdaps_mutex. + */ + static inline u8 __get_latch(u16 port) + { +@@ -82,7 +83,7 @@ + + /* + * __check_latch - Check a port latch for a given value. Returns zero if the +- * port contains the given value. Callers must hold hdaps_sem. ++ * port contains the given value. Callers must hold hdaps_mutex. + */ + static inline int __check_latch(u16 port, u8 val) + { +@@ -93,7 +94,7 @@ + + /* + * __wait_latch - Wait up to 100us for a port latch to get a certain value, +- * returning zero if the value is obtained. Callers must hold hdaps_sem. ++ * returning zero if the value is obtained. Callers must hold hdaps_mutex. + */ + static int __wait_latch(u16 port, u8 val) + { +@@ -110,7 +111,7 @@ + + /* + * __device_refresh - request a refresh from the accelerometer. Does not wait +- * for refresh to complete. Callers must hold hdaps_sem. ++ * for refresh to complete. Callers must hold hdaps_mutex. + */ + static void __device_refresh(void) + { +@@ -124,7 +125,7 @@ + /* + * __device_refresh_sync - request a synchronous refresh from the + * accelerometer. We wait for the refresh to complete. Returns zero if +- * successful and nonzero on error. Callers must hold hdaps_sem. ++ * successful and nonzero on error. Callers must hold hdaps_mutex. + */ + static int __device_refresh_sync(void) + { +@@ -134,7 +135,7 @@ + + /* + * __device_complete - indicate to the accelerometer that we are done reading +- * data, and then initiate an async refresh. Callers must hold hdaps_sem. ++ * data, and then initiate an async refresh. Callers must hold hdaps_mutex. + */ + static inline void __device_complete(void) + { +@@ -152,7 +153,7 @@ + { + int ret; + +- down(&hdaps_sem); ++ mutex_lock(&hdaps_mutex); + + /* do a sync refresh -- we need to be sure that we read fresh data */ + ret = __device_refresh_sync(); +@@ -163,7 +164,7 @@ + __device_complete(); + + out: +- up(&hdaps_sem); ++ mutex_unlock(&hdaps_mutex); + return ret; + } + +@@ -198,9 +199,9 @@ + { + int ret; + +- down(&hdaps_sem); ++ mutex_lock(&hdaps_mutex); + ret = __hdaps_read_pair(port1, port2, val1, val2); +- up(&hdaps_sem); ++ mutex_unlock(&hdaps_mutex); + + return ret; + } +@@ -213,7 +214,7 @@ + { + int total, ret = -ENXIO; + +- down(&hdaps_sem); ++ mutex_lock(&hdaps_mutex); + + outb(0x13, 0x1610); + outb(0x01, 0x161f); +@@ -279,7 +280,7 @@ + } + + out: +- up(&hdaps_sem); ++ mutex_unlock(&hdaps_mutex); + return ret; + } + +@@ -313,7 +314,7 @@ + }; + + /* +- * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem. ++ * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mutex. + */ + static void hdaps_calibrate(void) + { +@@ -325,7 +326,7 @@ + int x, y; + + /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ +- if (down_trylock(&hdaps_sem)) { ++ if (!mutex_trylock(&hdaps_mutex)) { + mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); + return; + } +@@ -340,7 +341,7 @@ + mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); + + out: +- up(&hdaps_sem); ++ mutex_unlock(&hdaps_mutex); + } + + +@@ -420,9 +421,9 @@ + struct device_attribute *attr, + const char *buf, size_t count) + { +- down(&hdaps_sem); ++ mutex_lock(&hdaps_mutex); + hdaps_calibrate(); +- up(&hdaps_sem); ++ mutex_unlock(&hdaps_mutex); + + return count; + } +--- linux-2.6.16.orig/drivers/hwmon/it87.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/it87.c 2006-03-22 17:06:16.000000000 +0100 +@@ -41,6 +41,7 @@ + #include <linux/hwmon-sysfs.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + +@@ -194,10 +195,10 @@ + struct it87_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -219,14 +220,12 @@ + }; + + +-static int it87_attach_adapter(struct i2c_adapter *adapter); + static int it87_isa_attach_adapter(struct i2c_adapter *adapter); + static int it87_detect(struct i2c_adapter *adapter, int address, int kind); + static int it87_detach_client(struct i2c_client *client); + +-static int it87_read_value(struct i2c_client *client, u8 register); +-static int it87_write_value(struct i2c_client *client, u8 register, +- u8 value); ++static int it87_read_value(struct i2c_client *client, u8 reg); ++static int it87_write_value(struct i2c_client *client, u8 reg, u8 value); + static struct it87_data *it87_update_device(struct device *dev); + static int it87_check_pwm(struct i2c_client *client); + static void it87_init_client(struct i2c_client *client, struct it87_data *data); +@@ -237,7 +236,9 @@ + .name = "it87", + }, + .id = I2C_DRIVERID_IT87, +- .attach_adapter = it87_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = it87_detect, + .detach_client = it87_detach_client, + }; + +@@ -290,11 +291,11 @@ + struct it87_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = IN_TO_REG(val); + it87_write_value(client, IT87_REG_VIN_MIN(nr), + data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, +@@ -307,11 +308,11 @@ + struct it87_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = IN_TO_REG(val); + it87_write_value(client, IT87_REG_VIN_MAX(nr), + data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -381,10 +382,10 @@ + struct it87_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_high[nr] = TEMP_TO_REG(val); + it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, +@@ -397,10 +398,10 @@ + struct it87_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_low[nr] = TEMP_TO_REG(val); + it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define show_temp_offset(offset) \ +@@ -440,7 +441,7 @@ + struct it87_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + data->sensor &= ~(1 << nr); + data->sensor &= ~(8 << nr); +@@ -450,11 +451,11 @@ + else if (val == 2) + data->sensor |= 8 << nr; + else if (val != 0) { +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define show_sensor_offset(offset) \ +@@ -524,7 +525,7 @@ + int val = simple_strtol(buf, NULL, 10); + u8 reg = it87_read_value(client, IT87_REG_FAN_DIV); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + switch (nr) { + case 0: data->fan_div[nr] = reg & 0x07; break; + case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; +@@ -533,7 +534,7 @@ + + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); + it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, +@@ -548,7 +549,7 @@ + int i, min[3]; + u8 old; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + old = it87_read_value(client, IT87_REG_FAN_DIV); + + for (i = 0; i < 3; i++) +@@ -576,7 +577,7 @@ + data->fan_min[i]=FAN_TO_REG(min[i], DIV_FROM_REG(data->fan_div[i])); + it87_write_value(client, IT87_REG_FAN_MIN(i), data->fan_min[i]); + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_pwm_enable(struct device *dev, +@@ -589,7 +590,7 @@ + struct it87_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (val == 0) { + int tmp; +@@ -606,11 +607,11 @@ + /* set saved pwm value, clear FAN_CTLX PWM mode bit */ + it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); + } else { +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, +@@ -626,11 +627,11 @@ + if (val < 0 || val > 255) + return -EINVAL; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->manual_pwm_ctl[nr] = val; + if (data->fan_main_ctrl & (1 << nr)) + it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -696,17 +697,6 @@ + #define device_create_file_vid(client) \ + device_create_file(&client->dev, &dev_attr_cpu0_vid) + +-/* This function is called when: +- * it87_driver is inserted (when this module is loaded), for each +- available adapter +- * when a new adapter is inserted (and it87_driver is still present) */ +-static int it87_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, it87_detect); +-} +- + static int it87_isa_attach_adapter(struct i2c_adapter *adapter) + { + return it87_detect(adapter, isa_address, -1); +@@ -776,7 +766,7 @@ + + new_client = &data->client; + if (is_isa) +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; +@@ -823,7 +813,7 @@ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->type = kind; + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -950,10 +940,10 @@ + + int res; + if (i2c_is_isa_client(client)) { +- down(&data->lock); ++ mutex_lock(&data->lock); + outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); + res = inb_p(client->addr + IT87_DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + return res; + } else + return i2c_smbus_read_byte_data(client, reg); +@@ -969,10 +959,10 @@ + struct it87_data *data = i2c_get_clientdata(client); + + if (i2c_is_isa_client(client)) { +- down(&data->lock); ++ mutex_lock(&data->lock); + outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); + outb_p(value, client->addr + IT87_DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + return 0; + } else + return i2c_smbus_write_byte_data(client, reg, value); +@@ -1098,7 +1088,7 @@ + struct it87_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -1160,7 +1150,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm63.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm63.c 2006-03-22 17:06:16.000000000 +0100 +@@ -45,6 +45,7 @@ + #include <linux/hwmon-sysfs.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* + * Addresses to scan +@@ -126,7 +127,6 @@ + * Functions declaration + */ + +-static int lm63_attach_adapter(struct i2c_adapter *adapter); + static int lm63_detach_client(struct i2c_client *client); + + static struct lm63_data *lm63_update_device(struct device *dev); +@@ -142,7 +142,9 @@ + .driver = { + .name = "lm63", + }, +- .attach_adapter = lm63_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm63_detect, + .detach_client = lm63_detach_client, + }; + +@@ -153,7 +155,7 @@ + struct lm63_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -192,13 +194,13 @@ + struct lm63_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan[1] = FAN_TO_REG(val); + i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB, + data->fan[1] & 0xFF); + i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB, + data->fan[1] >> 8); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -222,12 +224,12 @@ + return -EPERM; + + val = simple_strtoul(buf, NULL, 10); +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm1_value = val <= 0 ? 0 : + val >= 255 ? 2 * data->pwm1_freq : + (val * data->pwm1_freq * 2 + 127) / 255; + i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -253,10 +255,10 @@ + struct lm63_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp8[1] = TEMP8_TO_REG(val); + i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -284,13 +286,13 @@ + long val = simple_strtol(buf, NULL, 10); + int nr = attr->index; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp11[nr] = TEMP11_TO_REG(val); + i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], + data->temp11[nr] >> 8); + i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], + data->temp11[nr] & 0xff); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -314,11 +316,11 @@ + long val = simple_strtol(buf, NULL, 10); + long hyst; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + hyst = TEMP8_FROM_REG(data->temp8[2]) - val; + i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, + HYST_TO_REG(hyst)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -329,9 +331,19 @@ + return sprintf(buf, "%u\n", data->alarms); + } + ++static ssize_t show_alarm(struct device *dev, struct device_attribute *devattr, ++ char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct lm63_data *data = lm63_update_device(dev); ++ ++ return sprintf(buf, "%u\n", (data->alarms >> attr->index) & 1); ++} ++ + static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); + static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, + set_fan, 1); ++static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); + + static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1); + static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); +@@ -339,13 +351,18 @@ + static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0); + static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, + set_temp8, 1); ++static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); + + static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); ++static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2); + static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 1); ++static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); + static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 2); ++static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); + static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2); ++static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); + static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, + set_temp2_crit_hyst); + +@@ -355,13 +372,6 @@ + * Real code + */ + +-static int lm63_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm63_detect); +-} +- + /* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. +@@ -427,7 +437,7 @@ + + strlcpy(new_client->name, "lm63", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -448,6 +458,8 @@ + &sensor_dev_attr_fan1_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_min.dev_attr); ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_fan1_min_alarm.dev_attr); + } + device_create_file(&new_client->dev, &dev_attr_pwm1); + device_create_file(&new_client->dev, &dev_attr_pwm1_enable); +@@ -456,13 +468,23 @@ + device_create_file(&new_client->dev, + &sensor_dev_attr_temp2_input.dev_attr); + device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp2_input_fault.dev_attr); ++ device_create_file(&new_client->dev, + &sensor_dev_attr_temp2_min.dev_attr); + device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp2_min_alarm.dev_attr); ++ device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_max.dev_attr); + device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp1_max_alarm.dev_attr); ++ device_create_file(&new_client->dev, + &sensor_dev_attr_temp2_max.dev_attr); + device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp2_max_alarm.dev_attr); ++ device_create_file(&new_client->dev, + &sensor_dev_attr_temp2_crit.dev_attr); ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp2_crit_alarm.dev_attr); + device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst); + device_create_file(&new_client->dev, &dev_attr_alarms); + +@@ -530,7 +552,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct lm63_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + if (data->config & 0x04) { /* tachometer enabled */ +@@ -582,7 +604,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm75.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm75.c 2006-03-22 17:06:16.000000000 +0100 +@@ -25,6 +25,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include "lm75.h" + + +@@ -47,7 +48,7 @@ + struct lm75_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + u16 temp_input; /* Register values */ +@@ -55,7 +56,6 @@ + u16 temp_hyst; + }; + +-static int lm75_attach_adapter(struct i2c_adapter *adapter); + static int lm75_detect(struct i2c_adapter *adapter, int address, int kind); + static void lm75_init_client(struct i2c_client *client); + static int lm75_detach_client(struct i2c_client *client); +@@ -70,7 +70,9 @@ + .name = "lm75", + }, + .id = I2C_DRIVERID_LM75, +- .attach_adapter = lm75_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm75_detect, + .detach_client = lm75_detach_client, + }; + +@@ -91,10 +93,10 @@ + struct lm75_data *data = i2c_get_clientdata(client); \ + int temp = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = LM75_TEMP_TO_REG(temp); \ + lm75_write_value(client, reg, data->value); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + set(temp_max, LM75_REG_TEMP_OS); +@@ -104,13 +106,6 @@ + static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); + static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); + +-static int lm75_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm75_detect); +-} +- + /* This function is called by i2c_probe */ + static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) + { +@@ -188,7 +183,7 @@ + /* Fill in the remaining client fields and put it into the global list */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -264,7 +259,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct lm75_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -277,7 +272,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm77.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm77.c 2006-03-22 17:06:16.000000000 +0100 +@@ -32,6 +32,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; +@@ -51,7 +52,7 @@ + struct lm77_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + int temp_input; /* Temperatures */ +@@ -62,7 +63,6 @@ + u8 alarms; + }; + +-static int lm77_attach_adapter(struct i2c_adapter *adapter); + static int lm77_detect(struct i2c_adapter *adapter, int address, int kind); + static void lm77_init_client(struct i2c_client *client); + static int lm77_detach_client(struct i2c_client *client); +@@ -77,7 +77,9 @@ + .driver = { + .name = "lm77", + }, +- .attach_adapter = lm77_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm77_detect, + .detach_client = lm77_detach_client, + }; + +@@ -139,10 +141,10 @@ + struct lm77_data *data = i2c_get_clientdata(client); \ + long val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = val; \ + lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value)); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + +@@ -157,11 +159,11 @@ + struct lm77_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_hyst = data->temp_crit - val; + lm77_write_value(client, LM77_REG_TEMP_HYST, + LM77_TEMP_TO_REG(data->temp_hyst)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -173,7 +175,7 @@ + long val = simple_strtoul(buf, NULL, 10); + int oldcrithyst; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + oldcrithyst = data->temp_crit - data->temp_hyst; + data->temp_crit = val; + data->temp_hyst = data->temp_crit - oldcrithyst; +@@ -181,7 +183,7 @@ + LM77_TEMP_TO_REG(data->temp_crit)); + lm77_write_value(client, LM77_REG_TEMP_HYST, + LM77_TEMP_TO_REG(data->temp_hyst)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -204,13 +206,6 @@ + static DEVICE_ATTR(alarms, S_IRUGO, + show_alarms, NULL); + +-static int lm77_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm77_detect); +-} +- + /* This function is called by i2c_probe */ + static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) + { +@@ -306,7 +301,7 @@ + /* Fill in the remaining client fields and put it into the global list */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -380,7 +375,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct lm77_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -406,7 +401,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm78.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm78.c 2006-03-22 17:06:16.000000000 +0100 +@@ -27,6 +27,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + /* Addresses to scan */ +@@ -131,10 +132,10 @@ + struct lm78_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -152,13 +153,12 @@ + }; + + +-static int lm78_attach_adapter(struct i2c_adapter *adapter); + static int lm78_isa_attach_adapter(struct i2c_adapter *adapter); + static int lm78_detect(struct i2c_adapter *adapter, int address, int kind); + static int lm78_detach_client(struct i2c_client *client); + +-static int lm78_read_value(struct i2c_client *client, u8 register); +-static int lm78_write_value(struct i2c_client *client, u8 register, u8 value); ++static int lm78_read_value(struct i2c_client *client, u8 reg); ++static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value); + static struct lm78_data *lm78_update_device(struct device *dev); + static void lm78_init_client(struct i2c_client *client); + +@@ -168,7 +168,9 @@ + .name = "lm78", + }, + .id = I2C_DRIVERID_LM78, +- .attach_adapter = lm78_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm78_detect, + .detach_client = lm78_detach_client, + }; + +@@ -207,10 +209,10 @@ + struct lm78_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = IN_TO_REG(val); + lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -221,10 +223,10 @@ + struct lm78_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = IN_TO_REG(val); + lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -288,10 +290,10 @@ + struct lm78_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_over = TEMP_TO_REG(val); + lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -307,10 +309,10 @@ + struct lm78_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_hyst = TEMP_TO_REG(val); + lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -342,10 +344,10 @@ + struct lm78_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); + lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -368,7 +370,7 @@ + unsigned long min; + u8 reg; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + min = FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); + +@@ -380,7 +382,7 @@ + default: + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +@@ -398,7 +400,7 @@ + data->fan_min[nr] = + FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -464,17 +466,6 @@ + } + static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + +-/* This function is called when: +- * lm78_driver is inserted (when this module is loaded), for each +- available adapter +- * when a new adapter is inserted (and lm78_driver is still present) */ +-static int lm78_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm78_detect); +-} +- + static int lm78_isa_attach_adapter(struct i2c_adapter *adapter) + { + return lm78_detect(adapter, isa_address, -1); +@@ -548,7 +539,7 @@ + + new_client = &data->client; + if (is_isa) +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; +@@ -598,7 +589,7 @@ + data->type = kind; + + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -697,10 +688,10 @@ + int res; + if (i2c_is_isa_client(client)) { + struct lm78_data *data = i2c_get_clientdata(client); +- down(&data->lock); ++ mutex_lock(&data->lock); + outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); + res = inb_p(client->addr + LM78_DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + return res; + } else + return i2c_smbus_read_byte_data(client, reg); +@@ -717,10 +708,10 @@ + { + if (i2c_is_isa_client(client)) { + struct lm78_data *data = i2c_get_clientdata(client); +- down(&data->lock); ++ mutex_lock(&data->lock); + outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); + outb_p(value, client->addr + LM78_DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + return 0; + } else + return i2c_smbus_write_byte_data(client, reg, value); +@@ -742,7 +733,7 @@ + struct lm78_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -786,7 +777,7 @@ + data->fan_div[2] = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm80.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm80.c 2006-03-22 17:06:16.000000000 +0100 +@@ -28,6 +28,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, +@@ -108,7 +109,7 @@ + struct lm80_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -130,7 +131,6 @@ + * Functions declaration + */ + +-static int lm80_attach_adapter(struct i2c_adapter *adapter); + static int lm80_detect(struct i2c_adapter *adapter, int address, int kind); + static void lm80_init_client(struct i2c_client *client); + static int lm80_detach_client(struct i2c_client *client); +@@ -147,7 +147,9 @@ + .name = "lm80", + }, + .id = I2C_DRIVERID_LM80, +- .attach_adapter = lm80_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm80_detect, + .detach_client = lm80_detach_client, + }; + +@@ -191,10 +193,10 @@ + struct lm80_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock);\ ++ mutex_lock(&data->update_lock);\ + data->value = IN_TO_REG(val); \ + lm80_write_value(client, reg, data->value); \ +- up(&data->update_lock);\ ++ mutex_unlock(&data->update_lock);\ + return count; \ + } + set_in(min0, in_min[0], LM80_REG_IN_MIN(0)); +@@ -241,10 +243,10 @@ + struct lm80_data *data = i2c_get_clientdata(client); \ + long val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock);\ ++ mutex_lock(&data->update_lock);\ + data->value = FAN_TO_REG(val, DIV_FROM_REG(data->div)); \ + lm80_write_value(client, reg, data->value); \ +- up(&data->update_lock);\ ++ mutex_unlock(&data->update_lock);\ + return count; \ + } + set_fan(min1, fan_min[0], LM80_REG_FAN_MIN(1), fan_div[0]); +@@ -263,7 +265,7 @@ + u8 reg; + + /* Save fan_min */ +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + min = FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); + +@@ -275,7 +277,7 @@ + default: + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +@@ -286,7 +288,7 @@ + /* Restore fan_min */ + data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -325,10 +327,10 @@ + struct lm80_data *data = i2c_get_clientdata(client); \ + long val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = TEMP_LIMIT_TO_REG(val); \ + lm80_write_value(client, reg, data->value); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX); +@@ -386,13 +388,6 @@ + * Real code + */ + +-static int lm80_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm80_detect); +-} +- + static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) + { + int i, cur; +@@ -437,7 +432,7 @@ + /* Fill in the remaining client fields and put it into the global list */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -545,7 +540,7 @@ + struct lm80_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { + dev_dbg(&client->dev, "Starting lm80 update\n"); +@@ -585,7 +580,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm83.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm83.c 2006-03-22 17:06:16.000000000 +0100 +@@ -12,6 +12,10 @@ + * Since the datasheet omits to give the chip stepping code, I give it + * here: 0x03 (at register 0xff). + * ++ * Also supports the LM82 temp sensor, which is basically a stripped down ++ * model of the LM83. Datasheet is here: ++ * http://www.national.com/pf/LM/LM82.html ++ * + * 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 +@@ -35,6 +39,7 @@ + #include <linux/hwmon-sysfs.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* + * Addresses to scan +@@ -51,7 +56,7 @@ + * Insmod parameters + */ + +-I2C_CLIENT_INSMOD_1(lm83); ++I2C_CLIENT_INSMOD_2(lm83, lm82); + + /* + * The LM83 registers +@@ -114,7 +119,6 @@ + * Functions declaration + */ + +-static int lm83_attach_adapter(struct i2c_adapter *adapter); + static int lm83_detect(struct i2c_adapter *adapter, int address, int kind); + static int lm83_detach_client(struct i2c_client *client); + static struct lm83_data *lm83_update_device(struct device *dev); +@@ -128,7 +132,9 @@ + .name = "lm83", + }, + .id = I2C_DRIVERID_LM83, +- .attach_adapter = lm83_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm83_detect, + .detach_client = lm83_detach_client, + }; + +@@ -139,7 +145,7 @@ + struct lm83_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -171,11 +177,11 @@ + long val = simple_strtol(buf, NULL, 10); + int nr = attr->index; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp[nr] = TEMP_TO_REG(val); + i2c_smbus_write_byte_data(client, LM83_REG_W_HIGH[nr - 4], + data->temp[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -209,13 +215,6 @@ + * Real code + */ + +-static int lm83_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm83_detect); +-} +- + /* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. +@@ -282,6 +281,9 @@ + if (man_id == 0x01) { /* National Semiconductor */ + if (chip_id == 0x03) { + kind = lm83; ++ } else ++ if (chip_id == 0x01) { ++ kind = lm82; + } + } + +@@ -295,12 +297,15 @@ + + if (kind == lm83) { + name = "lm83"; ++ } else ++ if (kind == lm82) { ++ name = "lm82"; + } + + /* We can fill in the remaining client fields */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -318,32 +323,46 @@ + goto exit_detach; + } + ++ /* ++ * The LM82 can only monitor one external diode which is ++ * at the same register as the LM83 temp3 entry - so we ++ * declare 1 and 3 common, and then 2 and 4 only for the LM83. ++ */ ++ + device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_input.dev_attr); + device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_input.dev_attr); +- device_create_file(&new_client->dev, + &sensor_dev_attr_temp3_input.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp4_input.dev_attr); ++ + device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_max.dev_attr); + device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_max.dev_attr); +- device_create_file(&new_client->dev, + &sensor_dev_attr_temp3_max.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp4_max.dev_attr); ++ + device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_crit.dev_attr); + device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_crit.dev_attr); +- device_create_file(&new_client->dev, + &sensor_dev_attr_temp3_crit.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp4_crit.dev_attr); ++ + device_create_file(&new_client->dev, &dev_attr_alarms); + ++ if (kind == lm83) { ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp2_input.dev_attr); ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp4_input.dev_attr); ++ ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp2_max.dev_attr); ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp4_max.dev_attr); ++ ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp2_crit.dev_attr); ++ device_create_file(&new_client->dev, ++ &sensor_dev_attr_temp4_crit.dev_attr); ++ } ++ + return 0; + + exit_detach: +@@ -373,7 +392,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct lm83_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + int nr; +@@ -393,7 +412,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm85.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm85.c 2006-03-22 17:06:16.000000000 +0100 +@@ -31,6 +31,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* Addresses to scan */ + static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +@@ -331,10 +332,10 @@ + struct lm85_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + int valid; /* !=0 if following fields are valid */ + unsigned long last_reading; /* In jiffies */ + unsigned long last_config; /* In jiffies */ +@@ -368,13 +369,12 @@ + struct lm85_zone zone[3]; + }; + +-static int lm85_attach_adapter(struct i2c_adapter *adapter); + static int lm85_detect(struct i2c_adapter *adapter, int address, + int kind); + static int lm85_detach_client(struct i2c_client *client); + +-static int lm85_read_value(struct i2c_client *client, u8 register); +-static int lm85_write_value(struct i2c_client *client, u8 register, int value); ++static int lm85_read_value(struct i2c_client *client, u8 reg); ++static int lm85_write_value(struct i2c_client *client, u8 reg, int value); + static struct lm85_data *lm85_update_device(struct device *dev); + static void lm85_init_client(struct i2c_client *client); + +@@ -384,7 +384,9 @@ + .name = "lm85", + }, + .id = I2C_DRIVERID_LM85, +- .attach_adapter = lm85_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm85_detect, + .detach_client = lm85_detach_client, + }; + +@@ -407,10 +409,10 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val); + lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -499,10 +501,10 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm[nr] = PWM_TO_REG(val); + lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr) +@@ -559,10 +561,10 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = INS_TO_REG(nr, val); + lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_in_max(struct device *dev, char *buf, int nr) +@@ -577,10 +579,10 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = INS_TO_REG(nr, val); + lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define show_in_reg(offset) \ +@@ -640,10 +642,10 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_min[nr] = TEMP_TO_REG(val); + lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_temp_max(struct device *dev, char *buf, int nr) +@@ -658,10 +660,10 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[nr] = TEMP_TO_REG(val); + lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define show_temp_reg(offset) \ +@@ -713,12 +715,12 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->autofan[nr].config = (data->autofan[nr].config & (~0xe0)) + | ZONE_TO_REG(val) ; + lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), + data->autofan[nr].config); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_pwm_auto_pwm_min(struct device *dev, char *buf, int nr) +@@ -733,11 +735,11 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->autofan[nr].min_pwm = PWM_TO_REG(val); + lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr), + data->autofan[nr].min_pwm); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, char *buf, int nr) +@@ -752,7 +754,7 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->autofan[nr].min_off = val; + lm85_write_value(client, LM85_REG_AFAN_SPIKE1, data->smooth[0] + | data->syncpwm3 +@@ -760,7 +762,7 @@ + | (data->autofan[1].min_off ? 0x40 : 0) + | (data->autofan[2].min_off ? 0x80 : 0) + ); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_pwm_auto_pwm_freq(struct device *dev, char *buf, int nr) +@@ -775,13 +777,13 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->autofan[nr].freq = FREQ_TO_REG(val); + lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), + (data->zone[nr].range << 4) + | data->autofan[nr].freq + ); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define pwm_auto(offset) \ +@@ -857,7 +859,7 @@ + int min; + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + min = TEMP_FROM_REG(data->zone[nr].limit); + data->zone[nr].off_desired = TEMP_TO_REG(val); + data->zone[nr].hyst = HYST_TO_REG(min - val); +@@ -871,7 +873,7 @@ + (data->zone[2].hyst << 4) + ); + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_temp_auto_temp_min(struct device *dev, char *buf, int nr) +@@ -886,7 +888,7 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->zone[nr].limit = TEMP_TO_REG(val); + lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr), + data->zone[nr].limit); +@@ -913,7 +915,7 @@ + (data->zone[2].hyst << 4) + ); + } +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_temp_auto_temp_max(struct device *dev, char *buf, int nr) +@@ -930,7 +932,7 @@ + int min; + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + min = TEMP_FROM_REG(data->zone[nr].limit); + data->zone[nr].max_desired = TEMP_TO_REG(val); + data->zone[nr].range = RANGE_TO_REG( +@@ -938,7 +940,7 @@ + lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), + ((data->zone[nr].range & 0x0f) << 4) + | (data->autofan[nr].freq & 0x07)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t show_temp_auto_temp_crit(struct device *dev, char *buf, int nr) +@@ -953,11 +955,11 @@ + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->zone[nr].critical = TEMP_TO_REG(val); + lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr), + data->zone[nr].critical); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define temp_auto(offset) \ +@@ -1017,13 +1019,6 @@ + temp_auto(2); + temp_auto(3); + +-static int lm85_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm85_detect); +-} +- + static int lm85_detect(struct i2c_adapter *adapter, int address, + int kind) + { +@@ -1149,7 +1144,7 @@ + /* Fill in the remaining client fields */ + data->type = kind; + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -1368,7 +1363,7 @@ + struct lm85_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if ( !data->valid || + time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL) ) { +@@ -1571,7 +1566,7 @@ + + data->valid = 1; + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm87.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm87.c 2006-03-22 17:06:16.000000000 +0100 +@@ -60,6 +60,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* + * Addresses to scan +@@ -150,7 +151,6 @@ + * Functions declaration + */ + +-static int lm87_attach_adapter(struct i2c_adapter *adapter); + static int lm87_detect(struct i2c_adapter *adapter, int address, int kind); + static void lm87_init_client(struct i2c_client *client); + static int lm87_detach_client(struct i2c_client *client); +@@ -165,7 +165,9 @@ + .name = "lm87", + }, + .id = I2C_DRIVERID_LM87, +- .attach_adapter = lm87_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm87_detect, + .detach_client = lm87_detach_client, + }; + +@@ -176,7 +178,7 @@ + struct lm87_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -253,11 +255,11 @@ + struct lm87_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]); + lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) : + LM87_REG_AIN_MIN(nr-6), data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + + static void set_in_max(struct device *dev, const char *buf, int nr) +@@ -266,11 +268,11 @@ + struct lm87_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]); + lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) : + LM87_REG_AIN_MAX(nr-6), data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + + #define set_in(offset) \ +@@ -327,10 +329,10 @@ + struct lm87_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_low[nr] = TEMP_TO_REG(val); + lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + + static void set_temp_high(struct device *dev, const char *buf, int nr) +@@ -339,10 +341,10 @@ + struct lm87_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_high[nr] = TEMP_TO_REG(val); + lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + + #define set_temp(offset) \ +@@ -411,11 +413,11 @@ + struct lm87_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val, + FAN_DIV_FROM_REG(data->fan_div[nr])); + lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + } + + /* Note: we save and restore the fan minimum here, because its value is +@@ -431,7 +433,7 @@ + unsigned long min; + u8 reg; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + min = FAN_FROM_REG(data->fan_min[nr], + FAN_DIV_FROM_REG(data->fan_div[nr])); + +@@ -441,7 +443,7 @@ + case 4: data->fan_div[nr] = 2; break; + case 8: data->fan_div[nr] = 3; break; + default: +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +@@ -459,7 +461,7 @@ + data->fan_min[nr] = FAN_TO_REG(min, val); + lm87_write_value(client, LM87_REG_FAN_MIN(nr), + data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -522,10 +524,10 @@ + struct lm87_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->aout = AOUT_TO_REG(val); + lm87_write_value(client, LM87_REG_AOUT, data->aout); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); +@@ -534,13 +536,6 @@ + * Real code + */ + +-static int lm87_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm87_detect); +-} +- + /* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. +@@ -589,7 +584,7 @@ + /* We can fill in the remaining client fields */ + strlcpy(new_client->name, "lm87", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -744,7 +739,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct lm87_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + int i, j; +@@ -813,7 +808,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm90.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm90.c 2006-03-22 17:06:16.000000000 +0100 +@@ -78,6 +78,7 @@ + #include <linux/hwmon-sysfs.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* + * Addresses to scan +@@ -174,7 +175,6 @@ + * Functions declaration + */ + +-static int lm90_attach_adapter(struct i2c_adapter *adapter); + static int lm90_detect(struct i2c_adapter *adapter, int address, + int kind); + static void lm90_init_client(struct i2c_client *client); +@@ -190,7 +190,9 @@ + .name = "lm90", + }, + .id = I2C_DRIVERID_LM90, +- .attach_adapter = lm90_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm90_detect, + .detach_client = lm90_detach_client, + }; + +@@ -201,7 +203,7 @@ + struct lm90_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + int kind; +@@ -247,13 +249,13 @@ + long val = simple_strtol(buf, NULL, 10); + int nr = attr->index; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + if (data->kind == adt7461) + data->temp8[nr] = TEMP1_TO_REG_ADT7461(val); + else + data->temp8[nr] = TEMP1_TO_REG(val); + i2c_smbus_write_byte_data(client, reg[nr - 1], data->temp8[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -281,7 +283,7 @@ + long val = simple_strtol(buf, NULL, 10); + int nr = attr->index; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + if (data->kind == adt7461) + data->temp11[nr] = TEMP2_TO_REG_ADT7461(val); + else +@@ -290,7 +292,7 @@ + data->temp11[nr] >> 8); + i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], + data->temp11[nr] & 0xff); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -311,11 +313,11 @@ + long val = simple_strtol(buf, NULL, 10); + long hyst; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + hyst = TEMP1_FROM_REG(data->temp8[3]) - val; + i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, + HYST_TO_REG(hyst)); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -326,23 +328,42 @@ + return sprintf(buf, "%d\n", data->alarms); + } + +-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0); +-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); +-static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, +- set_temp8, 1); +-static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, +- set_temp11, 1); +-static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, +- set_temp8, 2); +-static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, +- set_temp11, 2); +-static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, +- set_temp8, 3); +-static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, +- set_temp8, 4); +-static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, +- set_temphyst, 3); +-static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); ++static ssize_t show_alarm(struct device *dev, struct device_attribute ++ *devattr, char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct lm90_data *data = lm90_update_device(dev); ++ ++ return sprintf(buf, "%d\n", (data->alarms >> attr->index) & 1); ++} ++ ++static struct sensor_device_attribute lm90_sensor_attr[] = { ++ SENSOR_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0), ++ SENSOR_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0), ++ SENSOR_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2), ++ SENSOR_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, ++ set_temp8, 1), ++ SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5), ++ SENSOR_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, ++ set_temp11, 1), ++ SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3), ++ SENSOR_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, ++ set_temp8, 2), ++ SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6), ++ SENSOR_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, ++ set_temp11, 2), ++ SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4), ++ SENSOR_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, ++ set_temp8, 3), ++ SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0), ++ SENSOR_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, ++ set_temp8, 4), ++ SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1), ++ SENSOR_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, ++ set_temphyst, 3), ++ SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4), ++}; ++ + static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + + /* pec used for ADM1032 only */ +@@ -413,13 +434,6 @@ + return 0; + } + +-static int lm90_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm90_detect); +-} +- + /* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. +@@ -428,7 +442,7 @@ + { + struct i2c_client *new_client; + struct lm90_data *data; +- int err = 0; ++ int i, err = 0; + const char *name = ""; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) +@@ -558,7 +572,7 @@ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; + data->kind = kind; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -574,26 +588,13 @@ + goto exit_detach; + } + +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp1_input.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_input.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp1_min.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_min.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp1_max.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_max.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp1_crit.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_crit.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp1_crit_hyst.dev_attr); +- device_create_file(&new_client->dev, +- &sensor_dev_attr_temp2_crit_hyst.dev_attr); ++ for (i = 0; i < ARRAY_SIZE(lm90_sensor_attr); i++) { ++ err = device_create_file(&new_client->dev, ++ &lm90_sensor_attr[i].dev_attr); ++ if (err) ++ goto exit_class; ++ } ++ + device_create_file(&new_client->dev, &dev_attr_alarms); + + if (new_client->flags & I2C_CLIENT_PEC) +@@ -601,6 +602,9 @@ + + return 0; + ++exit_class: ++ dev_err(&new_client->dev, "Sysfs interface creation failed\n"); ++ hwmon_device_unregister(data->class_dev); + exit_detach: + i2c_detach_client(new_client); + exit_free: +@@ -646,7 +650,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct lm90_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + u8 oldh, newh, l; +@@ -692,7 +696,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/lm92.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/lm92.c 2006-03-22 17:06:16.000000000 +0100 +@@ -46,6 +46,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* The LM92 and MAX6635 have 2 two-state pins for address selection, + resulting in 4 possible addresses. */ +@@ -96,7 +97,7 @@ + struct lm92_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -114,7 +115,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct lm92_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) + || !data->valid) { +@@ -134,7 +135,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +@@ -158,10 +159,10 @@ + struct lm92_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = TEMP_TO_REG(val); \ + i2c_smbus_write_word_data(client, reg, swab16(data->value)); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + set_temp(temp1_crit, LM92_REG_TEMP_CRIT); +@@ -194,11 +195,11 @@ + struct lm92_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val; + i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST, + swab16(TEMP_TO_REG(data->temp1_hyst))); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -348,7 +349,7 @@ + /* Fill in the remaining client fields */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the i2c subsystem a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -383,13 +384,6 @@ + return err; + } + +-static int lm92_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, lm92_detect); +-} +- + static int lm92_detach_client(struct i2c_client *client) + { + struct lm92_data *data = i2c_get_clientdata(client); +@@ -414,7 +408,9 @@ + .name = "lm92", + }, + .id = I2C_DRIVERID_LM92, +- .attach_adapter = lm92_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = lm92_detect, + .detach_client = lm92_detach_client, + }; + +--- linux-2.6.16.orig/drivers/hwmon/max1619.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/max1619.c 2006-03-22 17:06:16.000000000 +0100 +@@ -33,6 +33,7 @@ + #include <linux/i2c.h> + #include <linux/hwmon.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, + 0x29, 0x2a, 0x2b, +@@ -78,7 +79,6 @@ + * Functions declaration + */ + +-static int max1619_attach_adapter(struct i2c_adapter *adapter); + static int max1619_detect(struct i2c_adapter *adapter, int address, + int kind); + static void max1619_init_client(struct i2c_client *client); +@@ -93,7 +93,9 @@ + .driver = { + .name = "max1619", + }, +- .attach_adapter = max1619_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = max1619_detect, + .detach_client = max1619_detach_client, + }; + +@@ -104,7 +106,7 @@ + struct max1619_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -141,10 +143,10 @@ + struct max1619_data *data = i2c_get_clientdata(client); \ + long val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->value = TEMP_TO_REG(val); \ + i2c_smbus_write_byte_data(client, reg, data->value); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + +@@ -175,13 +177,6 @@ + * Real code + */ + +-static int max1619_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, max1619_detect); +-} +- + /* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. +@@ -262,7 +257,7 @@ + /* We can fill in the remaining client fields */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -330,7 +325,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct max1619_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + dev_dbg(&client->dev, "Updating max1619 data.\n"); +@@ -353,7 +348,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/sis5595.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/sis5595.c 2006-03-22 17:06:15.000000000 +0100 +@@ -60,6 +60,7 @@ + #include <linux/err.h> + #include <linux/init.h> + #include <linux/jiffies.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + +@@ -167,9 +168,9 @@ + struct sis5595_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + char maxins; /* == 3 if temp enabled, otherwise == 4 */ +@@ -192,8 +193,8 @@ + static int sis5595_detect(struct i2c_adapter *adapter); + static int sis5595_detach_client(struct i2c_client *client); + +-static int sis5595_read_value(struct i2c_client *client, u8 register); +-static int sis5595_write_value(struct i2c_client *client, u8 register, u8 value); ++static int sis5595_read_value(struct i2c_client *client, u8 reg); ++static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value); + static struct sis5595_data *sis5595_update_device(struct device *dev); + static void sis5595_init_client(struct i2c_client *client); + +@@ -231,10 +232,10 @@ + struct sis5595_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = IN_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -245,10 +246,10 @@ + struct sis5595_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = IN_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -310,10 +311,10 @@ + struct sis5595_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_over = TEMP_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -329,10 +330,10 @@ + struct sis5595_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_hyst = TEMP_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -364,10 +365,10 @@ + struct sis5595_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); + sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -390,7 +391,7 @@ + unsigned long val = simple_strtoul(buf, NULL, 10); + int reg; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + min = FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); + reg = sis5595_read_value(client, SIS5595_REG_FANDIV); +@@ -403,7 +404,7 @@ + default: + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +@@ -419,7 +420,7 @@ + data->fan_min[nr] = + FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -527,7 +528,7 @@ + + new_client = &data->client; + new_client->addr = address; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + i2c_set_clientdata(new_client, data); + new_client->adapter = adapter; + new_client->driver = &sis5595_driver; +@@ -548,7 +549,7 @@ + strlcpy(new_client->name, "sis5595", I2C_NAME_SIZE); + + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -635,20 +636,20 @@ + int res; + + struct sis5595_data *data = i2c_get_clientdata(client); +- down(&data->lock); ++ mutex_lock(&data->lock); + outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); + res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + return res; + } + + static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value) + { + struct sis5595_data *data = i2c_get_clientdata(client); +- down(&data->lock); ++ mutex_lock(&data->lock); + outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); + outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET); +- up(&data->lock); ++ mutex_unlock(&data->lock); + return 0; + } + +@@ -667,7 +668,7 @@ + struct sis5595_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -707,7 +708,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/smsc47b397.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/smsc47b397.c 2006-03-22 17:06:15.000000000 +0100 +@@ -35,6 +35,7 @@ + #include <linux/hwmon.h> + #include <linux/err.h> + #include <linux/init.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + /* Address is autodetected, there is no default value */ +@@ -92,9 +93,9 @@ + struct smsc47b397_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + +- struct semaphore update_lock; ++ struct mutex update_lock; + unsigned long last_updated; /* in jiffies */ + int valid; + +@@ -108,10 +109,10 @@ + struct smsc47b397_data *data = i2c_get_clientdata(client); + int res; + +- down(&data->lock); ++ mutex_lock(&data->lock); + outb(reg, client->addr); + res = inb_p(client->addr + 1); +- up(&data->lock); ++ mutex_unlock(&data->lock); + return res; + } + +@@ -121,7 +122,7 @@ + struct smsc47b397_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + dev_dbg(&client->dev, "starting device update...\n"); +@@ -144,7 +145,7 @@ + dev_dbg(&client->dev, "... device update complete\n"); + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +@@ -254,14 +255,14 @@ + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + new_client->adapter = adapter; + new_client->driver = &smsc47b397_driver; + new_client->flags = 0; + + strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE); + +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + if ((err = i2c_attach_client(new_client))) + goto error_free; +--- linux-2.6.16.orig/drivers/hwmon/smsc47m1.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/smsc47m1.c 2006-03-22 17:06:15.000000000 +0100 +@@ -34,6 +34,7 @@ + #include <linux/hwmon.h> + #include <linux/err.h> + #include <linux/init.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + /* Address is autodetected, there is no default value */ +@@ -102,9 +103,9 @@ + struct smsc47m1_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + +- struct semaphore update_lock; ++ struct mutex update_lock; + unsigned long last_updated; /* In jiffies */ + + u8 fan[2]; /* Register value */ +@@ -188,18 +189,18 @@ + struct smsc47m1_data *data = i2c_get_clientdata(client); + long rpmdiv, val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]); + + if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) { +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + + data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv); + smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), + data->fan_preload[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -220,14 +221,14 @@ + if (new_div == old_div) /* No change */ + return count; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + switch (new_div) { + case 1: data->fan_div[nr] = 0; break; + case 2: data->fan_div[nr] = 1; break; + case 4: data->fan_div[nr] = 2; break; + case 8: data->fan_div[nr] = 3; break; + default: +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +@@ -241,7 +242,7 @@ + data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191); + smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), + data->fan_preload[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -257,12 +258,12 @@ + if (val < 0 || val > 255) + return -EINVAL; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm[nr] &= 0x81; /* Preserve additional bits */ + data->pwm[nr] |= PWM_TO_REG(val); + smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), + data->pwm[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -278,12 +279,12 @@ + if (val != 0 && val != 1) + return -EINVAL; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm[nr] &= 0xFE; /* preserve the other bits */ + data->pwm[nr] |= !val; + smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), + data->pwm[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } +@@ -408,13 +409,13 @@ + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + new_client->adapter = adapter; + new_client->driver = &smsc47m1_driver; + new_client->flags = 0; + + strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE); +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* If no function is properly configured, there's no point in + actually registering the chip. */ +@@ -512,17 +513,17 @@ + { + int res; + +- down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); ++ mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); + res = inb_p(client->addr + reg); +- up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); ++ mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); + return res; + } + + static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value) + { +- down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); ++ mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); + outb_p(value, client->addr + reg); +- up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); ++ mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); + } + + static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, +@@ -531,7 +532,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct smsc47m1_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { + int i; +@@ -558,7 +559,7 @@ + data->last_updated = jiffies; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return data; + } + +--- linux-2.6.16.orig/drivers/hwmon/via686a.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/via686a.c 2006-03-22 17:06:15.000000000 +0100 +@@ -39,6 +39,7 @@ + #include <linux/hwmon.h> + #include <linux/err.h> + #include <linux/init.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + +@@ -296,7 +297,7 @@ + struct via686a_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -355,11 +356,11 @@ + struct via686a_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = IN_TO_REG(val, nr); + via686a_write_value(client, VIA686A_REG_IN_MIN(nr), + data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_in_max(struct device *dev, const char *buf, +@@ -368,11 +369,11 @@ + struct via686a_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = IN_TO_REG(val, nr); + via686a_write_value(client, VIA686A_REG_IN_MAX(nr), + data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define show_in_offset(offset) \ +@@ -432,11 +433,11 @@ + struct via686a_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_over[nr] = TEMP_TO_REG(val); + via686a_write_value(client, VIA686A_REG_TEMP_OVER[nr], + data->temp_over[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_temp_hyst(struct device *dev, const char *buf, +@@ -445,11 +446,11 @@ + struct via686a_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_hyst[nr] = TEMP_TO_REG(val); + via686a_write_value(client, VIA686A_REG_TEMP_HYST[nr], + data->temp_hyst[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + #define show_temp_offset(offset) \ +@@ -508,10 +509,10 @@ + struct via686a_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); + via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_fan_div(struct device *dev, const char *buf, +@@ -521,12 +522,12 @@ + int val = simple_strtol(buf, NULL, 10); + int old; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + old = via686a_read_value(client, VIA686A_REG_FANDIV); + data->fan_div[nr] = DIV_TO_REG(val); + old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); + via686a_write_value(client, VIA686A_REG_FANDIV, old); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -639,7 +640,7 @@ + strlcpy(new_client->name, client_name, I2C_NAME_SIZE); + + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) + goto exit_free; +@@ -733,7 +734,7 @@ + struct via686a_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -788,7 +789,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/vt8231.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/vt8231.c 2006-03-22 17:06:15.000000000 +0100 +@@ -35,6 +35,7 @@ + #include <linux/hwmon-sysfs.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + + static int force_addr; +@@ -148,7 +149,7 @@ + + struct vt8231_data { + struct i2c_client client; +- struct semaphore update_lock; ++ struct mutex update_lock; + struct class_device *class_dev; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ +@@ -223,10 +224,10 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); + vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -239,10 +240,10 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); + vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -281,11 +282,11 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, + 0, 255); + vt8231_write_value(client, regvoltmin[5], data->in_min[5]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -296,11 +297,11 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, + 0, 255); + vt8231_write_value(client, regvoltmax[5], data->in_max[5]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -351,10 +352,10 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); + vt8231_write_value(client, regtempmax[0], data->temp_max[0]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, +@@ -364,10 +365,10 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); + vt8231_write_value(client, regtempmin[0], data->temp_min[0]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -407,10 +408,10 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); + vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, +@@ -422,10 +423,10 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); + vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -520,10 +521,10 @@ + struct vt8231_data *data = i2c_get_clientdata(client); + int val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); + vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -539,7 +540,7 @@ + long min = FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + switch (val) { + case 1: data->fan_div[nr] = 0; break; + case 2: data->fan_div[nr] = 1; break; +@@ -548,7 +549,7 @@ + default: + dev_err(&client->dev, "fan_div value %ld not supported." + "Choose one of 1, 2, 4 or 8!\n", val); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +@@ -558,7 +559,7 @@ + + old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); + vt8231_write_value(client, VT8231_REG_FANDIV, old); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -660,7 +661,7 @@ + /* Fill in the remaining client fields and put into the global list */ + strlcpy(client->name, "vt8231", I2C_NAME_SIZE); + +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(client))) +@@ -745,7 +746,7 @@ + int i; + u16 low; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -804,7 +805,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/w83627ehf.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/w83627ehf.c 2006-03-22 17:06:16.000000000 +0100 +@@ -30,10 +30,7 @@ + Supports the following chips: + + Chip #vin #fan #pwm #temp chip_id man_id +- w83627ehf - 5 - 3 0x88 0x5ca3 +- +- This is a preliminary version of the driver, only supporting the +- fan and temperature inputs. The chip does much more than that. ++ w83627ehf 10 5 - 3 0x88 0x5ca3 + */ + + #include <linux/module.h> +@@ -42,7 +39,9 @@ + #include <linux/i2c.h> + #include <linux/i2c-isa.h> + #include <linux/hwmon.h> ++#include <linux/hwmon-sysfs.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + #include "lm75.h" + +@@ -119,6 +118,14 @@ + static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; + static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; + ++/* The W83627EHF registers for nr=7,8,9 are in bank 5 */ ++#define W83627EHF_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ ++ (0x554 + (((nr) - 7) * 2))) ++#define W83627EHF_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ ++ (0x555 + (((nr) - 7) * 2))) ++#define W83627EHF_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ ++ (0x550 + (nr) - 7)) ++ + #define W83627EHF_REG_TEMP1 0x27 + #define W83627EHF_REG_TEMP1_HYST 0x3a + #define W83627EHF_REG_TEMP1_OVER 0x39 +@@ -134,6 +141,10 @@ + #define W83627EHF_REG_DIODE 0x59 + #define W83627EHF_REG_SMI_OVT 0x4C + ++#define W83627EHF_REG_ALARM1 0x459 ++#define W83627EHF_REG_ALARM2 0x45A ++#define W83627EHF_REG_ALARM3 0x45B ++ + /* + * Conversions + */ +@@ -170,6 +181,20 @@ + return (temp + 500) / 1000; + } + ++/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */ ++ ++static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 }; ++ ++static inline long in_from_reg(u8 reg, u8 nr) ++{ ++ return reg * scale_in[nr]; ++} ++ ++static inline u8 in_to_reg(u32 val, u8 nr) ++{ ++ return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0, 255); ++} ++ + /* + * Data structures and manipulation thereof + */ +@@ -177,13 +202,16 @@ + struct w83627ehf_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + + /* Register values */ ++ u8 in[10]; /* Register value */ ++ u8 in_max[10]; /* Register value */ ++ u8 in_min[10]; /* Register value */ + u8 fan[5]; + u8 fan_min[5]; + u8 fan_div[5]; +@@ -194,6 +222,7 @@ + s16 temp[2]; + s16 temp_max[2]; + s16 temp_max_hyst[2]; ++ u32 alarms; + }; + + static inline int is_word_sized(u16 reg) +@@ -230,7 +259,7 @@ + struct w83627ehf_data *data = i2c_get_clientdata(client); + int res, word_sized = is_word_sized(reg); + +- down(&data->lock); ++ mutex_lock(&data->lock); + + w83627ehf_set_bank(client, reg); + outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); +@@ -242,7 +271,7 @@ + } + w83627ehf_reset_bank(client, reg); + +- up(&data->lock); ++ mutex_unlock(&data->lock); + + return res; + } +@@ -252,7 +281,7 @@ + struct w83627ehf_data *data = i2c_get_clientdata(client); + int word_sized = is_word_sized(reg); + +- down(&data->lock); ++ mutex_lock(&data->lock); + + w83627ehf_set_bank(client, reg); + outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); +@@ -264,7 +293,7 @@ + outb_p(value & 0xff, client->addr + DATA_REG_OFFSET); + w83627ehf_reset_bank(client, reg); + +- up(&data->lock); ++ mutex_unlock(&data->lock); + return 0; + } + +@@ -322,7 +351,7 @@ + struct w83627ehf_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) + || !data->valid) { +@@ -347,6 +376,16 @@ + data->fan_div[3] |= (i >> 5) & 0x04; + } + ++ /* Measured voltages and limits */ ++ for (i = 0; i < 10; i++) { ++ data->in[i] = w83627ehf_read_value(client, ++ W83627EHF_REG_IN(i)); ++ data->in_min[i] = w83627ehf_read_value(client, ++ W83627EHF_REG_IN_MIN(i)); ++ data->in_max[i] = w83627ehf_read_value(client, ++ W83627EHF_REG_IN_MAX(i)); ++ } ++ + /* Measured fan speeds and limits */ + for (i = 0; i < 5; i++) { + if (!(data->has_fan & (1 << i))) +@@ -393,23 +432,136 @@ + W83627EHF_REG_TEMP_HYST[i]); + } + ++ data->alarms = w83627ehf_read_value(client, ++ W83627EHF_REG_ALARM1) | ++ (w83627ehf_read_value(client, ++ W83627EHF_REG_ALARM2) << 8) | ++ (w83627ehf_read_value(client, ++ W83627EHF_REG_ALARM3) << 16); ++ + data->last_updated = jiffies; + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return data; + } + + /* + * Sysfs callback functions + */ ++#define show_in_reg(reg) \ ++static ssize_t \ ++show_##reg(struct device *dev, struct device_attribute *attr, \ ++ char *buf) \ ++{ \ ++ struct w83627ehf_data *data = w83627ehf_update_device(dev); \ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ ++ int nr = sensor_attr->index; \ ++ return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \ ++} ++show_in_reg(in) ++show_in_reg(in_min) ++show_in_reg(in_max) ++ ++#define store_in_reg(REG, reg) \ ++static ssize_t \ ++store_in_##reg (struct device *dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ struct i2c_client *client = to_i2c_client(dev); \ ++ struct w83627ehf_data *data = i2c_get_clientdata(client); \ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ ++ int nr = sensor_attr->index; \ ++ u32 val = simple_strtoul(buf, NULL, 10); \ ++ \ ++ mutex_lock(&data->update_lock); \ ++ data->in_##reg[nr] = in_to_reg(val, nr); \ ++ w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ ++ data->in_##reg[nr]); \ ++ mutex_unlock(&data->update_lock); \ ++ return count; \ ++} ++ ++store_in_reg(MIN, min) ++store_in_reg(MAX, max) ++ ++static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct w83627ehf_data *data = w83627ehf_update_device(dev); ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ return sprintf(buf, "%u\n", (data->alarms >> nr) & 0x01); ++} ++ ++static struct sensor_device_attribute sda_in_input[] = { ++ SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), ++ SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), ++ SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), ++ SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), ++ SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), ++ SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), ++ SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), ++ SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), ++ SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), ++ SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9), ++}; ++ ++static struct sensor_device_attribute sda_in_alarm[] = { ++ SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0), ++ SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1), ++ SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2), ++ SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3), ++ SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8), ++ SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 21), ++ SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 20), ++ SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16), ++ SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17), ++ SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 19), ++}; ++ ++static struct sensor_device_attribute sda_in_min[] = { ++ SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), ++ SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), ++ SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), ++ SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), ++ SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), ++ SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), ++ SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), ++ SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), ++ SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), ++ SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9), ++}; ++ ++static struct sensor_device_attribute sda_in_max[] = { ++ SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), ++ SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), ++ SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), ++ SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), ++ SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), ++ SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), ++ SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), ++ SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), ++ SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), ++ SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), ++}; ++ ++static void device_create_file_in(struct device *dev, int i) ++{ ++ device_create_file(dev, &sda_in_input[i].dev_attr); ++ device_create_file(dev, &sda_in_alarm[i].dev_attr); ++ device_create_file(dev, &sda_in_min[i].dev_attr); ++ device_create_file(dev, &sda_in_max[i].dev_attr); ++} + + #define show_fan_reg(reg) \ + static ssize_t \ +-show_##reg(struct device *dev, char *buf, int nr) \ ++show_##reg(struct device *dev, struct device_attribute *attr, \ ++ char *buf) \ + { \ + struct w83627ehf_data *data = w83627ehf_update_device(dev); \ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ ++ int nr = sensor_attr->index; \ + return sprintf(buf, "%d\n", \ + fan_from_reg(data->reg[nr], \ + div_from_reg(data->fan_div[nr]))); \ +@@ -418,23 +570,28 @@ + show_fan_reg(fan_min); + + static ssize_t +-show_fan_div(struct device *dev, char *buf, int nr) ++show_fan_div(struct device *dev, struct device_attribute *attr, ++ char *buf) + { + struct w83627ehf_data *data = w83627ehf_update_device(dev); +- return sprintf(buf, "%u\n", +- div_from_reg(data->fan_div[nr])); ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr])); + } + + static ssize_t +-store_fan_min(struct device *dev, const char *buf, size_t count, int nr) ++store_fan_min(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) + { + struct i2c_client *client = to_i2c_client(dev); + struct w83627ehf_data *data = i2c_get_clientdata(client); ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; + unsigned int val = simple_strtoul(buf, NULL, 10); + unsigned int reg; + u8 new_div; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + if (!val) { + /* No min limit, alarm disabled */ + data->fan_min[nr] = 255; +@@ -482,63 +639,55 @@ + } + w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr], + data->fan_min[nr]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return count; + } + +-#define sysfs_fan_offset(offset) \ +-static ssize_t \ +-show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \ +- char *buf) \ +-{ \ +- return show_fan(dev, buf, offset-1); \ +-} \ +-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ +- show_reg_fan_##offset, NULL); ++static struct sensor_device_attribute sda_fan_input[] = { ++ SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), ++ SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), ++ SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), ++ SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), ++ SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), ++}; + +-#define sysfs_fan_min_offset(offset) \ +-static ssize_t \ +-show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ +- char *buf) \ +-{ \ +- return show_fan_min(dev, buf, offset-1); \ +-} \ +-static ssize_t \ +-store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ +- const char *buf, size_t count) \ +-{ \ +- return store_fan_min(dev, buf, count, offset-1); \ +-} \ +-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ +- show_reg_fan##offset##_min, \ +- store_reg_fan##offset##_min); ++static struct sensor_device_attribute sda_fan_alarm[] = { ++ SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6), ++ SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7), ++ SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 10), ++ SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 11), ++ SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 23), ++}; + +-#define sysfs_fan_div_offset(offset) \ +-static ssize_t \ +-show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \ +- char *buf) \ +-{ \ +- return show_fan_div(dev, buf, offset - 1); \ +-} \ +-static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ +- show_reg_fan##offset##_div, NULL); +- +-sysfs_fan_offset(1); +-sysfs_fan_min_offset(1); +-sysfs_fan_div_offset(1); +-sysfs_fan_offset(2); +-sysfs_fan_min_offset(2); +-sysfs_fan_div_offset(2); +-sysfs_fan_offset(3); +-sysfs_fan_min_offset(3); +-sysfs_fan_div_offset(3); +-sysfs_fan_offset(4); +-sysfs_fan_min_offset(4); +-sysfs_fan_div_offset(4); +-sysfs_fan_offset(5); +-sysfs_fan_min_offset(5); +-sysfs_fan_div_offset(5); ++static struct sensor_device_attribute sda_fan_min[] = { ++ SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, ++ store_fan_min, 0), ++ SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, ++ store_fan_min, 1), ++ SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, ++ store_fan_min, 2), ++ SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, ++ store_fan_min, 3), ++ SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, ++ store_fan_min, 4), ++}; ++ ++static struct sensor_device_attribute sda_fan_div[] = { ++ SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), ++ SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), ++ SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2), ++ SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3), ++ SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), ++}; ++ ++static void device_create_file_fan(struct device *dev, int i) ++{ ++ device_create_file(dev, &sda_fan_input[i].dev_attr); ++ device_create_file(dev, &sda_fan_alarm[i].dev_attr); ++ device_create_file(dev, &sda_fan_div[i].dev_attr); ++ device_create_file(dev, &sda_fan_min[i].dev_attr); ++} + + #define show_temp1_reg(reg) \ + static ssize_t \ +@@ -561,27 +710,24 @@ + struct w83627ehf_data *data = i2c_get_clientdata(client); \ + u32 val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->temp1_##reg = temp1_to_reg(val); \ + w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \ + data->temp1_##reg); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + store_temp1_reg(OVER, max); + store_temp1_reg(HYST, max_hyst); + +-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL); +-static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR, +- show_temp1_max, store_temp1_max); +-static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR, +- show_temp1_max_hyst, store_temp1_max_hyst); +- + #define show_temp_reg(reg) \ + static ssize_t \ +-show_##reg (struct device *dev, char *buf, int nr) \ ++show_##reg(struct device *dev, struct device_attribute *attr, \ ++ char *buf) \ + { \ + struct w83627ehf_data *data = w83627ehf_update_device(dev); \ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ ++ int nr = sensor_attr->index; \ + return sprintf(buf, "%d\n", \ + LM75_TEMP_FROM_REG(data->reg[nr])); \ + } +@@ -591,55 +737,45 @@ + + #define store_temp_reg(REG, reg) \ + static ssize_t \ +-store_##reg (struct device *dev, const char *buf, size_t count, int nr) \ ++store_##reg(struct device *dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ + { \ + struct i2c_client *client = to_i2c_client(dev); \ + struct w83627ehf_data *data = i2c_get_clientdata(client); \ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ ++ int nr = sensor_attr->index; \ + u32 val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->reg[nr] = LM75_TEMP_TO_REG(val); \ + w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \ + data->reg[nr]); \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + store_temp_reg(OVER, temp_max); + store_temp_reg(HYST, temp_max_hyst); + +-#define sysfs_temp_offset(offset) \ +-static ssize_t \ +-show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \ +- char *buf) \ +-{ \ +- return show_temp(dev, buf, offset - 2); \ +-} \ +-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ +- show_reg_temp##offset, NULL); +- +-#define sysfs_temp_reg_offset(reg, offset) \ +-static ssize_t \ +-show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \ +- char *buf) \ +-{ \ +- return show_temp_##reg(dev, buf, offset - 2); \ +-} \ +-static ssize_t \ +-store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \ +- const char *buf, size_t count) \ +-{ \ +- return store_temp_##reg(dev, buf, count, offset - 2); \ +-} \ +-static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \ +- show_reg_temp##offset##_##reg, \ +- store_reg_temp##offset##_##reg); +- +-sysfs_temp_offset(2); +-sysfs_temp_reg_offset(max, 2); +-sysfs_temp_reg_offset(max_hyst, 2); +-sysfs_temp_offset(3); +-sysfs_temp_reg_offset(max, 3); +-sysfs_temp_reg_offset(max_hyst, 3); ++static struct sensor_device_attribute sda_temp[] = { ++ SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), ++ SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), ++ SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1), ++ SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max, ++ store_temp1_max, 0), ++ SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max, ++ store_temp_max, 0), ++ SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max, ++ store_temp_max, 1), ++ SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst, ++ store_temp1_max_hyst, 0), ++ SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, ++ store_temp_max_hyst, 0), ++ SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, ++ store_temp_max_hyst, 1), ++ SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), ++ SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), ++ SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), ++}; + + /* + * Driver and client management +@@ -673,6 +809,7 @@ + { + struct i2c_client *client; + struct w83627ehf_data *data; ++ struct device *dev; + int i, err = 0; + + if (!request_region(address + REGION_OFFSET, REGION_LENGTH, +@@ -689,14 +826,15 @@ + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = address; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + client->adapter = adapter; + client->driver = &w83627ehf_driver; + client->flags = 0; ++ dev = &client->dev; + + strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the i2c layer a new client has arrived */ + if ((err = i2c_attach_client(client))) +@@ -720,42 +858,21 @@ + data->has_fan |= (1 << 4); + + /* Register sysfs hooks */ +- data->class_dev = hwmon_device_register(&client->dev); ++ data->class_dev = hwmon_device_register(dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_detach; + } + +- device_create_file(&client->dev, &dev_attr_fan1_input); +- device_create_file(&client->dev, &dev_attr_fan1_min); +- device_create_file(&client->dev, &dev_attr_fan1_div); +- device_create_file(&client->dev, &dev_attr_fan2_input); +- device_create_file(&client->dev, &dev_attr_fan2_min); +- device_create_file(&client->dev, &dev_attr_fan2_div); +- device_create_file(&client->dev, &dev_attr_fan3_input); +- device_create_file(&client->dev, &dev_attr_fan3_min); +- device_create_file(&client->dev, &dev_attr_fan3_div); +- +- if (data->has_fan & (1 << 3)) { +- device_create_file(&client->dev, &dev_attr_fan4_input); +- device_create_file(&client->dev, &dev_attr_fan4_min); +- device_create_file(&client->dev, &dev_attr_fan4_div); +- } +- if (data->has_fan & (1 << 4)) { +- device_create_file(&client->dev, &dev_attr_fan5_input); +- device_create_file(&client->dev, &dev_attr_fan5_min); +- device_create_file(&client->dev, &dev_attr_fan5_div); +- } +- +- device_create_file(&client->dev, &dev_attr_temp1_input); +- device_create_file(&client->dev, &dev_attr_temp1_max); +- device_create_file(&client->dev, &dev_attr_temp1_max_hyst); +- device_create_file(&client->dev, &dev_attr_temp2_input); +- device_create_file(&client->dev, &dev_attr_temp2_max); +- device_create_file(&client->dev, &dev_attr_temp2_max_hyst); +- device_create_file(&client->dev, &dev_attr_temp3_input); +- device_create_file(&client->dev, &dev_attr_temp3_max); +- device_create_file(&client->dev, &dev_attr_temp3_max_hyst); ++ for (i = 0; i < 10; i++) ++ device_create_file_in(dev, i); ++ ++ for (i = 0; i < 5; i++) { ++ if (data->has_fan & (1 << i)) ++ device_create_file_fan(dev, i); ++ } ++ for (i = 0; i < ARRAY_SIZE(sda_temp); i++) ++ device_create_file(dev, &sda_temp[i].dev_attr); + + return 0; + +--- linux-2.6.16.orig/drivers/hwmon/w83627hf.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/w83627hf.c 2006-03-22 17:06:21.000000000 +0100 +@@ -28,6 +28,7 @@ + w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) + w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) + w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) ++ w83687thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) + w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) + + For other winbond chips, and for i2c support in the above chips, +@@ -45,7 +46,9 @@ + #include <linux/i2c-isa.h> + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> ++#include <linux/hwmon-sysfs.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + #include "lm75.h" + +@@ -62,7 +65,7 @@ + static unsigned short address; + + /* Insmod parameters */ +-enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf }; ++enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf, w83687thf }; + + static int reset; + module_param(reset, bool, 0); +@@ -100,6 +103,10 @@ + #define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ + #define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ + ++#define W83687THF_VID_EN 0x29 /* w83687thf only */ ++#define W83687THF_VID_CFG 0xF0 /* w83687thf only */ ++#define W83687THF_VID_DATA 0xF1 /* w83687thf only */ ++ + static inline void + superio_outb(int reg, int val) + { +@@ -138,6 +145,7 @@ + #define W627THF_DEVID 0x82 + #define W697_DEVID 0x60 + #define W637_DEVID 0x70 ++#define W687THF_DEVID 0x85 + #define WINB_ACT_REG 0x30 + #define WINB_BASE_REG 0x60 + /* Constants specified below */ +@@ -201,11 +209,11 @@ + #define W83627HF_REG_PWM1 0x5A + #define W83627HF_REG_PWM2 0x5B + +-#define W83627THF_REG_PWM1 0x01 /* 697HF and 637HF too */ +-#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */ +-#define W83627THF_REG_PWM3 0x11 /* 637HF too */ ++#define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ ++#define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ ++#define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ + +-#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */ ++#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF/687THF too */ + + static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; + static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, +@@ -285,10 +293,10 @@ + struct w83627hf_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -318,16 +326,15 @@ + Default = 3435. + Other Betas unimplemented */ + u8 vrm; +- u8 vrm_ovt; /* Register value, 627thf & 637hf only */ ++ u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ + }; + + + static int w83627hf_detect(struct i2c_adapter *adapter); + static int w83627hf_detach_client(struct i2c_client *client); + +-static int w83627hf_read_value(struct i2c_client *client, u16 register); +-static int w83627hf_write_value(struct i2c_client *client, u16 register, +- u16 value); ++static int w83627hf_read_value(struct i2c_client *client, u16 reg); ++static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value); + static struct w83627hf_data *w83627hf_update_device(struct device *dev); + static void w83627hf_init_client(struct i2c_client *client); + +@@ -360,12 +367,12 @@ + \ + val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->in_##reg[nr] = IN_TO_REG(val); \ + w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \ + data->in_##reg[nr]); \ + \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + store_in_reg(MIN, min) +@@ -413,7 +420,8 @@ + long in0; + + if ((data->vrm_ovt & 0x01) && +- (w83627thf == data->type || w83637hf == data->type)) ++ (w83627thf == data->type || w83637hf == data->type ++ || w83687thf == data->type)) + + /* use VRM9 calculation */ + in0 = (long)((reg * 488 + 70000 + 50) / 100); +@@ -451,10 +459,11 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if ((data->vrm_ovt & 0x01) && +- (w83627thf == data->type || w83637hf == data->type)) ++ (w83627thf == data->type || w83637hf == data->type ++ || w83687thf == data->type)) + + /* use VRM9 calculation */ + data->in_min[0] = +@@ -465,7 +474,7 @@ + data->in_min[0] = IN_TO_REG(val); + + w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -478,10 +487,11 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if ((data->vrm_ovt & 0x01) && +- (w83627thf == data->type || w83637hf == data->type)) ++ (w83627thf == data->type || w83637hf == data->type ++ || w83687thf == data->type)) + + /* use VRM9 calculation */ + data->in_max[0] = +@@ -492,7 +502,7 @@ + data->in_max[0] = IN_TO_REG(val); + + w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -507,6 +517,10 @@ + device_create_file(&client->dev, &dev_attr_in##offset##_input); \ + device_create_file(&client->dev, &dev_attr_in##offset##_min); \ + device_create_file(&client->dev, &dev_attr_in##offset##_max); \ ++device_create_file(&client->dev, \ ++ &sensor_dev_attr_in##offset##_alarm.dev_attr); \ ++device_create_file(&client->dev, \ ++ &sensor_dev_attr_in##offset##_beep.dev_attr); \ + } while (0) + + #define show_fan_reg(reg) \ +@@ -529,13 +543,13 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr - 1] = + FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); + w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr), + data->fan_min[nr - 1]); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -570,6 +584,10 @@ + do { \ + device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ + device_create_file(&client->dev, &dev_attr_fan##offset##_min); \ ++device_create_file(&client->dev, \ ++ &sensor_dev_attr_fan##offset##_alarm.dev_attr); \ ++device_create_file(&client->dev, \ ++ &sensor_dev_attr_fan##offset##_beep.dev_attr); \ + } while (0) + + #define show_temp_reg(reg) \ +@@ -597,7 +615,7 @@ + \ + val = simple_strtoul(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + \ + if (nr >= 2) { /* TEMP2 and TEMP3 */ \ + data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ +@@ -609,7 +627,7 @@ + data->temp_##reg); \ + } \ + \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + store_temp_reg(OVER, max); +@@ -651,6 +669,10 @@ + device_create_file(&client->dev, &dev_attr_temp##offset##_input); \ + device_create_file(&client->dev, &dev_attr_temp##offset##_max); \ + device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \ ++device_create_file(&client->dev, \ ++ &sensor_dev_attr_temp##offset##_alarm.dev_attr); \ ++device_create_file(&client->dev, \ ++ &sensor_dev_attr_temp##offset##_beep.dev_attr); \ + } while (0) + + static ssize_t +@@ -693,76 +715,152 @@ + } + static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); + #define device_create_file_alarms(client) \ +-device_create_file(&client->dev, &dev_attr_alarms) ++do { \ ++device_create_file(&client->dev, &dev_attr_alarms); \ ++device_create_file(&client->dev, &sensor_dev_attr_chassis_alarm.dev_attr); \ ++} while (0) + +-#define show_beep_reg(REG, reg) \ +-static ssize_t show_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \ +-{ \ +- struct w83627hf_data *data = w83627hf_update_device(dev); \ +- return sprintf(buf,"%ld\n", \ +- (long)BEEP_##REG##_FROM_REG(data->beep_##reg)); \ ++static ssize_t ++show_alarm_bit(struct device *dev, struct device_attribute *devattr, char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct w83627hf_data *data = w83627hf_update_device(dev); ++ ++ return sprintf(buf, "%u\n", (data->alarms >> attr->index) & 1); + } +-show_beep_reg(ENABLE, enable) +-show_beep_reg(MASK, mask) ++static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm_bit, NULL, 0); ++static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm_bit, NULL, 1); ++static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm_bit, NULL, 2); ++static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm_bit, NULL, 3); ++static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm_bit, NULL, 8); ++static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm_bit, NULL, 9); ++static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm_bit, NULL, 10); ++static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm_bit, NULL, 16); ++static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm_bit, NULL, 17); ++static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm_bit, NULL, 6); ++static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm_bit, NULL, 7); ++static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm_bit, NULL, 11); ++static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm_bit, NULL, 4); ++static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm_bit, NULL, 5); ++static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm_bit, NULL, 13); ++static SENSOR_DEVICE_ATTR(chassis_alarm, S_IRUGO, show_alarm_bit, NULL, 12); + +-#define BEEP_ENABLE 0 /* Store beep_enable */ +-#define BEEP_MASK 1 /* Store beep_mask */ ++static ssize_t show_beep_mask(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct w83627hf_data *data = w83627hf_update_device(dev); ++ return sprintf(buf, "%ld\n", ++ (long)BEEP_MASK_FROM_REG(data->beep_mask)); ++} + + static ssize_t +-store_beep_reg(struct device *dev, const char *buf, size_t count, +- int update_mask) ++store_beep_mask(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) + { + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); +- u32 val, val2; +- +- val = simple_strtoul(buf, NULL, 10); ++ u32 val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); +- +- if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ +- data->beep_mask = BEEP_MASK_TO_REG(val); +- w83627hf_write_value(client, W83781D_REG_BEEP_INTS1, +- data->beep_mask & 0xff); +- w83627hf_write_value(client, W83781D_REG_BEEP_INTS3, +- ((data->beep_mask) >> 16) & 0xff); +- val2 = (data->beep_mask >> 8) & 0x7f; +- } else { /* We are storing beep_enable */ +- val2 = +- w83627hf_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f; +- data->beep_enable = BEEP_ENABLE_TO_REG(val); +- } ++ mutex_lock(&data->update_lock); + ++ data->beep_mask = BEEP_MASK_TO_REG(val); ++ w83627hf_write_value(client, W83781D_REG_BEEP_INTS1, ++ data->beep_mask & 0xff); ++ w83627hf_write_value(client, W83781D_REG_BEEP_INTS3, ++ ((data->beep_mask) >> 16) & 0xff); + w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, +- val2 | data->beep_enable << 7); ++ ((data->beep_mask >> 8) & 0x7f) ++ | data->beep_enable << 7); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } +- +-#define sysfs_beep(REG, reg) \ +-static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \ +-{ \ +- return show_beep_##reg(dev, attr, buf); \ +-} \ +-static ssize_t \ +-store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +-{ \ +- return store_beep_reg(dev, buf, count, BEEP_##REG); \ +-} \ +-static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \ +- show_regs_beep_##reg, store_regs_beep_##reg); +- +-sysfs_beep(ENABLE, enable); +-sysfs_beep(MASK, mask); ++static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, \ ++ show_beep_mask, store_beep_mask); + + #define device_create_file_beep(client) \ + do { \ +-device_create_file(&client->dev, &dev_attr_beep_enable); \ ++device_create_file(&client->dev, &sensor_dev_attr_beep_enable.dev_attr); \ + device_create_file(&client->dev, &dev_attr_beep_mask); \ ++device_create_file(&client->dev, &sensor_dev_attr_chassis_beep.dev_attr); \ + } while (0) + + static ssize_t ++show_beep_bit(struct device *dev, struct device_attribute *devattr, char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct w83627hf_data *data = w83627hf_update_device(dev); ++ ++ return sprintf(buf, "%u\n", (data->beep_mask >> attr->index) & 1); ++} ++ ++static ssize_t ++store_beep_bit(struct device *dev, struct device_attribute *devattr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct w83627hf_data *data = i2c_get_clientdata(client); ++ u16 beepreg[3] = { W83781D_REG_BEEP_INTS1, W83781D_REG_BEEP_INTS2, ++ W83781D_REG_BEEP_INTS3 }; ++ u32 val; ++ u8 reg; ++ ++ val = simple_strtoul(buf, NULL, 10); ++ if (val != 0 && val != 1) ++ return -EINVAL; ++ ++ mutex_lock(&data->update_lock); ++ ++ reg = w83627hf_read_value(client, beepreg[attr->index >> 3]); ++ if (val) { ++ reg |= 1 << (attr->index & 0x07); ++ data->beep_mask |= 1 << attr->index; ++ } else { ++ reg &= ~(1 << (attr->index & 0x07)); ++ data->beep_mask &= ~(1 << attr->index); ++ } ++ w83627hf_write_value(client, beepreg[attr->index >> 3], reg); ++ ++ mutex_unlock(&data->update_lock); ++ return count; ++} ++ ++static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 0); ++static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 1); ++static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 2); ++static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 3); ++static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 8); ++static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 9); ++static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 10); ++static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 16); ++static SENSOR_DEVICE_ATTR(in8_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 17); ++static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 6); ++static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 7); ++static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 11); ++static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 4); ++static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 5); ++static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 13); ++static SENSOR_DEVICE_ATTR(chassis_beep, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 12); ++static SENSOR_DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, show_beep_bit, ++ store_beep_bit, 15); ++ ++static ssize_t + show_fan_div_reg(struct device *dev, char *buf, int nr) + { + struct w83627hf_data *data = w83627hf_update_device(dev); +@@ -783,7 +881,7 @@ + u8 reg; + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + /* Save fan_min */ + min = FAN_FROM_REG(data->fan_min[nr], +@@ -805,7 +903,7 @@ + data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -848,7 +946,7 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (data->type == w83627thf) { + /* bits 0-3 are reserved in 627THF */ +@@ -865,7 +963,7 @@ + data->pwm[nr - 1]); + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -907,7 +1005,7 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + switch (val) { + case 1: /* PII/Celeron diode */ +@@ -941,7 +1039,7 @@ + break; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -980,7 +1078,8 @@ + if(val != W627_DEVID && + val != W627THF_DEVID && + val != W697_DEVID && +- val != W637_DEVID) { ++ val != W637_DEVID && ++ val != W687THF_DEVID) { + superio_exit(); + return -ENODEV; + } +@@ -1034,6 +1133,8 @@ + kind = w83627thf; + else if(val == W637_DEVID) + kind = w83637hf; ++ else if (val == W687THF_DEVID) ++ kind = w83687thf; + else { + dev_info(&adapter->dev, + "Unsupported chip (dev_id=0x%02X).\n", val); +@@ -1057,7 +1158,7 @@ + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + new_client->adapter = adapter; + new_client->driver = &w83627hf_driver; + new_client->flags = 0; +@@ -1071,13 +1172,15 @@ + client_name = "w83697hf"; + } else if (kind == w83637hf) { + client_name = "w83637hf"; ++ } else if (kind == w83687thf) { ++ client_name = "w83687thf"; + } + + /* Fill in the remaining client fields and put into the global list */ + strlcpy(new_client->name, client_name, I2C_NAME_SIZE); + data->type = kind; + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -1106,7 +1209,7 @@ + device_create_file_in(new_client, 2); + device_create_file_in(new_client, 3); + device_create_file_in(new_client, 4); +- if (kind != w83627thf && kind != w83637hf) { ++ if (kind == w83627hf || kind == w83697hf) { + device_create_file_in(new_client, 5); + device_create_file_in(new_client, 6); + } +@@ -1139,7 +1242,7 @@ + + device_create_file_pwm(new_client, 1); + device_create_file_pwm(new_client, 2); +- if (kind == w83627thf || kind == w83637hf) ++ if (kind == w83627thf || kind == w83637hf || kind == w83687thf) + device_create_file_pwm(new_client, 3); + + device_create_file_sensor(new_client, 1); +@@ -1187,7 +1290,7 @@ + struct w83627hf_data *data = i2c_get_clientdata(client); + int res, word_sized; + +- down(&data->lock); ++ mutex_lock(&data->lock); + word_sized = (((reg & 0xff00) == 0x100) + || ((reg & 0xff00) == 0x200)) + && (((reg & 0x00ff) == 0x50) +@@ -1213,7 +1316,7 @@ + client->addr + W83781D_ADDR_REG_OFFSET); + outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); + } +- up(&data->lock); ++ mutex_unlock(&data->lock); + return res; + } + +@@ -1247,12 +1350,39 @@ + return res; + } + ++static int w83687thf_read_vid(struct i2c_client *client) ++{ ++ int res = 0xff; ++ ++ superio_enter(); ++ superio_select(W83627HF_LD_HWM); ++ ++ /* Make sure these GPIO pins are enabled */ ++ if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) { ++ dev_dbg(&client->dev, "VID disabled, no VID function\n"); ++ goto exit; ++ } ++ ++ /* Make sure the pins are configured for input */ ++ if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) { ++ dev_dbg(&client->dev, "VID configured as output, " ++ "no VID function\n"); ++ goto exit; ++ } ++ ++ res = superio_inb(W83687THF_VID_DATA) & 0x3f; ++ ++exit: ++ superio_exit(); ++ return res; ++} ++ + static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) + { + struct w83627hf_data *data = i2c_get_clientdata(client); + int word_sized; + +- down(&data->lock); ++ mutex_lock(&data->lock); + word_sized = (((reg & 0xff00) == 0x100) + || ((reg & 0xff00) == 0x200)) + && (((reg & 0x00ff) == 0x53) +@@ -1277,7 +1407,7 @@ + client->addr + W83781D_ADDR_REG_OFFSET); + outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); + } +- up(&data->lock); ++ mutex_unlock(&data->lock); + return 0; + } + +@@ -1324,10 +1454,13 @@ + data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); + } else if (w83627thf == data->type) { + data->vid = w83627thf_read_gpio5(client); ++ } else if (w83687thf == data->type) { ++ data->vid = w83687thf_read_vid(client); + } + + /* Read VRM & OVT Config only once */ +- if (w83627thf == data->type || w83637hf == data->type) { ++ if (w83627thf == data->type || w83637hf == data->type ++ || w83687thf == data->type) { + data->vrm_ovt = + w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); + } +@@ -1387,14 +1520,14 @@ + struct w83627hf_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + for (i = 0; i <= 8; i++) { + /* skip missing sensors */ + if (((data->type == w83697hf) && (i == 1)) || +- ((data->type == w83627thf || data->type == w83637hf) ++ ((data->type != w83627hf && data->type != w83697hf) + && (i == 5 || i == 6))) + continue; + data->in[i] = +@@ -1470,7 +1603,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/w83781d.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/w83781d.c 2006-03-22 17:06:16.000000000 +0100 +@@ -42,6 +42,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-vid.h> + #include <linux/err.h> ++#include <linux/mutex.h> + #include <asm/io.h> + #include "lm75.h" + +@@ -56,6 +57,10 @@ + I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " + "{bus, clientaddr, subclientaddr1, subclientaddr2}"); + ++static int reset; ++module_param(reset, bool, 0); ++MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); ++ + static int init = 1; + module_param(init, bool, 0); + MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); +@@ -226,10 +231,10 @@ + struct w83781d_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore lock; ++ struct mutex lock; + enum chips type; + +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + +@@ -262,14 +267,12 @@ + u8 vrm; + }; + +-static int w83781d_attach_adapter(struct i2c_adapter *adapter); + static int w83781d_isa_attach_adapter(struct i2c_adapter *adapter); + static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); + static int w83781d_detach_client(struct i2c_client *client); + +-static int w83781d_read_value(struct i2c_client *client, u16 register); +-static int w83781d_write_value(struct i2c_client *client, u16 register, +- u16 value); ++static int w83781d_read_value(struct i2c_client *client, u16 reg); ++static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value); + static struct w83781d_data *w83781d_update_device(struct device *dev); + static void w83781d_init_client(struct i2c_client *client); + +@@ -278,7 +281,9 @@ + .name = "w83781d", + }, + .id = I2C_DRIVERID_W83781D, +- .attach_adapter = w83781d_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = w83781d_detect, + .detach_client = w83781d_detach_client, + }; + +@@ -311,11 +316,11 @@ + \ + val = simple_strtoul(buf, NULL, 10) / 10; \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + data->in_##reg[nr] = IN_TO_REG(val); \ + w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ + \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + store_in_reg(MIN, min); +@@ -381,13 +386,13 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->fan_min[nr - 1] = + FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); + w83781d_write_value(client, W83781D_REG_FAN_MIN(nr), + data->fan_min[nr - 1]); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -446,7 +451,7 @@ + \ + val = simple_strtol(buf, NULL, 10); \ + \ +- down(&data->update_lock); \ ++ mutex_lock(&data->update_lock); \ + \ + if (nr >= 2) { /* TEMP2 and TEMP3 */ \ + data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ +@@ -458,7 +463,7 @@ + data->temp_##reg); \ + } \ + \ +- up(&data->update_lock); \ ++ mutex_unlock(&data->update_lock); \ + return count; \ + } + store_temp_reg(OVER, max); +@@ -571,7 +576,7 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ + data->beep_mask = BEEP_MASK_TO_REG(val, data->type); +@@ -592,7 +597,7 @@ + w83781d_write_value(client, W83781D_REG_BEEP_INTS2, + val2 | data->beep_enable << 7); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -637,7 +642,7 @@ + u8 reg; + unsigned long val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + /* Save fan_min */ + min = FAN_FROM_REG(data->fan_min[nr], +@@ -662,7 +667,7 @@ + data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -709,10 +714,10 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + data->pwm[nr - 1] = PWM_TO_REG(val); + w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]); +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -725,7 +730,7 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + switch (val) { + case 0: +@@ -742,11 +747,11 @@ + break; + + default: +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return -EINVAL; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -808,7 +813,7 @@ + + val = simple_strtoul(buf, NULL, 10); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + switch (val) { + case 1: /* PII/Celeron diode */ +@@ -841,7 +846,7 @@ + break; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + return count; + } + +@@ -865,18 +870,6 @@ + device_create_file(&client->dev, &dev_attr_temp##offset##_type); \ + } while (0) + +-/* This function is called when: +- * w83781d_driver is inserted (when this module is loaded), for each +- available adapter +- * when a new adapter is inserted (and w83781d_driver is still present) */ +-static int +-w83781d_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, w83781d_detect); +-} +- + static int + w83781d_isa_attach_adapter(struct i2c_adapter *adapter) + { +@@ -1073,7 +1066,7 @@ + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; +- init_MUTEX(&data->lock); ++ mutex_init(&data->lock); + new_client->adapter = adapter; + new_client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; + new_client->flags = 0; +@@ -1178,7 +1171,7 @@ + data->type = kind; + + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) +@@ -1325,7 +1318,7 @@ + int res, word_sized, bank; + struct i2c_client *cl; + +- down(&data->lock); ++ mutex_lock(&data->lock); + if (i2c_is_isa_client(client)) { + word_sized = (((reg & 0xff00) == 0x100) + || ((reg & 0xff00) == 0x200)) +@@ -1383,7 +1376,7 @@ + if (bank > 2) + i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); + } +- up(&data->lock); ++ mutex_unlock(&data->lock); + return res; + } + +@@ -1394,7 +1387,7 @@ + int word_sized, bank; + struct i2c_client *cl; + +- down(&data->lock); ++ mutex_lock(&data->lock); + if (i2c_is_isa_client(client)) { + word_sized = (((reg & 0xff00) == 0x100) + || ((reg & 0xff00) == 0x200)) +@@ -1447,7 +1440,7 @@ + if (bank > 2) + i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); + } +- up(&data->lock); ++ mutex_unlock(&data->lock); + return 0; + } + +@@ -1459,8 +1452,17 @@ + int type = data->type; + u8 tmp; + +- if (init && type != as99127f) { /* this resets registers we don't have ++ if (reset && type != as99127f) { /* this resets registers we don't have + documentation for on the as99127f */ ++ /* Resetting the chip has been the default for a long time, ++ but it causes the BIOS initializations (fan clock dividers, ++ thermal sensor types...) to be lost, so it is now optional. ++ It might even go away if nobody reports it as being useful, ++ as I see very little reason why this would be needed at ++ all. */ ++ dev_info(&client->dev, "If reset=1 solved a problem you were " ++ "having, please report!\n"); ++ + /* save these registers */ + i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); + p = w83781d_read_value(client, W83781D_REG_PWMCLK12); +@@ -1477,6 +1479,13 @@ + w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); + } + ++ /* Disable power-on abnormal beep, as advised by the datasheet. ++ Already done if reset=1. */ ++ if (init && !reset && type != as99127f) { ++ i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); ++ w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); ++ } ++ + data->vrm = vid_which_vrm(); + + if ((type != w83781d) && (type != as99127f)) { +@@ -1533,7 +1542,7 @@ + struct w83781d_data *data = i2c_get_clientdata(client); + int i; + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { +@@ -1641,7 +1650,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/drivers/hwmon/w83l785ts.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/w83l785ts.c 2006-03-22 17:06:16.000000000 +0100 +@@ -39,6 +39,7 @@ + #include <linux/hwmon.h> + #include <linux/hwmon-sysfs.h> + #include <linux/err.h> ++#include <linux/mutex.h> + + /* How many retries on register read error */ + #define MAX_RETRIES 5 +@@ -80,7 +81,6 @@ + * Functions declaration + */ + +-static int w83l785ts_attach_adapter(struct i2c_adapter *adapter); + static int w83l785ts_detect(struct i2c_adapter *adapter, int address, + int kind); + static int w83l785ts_detach_client(struct i2c_client *client); +@@ -96,7 +96,9 @@ + .name = "w83l785ts", + }, + .id = I2C_DRIVERID_W83L785TS, +- .attach_adapter = w83l785ts_attach_adapter, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = w83l785ts_detect, + .detach_client = w83l785ts_detach_client, + }; + +@@ -107,7 +109,7 @@ + struct w83l785ts_data { + struct i2c_client client; + struct class_device *class_dev; +- struct semaphore update_lock; ++ struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + +@@ -135,13 +137,6 @@ + * Real code + */ + +-static int w83l785ts_attach_adapter(struct i2c_adapter *adapter) +-{ +- if (!(adapter->class & I2C_CLASS_HWMON)) +- return 0; +- return i2c_probe(adapter, &addr_data, w83l785ts_detect); +-} +- + /* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. +@@ -221,7 +216,7 @@ + /* We can fill in the remaining client fields. */ + strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE); + data->valid = 0; +- init_MUTEX(&data->update_lock); ++ mutex_init(&data->update_lock); + + /* Default values in case the first read fails (unlikely). */ + data->temp[1] = data->temp[0] = 0; +@@ -299,7 +294,7 @@ + struct i2c_client *client = to_i2c_client(dev); + struct w83l785ts_data *data = i2c_get_clientdata(client); + +- down(&data->update_lock); ++ mutex_lock(&data->update_lock); + + if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) { + dev_dbg(&client->dev, "Updating w83l785ts data.\n"); +@@ -312,7 +307,7 @@ + data->valid = 1; + } + +- up(&data->update_lock); ++ mutex_unlock(&data->update_lock); + + return data; + } +--- linux-2.6.16.orig/Documentation/hwmon/w83627hf 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/Documentation/hwmon/w83627hf 2006-03-22 17:06:15.000000000 +0100 +@@ -18,6 +18,10 @@ + Prefix: 'w83637hf' + Addresses scanned: ISA address retrieved from Super I/O registers + Datasheet: http://www.winbond.com/PDF/sheet/w83637hf.pdf ++ * Winbond W83687THF ++ Prefix: 'w83687thf' ++ Addresses scanned: ISA address retrieved from Super I/O registers ++ Datasheet: Provided by Winbond on request + + Authors: + Frodo Looijaard <frodol@dds.nl>, +--- linux-2.6.16.orig/drivers/hwmon/Kconfig 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/Kconfig 2006-03-22 17:06:16.000000000 +0100 +@@ -236,11 +236,11 @@ + will be called lm80. + + config SENSORS_LM83 +- tristate "National Semiconductor LM83" ++ tristate "National Semiconductor LM83 and compatibles" + depends on HWMON && I2C + help + If you say yes here you get support for National Semiconductor +- LM83 sensor chips. ++ LM82 and LM83 sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm83. +@@ -333,11 +333,32 @@ + help + If you say yes here you get support for the integrated fan + monitoring and control capabilities of the SMSC LPC47B27x, +- LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips. ++ LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and ++ LPC47M997 chips. ++ ++ The temperature and voltage sensor features of the LPC47M192 ++ and LPC47M997 are supported by another driver, select also ++ "SMSC LPC47M192 and compatibles" below for those. + + This driver can also be built as a module. If so, the module + will be called smsc47m1. + ++config SENSORS_SMSC47M192 ++ tristate "SMSC LPC47M192 and compatibles" ++ depends on HWMON && I2C && EXPERIMENTAL ++ select HWMON_VID ++ help ++ If you say yes here you get support for the temperature and ++ voltage sensors of the SMSC LPC47M192 and LPC47M997 chips. ++ ++ The fan monitoring and control capabilities of these chips ++ are supported by another driver, select ++ "SMSC LPC47M10x and compatibles" above. You need both drivers ++ if you want fan control and voltage/temperature sensor support. ++ ++ This driver can also be built as a module. If so, the module ++ will be called smsc47m192. ++ + config SENSORS_SMSC47B397 + tristate "SMSC LPC47B397-NC" + depends on HWMON && I2C && EXPERIMENTAL +@@ -406,13 +427,14 @@ + will be called w83l785ts. + + config SENSORS_W83627HF +- tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF" +- depends on HWMON && I2C && EXPERIMENTAL ++ tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF" ++ depends on HWMON && I2C + select I2C_ISA + select HWMON_VID + help + If you say yes here you get support for the Winbond W836X7 series +- of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF ++ of sensor chips: the W83627HF, W83627THF, W83637HF, W83687THF and ++ W83697HF. + + This driver can also be built as a module. If so, the module + will be called w83627hf. +--- linux-2.6.16.orig/drivers/hwmon/hwmon-vid.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/hwmon-vid.c 2006-03-22 17:06:15.000000000 +0100 +@@ -54,6 +54,10 @@ + (IMVP-II). You can find more information in the datasheet of Max1718 + http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 + ++ The 13 specification corresponds to the Intel Pentium M series. There ++ doesn't seem to be any named specification for these. The conversion ++ tables are detailed directly in the various Pentium M datasheets: ++ http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm + */ + + /* vrm is the VRM/VRD document version multiplied by 10. +@@ -100,6 +104,8 @@ + case 17: /* Intel IMVP-II */ + return(val & 0x10 ? 975 - (val & 0xF) * 25 : + 1750 - val * 50); ++ case 13: ++ return(1708 - (val & 0x3f) * 16); + default: /* report 0 for unknown */ + printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n"); + return 0; +@@ -129,8 +135,9 @@ + static struct vrm_model vrm_models[] = { + {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ + {X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */ +- {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 85}, /* 0.13um too */ ++ {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ + {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ ++ {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ + {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ + {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */ + {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ +--- linux-2.6.16.orig/Documentation/hwmon/w83781d 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/Documentation/hwmon/w83781d 2006-03-22 17:06:15.000000000 +0100 +@@ -36,6 +36,11 @@ + Use 'init=0' to bypass initializing the chip. + Try this if your computer crashes when you load the module. + ++* reset int ++ (default 0) ++ The driver used to reset the chip on load, but does no more. Use ++ 'reset=1' to restore the old behavior. Report if you need to do this. ++ + force_subclients=bus,caddr,saddr,saddr + This is used to force the i2c addresses for subclients of + a certain chip. Typical usage is `force_subclients=0,0x2d,0x4a,0x4b' +@@ -123,6 +128,25 @@ + your computer speaker. It is possible to enable all beeping globally, + or only the beeping for some alarms. + ++Individual alarm and beep bits: ++ ++0x000001: in0 ++0x000002: in1 ++0x000004: in2 ++0x000008: in3 ++0x000010: temp1 ++0x000020: temp2 (+temp3 on W83781D) ++0x000040: fan1 ++0x000080: fan2 ++0x000100: in4 ++0x000200: in5 ++0x000400: in6 ++0x000800: fan3 ++0x001000: chassis ++0x002000: temp3 (W83782D and W83627HF only) ++0x010000: in7 (W83782D and W83627HF only) ++0x020000: in8 (W83782D and W83627HF only) ++ + If an alarm triggers, it will remain triggered until the hardware register + is read at least once. This means that the cause for the alarm may + already have disappeared! Note that in the current implementation, all +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-frodo.c 2006-03-22 17:06:09.000000000 +0100 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,85 +0,0 @@ +- +-/* +- * linux/drivers/i2c/i2c-frodo.c +- * +- * Author: Abraham van der Merwe <abraham@2d3d.co.za> +- * +- * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110 +- * Development board (Frodo). +- * +- * This source code 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 <linux/module.h> +-#include <linux/kernel.h> +-#include <linux/init.h> +-#include <linux/delay.h> +-#include <linux/i2c.h> +-#include <linux/i2c-algo-bit.h> +-#include <asm/hardware.h> +- +- +-static void frodo_setsda (void *data,int state) +-{ +- if (state) +- FRODO_CPLD_I2C |= FRODO_I2C_SDA_OUT; +- else +- FRODO_CPLD_I2C &= ~FRODO_I2C_SDA_OUT; +-} +- +-static void frodo_setscl (void *data,int state) +-{ +- if (state) +- FRODO_CPLD_I2C |= FRODO_I2C_SCL_OUT; +- else +- FRODO_CPLD_I2C &= ~FRODO_I2C_SCL_OUT; +-} +- +-static int frodo_getsda (void *data) +-{ +- return ((FRODO_CPLD_I2C & FRODO_I2C_SDA_IN) != 0); +-} +- +-static int frodo_getscl (void *data) +-{ +- return ((FRODO_CPLD_I2C & FRODO_I2C_SCL_IN) != 0); +-} +- +-static struct i2c_algo_bit_data bit_frodo_data = { +- .setsda = frodo_setsda, +- .setscl = frodo_setscl, +- .getsda = frodo_getsda, +- .getscl = frodo_getscl, +- .udelay = 80, +- .mdelay = 80, +- .timeout = HZ +-}; +- +-static struct i2c_adapter frodo_ops = { +- .owner = THIS_MODULE, +- .id = I2C_HW_B_FRODO, +- .algo_data = &bit_frodo_data, +- .dev = { +- .name = "Frodo adapter driver", +- }, +-}; +- +-static int __init i2c_frodo_init (void) +-{ +- return i2c_bit_add_bus(&frodo_ops); +-} +- +-static void __exit i2c_frodo_exit (void) +-{ +- i2c_bit_del_bus(&frodo_ops); +-} +- +-MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>"); +-MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo"); +-MODULE_LICENSE ("GPL"); +- +-module_init (i2c_frodo_init); +-module_exit (i2c_frodo_exit); +- +--- linux-2.6.16.orig/include/linux/i2c-id.h 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/include/linux/i2c-id.h 2006-03-22 17:06:15.000000000 +0100 +@@ -172,7 +172,6 @@ + #define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */ + #define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */ + #define I2C_HW_B_TSUNA 0x010012 /* DEC Tsunami chipset */ +-#define I2C_HW_B_FRODO 0x010013 /* 2d3D SA-1110 Development Board */ + #define I2C_HW_B_OMAHA 0x010014 /* Omaha I2C interface (ARM) */ + #define I2C_HW_B_GUIDE 0x010015 /* Guide bit-basher */ + #define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */ +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-ite.c 2006-03-22 17:06:09.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-ite.c 2006-03-22 17:06:15.000000000 +0100 +@@ -200,9 +200,7 @@ + .owner = THIS_MODULE, + .id = I2C_HW_I_IIC, + .algo_data = &iic_ite_data, +- .dev = { +- .name = "ITE IIC adapter", +- }, ++ .name = "ITE IIC adapter", + }; + + /* Called when the module is loaded. This function starts the +--- linux-2.6.16.orig/drivers/i2c/chips/isp1301_omap.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/chips/isp1301_omap.c 2006-03-22 17:06:15.000000000 +0100 +@@ -1635,8 +1635,6 @@ + .driver = { + .name = "isp1301_omap", + }, +- .id = 1301, /* FIXME "official", i2c-ids.h */ +- .class = I2C_CLASS_HWMON, + .attach_adapter = isp1301_scan_bus, + .detach_client = isp1301_detach_client, + }; +--- linux-2.6.16.orig/Documentation/i2c/busses/i2c-piix4 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/Documentation/i2c/busses/i2c-piix4 2006-03-22 17:06:16.000000000 +0100 +@@ -4,8 +4,10 @@ + * Intel 82371AB PIIX4 and PIIX4E + * Intel 82443MX (440MX) + Datasheet: Publicly available at the Intel website +- * ServerWorks OSB4, CSB5 and CSB6 southbridges ++ * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges + Datasheet: Only available via NDA from ServerWorks ++ * ATI IXP southbridges IXP200, IXP300, IXP400 ++ Datasheet: Not publicly available + * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge + Datasheet: Publicly available at the SMSC website http://www.smsc.com + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-piix4.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-piix4.c 2006-03-22 17:06:16.000000000 +0100 +@@ -22,7 +22,7 @@ + /* + Supports: + Intel PIIX4, 440MX +- Serverworks OSB4, CSB5, CSB6 ++ Serverworks OSB4, CSB5, CSB6, HT-1000 + SMSC Victory66 + + Note: we assume there can only be one device, with one SMBus interface. +@@ -406,19 +406,27 @@ + + static struct i2c_adapter piix4_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + + static struct pci_device_id piix4_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3), + .driver_data = 3 }, ++ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS), ++ .driver_data = 0 }, ++ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS), ++ .driver_data = 0 }, ++ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS), ++ .driver_data = 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4), + .driver_data = 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5), + .driver_data = 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6), + .driver_data = 0 }, ++ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB), ++ .driver_data = 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3), + .driver_data = 3 }, + { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3), +--- linux-2.6.16.orig/include/linux/pci_ids.h 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/include/linux/pci_ids.h 2006-03-22 17:06:16.000000000 +0100 +@@ -351,8 +351,11 @@ + #define PCI_DEVICE_ID_ATI_RS480 0x5950 + /* ATI IXP Chipset */ + #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 ++#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 ++#define PCI_DEVICE_ID_ATI_IXP300_SMBUS 0x4363 + #define PCI_DEVICE_ID_ATI_IXP300_IDE 0x4369 + #define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e ++#define PCI_DEVICE_ID_ATI_IXP400_SMBUS 0x4372 + #define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 + #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 + +@@ -1369,6 +1372,7 @@ + #define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 + #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 + #define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 ++#define PCI_DEVICE_ID_SERVERWORKS_HT1000SB 0x0205 + #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 + #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212 + #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-ixp4xx.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-ixp4xx.c 2006-03-22 17:06:16.000000000 +0100 +@@ -125,7 +125,9 @@ + drv_data->algo_data.mdelay = 10; + drv_data->algo_data.timeout = 100; + ++ drv_data->adapter.owner = THIS_MODULE; + drv_data->adapter.id = I2C_HW_B_IXP4XX; ++ drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DATA; + strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, + I2C_NAME_SIZE); + drv_data->adapter.algo_data = &drv_data->algo_data; +--- linux-2.6.16.orig/drivers/media/video/adv7170.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/adv7170.c 2006-03-22 17:06:15.000000000 +0100 +@@ -53,7 +53,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(x) (x)->name + +@@ -125,24 +124,21 @@ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ + struct adv7170 *encoder = i2c_get_clientdata(client); +- struct i2c_msg msg; + u8 block_data[32]; ++ int block_len; + +- msg.addr = client->addr; +- msg.flags = 0; + while (len >= 2) { +- msg.buf = (char *) block_data; +- msg.len = 0; +- block_data[msg.len++] = reg = data[0]; ++ block_len = 0; ++ block_data[block_len++] = reg = data[0]; + do { +- block_data[msg.len++] = ++ block_data[block_len++] = + encoder->reg[reg++] = data[1]; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && +- msg.len < 32); +- if ((ret = i2c_transfer(client->adapter, +- &msg, 1)) < 0) ++ block_len < 32); ++ if ((ret = i2c_master_send(client, block_data, ++ block_len)) < 0) + break; + } + } else { +--- linux-2.6.16.orig/drivers/media/video/adv7175.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/adv7175.c 2006-03-22 17:06:16.000000000 +0100 +@@ -49,7 +49,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(s) (s)->name + +@@ -68,8 +67,6 @@ + /* ----------------------------------------------------------------------- */ + + struct adv7175 { +- unsigned char reg[128]; +- + int norm; + int input; + int enable; +@@ -95,9 +92,6 @@ + u8 reg, + u8 value) + { +- struct adv7175 *encoder = i2c_get_clientdata(client); +- +- encoder->reg[reg] = value; + return i2c_smbus_write_byte_data(client, reg, value); + } + +@@ -120,25 +114,21 @@ + * the adapter understands raw I2C */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ +- struct adv7175 *encoder = i2c_get_clientdata(client); +- struct i2c_msg msg; + u8 block_data[32]; ++ int block_len; + +- msg.addr = client->addr; +- msg.flags = 0; + while (len >= 2) { +- msg.buf = (char *) block_data; +- msg.len = 0; +- block_data[msg.len++] = reg = data[0]; ++ block_len = 0; ++ block_data[block_len++] = reg = data[0]; + do { +- block_data[msg.len++] = +- encoder->reg[reg++] = data[1]; ++ block_data[block_len++] = data[1]; ++ reg++; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && +- msg.len < 32); +- if ((ret = i2c_transfer(client->adapter, +- &msg, 1)) < 0) ++ block_len < 32); ++ if ((ret = i2c_master_send(client, block_data, ++ block_len)) < 0) + break; + } + } else { +@@ -171,24 +161,6 @@ + adv7175_write(client, 0x05, 0x25); + } + +-#ifdef ENCODER_DUMP +-static void +-dump (struct i2c_client *client) +-{ +- struct adv7175 *encoder = i2c_get_clientdata(client); +- int i, j; +- +- printk(KERN_INFO "%s: registry dump\n", I2C_NAME(client)); +- for (i = 0; i < 182 / 8; i++) { +- printk("%s: 0x%02x -", I2C_NAME(client), i * 8); +- for (j = 0; j < 8; j++) { +- printk(" 0x%02x", encoder->reg[i * 8 + j]); +- } +- printk("\n"); +- } +-} +-#endif +- + /* ----------------------------------------------------------------------- */ + // Output filter: S-Video Composite + +@@ -407,14 +379,6 @@ + } + break; + +-#ifdef ENCODER_DUMP +- case ENCODER_DUMP: +- { +- dump(client); +- } +- break; +-#endif +- + default: + return -EINVAL; + } +@@ -424,24 +388,6 @@ + + /* ----------------------------------------------------------------------- */ + +-/* +- * Generic i2c probe +- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' +- */ +-static unsigned short normal_i2c[] = +- { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, +- I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1, +- I2C_CLIENT_END +-}; +- +-static unsigned short ignore = I2C_CLIENT_END; +- +-static struct i2c_client_address_data addr_data = { +- .normal_i2c = normal_i2c, +- .probe = &ignore, +- .ignore = &ignore, +-}; +- + static struct i2c_driver i2c_driver_adv7175; + + static int +@@ -516,16 +462,6 @@ + } + + static int +-adv7175_attach_adapter (struct i2c_adapter *adapter) +-{ +- dprintk(1, +- KERN_INFO +- "adv7175.c: starting probe for adapter %s (0x%x)\n", +- I2C_NAME(adapter), adapter->id); +- return i2c_probe(adapter, &addr_data, &adv7175_detect_client); +-} +- +-static int + adv7175_detach_client (struct i2c_client *client) + { + struct adv7175 *encoder = i2c_get_clientdata(client); +@@ -551,7 +487,7 @@ + + .id = I2C_DRIVERID_ADV7175, + +- .attach_adapter = adv7175_attach_adapter, ++ .detect_client = adv7175_detect_client, + .detach_client = adv7175_detach_client, + .command = adv7175_command, + }; +--- linux-2.6.16.orig/drivers/media/video/bt819.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/bt819.c 2006-03-22 17:06:15.000000000 +0100 +@@ -53,7 +53,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(s) (s)->name + +@@ -141,24 +140,21 @@ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ + struct bt819 *decoder = i2c_get_clientdata(client); +- struct i2c_msg msg; + u8 block_data[32]; ++ int block_len; + +- msg.addr = client->addr; +- msg.flags = 0; + while (len >= 2) { +- msg.buf = (char *) block_data; +- msg.len = 0; +- block_data[msg.len++] = reg = data[0]; ++ block_len = 0; ++ block_data[block_len++] = reg = data[0]; + do { +- block_data[msg.len++] = ++ block_data[block_len++] = + decoder->reg[reg++] = data[1]; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && +- msg.len < 32); +- if ((ret = i2c_transfer(client->adapter, +- &msg, 1)) < 0) ++ block_len < 32); ++ if ((ret = i2c_master_send(client, block_data, ++ block_len)) < 0) + break; + } + } else { +--- linux-2.6.16.orig/drivers/media/video/bt856.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/bt856.c 2006-03-22 17:06:15.000000000 +0100 +@@ -53,7 +53,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(s) (s)->name + +@@ -71,17 +70,14 @@ + + /* ----------------------------------------------------------------------- */ + +-#define REG_OFFSET 0xCE ++#define REG_OFFSET 0xDA ++#define BT856_NR_REG 6 + + struct bt856 { +- unsigned char reg[32]; ++ unsigned char reg[BT856_NR_REG]; + + int norm; + int enable; +- int bright; +- int contrast; +- int hue; +- int sat; + }; + + #define I2C_BT856 0x88 +@@ -120,8 +116,8 @@ + struct bt856 *encoder = i2c_get_clientdata(client); + + printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); +- for (i = 0xd6; i <= 0xde; i += 2) +- printk(" %02x", encoder->reg[i - REG_OFFSET]); ++ for (i = 0; i < BT856_NR_REG; i += 2) ++ printk(" %02x", encoder->reg[i]); + printk("\n"); + } + +--- linux-2.6.16.orig/drivers/media/video/saa7110.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/saa7110.c 2006-03-22 17:06:16.000000000 +0100 +@@ -39,7 +39,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(s) (s)->name + +@@ -59,8 +58,6 @@ + #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ + #define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ + +-#define I2C_SAA7110 0x9C /* or 0x9E */ +- + #define SAA7110_NR_REG 0x35 + + struct saa7110 { +@@ -108,13 +105,8 @@ + * the adapter understands raw I2C */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + struct saa7110 *decoder = i2c_get_clientdata(client); +- struct i2c_msg msg; + +- msg.len = len; +- msg.buf = (char *) data; +- msg.addr = client->addr; +- msg.flags = 0; +- ret = i2c_transfer(client->adapter, &msg, 1); ++ ret = i2c_master_send(client, data, len); + + /* Cache the written data */ + memcpy(decoder->reg + reg, data + 1, len - 1); +@@ -432,15 +424,13 @@ + break; + + case DECODER_DUMP: +- for (v = 0; v < 0x34; v += 16) { ++ for (v = 0; v < SAA7110_NR_REG; v += 16) { + int j; +- dprintk(1, KERN_INFO "%s: %03x\n", I2C_NAME(client), ++ dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client), + v); +- for (j = 0; j < 16; j++) { +- dprintk(1, KERN_INFO " %02x", +- decoder->reg[v + j]); +- } +- dprintk(1, KERN_INFO "\n"); ++ for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) ++ dprintk(1, " %02x", decoder->reg[v + j]); ++ dprintk(1, "\n"); + } + break; + +@@ -454,24 +444,6 @@ + + /* ----------------------------------------------------------------------- */ + +-/* +- * Generic i2c probe +- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' +- */ +-static unsigned short normal_i2c[] = { +- I2C_SAA7110 >> 1, +- (I2C_SAA7110 >> 1) + 1, +- I2C_CLIENT_END +-}; +- +-static unsigned short ignore = I2C_CLIENT_END; +- +-static struct i2c_client_address_data addr_data = { +- .normal_i2c = normal_i2c, +- .probe = &ignore, +- .ignore = &ignore, +-}; +- + static struct i2c_driver i2c_driver_saa7110; + + static int +@@ -555,16 +527,6 @@ + } + + static int +-saa7110_attach_adapter (struct i2c_adapter *adapter) +-{ +- dprintk(1, +- KERN_INFO +- "saa7110.c: starting probe for adapter %s (0x%x)\n", +- I2C_NAME(adapter), adapter->id); +- return i2c_probe(adapter, &addr_data, &saa7110_detect_client); +-} +- +-static int + saa7110_detach_client (struct i2c_client *client) + { + struct saa7110 *decoder = i2c_get_clientdata(client); +@@ -590,7 +552,7 @@ + + .id = I2C_DRIVERID_SAA7110, + +- .attach_adapter = saa7110_attach_adapter, ++ .detect_client = saa7110_detect_client, + .detach_client = saa7110_detach_client, + .command = saa7110_command, + }; +--- linux-2.6.16.orig/drivers/media/video/saa7111.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/saa7111.c 2006-03-22 17:06:15.000000000 +0100 +@@ -52,7 +52,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(s) (s)->name + +@@ -70,8 +69,10 @@ + + /* ----------------------------------------------------------------------- */ + ++#define SAA7111_NR_REG 0x18 ++ + struct saa7111 { +- unsigned char reg[32]; ++ unsigned char reg[SAA7111_NR_REG]; + + int norm; + int input; +@@ -110,24 +111,21 @@ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ + struct saa7111 *decoder = i2c_get_clientdata(client); +- struct i2c_msg msg; + u8 block_data[32]; ++ int block_len; + +- msg.addr = client->addr; +- msg.flags = 0; + while (len >= 2) { +- msg.buf = (char *) block_data; +- msg.len = 0; +- block_data[msg.len++] = reg = data[0]; ++ block_len = 0; ++ block_data[block_len++] = reg = data[0]; + do { +- block_data[msg.len++] = ++ block_data[block_len++] = + decoder->reg[reg++] = data[1]; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && +- msg.len < 32); +- if ((ret = i2c_transfer(client->adapter, +- &msg, 1)) < 0) ++ block_len < 32); ++ if ((ret = i2c_master_send(client, block_data, ++ block_len)) < 0) + break; + } + } else { +@@ -227,11 +225,11 @@ + { + int i; + +- for (i = 0; i < 32; i += 16) { ++ for (i = 0; i < SAA7111_NR_REG; i += 16) { + int j; + + printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); +- for (j = 0; j < 16; ++j) { ++ for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { + printk(" %02x", + saa7111_read(client, i + j)); + } +--- linux-2.6.16.orig/drivers/media/video/saa7114.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/saa7114.c 2006-03-22 17:06:15.000000000 +0100 +@@ -55,7 +55,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(x) (x)->name + +@@ -139,9 +138,6 @@ + u8 reg, + u8 value) + { +- /*struct saa7114 *decoder = i2c_get_clientdata(client);*/ +- +- /*decoder->reg[reg] = value;*/ + return i2c_smbus_write_byte_data(client, reg, value); + } + +@@ -157,25 +153,21 @@ + * the adapter understands raw I2C */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ +- /*struct saa7114 *decoder = i2c_get_clientdata(client);*/ +- struct i2c_msg msg; + u8 block_data[32]; ++ int block_len; + +- msg.addr = client->addr; +- msg.flags = 0; + while (len >= 2) { +- msg.buf = (char *) block_data; +- msg.len = 0; +- block_data[msg.len++] = reg = data[0]; ++ block_len = 0; ++ block_data[block_len++] = reg = data[0]; + do { +- block_data[msg.len++] = +- /*decoder->reg[reg++] =*/ data[1]; ++ block_data[block_len++] = data[1]; ++ reg++; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && +- msg.len < 32); +- if ((ret = i2c_transfer(client->adapter, +- &msg, 1)) < 0) ++ block_len < 32); ++ if ((ret = i2c_master_send(client, block_data, ++ block_len)) < 0) + break; + } + } else { +--- linux-2.6.16.orig/drivers/media/video/saa711x.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/saa711x.c 2006-03-22 17:06:15.000000000 +0100 +@@ -45,7 +45,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(s) (s)->name + +--- linux-2.6.16.orig/drivers/media/video/saa7185.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/saa7185.c 2006-03-22 17:06:15.000000000 +0100 +@@ -49,7 +49,6 @@ + MODULE_LICENSE("GPL"); + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(s) (s)->name + +@@ -113,24 +112,21 @@ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ + struct saa7185 *encoder = i2c_get_clientdata(client); +- struct i2c_msg msg; + u8 block_data[32]; ++ int block_len; + +- msg.addr = client->addr; +- msg.flags = 0; + while (len >= 2) { +- msg.buf = (char *) block_data; +- msg.len = 0; +- block_data[msg.len++] = reg = data[0]; ++ block_len = 0; ++ block_data[block_len++] = reg = data[0]; + do { +- block_data[msg.len++] = ++ block_data[block_len++] = + encoder->reg[reg++] = data[1]; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && +- msg.len < 32); +- if ((ret = i2c_transfer(client->adapter, +- &msg, 1)) < 0) ++ block_len < 32); ++ if ((ret = i2c_master_send(client, block_data, ++ block_len)) < 0) + break; + } + } else { +--- linux-2.6.16.orig/drivers/media/video/vpx3220.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/vpx3220.c 2006-03-22 17:06:15.000000000 +0100 +@@ -30,7 +30,6 @@ + #include <asm/uaccess.h> + + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + + #define I2C_NAME(x) (x)->name + +--- linux-2.6.16.orig/sound/oss/dmasound/dmasound_awacs.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/sound/oss/dmasound/dmasound_awacs.c 2006-03-22 17:06:15.000000000 +0100 +@@ -88,8 +88,6 @@ + #include <linux/pmu.h> + #endif + +-#include <linux/i2c-dev.h> +- + #include <asm/uaccess.h> + #include <asm/prom.h> + #include <asm/machdep.h> +--- linux-2.6.16.orig/sound/ppc/daca.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/sound/ppc/daca.c 2006-03-22 17:06:15.000000000 +0100 +@@ -22,7 +22,6 @@ + #include <sound/driver.h> + #include <linux/init.h> + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + #include <linux/kmod.h> + #include <linux/slab.h> + #include <sound/core.h> +--- linux-2.6.16.orig/sound/ppc/keywest.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/sound/ppc/keywest.c 2006-03-22 17:06:15.000000000 +0100 +@@ -23,7 +23,6 @@ + #include <linux/init.h> + #include <linux/i2c.h> + #include <linux/delay.h> +-#include <linux/i2c-dev.h> + #include <linux/slab.h> + #include <sound/core.h> + #include "pmac.h" +--- linux-2.6.16.orig/sound/ppc/toonie.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/sound/ppc/toonie.c 2006-03-22 17:06:15.000000000 +0100 +@@ -22,7 +22,6 @@ + #include <linux/init.h> + #include <linux/delay.h> + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + #include <linux/kmod.h> + #include <linux/slab.h> + #include <linux/interrupt.h> +--- linux-2.6.16.orig/sound/ppc/tumbler.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/sound/ppc/tumbler.c 2006-03-22 17:06:15.000000000 +0100 +@@ -28,7 +28,6 @@ + #include <linux/init.h> + #include <linux/delay.h> + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + #include <linux/kmod.h> + #include <linux/slab.h> + #include <linux/interrupt.h> +--- linux-2.6.16.orig/drivers/hwmon/hwmon.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/hwmon.c 2006-03-22 17:06:15.000000000 +0100 +@@ -17,6 +17,7 @@ + #include <linux/idr.h> + #include <linux/hwmon.h> + #include <linux/gfp.h> ++#include <linux/spinlock.h> + + #define HWMON_ID_PREFIX "hwmon" + #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" +@@ -24,6 +25,7 @@ + static struct class *hwmon_class; + + static DEFINE_IDR(hwmon_idr); ++static DEFINE_SPINLOCK(idr_lock); + + /** + * hwmon_device_register - register w/ hwmon sysfs class +@@ -37,20 +39,30 @@ + struct class_device *hwmon_device_register(struct device *dev) + { + struct class_device *cdev; +- int id; ++ int id, err; + +- if (idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0) ++again: ++ if (unlikely(idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0)) + return ERR_PTR(-ENOMEM); + +- if (idr_get_new(&hwmon_idr, NULL, &id) < 0) +- return ERR_PTR(-ENOMEM); ++ spin_lock(&idr_lock); ++ err = idr_get_new(&hwmon_idr, NULL, &id); ++ spin_unlock(&idr_lock); ++ ++ if (unlikely(err == -EAGAIN)) ++ goto again; ++ else if (unlikely(err)) ++ return ERR_PTR(err); + + id = id & MAX_ID_MASK; + cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev, + HWMON_ID_FORMAT, id); + +- if (IS_ERR(cdev)) ++ if (IS_ERR(cdev)) { ++ spin_lock(&idr_lock); + idr_remove(&hwmon_idr, id); ++ spin_unlock(&idr_lock); ++ } + + return cdev; + } +@@ -64,9 +76,11 @@ + { + int id; + +- if (sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1) { ++ if (likely(sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1)) { + class_device_unregister(cdev); ++ spin_lock(&idr_lock); + idr_remove(&hwmon_idr, id); ++ spin_unlock(&idr_lock); + } else + dev_dbg(cdev->dev, + "hwmon_device_unregister() failed: bad class ID!\n"); +--- linux-2.6.16.orig/arch/m68k/bvme6000/rtc.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/arch/m68k/bvme6000/rtc.c 2006-03-22 17:06:15.000000000 +0100 +@@ -18,6 +18,7 @@ + #include <linux/module.h> + #include <linux/mc146818rtc.h> /* For struct rtc_time and ioctls, etc */ + #include <linux/smp_lock.h> ++#include <linux/bcd.h> + #include <asm/bvme6000hw.h> + + #include <asm/io.h> +@@ -32,9 +33,6 @@ + * ioctls. + */ + +-#define BCD2BIN(val) (((val)&15) + ((val)>>4)*10) +-#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10) +- + static unsigned char days_in_mo[] = + {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +--- linux-2.6.16.orig/drivers/video/matrox/matroxfb_maven.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/video/matrox/matroxfb_maven.c 2006-03-22 17:06:15.000000000 +0100 +@@ -129,7 +129,7 @@ + + struct maven_data { + struct matrox_fb_info* primary_head; +- struct i2c_client* client; ++ struct i2c_client client; + int version; + }; + +@@ -970,7 +970,7 @@ + + static int maven_program_timming(struct maven_data* md, + const struct mavenregs* m) { +- struct i2c_client* c = md->client; ++ struct i2c_client* c = &md->client; + + if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) { + LR(0x80); +@@ -1007,7 +1007,7 @@ + } + + static inline int maven_resync(struct maven_data* md) { +- struct i2c_client* c = md->client; ++ struct i2c_client* c = &md->client; + maven_set_reg(c, 0x95, 0x20); /* start whole thing */ + return 0; + } +@@ -1065,48 +1065,48 @@ + maven_compute_bwlevel(md, &blacklevel, &whitelevel); + blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8); + whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8); +- maven_set_reg_pair(md->client, 0x0e, blacklevel); +- maven_set_reg_pair(md->client, 0x1e, whitelevel); ++ maven_set_reg_pair(&md->client, 0x0e, blacklevel); ++ maven_set_reg_pair(&md->client, 0x1e, whitelevel); + } + break; + case V4L2_CID_SATURATION: + { +- maven_set_reg(md->client, 0x20, p->value); +- maven_set_reg(md->client, 0x22, p->value); ++ maven_set_reg(&md->client, 0x20, p->value); ++ maven_set_reg(&md->client, 0x22, p->value); + } + break; + case V4L2_CID_HUE: + { +- maven_set_reg(md->client, 0x25, p->value); ++ maven_set_reg(&md->client, 0x25, p->value); + } + break; + case V4L2_CID_GAMMA: + { + const struct maven_gamma* g; + g = maven_compute_gamma(md); +- maven_set_reg(md->client, 0x83, g->reg83); +- maven_set_reg(md->client, 0x84, g->reg84); +- maven_set_reg(md->client, 0x85, g->reg85); +- maven_set_reg(md->client, 0x86, g->reg86); +- maven_set_reg(md->client, 0x87, g->reg87); +- maven_set_reg(md->client, 0x88, g->reg88); +- maven_set_reg(md->client, 0x89, g->reg89); +- maven_set_reg(md->client, 0x8a, g->reg8a); +- maven_set_reg(md->client, 0x8b, g->reg8b); ++ maven_set_reg(&md->client, 0x83, g->reg83); ++ maven_set_reg(&md->client, 0x84, g->reg84); ++ maven_set_reg(&md->client, 0x85, g->reg85); ++ maven_set_reg(&md->client, 0x86, g->reg86); ++ maven_set_reg(&md->client, 0x87, g->reg87); ++ maven_set_reg(&md->client, 0x88, g->reg88); ++ maven_set_reg(&md->client, 0x89, g->reg89); ++ maven_set_reg(&md->client, 0x8a, g->reg8a); ++ maven_set_reg(&md->client, 0x8b, g->reg8b); + } + break; + case MATROXFB_CID_TESTOUT: + { + unsigned char val +- = maven_get_reg (md->client,0x8d); ++ = maven_get_reg(&md->client,0x8d); + if (p->value) val |= 0x10; + else val &= ~0x10; +- maven_set_reg (md->client, 0x8d, val); ++ maven_set_reg(&md->client, 0x8d, val); + } + break; + case MATROXFB_CID_DEFLICKER: + { +- maven_set_reg(md->client, 0x93, maven_compute_deflicker(md)); ++ maven_set_reg(&md->client, 0x93, maven_compute_deflicker(md)); + } + break; + } +@@ -1185,7 +1185,6 @@ + MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo); + + md->primary_head = MINFO; +- md->client = clnt; + down_write(&ACCESS_FBINFO(altout.lock)); + ACCESS_FBINFO(outputs[1]).output = &maven_altout; + ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; +@@ -1243,19 +1242,17 @@ + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_PROTOCOL_MANGLING)) + goto ERROR0; +- if (!(new_client = (struct i2c_client*)kmalloc(sizeof(*new_client) + sizeof(*data), +- GFP_KERNEL))) { ++ if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { + err = -ENOMEM; + goto ERROR0; + } +- memset(new_client, 0, sizeof(*new_client) + sizeof(*data)); +- data = (struct maven_data*)(new_client + 1); ++ new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &maven_driver; + new_client->flags = 0; +- strcpy(new_client->name, "maven client"); ++ strlcpy(new_client->name, "maven", I2C_NAME_SIZE); + if ((err = i2c_attach_client(new_client))) + goto ERROR3; + err = maven_init_client(new_client); +@@ -1279,12 +1276,10 @@ + static int maven_detach_client(struct i2c_client* client) { + int err; + +- if ((err = i2c_detach_client(client))) { +- printk(KERN_ERR "maven: Cannot deregister client\n"); ++ if ((err = i2c_detach_client(client))) + return err; +- } + maven_shutdown_client(client); +- kfree(client); ++ kfree(i2c_get_clientdata(client)); + return 0; + } + +@@ -1297,20 +1292,13 @@ + .detach_client = maven_detach_client, + }; + +-/* ************************** */ +- +-static int matroxfb_maven_init(void) { +- int err; +- +- err = i2c_add_driver(&maven_driver); +- if (err) { +- printk(KERN_ERR "maven: Maven driver failed to register (%d).\n", err); +- return err; +- } +- return 0; ++static int __init matroxfb_maven_init(void) ++{ ++ return i2c_add_driver(&maven_driver); + } + +-static void matroxfb_maven_exit(void) { ++static void __exit matroxfb_maven_exit(void) ++{ + i2c_del_driver(&maven_driver); + } + +--- linux-2.6.16.orig/drivers/macintosh/therm_pm72.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/macintosh/therm_pm72.c 2006-03-22 17:06:15.000000000 +0100 +@@ -104,7 +104,6 @@ + #include <linux/kernel.h> + #include <linux/delay.h> + #include <linux/sched.h> +-#include <linux/i2c.h> + #include <linux/slab.h> + #include <linux/init.h> + #include <linux/spinlock.h> +@@ -113,7 +112,6 @@ + #include <linux/reboot.h> + #include <linux/kmod.h> + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + #include <asm/prom.h> + #include <asm/machdep.h> + #include <asm/io.h> +--- linux-2.6.16.orig/drivers/macintosh/windfarm_lm75_sensor.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/macintosh/windfarm_lm75_sensor.c 2006-03-22 17:06:15.000000000 +0100 +@@ -15,7 +15,6 @@ + #include <linux/init.h> + #include <linux/wait.h> + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + #include <asm/prom.h> + #include <asm/machdep.h> + #include <asm/io.h> +--- linux-2.6.16.orig/drivers/macintosh/windfarm_max6690_sensor.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/macintosh/windfarm_max6690_sensor.c 2006-03-22 17:06:15.000000000 +0100 +@@ -11,7 +11,6 @@ + #include <linux/init.h> + #include <linux/slab.h> + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + #include <asm/prom.h> + #include <asm/pmac_low_i2c.h> + +--- linux-2.6.16.orig/drivers/macintosh/windfarm_smu_sat.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/drivers/macintosh/windfarm_smu_sat.c 2006-03-22 17:06:15.000000000 +0100 +@@ -13,7 +13,6 @@ + #include <linux/init.h> + #include <linux/wait.h> + #include <linux/i2c.h> +-#include <linux/i2c-dev.h> + #include <asm/semaphore.h> + #include <asm/prom.h> + #include <asm/smu.h> +--- linux-2.6.16.orig/arch/i386/kernel/traps.c 2006-03-22 17:06:08.000000000 +0100 ++++ linux-2.6.16/arch/i386/kernel/traps.c 2006-03-22 17:06:15.000000000 +0100 +@@ -166,8 +166,7 @@ + stack = (unsigned long*)context->previous_esp; + if (!stack) + break; +- printk(log_lvl); +- printk(" =======================\n"); ++ printk("%s =======================\n", log_lvl); + } + } + +@@ -196,14 +195,12 @@ + break; + if (i && ((i % 8) == 0)) { + printk("\n"); +- printk(log_lvl); +- printk(" "); ++ printk("%s ", log_lvl); + } + printk("%08lx ", *stack++); + } + printk("\n"); +- printk(log_lvl); +- printk("Call Trace:\n"); ++ printk("%sCall Trace:\n", log_lvl); + show_trace_log_lvl(task, esp, log_lvl); + } + +--- linux-2.6.16.orig/drivers/media/video/zoran_card.c 2006-03-22 17:06:07.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/zoran_card.c 2006-03-22 17:06:16.000000000 +0100 +@@ -452,6 +452,8 @@ + .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS, + .i2c_decoder = I2C_DRIVERID_SAA7110, + .i2c_encoder = I2C_DRIVERID_ADV7175, ++ .decoder_addr = 0x4e, ++ .encoder_addr = 0x2b, + .video_codec = CODEC_TYPE_ZR36060, + + .inputs = 3, +@@ -995,10 +997,7 @@ + static int __devinit + zr36057_init (struct zoran *zr) + { +- u32 *mem; +- void *vdev; +- unsigned mem_needed; +- int j; ++ int j, err; + int two = 2; + int zero = 0; + +@@ -1049,19 +1048,16 @@ + + /* allocate memory *before* doing anything to the hardware + * in case allocation fails */ +- mem_needed = BUZ_NUM_STAT_COM * 4; +- mem = kzalloc(mem_needed, GFP_KERNEL); +- vdev = (void *) kmalloc(sizeof(struct video_device), GFP_KERNEL); +- if (!mem || !vdev) { ++ zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL); ++ zr->video_dev = kmalloc(sizeof(struct video_device), GFP_KERNEL); ++ if (!zr->stat_com || !zr->video_dev) { + dprintk(1, + KERN_ERR + "%s: zr36057_init() - kmalloc (STAT_COM) failed\n", + ZR_DEVNAME(zr)); +- kfree(vdev); +- kfree(mem); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto exit_free; + } +- zr->stat_com = mem; + for (j = 0; j < BUZ_NUM_STAT_COM; j++) { + zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */ + } +@@ -1069,16 +1065,11 @@ + /* + * Now add the template and register the device unit. + */ +- zr->video_dev = vdev; + memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); + strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); +- if (video_register_device(zr->video_dev, VFL_TYPE_GRABBER, +- video_nr) < 0) { +- zoran_unregister_i2c(zr); +- kfree((void *) zr->stat_com); +- kfree(vdev); +- return -1; +- } ++ err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr); ++ if (err < 0) ++ goto exit_unregister; + + zoran_init_hardware(zr); + if (*zr_debug > 2) +@@ -1092,6 +1083,13 @@ + zr->zoran_proc = NULL; + zr->initialized = 1; + return 0; ++ ++exit_unregister: ++ zoran_unregister_i2c(zr); ++exit_free: ++ kfree(zr->stat_com); ++ kfree(zr->video_dev); ++ return err; + } + + static void +@@ -1121,7 +1119,7 @@ + btwrite(0, ZR36057_SPGPPCR); + free_irq(zr->pci_dev->irq, zr); + /* unmap and free memory */ +- kfree((void *) zr->stat_com); ++ kfree(zr->stat_com); + zoran_proc_cleanup(zr); + iounmap(zr->zr36057_mem); + pci_disable_device(zr->pci_dev); +@@ -1349,6 +1347,14 @@ + i2c_dec_name = NULL; + } + ++ if (zoran_register_i2c(zr) < 0) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - can't initialize i2c bus\n", ++ ZR_DEVNAME(zr)); ++ goto zr_free_irq; ++ } ++ + if (i2c_dec_name) { + if ((result = request_module(i2c_dec_name)) < 0) { + dprintk(1, +@@ -1356,6 +1362,10 @@ + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_dec_name, result); + } ++ ++ i2c_probe_device(&zr->i2c_adapter, ++ zr->card.i2c_decoder, ++ zr->card.decoder_addr, 0); + } + + /* i2c encoder */ +@@ -1376,14 +1386,10 @@ + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_enc_name, result); + } +- } + +- if (zoran_register_i2c(zr) < 0) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - can't initialize i2c bus\n", +- ZR_DEVNAME(zr)); +- goto zr_free_irq; ++ i2c_probe_device(&zr->i2c_adapter, ++ zr->card.i2c_encoder, ++ zr->card.encoder_addr, 0); + } + + dprintk(2, +--- linux-2.6.16.orig/Documentation/hwmon/lm83 2006-03-22 17:06:07.000000000 +0100 ++++ linux-2.6.16/Documentation/hwmon/lm83 2006-03-22 17:06:16.000000000 +0100 +@@ -7,6 +7,10 @@ + Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e + Datasheet: Publicly available at the National Semiconductor website + http://www.national.com/pf/LM/LM83.html ++ * National Semiconductor LM82 ++ Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e ++ Datasheet: Publicly available at the National Semiconductor website ++ http://www.national.com/pf/LM/LM82.html + + + Author: Jean Delvare <khali@linux-fr.org> +@@ -15,10 +19,11 @@ + ----------- + + The LM83 is a digital temperature sensor. It senses its own temperature as +-well as the temperature of up to three external diodes. It is compatible +-with many other devices such as the LM84 and all other ADM1021 clones. +-The main difference between the LM83 and the LM84 in that the later can +-only sense the temperature of one external diode. ++well as the temperature of up to three external diodes. The LM82 is ++a stripped down version of the LM83 that only supports one external diode. ++Both are compatible with many other devices such as the LM84 and all ++other ADM1021 clones. The main difference between the LM83 and the LM84 ++in that the later can only sense the temperature of one external diode. + + Using the adm1021 driver for a LM83 should work, but only two temperatures + will be reported instead of four. +@@ -36,6 +41,9 @@ + Iwill MPX2 + Soltek SL-75DRV5 + ++The LM82 is confirmed to have been found on most AMD Geode reference ++designs and test platforms. ++ + The driver has been successfully tested by Magnus Forsström, who I'd + like to thank here. More testers will be of course welcome. + +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.16/Documentation/hwmon/smsc47m192 2006-03-22 17:06:16.000000000 +0100 +@@ -0,0 +1,102 @@ ++Kernel driver smsc47m192 ++======================== ++ ++Supported chips: ++ * SMSC LPC47M192 and LPC47M997 ++ Prefix: 'smsc47m192' ++ Addresses scanned: I2C 0x2c - 0x2d ++ Datasheet: The datasheet for LPC47M192 is publicly available from ++ http://www.smsc.com/ ++ The LPC47M997 is compatible for hardware monitoring. ++ ++Author: Hartmut Rick <linux@rick.claranet.de> ++ Special thanks to Jean Delvare for careful checking ++ of the code and many helpful comments and suggestions. ++ ++ ++Description ++----------- ++ ++This driver implements support for the hardware sensor capabilities ++of the SMSC LPC47M192 and LPC47M997 Super-I/O chips. ++ ++These chips support 3 temperature channels and 8 voltage inputs ++as well as CPU voltage VID input. ++ ++They do also have fan monitoring and control capabilities, but the ++these features are accessed via ISA bus and are not supported by this ++driver. Use the 'smsc47m1' driver for fan monitoring and control. ++ ++Voltages and temperatures are measured by an 8-bit ADC, the resolution ++of the temperatures is 1 bit per degree C. ++Voltages are scaled such that the nominal voltage corresponds to ++192 counts, i.e. 3/4 of the full range. Thus the available range for ++each voltage channel is 0V ... 255/192*(nominal voltage), the resolution ++is 1 bit per (nominal voltage)/192. ++Both voltage and temperature values are scaled by 1000, the sys files ++show voltages in mV and temperatures in units of 0.001 degC. ++ ++The +12V analog voltage input channel (in4_input) is multiplexed with ++bit 4 of the encoded CPU voltage. This means that you either get ++a +12V voltage measurement or a 5 bit CPU VID, but not both. ++The default setting is to use the pin as 12V input, and use only 4 bit VID. ++This driver assumes that the information in the configuration register ++is correct, i.e. that the BIOS has updated the configuration if ++the motherboard has this input wired to VID4. ++ ++The temperature and voltage readings are updated once every 1.5 seconds. ++Reading them more often repeats the same values. ++ ++ ++sysfs interface ++--------------- ++ ++in0_input - +2.5V voltage input ++in1_input - CPU voltage input (nominal 2.25V) ++in2_input - +3.3V voltage input ++in3_input - +5V voltage input ++in4_input - +12V voltage input (may be missing if used as VID4) ++in5_input - Vcc voltage input (nominal 3.3V) ++ This is the supply voltage of the sensor chip itself. ++in6_input - +1.5V voltage input ++in7_input - +1.8V voltage input ++ ++in[0-7]_min, ++in[0-7]_max - lower and upper alarm thresholds for in[0-7]_input reading ++ ++ All voltages are read and written in mV. ++ ++in[0-7]_alarm - alarm flags for voltage inputs ++ These files read '1' in case of alarm, '0' otherwise. ++ ++temp1_input - chip temperature measured by on-chip diode ++temp[2-3]_input - temperature measured by external diodes (one of these would ++ typically be wired to the diode inside the CPU) ++ ++temp[1-3]_min, ++temp[1-3]_max - lower and upper alarm thresholds for temperatures ++ ++temp[1-3]_offset - temperature offset registers ++ The chip adds the offsets stored in these registers to ++ the corresponding temperature readings. ++ Note that temp1 and temp2 offsets share the same register, ++ they cannot both be different from zero at the same time. ++ Writing a non-zero number to one of them will reset the other ++ offset to zero. ++ ++ All temperatures and offsets are read and written in ++ units of 0.001 degC. ++ ++temp[1-3]_alarm - alarm flags for temperature inputs, '1' in case of alarm, ++ '0' otherwise. ++temp[2-3]_input_fault - diode fault flags for temperature inputs 2 and 3. ++ A fault is detected if the two pins for the corresponding ++ sensor are open or shorted, or any of the two is shorted ++ to ground or Vcc. '1' indicates a diode fault. ++ ++cpu0_vid - CPU voltage as received from the CPU ++ ++vrm - CPU VID standard used for decoding CPU voltage ++ ++ The *_min, *_max, *_offset and vrm files can be read and ++ written, all others are read-only. +--- linux-2.6.16.orig/Documentation/hwmon/sysfs-interface 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/Documentation/hwmon/sysfs-interface 2006-03-22 17:06:16.000000000 +0100 +@@ -218,6 +218,12 @@ + from the critical value. + Read/Write value. + ++temp[1-4]_offset ++ Temperature offset which is added to the temperature reading ++ by the chip. ++ Unit: millidegree Celsius ++ Read/Write value. ++ + If there are multiple temperature sensors, temp1_* is + generally the sensor inside the chip itself, + reported as "motherboard temperature". temp2_* to +@@ -246,9 +252,68 @@ + Read only. + + +-********* +-* Other * +-********* ++********** ++* Alarms * ++********** ++ ++Each channel or limit may have an associated alarm file, containing a ++boolean value. 1 means than an alarm condition exists, 0 means no alarm. ++ ++Usually a given chip will either use channel-related alarms, or ++limit-related alarms, not both. The driver should just reflect the hardware ++implementation. ++ ++in[0-n]_alarm ++fan[1-n]_alarm ++temp[1-n]_alarm ++ Channel alarm ++ Boolean ++ Read-only ++ ++OR ++ ++in[0-n]_min_alarm ++in[0-n]_max_alarm ++fan[1-n]_min_alarm ++temp[1-n]_min_alarm ++temp[1-n]_max_alarm ++temp[1-n]_crit_alarm ++ Limit alarm ++ Boolean ++ Read-only ++ ++In theory, a chip could provide per-limit beep masking, but no such chip ++was seen so far. ++ ++Each input channel may have an associated fault file. This can be used ++to notify open diodes, unconnected fans etc. where the hardware ++supports it. When this boolean has value 1, the measurement for that ++channel should not be trusted. ++ ++fan[1-n]_input_fault ++temp[1-n]_input_fault ++ Input fault condition ++ Boolean ++ Read-only ++ ++Some chips also offer the possibility to get beeped when an alarm occurs: ++ ++beep_enable Master beep enable ++ 0 to disable. ++ 1 to enable. ++ Read/Write ++ ++in[0-n]_beep ++fan[1-n]_beep ++temp[1-n]_beep ++ Channel beep ++ 0 to disable. ++ 1 to enable. ++ Read/write ++ ++Old drivers provided a different, non-standard interface to alarms and ++beeps. These interface files are deprecated, but will be kept around ++for compatibility reasons: + + alarms Alarm bitmask. + Read only. +@@ -259,33 +324,22 @@ + if it is still valid. + Generally a direct representation of a chip's internal + alarm registers; there is no standard for the position +- of individual bits. ++ of individual bits. For this reason, the use of this ++ interface file for new drivers is discouraged. Use ++ individual *_alarm and *_fault files instead. + Bits are defined in kernel/include/sensors.h. + +-alarms_in Alarm bitmask relative to in (voltage) channels +- Read only +- A '1' bit means an alarm, LSB corresponds to in0 and so on +- Prefered to 'alarms' for newer chips +- +-alarms_fan Alarm bitmask relative to fan channels +- Read only +- A '1' bit means an alarm, LSB corresponds to fan1 and so on +- Prefered to 'alarms' for newer chips +- +-alarms_temp Alarm bitmask relative to temp (temperature) channels +- Read only +- A '1' bit means an alarm, LSB corresponds to temp1 and so on +- Prefered to 'alarms' for newer chips +- +-beep_enable Beep/interrupt enable +- 0 to disable. +- 1 to enable. +- Read/Write +- + beep_mask Bitmask for beep. +- Same format as 'alarms' with the same bit locations. ++ Same format as 'alarms' with the same bit locations, ++ use discouraged for the same reason. Use individual ++ *_beep files instead. + Read/Write + ++ ++********* ++* Other * ++********* ++ + eeprom Raw EEPROM data in binary form. + Read only. + +--- linux-2.6.16.orig/drivers/hwmon/Makefile 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/drivers/hwmon/Makefile 2006-03-22 17:06:16.000000000 +0100 +@@ -40,6 +40,7 @@ + obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o + obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o + obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o ++obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o + obj-$(CONFIG_SENSORS_VIA686A) += via686a.o + obj-$(CONFIG_SENSORS_VT8231) += vt8231.o + obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.16/drivers/hwmon/smsc47m192.c 2006-03-22 17:06:16.000000000 +0100 +@@ -0,0 +1,638 @@ ++/* ++ smsc47m192.c - Support for hardware monitoring block of ++ SMSC LPC47M192 and LPC47M997 Super I/O chips ++ ++ Copyright (C) 2006 Hartmut Rick <linux@rick.claranet.de> ++ ++ Derived from lm78.c and other chip drivers. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/slab.h> ++#include <linux/jiffies.h> ++#include <linux/i2c.h> ++#include <linux/hwmon.h> ++#include <linux/hwmon-sysfs.h> ++#include <linux/hwmon-vid.h> ++#include <linux/err.h> ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; ++ ++/* Insmod parameters */ ++I2C_CLIENT_INSMOD_1(smsc47m192); ++ ++/* SMSC47M192 registers */ ++#define SMSC47M192_REG_IN(nr) ((nr)<6 ? (0x20 + (nr)) : \ ++ (0x50 + (nr) - 6)) ++#define SMSC47M192_REG_IN_MAX(nr) ((nr)<6 ? (0x2b + (nr) * 2) : \ ++ (0x54 + (((nr) - 6) * 2))) ++#define SMSC47M192_REG_IN_MIN(nr) ((nr)<6 ? (0x2c + (nr) * 2) : \ ++ (0x55 + (((nr) - 6) * 2))) ++static u8 SMSC47M192_REG_TEMP[3] = { 0x27, 0x26, 0x52 }; ++static u8 SMSC47M192_REG_TEMP_MAX[3] = { 0x39, 0x37, 0x58 }; ++static u8 SMSC47M192_REG_TEMP_MIN[3] = { 0x3A, 0x38, 0x59 }; ++#define SMSC47M192_REG_TEMP_OFFSET(nr) ((nr)==2 ? 0x1e : 0x1f) ++#define SMSC47M192_REG_ALARM1 0x41 ++#define SMSC47M192_REG_ALARM2 0x42 ++#define SMSC47M192_REG_VID 0x47 ++#define SMSC47M192_REG_VID4 0x49 ++#define SMSC47M192_REG_CONFIG 0x40 ++#define SMSC47M192_REG_SFR 0x4f ++#define SMSC47M192_REG_COMPANY_ID 0x3e ++#define SMSC47M192_REG_VERSION 0x3f ++ ++/* generalised scaling with integer rounding */ ++static inline int SCALE(long val, int mul, int div) ++{ ++ if (val < 0) ++ return (val * mul - div / 2) / div; ++ else ++ return (val * mul + div / 2) / div; ++} ++ ++/* Conversions */ ++ ++/* smsc47m192 internally scales voltage measurements */ ++static const u16 nom_mv[] = { 2500, 2250, 3300, 5000, 12000, 3300, 1500, 1800 }; ++ ++static inline unsigned int IN_FROM_REG(u8 reg, int n) ++{ ++ return SCALE(reg, nom_mv[n], 192); ++} ++ ++static inline u8 IN_TO_REG(unsigned long val, int n) ++{ ++ return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255); ++} ++ ++/* TEMP: 0.001 degC units (-128C to +127C) ++ REG: 1C/bit, two's complement */ ++static inline s8 TEMP_TO_REG(int val) ++{ ++ return SENSORS_LIMIT(SCALE(val, 1, 1000), -128000, 127000); ++} ++ ++static inline int TEMP_FROM_REG(s8 val) ++{ ++ return val * 1000; ++} ++ ++struct smsc47m192_data { ++ struct i2c_client client; ++ struct class_device *class_dev; ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[8]; /* Register value */ ++ u8 in_max[8]; /* Register value */ ++ u8 in_min[8]; /* Register value */ ++ s8 temp[3]; /* Register value */ ++ s8 temp_max[3]; /* Register value */ ++ s8 temp_min[3]; /* Register value */ ++ s8 temp_offset[3]; /* Register value */ ++ u16 alarms; /* Register encoding, combined */ ++ u8 vid; /* Register encoding, combined */ ++ u8 vrm; ++}; ++ ++static int smsc47m192_detect(struct i2c_adapter *adapter, int address, ++ int kind); ++static int smsc47m192_detach_client(struct i2c_client *client); ++static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); ++ ++static struct i2c_driver smsc47m192_driver = { ++ .driver = { ++ .name = "smsc47m192", ++ }, ++ .class = I2C_CLASS_HWMON, ++ .address_data = &addr_data, ++ .detect_client = smsc47m192_detect, ++ .detach_client = smsc47m192_detach_client, ++}; ++ ++/* Voltages */ ++static ssize_t show_in(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr)); ++} ++ ++static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr)); ++} ++ ++static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr)); ++} ++ ++static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ unsigned long val = simple_strtoul(buf, NULL, 10); ++ ++ down(&data->update_lock); ++ data->in_min[nr] = IN_TO_REG(val, nr); ++ i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ up(&data->update_lock); ++ return count; ++} ++ ++static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ unsigned long val = simple_strtoul(buf, NULL, 10); ++ ++ down(&data->update_lock); ++ data->in_max[nr] = IN_TO_REG(val, nr); ++ i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ up(&data->update_lock); ++ return count; ++} ++ ++#define show_in_offset(offset) \ ++static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ ++ show_in, NULL, offset); \ ++static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ ++ show_in_min, set_in_min, offset); \ ++static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ ++ show_in_max, set_in_max, offset); ++ ++show_in_offset(0) ++show_in_offset(1) ++show_in_offset(2) ++show_in_offset(3) ++show_in_offset(4) ++show_in_offset(5) ++show_in_offset(6) ++show_in_offset(7) ++ ++/* Temperatures */ ++static ssize_t show_temp(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); ++} ++ ++static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr])); ++} ++ ++static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr])); ++} ++ ++static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ long val = simple_strtol(buf, NULL, 10); ++ ++ down(&data->update_lock); ++ data->temp_min[nr] = TEMP_TO_REG(val); ++ i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr], ++ data->temp_min[nr]); ++ up(&data->update_lock); ++ return count; ++} ++ ++static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ long val = simple_strtol(buf, NULL, 10); ++ ++ down(&data->update_lock); ++ data->temp_max[nr] = TEMP_TO_REG(val); ++ i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr], ++ data->temp_max[nr]); ++ up(&data->update_lock); ++ return count; ++} ++ ++static ssize_t show_temp_offset(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_offset[nr])); ++} ++ ++static ssize_t set_temp_offset(struct device *dev, struct device_attribute ++ *attr, const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); ++ long val = simple_strtol(buf, NULL, 10); ++ ++ down(&data->update_lock); ++ data->temp_offset[nr] = TEMP_TO_REG(val); ++ if (nr>1) ++ i2c_smbus_write_byte_data(client, ++ SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]); ++ else if (data->temp_offset[nr] != 0) { ++ /* offset[0] and offset[1] share the same register, ++ SFR bit 4 activates offset[0] */ ++ i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR, ++ (sfr & 0xef) | (nr==0 ? 0x10 : 0)); ++ data->temp_offset[1-nr] = 0; ++ i2c_smbus_write_byte_data(client, ++ SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]); ++ } else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0)) ++ i2c_smbus_write_byte_data(client, ++ SMSC47M192_REG_TEMP_OFFSET(nr), 0); ++ up(&data->update_lock); ++ return count; ++} ++ ++#define show_temp_index(index) \ ++static SENSOR_DEVICE_ATTR(temp##index##_input, S_IRUGO, \ ++ show_temp, NULL, index-1); \ ++static SENSOR_DEVICE_ATTR(temp##index##_min, S_IRUGO | S_IWUSR, \ ++ show_temp_min, set_temp_min, index-1); \ ++static SENSOR_DEVICE_ATTR(temp##index##_max, S_IRUGO | S_IWUSR, \ ++ show_temp_max, set_temp_max, index-1); \ ++static SENSOR_DEVICE_ATTR(temp##index##_offset, S_IRUGO | S_IWUSR, \ ++ show_temp_offset, set_temp_offset, index-1); ++ ++show_temp_index(1) ++show_temp_index(2) ++show_temp_index(3) ++ ++/* VID */ ++static ssize_t show_vid(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); ++} ++static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); ++ ++static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%d\n", data->vrm); ++} ++ ++static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ data->vrm = simple_strtoul(buf, NULL, 10); ++ return count; ++} ++static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); ++ ++/* Alarms */ ++static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int nr = sensor_attr->index; ++ struct smsc47m192_data *data = smsc47m192_update_device(dev); ++ return sprintf(buf, "%u\n", (data->alarms & nr) ? 1 : 0); ++} ++ ++static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010); ++static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020); ++static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040); ++static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 0x4000); ++static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 0x8000); ++static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001); ++static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002); ++static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004); ++static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 0x0008); ++static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 0x0100); ++static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 0x0200); ++static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 0x0400); ++static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 0x0800); ++ ++static void smsc47m192_init_client(struct i2c_client *client) ++{ ++ int i; ++ u8 config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); ++ u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); ++ ++ /* select cycle mode (pause 1 sec between updates) */ ++ i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR, ++ (sfr & 0xfd) | 0x02); ++ if (!(config & 0x01)) { ++ /* initialize alarm limits */ ++ for (i=0; i<8; i++) { ++ i2c_smbus_write_byte_data(client, ++ SMSC47M192_REG_IN_MIN(i), 0); ++ i2c_smbus_write_byte_data(client, ++ SMSC47M192_REG_IN_MAX(i), 0xff); ++ } ++ for (i=0; i<3; i++) { ++ i2c_smbus_write_byte_data(client, ++ SMSC47M192_REG_TEMP_MIN[i], 0x80); ++ i2c_smbus_write_byte_data(client, ++ SMSC47M192_REG_TEMP_MAX[i], 0x7f); ++ } ++ ++ /* start monitoring */ ++ i2c_smbus_write_byte_data(client, SMSC47M192_REG_CONFIG, ++ (config & 0xf7) | 0x01); ++ } ++} ++ ++/* This function is called by i2c_probe */ ++static int smsc47m192_detect(struct i2c_adapter *adapter, int address, ++ int kind) ++{ ++ struct i2c_client *client; ++ struct smsc47m192_data *data; ++ int err = 0; ++ int version, config; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto exit; ++ ++ if (!(data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ client = &data->client; ++ i2c_set_clientdata(client, data); ++ client->addr = address; ++ client->adapter = adapter; ++ client->driver = &smsc47m192_driver; ++ ++ if (kind == 0) ++ kind = smsc47m192; ++ ++ /* Detection criteria from sensors_detect script */ ++ if (kind < 0) { ++ if (i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_COMPANY_ID) == 0x55 ++ && ((version = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_VERSION)) & 0xf0) == 0x20 ++ && (i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_VID) & 0x70) == 0x00 ++ && (i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_VID4) & 0xfe) == 0x80) { ++ dev_info(&adapter->dev, ++ "found SMSC47M192 or SMSC47M997, " ++ "version 2, stepping A%d\n", version & 0x0f); ++ } else { ++ dev_dbg(&adapter->dev, ++ "SMSC47M192 detection failed at 0x%02x\n", ++ address); ++ goto exit_free; ++ } ++ } ++ ++ /* Fill in the remaining client fields and put into the global list */ ++ strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); ++ data->vrm = vid_which_vrm(); ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(client))) ++ goto exit_free; ++ ++ /* Initialize the SMSC47M192 chip */ ++ smsc47m192_init_client(client); ++ ++ /* Register sysfs hooks */ ++ data->class_dev = hwmon_device_register(&client->dev); ++ if (IS_ERR(data->class_dev)) { ++ err = PTR_ERR(data->class_dev); ++ goto exit_detach; ++ } ++ ++ device_create_file(&client->dev, &sensor_dev_attr_in0_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in0_min.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in0_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in0_alarm.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in1_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in1_min.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in1_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in1_alarm.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in2_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in2_min.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in2_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in2_alarm.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in3_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in3_min.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in3_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in3_alarm.dev_attr); ++ ++ /* Pin 110 is either in4 (+12V) or VID4 */ ++ config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); ++ if (!(config & 0x20)) { ++ device_create_file(&client->dev, ++ &sensor_dev_attr_in4_input.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_in4_min.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_in4_max.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_in4_alarm.dev_attr); ++ } ++ device_create_file(&client->dev, &sensor_dev_attr_in5_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in5_min.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in5_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in5_alarm.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in6_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in6_min.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in6_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in6_alarm.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in7_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in7_min.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in7_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_in7_alarm.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp1_min.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_temp1_offset.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp1_alarm.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp2_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp2_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp2_min.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_temp2_offset.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp2_alarm.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_temp2_input_fault.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp3_input.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp3_max.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp3_min.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_temp3_offset.dev_attr); ++ device_create_file(&client->dev, &sensor_dev_attr_temp3_alarm.dev_attr); ++ device_create_file(&client->dev, ++ &sensor_dev_attr_temp3_input_fault.dev_attr); ++ device_create_file(&client->dev, &dev_attr_cpu0_vid); ++ device_create_file(&client->dev, &dev_attr_vrm); ++ ++ return 0; ++ ++exit_detach: ++ i2c_detach_client(client); ++exit_free: ++ kfree(data); ++exit: ++ return err; ++} ++ ++static int smsc47m192_detach_client(struct i2c_client *client) ++{ ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ int err; ++ ++ hwmon_device_unregister(data->class_dev); ++ ++ if ((err = i2c_detach_client(client))) ++ return err; ++ ++ kfree(data); ++ ++ return 0; ++} ++ ++static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct smsc47m192_data *data = i2c_get_clientdata(client); ++ int i, config; ++ ++ down(&data->update_lock); ++ ++ if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ++ || !data->valid) { ++ u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); ++ ++ dev_dbg(&client->dev, "Starting smsc47m192 update\n"); ++ ++ for (i = 0; i <= 7; i++) { ++ data->in[i] = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_IN(i)); ++ data->in_min[i] = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_IN_MIN(i)); ++ data->in_max[i] = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_IN_MAX(i)); ++ } ++ for (i = 0; i < 3; i++) { ++ data->temp[i] = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_TEMP[i]); ++ data->temp_max[i] = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_TEMP_MAX[i]); ++ data->temp_min[i] = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_TEMP_MIN[i]); ++ } ++ for (i = 1; i < 3; i++) ++ data->temp_offset[i] = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_TEMP_OFFSET(i)); ++ /* first offset is temp_offset[0] if SFR bit 4 is set, ++ temp_offset[1] otherwise */ ++ if (sfr & 0x10) { ++ data->temp_offset[0] = data->temp_offset[1]; ++ data->temp_offset[1] = 0; ++ } else ++ data->temp_offset[0] = 0; ++ ++ data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID) ++ & 0x0f; ++ config = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_CONFIG); ++ if (config & 0x20) ++ data->vid |= (i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_VID4) & 0x01) << 4; ++ data->alarms = i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_ALARM1) | ++ (i2c_smbus_read_byte_data(client, ++ SMSC47M192_REG_ALARM2) << 8); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++ ++ return data; ++} ++ ++static int __init smsc47m192_init(void) ++{ ++ return i2c_add_driver(&smsc47m192_driver); ++} ++ ++static void __exit smsc47m192_exit(void) ++{ ++ i2c_del_driver(&smsc47m192_driver); ++} ++ ++MODULE_AUTHOR("Hartmut Rick <linux@rick.claranet.de>"); ++MODULE_DESCRIPTION("SMSC47M192 driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(smsc47m192_init); ++module_exit(smsc47m192_exit); +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-sis96x.c 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-sis96x.c 2006-03-22 17:06:16.000000000 +0100 +@@ -43,13 +43,6 @@ + #include <linux/init.h> + #include <asm/io.h> + +-/* +- HISTORY: +- 2003-05-11 1.0.0 Updated from lm_sensors project for kernel 2.5 +- (was i2c-sis645.c from lm_sensors 2.7.0) +-*/ +-#define SIS96x_VERSION "1.0.0" +- + /* base address register in PCI config space */ + #define SIS96x_BAR 0x04 + +@@ -256,7 +249,7 @@ + + static struct i2c_adapter sis96x_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +@@ -337,7 +330,6 @@ + + static int __init i2c_sis96x_init(void) + { +- printk(KERN_INFO "i2c-sis96x version %s\n", SIS96x_VERSION); + return pci_register_driver(&sis96x_driver); + } + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-parport-light.c 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-parport-light.c 2006-03-22 17:06:16.000000000 +0100 +@@ -111,7 +111,7 @@ + + static struct i2c_adapter parport_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .id = I2C_HW_B_LP, + .algo_data = &parport_algo_data, + .name = "Parallel port adapter (light)", +@@ -121,9 +121,14 @@ + + static int __init i2c_parport_init(void) + { +- if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { ++ if (type < 0) { ++ printk(KERN_WARNING "i2c-parport: adapter type unspecified\n"); ++ return -ENODEV; ++ } ++ ++ if (type >= ARRAY_SIZE(adapter_parm)) { + printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); +- type = 0; ++ return -ENODEV; + } + + if (base == 0) { +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-parport.h 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-parport.h 2006-03-22 17:06:16.000000000 +0100 +@@ -90,7 +90,7 @@ + }, + }; + +-static int type; ++static int type = -1; + module_param(type, int, 0); + MODULE_PARM_DESC(type, + "Type of adapter:\n" +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-parport.c 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-parport.c 2006-03-22 17:06:16.000000000 +0100 +@@ -146,7 +146,7 @@ + + static struct i2c_adapter parport_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .id = I2C_HW_B_LP, + .name = "Parallel port adapter", + }; +@@ -241,9 +241,14 @@ + + static int __init i2c_parport_init(void) + { +- if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { ++ if (type < 0) { ++ printk(KERN_WARNING "i2c-parport: adapter type unspecified\n"); ++ return -ENODEV; ++ } ++ ++ if (type >= ARRAY_SIZE(adapter_parm)) { + printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); +- type = 0; ++ return -ENODEV; + } + + return parport_register_driver(&i2c_parport_driver); +--- linux-2.6.16.orig/Documentation/i2c/busses/i2c-parport 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/Documentation/i2c/busses/i2c-parport 2006-03-22 17:06:16.000000000 +0100 +@@ -12,18 +12,22 @@ + teletext adapters) + + It currently supports the following devices: +- * Philips adapter +- * home brew teletext adapter +- * Velleman K8000 adapter +- * ELV adapter +- * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032) +- * Barco LPT->DVI (K5800236) adapter ++ * (type=0) Philips adapter ++ * (type=1) home brew teletext adapter ++ * (type=2) Velleman K8000 adapter ++ * (type=3) ELV adapter ++ * (type=4) Analog Devices ADM1032 evaluation board ++ * (type=5) Analog Devices evaluation boards: ADM1025, ADM1030, ADM1031 ++ * (type=6) Barco LPT->DVI (K5800236) adapter + + These devices use different pinout configurations, so you have to tell + the driver what you have, using the type module parameter. There is no + way to autodetect the devices. Support for different pinout configurations + can be easily added when needed. + ++Earlier kernels defaulted to type=0 (Philips). But now, if the type ++parameter is missing, the driver will simply fail to initialize. ++ + + Building your own adapter + ------------------------- +--- linux-2.6.16.orig/Documentation/i2c/writing-clients 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/Documentation/i2c/writing-clients 2006-03-22 17:06:16.000000000 +0100 +@@ -28,7 +28,9 @@ + .driver = { + .name = "foo", + }, +- .attach_adapter = &foo_attach_adapter, ++ .class = I2C_CLASS_SOMETHING, ++ .address_data = &addr_data, ++ .detect_client = &foo_detect_client, + .detach_client = &foo_detach_client, + .command = &foo_command /* may be NULL */ + } +@@ -141,8 +143,8 @@ + are defined in i2c.h to help you support them, as well as a generic + detection algorithm. + +-You do not have to use this parameter interface; but don't try to use +-function i2c_probe() if you don't. ++You do not have to use this parameter interface; but then the i2c core won't ++be able to probe for devices for you. + + NOTE: If you want to write a `sensors' driver, the interface is slightly + different! See below. +@@ -201,35 +203,49 @@ + ----------------------- + + Whenever a new adapter is inserted, or for all adapters if the driver is +-being registered, the callback attach_adapter() is called. Now is the +-time to determine what devices are present on the adapter, and to register +-a client for each of them. +- +-The attach_adapter callback is really easy: we just call the generic +-detection function. This function will scan the bus for us, using the +-information as defined in the lists explained above. If a device is +-detected at a specific address, another callback is called. ++being registered, your driver may be notified through one of two ++callbacks, depending on the degree of control you need to exercise over ++the probing process. This is the time to determine what devices are ++present on the adapter and to register a client for each device your ++driver supports. ++ ++The easiest way to handle the probing process is to simply set the `class', ++`address_data', and `detect_client' fields in the i2c_driver structure. ++The `class' field is a bitmask of all the adapter classes which should be ++probed for devices supported by this driver. You should set it to one of ++the I2C_CLASS_* constants defined in i2c.h. The `address_data' field ++should be set to `&addr_data', which is defined by the macros explained ++above, so you do not have to define it yourself. When a new adapter is ++attached, the bus is scanned for the addresses defined in the lists above, ++and the detect_client callback gets called when a device is detected at a ++specific address. ++ ++If you prefer, you can omit the `class', `address_data', and ++`detect_client' fields from your i2c_driver structure, and instead set ++`attach_adapter'. The `attach_adapter' callback gets called every time a ++new adapter is attached and the bus needs to be scanned, so if you need to ++perform any special checks or configuration before you scan a bus for ++devices, you should use attach_adapter. If the bus is suitable, you can ++then call the generic i2c_probe function to scan for the addresses in the ++lists explained above, and the callback passed in the third parameter will ++get called for each device detected. + + int foo_attach_adapter(struct i2c_adapter *adapter) + { + return i2c_probe(adapter,&addr_data,&foo_detect_client); + } + +-Remember, structure `addr_data' is defined by the macros explained above, +-so you do not have to define it yourself. +- +-The i2c_probe function will call the foo_detect_client +-function only for those i2c addresses that actually have a device on +-them (unless a `force' parameter was used). In addition, addresses that +-are already in use (by some other registered client) are skipped. ++With either mechanism, addresses that are already in use (by some other ++registered client) are skipped. + + + The detect client function + -------------------------- + +-The detect client function is called by i2c_probe. The `kind' parameter +-contains -1 for a probed detection, 0 for a forced detection, or a positive +-number for a forced detection with a chip type forced. ++The detect client function is called by the address probing mechanism. ++The `kind' parameter contains -1 for a probed detection, 0 for a forced ++detection, or a positive number for a forced detection with a chip type ++forced. + + Below, some things are only needed if this is a `sensors' driver. Those + parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */ +--- linux-2.6.16.orig/Documentation/i2c/porting-clients 2006-03-22 17:06:00.000000000 +0100 ++++ linux-2.6.16/Documentation/i2c/porting-clients 2006-03-22 17:06:16.000000000 +0100 +@@ -100,6 +100,9 @@ + Drop any 24RF08 corruption prevention you find, as this is now done + at the i2c-core level, and doing it twice voids it. + Don't add I2C_CLIENT_ALLOW_USE to client->flags, it's the default now. ++ If you want auto probing of your driver, use driver->addr_data ++ (this is strongly encouraged if your attach_adapter is a one-liner ++ which calls i2c_probe). + + * [Init] Limits must not be set by the driver (can be done later in + user-space). Chip should not be reset default (although a module +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-ali1563.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-ali1563.c 2006-03-22 17:06:16.000000000 +0100 +@@ -374,7 +374,7 @@ + + static struct i2c_adapter ali1563_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &ali1563_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-ali15x3.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-ali15x3.c 2006-03-22 17:06:16.000000000 +0100 +@@ -470,7 +470,7 @@ + + static struct i2c_adapter ali15x3_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-amd756.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-amd756.c 2006-03-22 17:06:16.000000000 +0100 +@@ -301,7 +301,7 @@ + + struct i2c_adapter amd756_smbus = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-amd8111.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-amd8111.c 2006-03-22 17:06:16.000000000 +0100 +@@ -351,7 +351,7 @@ + smbus->adapter.owner = THIS_MODULE; + snprintf(smbus->adapter.name, I2C_NAME_SIZE, + "SMBus2 AMD8111 adapter at %04x", smbus->base); +- smbus->adapter.class = I2C_CLASS_HWMON; ++ smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DATA; + smbus->adapter.algo = &smbus_algorithm; + smbus->adapter.algo_data = smbus; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-elektor.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-elektor.c 2006-03-22 17:06:16.000000000 +0100 +@@ -202,7 +202,7 @@ + + static struct i2c_adapter pcf_isa_ops = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .id = I2C_HW_P_ELEK, + .algo_data = &pcf_isa_data, + .name = "i2c-elektor", +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-i801.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-i801.c 2006-03-22 17:06:16.000000000 +0100 +@@ -513,7 +513,7 @@ + + static struct i2c_adapter i801_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-i810.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-i810.c 2006-03-22 17:06:16.000000000 +0100 +@@ -188,6 +188,7 @@ + + static struct i2c_adapter i810_ddc_adapter = { + .owner = THIS_MODULE, ++ .class = I2C_CLASS_DATA, + .name = "I810/I815 DDC Adapter", + .algo_data = &i810_ddc_bit_data, + }; +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-ibm_iic.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-ibm_iic.c 2006-03-22 17:06:16.000000000 +0100 +@@ -724,8 +724,9 @@ + adap = &dev->adap; + strcpy(adap->name, "IBM IIC"); + i2c_set_adapdata(adap, dev); ++ adap->owner = THIS_MODULE; + adap->id = I2C_HW_OCP; +- adap->class = I2C_CLASS_HWMON; ++ adap->class = I2C_CLASS_HWMON | I2C_CLASS_DATA; + adap->algo = &iic_algo; + adap->client_register = NULL; + adap->client_unregister = NULL; +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-ixp2000.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-ixp2000.c 2006-03-22 17:06:16.000000000 +0100 +@@ -117,7 +117,9 @@ + drv_data->algo_data.mdelay = 6; + drv_data->algo_data.timeout = 100; + +- drv_data->adapter.id = I2C_HW_B_IXP2000, ++ drv_data->adapter.owner = THIS_MODULE; ++ drv_data->adapter.class = I2C_CLASS_DATA; ++ drv_data->adapter.id = I2C_HW_B_IXP2000; + strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, + I2C_NAME_SIZE); + drv_data->adapter.algo_data = &drv_data->algo_data, +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-mpc.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-mpc.c 2006-03-22 17:06:16.000000000 +0100 +@@ -283,7 +283,7 @@ + .name = "MPC adapter", + .id = I2C_HW_MPC107, + .algo = &mpc_algo, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .timeout = 1, + .retries = 1 + }; +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-mv64xxx.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-mv64xxx.c 2006-03-22 17:06:16.000000000 +0100 +@@ -519,7 +519,7 @@ + drv_data->adapter.id = I2C_HW_MV64XXX; + drv_data->adapter.algo = &mv64xxx_i2c_algo; + drv_data->adapter.owner = THIS_MODULE; +- drv_data->adapter.class = I2C_CLASS_HWMON; ++ drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DATA; + drv_data->adapter.timeout = pdata->timeout; + drv_data->adapter.retries = pdata->retries; + platform_set_drvdata(pd, drv_data); +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-nforce2.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-nforce2.c 2006-03-22 17:06:16.000000000 +0100 +@@ -113,7 +113,7 @@ + + static struct i2c_adapter nforce2_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-prosavage.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-prosavage.c 2006-03-22 17:06:16.000000000 +0100 +@@ -172,6 +172,7 @@ + { + int ret; + p->adap.owner = THIS_MODULE; ++ p->adap.class = I2C_CLASS_DATA; + p->adap.id = I2C_HW_B_S3VIA; + p->adap.algo_data = &p->algo; + p->adap.dev.parent = &dev->dev; +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-s3c2410.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-s3c2410.c 2006-03-22 17:06:16.000000000 +0100 +@@ -580,7 +580,7 @@ + .owner = THIS_MODULE, + .algo = &s3c24xx_i2c_algorithm, + .retries = 2, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + }, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-savage4.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-savage4.c 2006-03-22 17:06:16.000000000 +0100 +@@ -146,6 +146,7 @@ + + static struct i2c_adapter savage4_i2c_adapter = { + .owner = THIS_MODULE, ++ .class = I2C_CLASS_DATA, + .name = "I2C Savage4 adapter", + .algo_data = &sav_i2c_bit_data, + }; +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-sibyte.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-sibyte.c 2006-03-22 17:06:16.000000000 +0100 +@@ -31,7 +31,7 @@ + { + .owner = THIS_MODULE, + .id = I2C_HW_SIBYTE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = NULL, + .algo_data = &sibyte_board_data[0], + .name = "SiByte SMBus 0", +@@ -39,7 +39,7 @@ + { + .owner = THIS_MODULE, + .id = I2C_HW_SIBYTE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = NULL, + .algo_data = &sibyte_board_data[1], + .name = "SiByte SMBus 1", +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-sis5595.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-sis5595.c 2006-03-22 17:06:16.000000000 +0100 +@@ -365,7 +365,7 @@ + + static struct i2c_adapter sis5595_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-sis630.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-sis630.c 2006-03-22 17:06:16.000000000 +0100 +@@ -457,7 +457,7 @@ + + static struct i2c_adapter sis630_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-stub.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-stub.c 2006-03-22 17:06:16.000000000 +0100 +@@ -115,7 +115,7 @@ + + static struct i2c_adapter stub_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_ALL, + .algo = &smbus_algorithm, + .name = "SMBus stub driver", + }; +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-via.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-via.c 2006-03-22 17:06:16.000000000 +0100 +@@ -87,7 +87,7 @@ + + static struct i2c_adapter vt586b_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .name = "VIA i2c", + .algo_data = &bit_data, + }; +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-viapro.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-viapro.c 2006-03-22 17:06:16.000000000 +0100 +@@ -304,7 +304,7 @@ + + static struct i2c_adapter vt596_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_HWMON, ++ .class = I2C_CLASS_HWMON | I2C_CLASS_DATA, + .algo = &smbus_algorithm, + }; + +--- linux-2.6.16.orig/drivers/i2c/busses/i2c-voodoo3.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/i2c/busses/i2c-voodoo3.c 2006-03-22 17:06:16.000000000 +0100 +@@ -183,7 +183,7 @@ + + static struct i2c_adapter voodoo3_ddc_adapter = { + .owner = THIS_MODULE, +- .class = I2C_CLASS_DDC, ++ .class = I2C_CLASS_DATA, + .name = "DDC Voodoo3/Banshee adapter", + .algo_data = &voo_ddc_bit_data, + }; +--- linux-2.6.16.orig/drivers/video/aty/radeon_i2c.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/video/aty/radeon_i2c.c 2006-03-22 17:06:16.000000000 +0100 +@@ -75,6 +75,7 @@ + + strcpy(chan->adapter.name, name); + chan->adapter.owner = THIS_MODULE; ++ chan->adapter.class = I2C_CLASS_DATA; + chan->adapter.id = I2C_HW_B_RADEON; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &chan->rinfo->pdev->dev; +--- linux-2.6.16.orig/drivers/video/i810/i810-i2c.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/video/i810/i810-i2c.c 2006-03-22 17:06:16.000000000 +0100 +@@ -85,12 +85,14 @@ + return ((i810_readl(mmio, chan->ddc_base) & SDA_VAL_IN) != 0); + } + +-static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name) ++static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name, ++ unsigned long i2c_class) + { + int rc; + + strcpy(chan->adapter.name, name); + chan->adapter.owner = THIS_MODULE; ++ chan->adapter.class = i2c_class; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &chan->par->dev->dev; + chan->adapter.id = I2C_HW_B_I810; +@@ -130,11 +132,11 @@ + par->chan[2].par = par; + + par->chan[0].ddc_base = GPIOA; +- i810_setup_i2c_bus(&par->chan[0], "I810-DDC"); ++ i810_setup_i2c_bus(&par->chan[0], "I810-DDC", I2C_CLASS_DATA); + par->chan[1].ddc_base = GPIOB; +- i810_setup_i2c_bus(&par->chan[1], "I810-I2C"); ++ i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 0); + par->chan[2].ddc_base = GPIOC; +- i810_setup_i2c_bus(&par->chan[2], "I810-GPIOC"); ++ i810_setup_i2c_bus(&par->chan[2], "I810-GPIOC", 0); + } + + void i810_delete_i2c_busses(struct i810fb_par *par) +--- linux-2.6.16.orig/drivers/video/matrox/i2c-matroxfb.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/video/matrox/i2c-matroxfb.c 2006-03-22 17:06:16.000000000 +0100 +@@ -104,13 +104,15 @@ + }; + + static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, +- unsigned int data, unsigned int clock, const char* name) { ++ unsigned int data, unsigned int clock, const char* name, ++ unsigned int i2c_class) { + int err; + + b->minfo = minfo; + b->mask.data = data; + b->mask.clock = clock; + b->adapter = matrox_i2c_adapter_template; ++ b->adapter.class = i2c_class; + snprintf(b->adapter.name, I2C_NAME_SIZE, name, + minfo->fbcon.node); + i2c_set_adapdata(&b->adapter, b); +@@ -160,22 +162,28 @@ + switch (ACCESS_FBINFO(chip)) { + case MGA_2064: + case MGA_2164: +- err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1B_DATA, DDC1B_CLK, "DDC:fb%u #0"); ++ err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1B_DATA, ++ DDC1B_CLK, "DDC:fb%u #0", ++ I2C_CLASS_DATA); + break; + default: +- err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1_DATA, DDC1_CLK, "DDC:fb%u #0"); ++ err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1_DATA, ++ DDC1_CLK, "DDC:fb%u #0", ++ I2C_CLASS_DATA); + break; + } + if (err) + goto fail_ddc1; + if (ACCESS_FBINFO(devflags.dualhead)) { +- err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, "DDC:fb%u #1"); ++ err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, ++ "DDC:fb%u #1", I2C_CLASS_DATA); + if (err == -ENODEV) { + printk(KERN_INFO "i2c-matroxfb: VGA->TV plug detected, DDC unavailable.\n"); + } else if (err) + printk(KERN_INFO "i2c-matroxfb: Could not register secondary output i2c bus. Continuing anyway.\n"); + /* Register maven bus even on G450/G550 */ +- err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, "MAVEN:fb%u"); ++ err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, ++ "MAVEN:fb%u", 0); + if (err) + printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n"); + } +--- linux-2.6.16.orig/drivers/video/nvidia/nv_i2c.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/video/nvidia/nv_i2c.c 2006-03-22 17:06:16.000000000 +0100 +@@ -96,6 +96,7 @@ + + strcpy(chan->adapter.name, name); + chan->adapter.owner = THIS_MODULE; ++ chan->adapter.class = I2C_CLASS_DATA; + chan->adapter.id = I2C_HW_B_NVIDIA; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &chan->par->pci_dev->dev; +--- linux-2.6.16.orig/drivers/video/riva/rivafb-i2c.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/video/riva/rivafb-i2c.c 2006-03-22 17:06:16.000000000 +0100 +@@ -98,6 +98,7 @@ + + strcpy(chan->adapter.name, name); + chan->adapter.owner = THIS_MODULE; ++ chan->adapter.class = I2C_CLASS_DATA; + chan->adapter.id = I2C_HW_B_RIVA; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &chan->par->pdev->dev; +--- linux-2.6.16.orig/drivers/video/savage/savagefb-i2c.c 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/video/savage/savagefb-i2c.c 2006-03-22 17:06:16.000000000 +0100 +@@ -145,6 +145,7 @@ + if (chan->par) { + strcpy(chan->adapter.name, name); + chan->adapter.owner = THIS_MODULE; ++ chan->adapter.class = I2C_CLASS_DATA; + chan->adapter.id = I2C_HW_B_SAVAGE; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &chan->par->pcidev->dev; +--- linux-2.6.16.orig/drivers/media/video/zoran.h 2006-03-22 17:05:59.000000000 +0100 ++++ linux-2.6.16/drivers/media/video/zoran.h 2006-03-22 17:06:16.000000000 +0100 +@@ -355,6 +355,7 @@ + enum card_type type; + char name[32]; + u16 i2c_decoder, i2c_encoder; /* I2C types */ ++ u16 decoder_addr, encoder_addr; /* I2C chips address */ + u16 video_vfe, video_codec; /* videocodec types */ + u16 audio_chip; /* audio type */ + u16 vendor_id, device_id; /* subsystem vendor/device ID */ diff --git a/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 b/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 deleted file mode 100644 index ea23ff47d3..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc4-ide2 +++ /dev/null @@ -1,18474 +0,0 @@ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/arch/i386/pci/fixup.c linux-2.6.16-rc4/arch/i386/pci/fixup.c ---- linux.vanilla-2.6.16-rc4/arch/i386/pci/fixup.c 2006-02-20 11:22:15.000000000 +0000 -+++ linux-2.6.16-rc4/arch/i386/pci/fixup.c 2006-02-01 14:49:17.000000000 +0000 -@@ -74,52 +74,6 @@ - } - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810); - --static void __devinit pci_fixup_ide_bases(struct pci_dev *d) --{ -- int i; -- -- /* -- * PCI IDE controllers use non-standard I/O port decoding, respect it. -- */ -- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) -- return; -- DBG("PCI: IDE base address fixup for %s\n", pci_name(d)); -- for(i=0; i<4; i++) { -- struct resource *r = &d->resource[i]; -- if ((r->start & ~0x80) == 0x374) { -- r->start |= 2; -- r->end = r->start; -- } -- } --} --DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -- --static void __devinit pci_fixup_ide_trash(struct pci_dev *d) --{ -- int i; -- -- /* -- * Runs the fixup only for the first IDE controller -- * (Shai Fultheim - shai@ftcon.com) -- */ -- static int called = 0; -- if (called) -- return; -- called = 1; -- -- /* -- * There exist PCI IDE controllers which have utter garbage -- * in first four base registers. Ignore that. -- */ -- DBG("PCI: IDE base address trash cleared for %s\n", pci_name(d)); -- for(i=0; i<4; i++) -- d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0; --} --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash); --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_trash); --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_trash); --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_trash); -- - static void __devinit pci_fixup_latency(struct pci_dev *d) - { - /* -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/pci/probe.c linux-2.6.16-rc4/drivers/pci/probe.c ---- linux.vanilla-2.6.16-rc4/drivers/pci/probe.c 2006-02-20 11:22:17.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/pci/probe.c 2006-02-01 15:56:28.000000000 +0000 -@@ -627,6 +627,7 @@ - static int pci_setup_device(struct pci_dev * dev) - { - u32 class; -+ u16 cmd; - - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), - dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); -@@ -654,6 +655,31 @@ - pci_read_bases(dev, 6, PCI_ROM_ADDRESS); - pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); - pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); -+ -+ /* -+ * Do the ugly legacy mode stuff here rather than broken chip -+ * quirk code. Legacy mode ATA controllers have fixed -+ * addresses. These are not always echoed in BAR0-3, and -+ * BAR0-3 in a few cases contain junk! -+ */ -+ if (class == PCI_CLASS_STORAGE_IDE) { -+ u8 progif; -+ pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); -+ if ((progif & 5) != 5) { -+ dev->resource[0].start = 0x1F0; -+ dev->resource[0].end = 0x1F7; -+ dev->resource[0].flags = IORESOURCE_IO; -+ dev->resource[1].start = 0x3F6; -+ dev->resource[1].end = 0x3F6; -+ dev->resource[1].flags = IORESOURCE_IO; -+ dev->resource[2].start = 0x170; -+ dev->resource[2].end = 0x177; -+ dev->resource[2].flags = IORESOURCE_IO; -+ dev->resource[3].start = 0x376; -+ dev->resource[3].end = 0x376; -+ dev->resource[3].flags = IORESOURCE_IO; -+ } -+ } - break; - - case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/ata_generic.c linux-2.6.16-rc4/drivers/scsi/ata_generic.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/ata_generic.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/ata_generic.c 2006-02-16 15:35:41.000000000 +0000 -@@ -0,0 +1,241 @@ -+/* -+ * ata_generic.c - Generic PATA/SATA controller driver. -+ * Copyright 2005 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * Elements from ide/pci/generic.c -+ * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> -+ * Portions (C) Copyright 2002 Red Hat Inc <alan@redhat.com> -+ * -+ * May be copied or modified under the terms of the GNU General Public License -+ * -+ * Driver for PCI IDE interfaces implementing the standard bus mastering -+ * interface functionality. This assumes the BIOS did the drive set up and -+ * tuning for us. By default we do not grab all IDE class devices as they -+ * may have other drivers or need fixups to avoid problems. Instead we keep -+ * a default list of stuff without documentation/driver that appears to -+ * work. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include "scsi.h" -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "generic" -+#define DRV_VERSION "0.1" -+ -+/* -+ * A generic parallel ATA driver using libata -+ */ -+ -+static void genpata_phy_reset(struct ata_port *ap) -+{ -+ /* We know the BIOS already did the mode work. Don't tempt any -+ one else to "fix" things */ -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * genpata_set_mode - mode setting -+ * @ap: interface to set up -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. -+ * The BIOS configured everything. Our job is not to fiddle. We -+ * read the dma enabled bits from the PCI configuration of the device -+ * and respect them. -+ */ -+ -+static void genpata_set_mode(struct ata_port *ap) -+{ -+ int dma_enabled; -+ int i; -+ -+ /* Bits 5 and 6 indicate if DMA is active on master/slave */ -+ dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ /* We don't really care */ -+ dev->pio_mode = XFER_PIO_0; -+ dev->dma_mode = XFER_MW_DMA_0; -+ /* We do need the right mode information for DMA or PIO -+ and this comes from the current configuration flags */ -+ /* FIXME: at some point in the future this should become -+ a library helper which reads the disk modes from the -+ disk as well */ -+ if (dma_enabled & (1 << (5 + i))) { -+ dev->xfer_mode = XFER_MW_DMA_0; -+ dev->xfer_shift = ATA_SHIFT_MWDMA; -+ dev->flags &= ~ATA_DFLAG_PIO; -+ } else { -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ } -+ } -+} -+ -+static struct scsi_host_template genpata_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations genpata_port_ops = { -+ .set_mode = genpata_set_mode, -+ -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = genpata_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .data_xfer = ata_pio_data_xfer, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int ide_generic_all; /* Set to claim all devices */ -+ -+static int __init ide_generic_all_on(char *unused) -+{ -+ ide_generic_all = 1; -+ printk(KERN_INFO "ATA generic will claim all unknown PCI IDE class storage controllers.\n"); -+ return 1; -+} -+ -+__setup("all-generic-ide", ide_generic_all_on); -+ -+/** -+ * pata_generic_init - attach generic IDE -+ * @dev: PCI device found -+ * @id: match entry -+ * -+ * Called each time a matching IDE interface is found. We check if the -+ * interface is one we wish to claim and if so we perform any chip -+ * specific hacks then let the ATA layer do the heavy lifting. -+ */ -+ -+static int pata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ u16 command; -+ static struct ata_port_info info = { -+ .sht = &genpata_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_IRQ_MASK, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &genpata_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ /* Don't use the generic entry unless instructed to do so */ -+ if (id->driver_data == 1 && ide_generic_all == 0) -+ return -ENODEV; -+ -+ /* Devices that need care */ -+ if (dev->vendor == PCI_VENDOR_ID_UMC && -+ dev->device == PCI_DEVICE_ID_UMC_UM8886A && -+ (!(PCI_FUNC(dev->devfn) & 1))) -+ return -ENODEV; -+ -+ if (dev->vendor == PCI_VENDOR_ID_OPTI && -+ dev->device == PCI_DEVICE_ID_OPTI_82C558 && -+ (!(PCI_FUNC(dev->devfn) & 1))) -+ return -ENODEV; -+ -+ /* Don't re-enable devices in generic mode or we will break some -+ motherboards with disabled and unused IDE controllers */ -+ pci_read_config_word(dev, PCI_COMMAND, &command); -+ if (!(command & PCI_COMMAND_IO)) -+ return -ENODEV; -+ -+ if (dev->vendor == PCI_VENDOR_ID_AL) -+ ata_pci_clear_simplex(dev); -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id pata_generic[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), }, -+ /* Must come last. If you add entries adjust this table appropriately */ -+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1}, -+ { 0, }, -+}; -+ -+static struct pci_driver pata_generic_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pata_generic, -+ .probe = pata_generic_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init pata_generic_init(void) -+{ -+ return pci_module_init(&pata_generic_pci_driver); -+} -+ -+ -+static void __exit pata_generic_exit(void) -+{ -+ pci_unregister_driver(&pata_generic_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for generic ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pata_generic); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(pata_generic_init); -+module_exit(pata_generic_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/ata_piix.c linux-2.6.16-rc4/drivers/scsi/ata_piix.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/ata_piix.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/ata_piix.c 2006-02-20 20:06:17.000000000 +0000 -@@ -91,9 +91,10 @@ - #include <linux/device.h> - #include <scsi/scsi_host.h> - #include <linux/libata.h> -+#include <linux/ata.h> - - #define DRV_NAME "ata_piix" --#define DRV_VERSION "1.05" -+#define DRV_VERSION "1.05-ac7" - - enum { - PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ -@@ -122,6 +123,17 @@ - piix4_pata = 2, - ich6_sata = 3, - ich6_sata_ahci = 4, -+ ich0_pata = 5, -+ ich2_pata = 6, -+ ich3_pata = 7, -+ ich4_pata = 8, -+ cich_pata = 9, -+ piix3_pata = 10, -+ esb_pata = 11, -+ ich_pata = 12, -+ ich6_pata = 13, -+ ich7_pata = 14, -+ esb2_pata = 15, - - PIIX_AHCI_DEVICE = 6, - }; -@@ -130,20 +142,69 @@ - const struct pci_device_id *ent); - - static void piix_pata_phy_reset(struct ata_port *ap); -+static void ich_pata_phy_reset(struct ata_port *ap); - static void piix_sata_phy_reset(struct ata_port *ap); - static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); - static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); -+static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); - - static unsigned int in_module_init = 1; - - static const struct pci_device_id piix_pci_tbl[] = { - #ifdef ATA_ENABLE_PATA -+#if 0 -+ /* Neptune and earlier are simple PIO */ -+ /* 430HX and friends. MWDMA */ -+ { 0x8086, 0x122e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, -+ { 0x8086, 0x1230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, -+ /* Intel PIIX3 */ -+ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, -+#endif -+ /* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */ -+ /* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */ - { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, - { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, - { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, -+ /* Intel PIIX4 */ -+ { 0x8086, 0x7199, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, -+ /* Intel PIIX4 */ -+ { 0x8086, 0x7601, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, -+ /* Intel PIIX */ -+ { 0x8086, 0x84CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, -+ /* Intel ICH (i810, i815, i840) UDMA 66*/ -+ { 0x8086, 0x2411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata }, -+ /* Intel ICH0 : UDMA 33*/ -+ { 0x8086, 0x2421, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich0_pata }, -+ /* Intel ICH2M */ -+ { 0x8086, 0x244A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich2_pata }, -+ /* Intel ICH2 (i810E2, i845, 850, 860) UDMA 100 */ -+ { 0x8086, 0x244B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich2_pata }, -+ /* Intel ICH3M */ -+ { 0x8086, 0x248A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich3_pata }, -+ /* Intel ICH3 (E7500/1) UDMA 100 */ -+ { 0x8086, 0x248B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich3_pata }, -+#if 0 -+ { 0x8086, 0x24C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, dunno_pata }, -+#endif -+ /* Intel ICH4 (i845GV, i845E, i852, i855) UDMA 100 */ -+ { 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich4_pata }, -+ { 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich4_pata }, -+ /* Intel ICH5 */ -+ { 0x8086, 0x24DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, -+ /* C-ICH (i810E2) */ -+ { 0x8086, 0x245B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, cich_pata }, -+ /* ESB (855GME/875P + 6300ESB) UDMA 100 */ -+ { 0x8086, 0x25A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_pata }, -+ /* ICH6 (and 6) (i915) UDMA 100 */ -+ { 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_pata }, -+ /* ICH7/7-R (i945, i975) UDMA 100*/ -+ { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_pata }, -+ { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_pata }, - #endif -- -- /* NOTE: The following PCI ids must be kept in sync with the -+ /* -+ * SATA ports -+ * -+ * NOTE: The following PCI ids must be kept in sync with the - * list in drivers/pci/quirks.c. - */ - -@@ -213,6 +274,40 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations ich_pata_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = piix_set_piomode, -+ .set_dmamode = ich_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = ich_pata_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ -+ .data_xfer = ata_pio_data_xfer, - - .eng_timeout = ata_eng_timeout, - -@@ -242,6 +337,8 @@ - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - -+ .data_xfer = ata_pio_data_xfer, -+ - .eng_timeout = ata_eng_timeout, - - .irq_handler = ata_interrupt, -@@ -253,47 +350,39 @@ - }; - - static struct ata_port_info piix_port_info[] = { -- /* ich5_pata */ -+ /* ich5_pata: 0*/ - { - .sht = &piix_sht, - .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | - PIIX_FLAG_CHECKINTR, - .pio_mask = 0x1f, /* pio0-4 */ --#if 0 - .mwdma_mask = 0x06, /* mwdma1-2 */ --#else -- .mwdma_mask = 0x00, /* mwdma broken */ --#endif -- .udma_mask = 0x3f, /* udma0-5 */ -- .port_ops = &piix_pata_ops, -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &ich_pata_ops, - }, - -- /* ich5_sata */ -+ /* ich5_sata: 1 */ - { - .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | - PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ -- .udma_mask = 0x7f, /* udma0-6 */ -+ .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - -- /* piix4_pata */ -+ /* piix4_pata: 2 */ - { - .sht = &piix_sht, - .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, - .pio_mask = 0x1f, /* pio0-4 */ --#if 0 - .mwdma_mask = 0x06, /* mwdma1-2 */ --#else -- .mwdma_mask = 0x00, /* mwdma broken */ --#endif - .udma_mask = ATA_UDMA_MASK_40C, - .port_ops = &piix_pata_ops, - }, - -- /* ich6_sata */ -+ /* ich6_sata: 3 */ - { - .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | -@@ -301,11 +390,11 @@ - ATA_FLAG_SLAVE_POSS, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ -- .udma_mask = 0x7f, /* udma0-6 */ -+ .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - -- /* ich6_sata_ahci */ -+ /* ich6_sata_ahci: 4 */ - { - .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | -@@ -313,9 +402,119 @@ - ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ -- .udma_mask = 0x7f, /* udma0-6 */ -+ .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, -+ -+ /* ich0_pata: 5 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = ATA_UDMA4, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich2_pata: 6 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich3_pata: 7 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich4_pata: 8 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* cich_pata: 9 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* piix3_pata: 10 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .udma_mask = ATA_UDMA_MASK_40C, -+ .port_ops = &piix_pata_ops, -+ }, -+ -+ /* esb_pata: 11 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &piix_pata_ops, -+ }, -+ -+ /* ich_pata: 12 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = ATA_UDMA4, /* UDMA66 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich6_pata: 13 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = ATA_UDMA6, /* UDMA133 */ -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* ich7_pata: 14 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &ich_pata_ops, -+ }, -+ -+ /* esb2_pata: 15 */ -+ { -+ .sht = &piix_sht, -+ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, /* pio 0-4 */ -+ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &ich_pata_ops, -+ }, - }; - - static struct pci_bits piix_enable_bits[] = { -@@ -339,7 +538,7 @@ - * LOCKING: - * None (inherited from caller). - */ --static void piix_pata_cbl_detect(struct ata_port *ap) -+static void ich_pata_cbl_detect(struct ata_port *ap) - { - struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); - u8 tmp, mask; -@@ -366,8 +565,9 @@ - * piix_pata_phy_reset - Probe specified port on PATA host controller - * @ap: Port to probe - * -- * Probe PATA phy. -- * -+ * Probe PATA phy. Unlike the ICH we have no IOCFG register and -+ * don't do UDMA66+ anyway. -+ - * LOCKING: - * None (inherited from caller). - */ -@@ -381,11 +581,34 @@ - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return; - } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} - -- piix_pata_cbl_detect(ap); - -- ata_port_probe(ap); -+/** -+ * ich_pata_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * Probe PATA phy. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void ich_pata_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); - -+ if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ -+ ich_pata_cbl_detect(ap); -+ ata_port_probe(ap); - ata_bus_reset(ap); - } - -@@ -481,6 +704,13 @@ - unsigned int slave_port = 0x44; - u16 master_data; - u8 slave_data; -+ u8 udma_enable; -+ int control = 0; -+ -+ /* -+ * See Intel Document 298600-004 for the timing programing rules -+ * for ICH controllers. -+ */ - - static const /* ISP RTC */ - u8 timings[][2] = { { 0, 0 }, -@@ -489,20 +719,30 @@ - { 2, 1 }, - { 2, 3 }, }; - -+ if (pio > 2) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IE enable */ -+ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ - pci_read_config_word(dev, master_port, &master_data); - if (is_slave) { -+ /* Enable SITRE (seperate slave timing register) */ - master_data |= 0x4000; -- /* enable PPE, IE and TIME */ -- master_data |= 0x0070; -+ /* enable PPE1, IE1 and TIME1 as needed */ -+ master_data |= (control << 4); - pci_read_config_byte(dev, slave_port, &slave_data); - slave_data &= (ap->hard_port_no ? 0x0f : 0xf0); -- slave_data |= -- (timings[pio][0] << 2) | -- (timings[pio][1] << (ap->hard_port_no ? 4 : 0)); -+ /* Load the timing nibble for this slave */ -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); - } else { -+ /* Master keeps the bits in a different format */ - master_data &= 0xccf8; -- /* enable PPE, IE and TIME */ -- master_data |= 0x0007; -+ /* Enable PPE, IE and TIME as appropriate */ -+ master_data |= control; - master_data |= - (timings[pio][0] << 12) | - (timings[pio][1] << 8); -@@ -510,84 +750,165 @@ - pci_write_config_word(dev, master_port, master_data); - if (is_slave) - pci_write_config_byte(dev, slave_port, slave_data); -+ -+ /* Ensure the UDMA bit is off - it will be turned back on if -+ UDMA is selected */ -+ -+ if (ap->udma_mask) { -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ udma_enable &= ~(1 << (2 * ap->hard_port_no + adev->devno)); -+ pci_write_config_byte(dev, 0x48, udma_enable); -+ } - } - - /** -- * piix_set_dmamode - Initialize host controller PATA PIO timings -+ * do_piix_set_dmamode - Initialize host controller PATA PIO timings - * @ap: Port whose timings we are configuring -- * @adev: um -- * @udma: udma mode, 0 - 6 -+ * @adev: device to configure -+ * @isich: True if the device is an ICH and has IOCFG registers - * -- * Set UDMA mode for device, in host controller PCI config space. -+ * Set MW/UDMA mode for device, in host controller PCI config space. -+ * Note: We know the caller has already set the PIO mode. In doing -+ * so it has correctly set PPE, SITRE, IORDY and TIME1. We rely on that. - * - * LOCKING: - * None (inherited from caller). - */ - --static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, int isich) - { -- unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */ - struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -- u8 maslave = ap->hard_port_no ? 0x42 : 0x40; -- u8 speed = udma; -- unsigned int drive_dn = (ap->hard_port_no ? 2 : 0) + adev->devno; -- int a_speed = 3 << (drive_dn * 4); -- int u_flag = 1 << drive_dn; -- int v_flag = 0x01 << drive_dn; -- int w_flag = 0x10 << drive_dn; -- int u_speed = 0; -- int sitre; -- u16 reg4042, reg4a; -- u8 reg48, reg54, reg55; -- -- pci_read_config_word(dev, maslave, ®4042); -- DPRINTK("reg4042 = 0x%04x\n", reg4042); -- sitre = (reg4042 & 0x4000) ? 1 : 0; -- pci_read_config_byte(dev, 0x48, ®48); -- pci_read_config_word(dev, 0x4a, ®4a); -- pci_read_config_byte(dev, 0x54, ®54); -- pci_read_config_byte(dev, 0x55, ®55); -- -- switch(speed) { -- case XFER_UDMA_4: -- case XFER_UDMA_2: u_speed = 2 << (drive_dn * 4); break; -- case XFER_UDMA_6: -- case XFER_UDMA_5: -- case XFER_UDMA_3: -- case XFER_UDMA_1: u_speed = 1 << (drive_dn * 4); break; -- case XFER_UDMA_0: u_speed = 0 << (drive_dn * 4); break; -- case XFER_MW_DMA_2: -- case XFER_MW_DMA_1: break; -- default: -- BUG(); -- return; -- } -+ u8 master_port = ap->hard_port_no ? 0x42 : 0x40; -+ u16 master_data; -+ u8 speed = adev->dma_mode; -+ int devid = adev->devno + 2 * ap->hard_port_no; -+ u8 udma_enable; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; - -+ pci_read_config_word(dev, master_port, &master_data); -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ - if (speed >= XFER_UDMA_0) { -- if (!(reg48 & u_flag)) -- pci_write_config_byte(dev, 0x48, reg48 | u_flag); -- if (speed == XFER_UDMA_5) { -- pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag); -- } else { -- pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); -+ unsigned int udma = adev->dma_mode - XFER_UDMA_0; -+ u16 udma_timing; -+ u16 ideconf; -+ int u_clock, u_speed; -+ -+ /* -+ * UDMA is handled by a combination of clock switching and -+ * selection of dividers -+ * -+ * Handy rule: Odd modes are UDMATIMx 01, even are 02 -+ * except UDMA0 which is 00 -+ */ -+ u_speed = min(2 - (udma & 1), udma); -+ if (udma == 5) -+ u_clock = 0x1000; /* 100Mhz */ -+ else if (udma > 2) -+ u_clock = 1; /* 66Mhz */ -+ else -+ u_clock = 0; /* 33Mhz */ -+ -+ udma_enable |= (1 << devid); -+ -+ /* Load the CT/RP selection */ -+ pci_read_config_word(dev, 0x4A, &udma_timing); -+ udma_timing &= ~(3 << (4 * devid)); -+ udma_timing |= u_speed << (4 * devid); -+ pci_write_config_word(dev, 0x4A, udma_timing); -+ -+ if (isich) { -+ /* Select a 33/66/100Mhz clock */ -+ pci_read_config_word(dev, 0x54, &ideconf); -+ ideconf &= ~(0x1001 << devid); -+ ideconf |= u_clock << devid; -+ /* For ICH or later we should set bit 10 for better -+ performance (WR_PingPong_En) */ -+ pci_write_config_word(dev, 0x54, ideconf); - } -- if ((reg4a & a_speed) != u_speed) -- pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed); -- if (speed > XFER_UDMA_2) { -- if (!(reg54 & v_flag)) -- pci_write_config_byte(dev, 0x54, reg54 | v_flag); -- } else -- pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); - } else { -- if (reg48 & u_flag) -- pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); -- if (reg4a & a_speed) -- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); -- if (reg54 & v_flag) -- pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); -- if (reg55 & w_flag) -- pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally along with TIME1. PPE has already -+ * been set when the PIO timing was set. -+ */ -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ unsigned int control; -+ u8 slave_data; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ -+ control = 3; /* IORDY|TIME1 */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO into PIO0 */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ /* Enable DMA timing only */ -+ control |= 8; /* PIO cycles in PIO0 */ -+ -+ if (adev->devno) { /* Slave */ -+ master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ -+ master_data |= control << 4; -+ pci_read_config_byte(dev, 0x44, &slave_data); -+ slave_data &= (0x0F + 0xE1 * ap->hard_port_no); -+ /* Load the matching timing */ -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); -+ pci_write_config_byte(dev, 0x44, slave_data); -+ } else { /* Master */ -+ master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY -+ and master timing bits */ -+ master_data |= control; -+ master_data |= -+ (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ } -+ udma_enable &= ~(1 << devid); -+ pci_write_config_word(dev, master_port, master_data); - } -+ /* Don't scribble on 0x48 if the controller does not support UDMA */ -+ if (ap->udma_mask) -+ pci_write_config_byte(dev, 0x48, udma_enable); -+} -+ -+/** -+ * piix_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set MW/UDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ do_pata_set_dmamode(ap, adev, 0); -+} -+ -+/** -+ * ich_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set MW/UDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ do_pata_set_dmamode(ap, adev, 1); - } - - #define AHCI_PCI_BAR 5 -@@ -646,15 +967,15 @@ - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); - pci_read_config_word(pdev, 0x41, &cfg); - /* Only on the original revision: IDE DMA can hang */ -- if(rev == 0x00) -+ if (rev == 0x00) - no_piix_dma = 1; - /* On all revisions below 5 PXB bus lock must be disabled for IDE */ -- else if(cfg & (1<<14) && rev < 5) -+ else if (cfg & (1<<14) && rev < 5) - no_piix_dma = 2; - } -- if(no_piix_dma) -+ if (no_piix_dma) - dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n"); -- if(no_piix_dma == 2) -+ if (no_piix_dma == 2) - dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n"); - return no_piix_dma; - } -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/Kconfig linux-2.6.16-rc4/drivers/scsi/Kconfig ---- linux.vanilla-2.6.16-rc4/drivers/scsi/Kconfig 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/Kconfig 2006-02-20 17:27:24.000000000 +0000 -@@ -599,6 +599,316 @@ - depends on IDE=y && !BLK_DEV_IDE_SATA && (SCSI_SATA_AHCI || SCSI_ATA_PIIX) - default y - -+config SCSI_PATA_ALI -+ tristate "ALi PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the ALi ATA interfaces -+ found on the many ALi chipsets. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_AMD -+ tristate "AMD/NVidia PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the AMD and NVidia PATA -+ interfaces found on the chipsets for Athlon/Athlon64. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_ARTOP -+ tristate "ARTOP 6210/6260 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for ARTOP PATA controllers. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_ATIIXP -+ tristate "ATI PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the ATI ATA interfaces -+ found on the many ATI chipsets. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CMD64X -+ tristate "CMD64x PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the CMD64x series chips -+ except for the CMD640. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CS5520 -+ tristate "CS5510/5520 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the Cyrix 5510/5520 -+ companion chip used with the MediaGX/Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CS5530 -+ tristate "CS5530 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Cyrix/NatSemi/AMD CS5530 -+ companion chip used with the MediaGX/Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CS5535 -+ tristate "CS5535 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && X86 && !X86_64 && EXPERIMENTAL -+ help -+ This option enables support for the NatSemi/AMD CS5535 -+ companion chip used with the Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_CYPRESS -+ tristate "Cypress CY82C693 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Cypress/Contaq CY82C693 -+ chipset found in some Alpha systems -+ -+ If unsure, say N. -+ -+config SCSI_PATA_EFAR -+ tristate "EFAR SLC90E66 support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the EFAR SLC90E66 -+ IDE controller found on some older machines. -+ -+ If unsure, say N. -+ -+config SCSI_ATA_GENERIC -+ tristate "Generic PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for generic BIOS configured -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_HPT37X -+ tristate "HPT 370/370A/371/372/374/302 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the majority of the later HPT -+ PATA controllers via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_HPT3X2N -+ tristate "HPT 372N/302N PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the N variant HPT PATA -+ controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_HPT3X3 -+ tristate "HPT 343/363 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the HPT 343/363 -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_ISAPNP -+ tristate "ISA Plug and Play PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && EXPERIMENTAL -+ help -+ This option enables support for ISA plug & play ATA -+ controllers such as those found on old soundcards. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_IT8172 -+ tristate "IT8172 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the ITE 8172 PATA controller -+ via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_IT821X -+ tristate "IT821x PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the ITE 8211 and 8212 -+ PATA controllers via the new ATA layer, including RAID -+ mode. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_LEGACY -+ tristate "Legacy ISA PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for ISA bus legacy PATA -+ interfaces on ide2-5 and allows them to be accessed via -+ the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_MPIIX -+ tristate "Intel PATA MPIIX support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for MPIIX PATA support. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_NETCELL -+ tristate "NETCELL Revolution RAID support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the Netcell Revolution RAID -+ PATA controller. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_NS87410 -+ tristate "Nat Semi NS87410 PATA support (Experimental)" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the National Semiconductor -+ NS87410 PCI-IDE controller. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_OLDPIIX -+ tristate "Intel PATA old PIIX support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for early PIIX PATA interfaces. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_OPTI -+ tristate "OPTI621/6215 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables full PIO support for the early Opti ATA -+ controllers found on some old motherboards. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_PCMCIA -+ tristate "PCMCIA PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCMCIA -+ help -+ This option enables support for PCMCIA ATA interfaces, including -+ compact flash card adapters via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_PDC_OLD -+ tristate "Older Promise PATA controller support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Promise 20246, 20262, 20263, -+ 20265 and 20267 adapters. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_QDI -+ tristate "QDI VLB PATA support" -+ depends on SCSI_SATA -+ help -+ Support for QDI 6500 and 6580 PATA controllers on VESA local bus. -+ -+config SCSI_PATA_RADISYS -+ tristate "RADISYS 82600 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the RADISYS 82600 -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_RZ1000 -+ tristate "PC Tech RZ1000 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables basic support for the PC Tech RZ1000/1 -+ PATA controllers via the new ATA layer -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SC1200 -+ tristate "SC1200 PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the NatSemi/AMD SC1200 SoC -+ companion chip used with the Geode processor family. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SERVERWORKS -+ tristate "SERVERWORKS OSB4/CSB5/CSB6 PATA support (Experimental)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for the Serverworks OSB4/CSB5 and -+ CSB6 IDE controllers, via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SIL680 -+ tristate "CMD / Silicon Image 680 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for CMD / Silicon Image 680 PATA. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_SIS -+ tristate "SiS PATA support (Experimental)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ This option enables support for SiS PATA controllers -+ -+ If unsure, say N. -+ -+config SCSI_PATA_TRIFLEX -+ tristate "Compaq Triflex PATA support (Raving Lunatic)" -+ depends on SCSI_SATA && PCI && EXPERIMENTAL -+ help -+ Enable support for the Compaq 'Triflex' IDE controller as found -+ on many Compaq Pentium-Pro systems, via the new ATA layer. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_VIA -+ tristate "VIA PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for the VIA PATA interfaces -+ found on the many VIA chipsets. -+ -+ If unsure, say N. -+ -+config SCSI_PATA_WINBOND -+ tristate "Winbond SL82C105 PATA support" -+ depends on SCSI_SATA && PCI -+ help -+ This option enables support for SL82C105 PATA devices found in the -+ Netwinder and some other systems -+ -+ If unsure, say N. -+ -+ - config SCSI_BUSLOGIC - tristate "BusLogic SCSI support" - depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/libata-core.c linux-2.6.16-rc4/drivers/scsi/libata-core.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/libata-core.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/libata-core.c 2006-02-23 13:37:47.358092040 +0000 -@@ -68,9 +68,10 @@ - static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); - static void ata_set_mode(struct ata_port *ap); - static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); --static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift); -+static unsigned int ata_get_mode_mask(const struct ata_port *ap, struct ata_device *adev, int shift); - static int fgb(u32 bitmap); - static int ata_choose_xfer_mode(const struct ata_port *ap, -+ struct ata_device *adev, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out); - static void __ata_qc_complete(struct ata_queued_cmd *qc); -@@ -78,7 +79,7 @@ - static unsigned int ata_unique_id = 1; - static struct workqueue_struct *ata_wq; - --int atapi_enabled = 0; -+int atapi_enabled = 1; - module_param(atapi_enabled, int, 0444); - MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); - -@@ -1205,6 +1206,48 @@ - return 0; - } - -+static void ata_dev_check_hpa(struct ata_port *ap, struct ata_device *dev) -+{ -+ struct ata_taskfile tf; -+ unsigned long long true_size; -+ unsigned int err_mask; -+ -+ if (!ata_id_has_hpa(dev->id) || !ata_id_hpa_enabled(dev->id)) -+ return; -+ -+ /* Issue a query for HPA */ -+ ata_dev_select(ap, dev->devno, 1, 1); -+ ata_tf_init(ap, &tf, dev->devno); -+ -+ if (dev->flags & ATA_DFLAG_LBA48) { -+ tf.command = ATA_CMD_READ_NATIVE_MAX_EXT; -+ tf.device |= 0x40; -+ err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); -+ if (err_mask) -+ return; -+ /* Ok HPA is live */ -+ true_size = (tf.hob_lbah << 16) | (tf.hob_lbam << 8) | (tf.hob_lbal); -+ true_size <<= 24; -+ true_size |= (tf.lbah << 16) | (tf.lbam << 8) | tf.lbal; -+ } else { -+ tf.command = ATA_CMD_READ_NATIVE_MAX; -+ tf.device |= 0x40; -+ err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); -+ if (err_mask) -+ return; -+ /* Ok HPA is live */ -+ true_size = ((tf.device & 0x0F) << 24) | -+ (tf.lbah << 16) | -+ (tf.lbam << 8) | -+ tf.lbal; -+ } -+ dev->flags |= ATA_DFLAG_HPA; -+ /* Should save the HPA value and expose it for dmraid then -+ remove the clipping */ -+ printk(KERN_INFO "HPA present: true size %lld sectors.\n", -+ true_size + 1); -+} -+ - /** - * ata_dev_identify - obtain IDENTIFY x DEVICE page - * @ap: port on which device we wish to probe resides -@@ -1328,7 +1371,7 @@ - - /* ATA-specific feature tests */ - if (dev->class == ATA_DEV_ATA) { -- if (!ata_id_is_ata(dev->id)) /* sanity check */ -+ if (!ata_id_is_ata(dev->id) && !ata_id_is_cfa(dev->id)) /* sanity check */ - goto err_out_nosup; - - /* get major version */ -@@ -1400,6 +1443,13 @@ - } - - ap->host->max_cmd_len = 16; -+ -+ /* -+ * See if we have the HPA misfeature on the drive -+ */ -+#if 0 /* TESTING */ -+ ata_dev_check_hpa(ap, dev); -+#endif - } - - /* ATAPI-specific feature tests */ -@@ -1485,10 +1535,24 @@ - ap->ops->phy_reset(ap); - if (ap->flags & ATA_FLAG_PORT_DISABLED) - goto err_out; -+ -+ /* The reset means we are in PIO 0, but the controller may not -+ yet be correctly set up and may have old BIOS settings, or just -+ no settings at all. Set all the devices to PIO 0 */ -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) -+ ap->device[i].pio_mode = XFER_PIO_0; - - for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *adev = & ap->device[i]; -+ -+ /* Set up the controller on this port for PIO 0. We must not -+ send the drive speed setting commands at this point */ -+ if (ap->ops->set_piomode) -+ ap->ops->set_piomode(ap, adev); -+ - ata_dev_identify(ap, i); -- if (ata_dev_present(&ap->device[i])) { -+ if (ata_dev_present(adev)) { - found = 1; - ata_dev_config(ap,i); - } -@@ -1497,7 +1561,11 @@ - if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED)) - goto err_out_disable; - -- ata_set_mode(ap); -+ if(ap->ops->set_mode) -+ ap->ops->set_mode(ap); -+ else -+ ata_set_mode(ap); -+ - if (ap->flags & ATA_FLAG_PORT_DISABLED) - goto err_out_disable; - -@@ -1612,6 +1680,23 @@ - } - - /** -+ * ata_dev_pair - return other device on cable -+ * @ap: port -+ * @adev: device -+ * -+ * Obtain the other device on the same cable, or if none is -+ * present NULL is returned -+ */ -+ -+struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_device *pair = &ap->device[1 - adev->devno]; -+ if (!ata_dev_present(pair)) -+ return NULL; -+ return pair; -+} -+ -+/** - * ata_port_disable - Disable port. - * @ap: Port to be disabled. - * -@@ -1824,16 +1909,19 @@ - ap->id, dev->devno, xfer_mode_str[idx]); - } - --static int ata_host_set_pio(struct ata_port *ap) -+static int ata_host_set_pio(struct ata_port *ap, struct ata_device *adev) - { - unsigned int mask; -- int x, i; -+ int x; - u8 base, xfer_mode; - -- mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO); -+ if (!ata_dev_present(adev)) -+ return 0; -+ -+ mask = ata_get_mode_mask(ap, adev, ATA_SHIFT_PIO); - x = fgb(mask); - if (x < 0) { -- printk(KERN_WARNING "ata%u: no PIO support\n", ap->id); -+ printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, adev->devno); - return -1; - } - -@@ -1843,34 +1931,24 @@ - DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n", - (int)base, (int)xfer_mode, mask, x); - -- for (i = 0; i < ATA_MAX_DEVICES; i++) { -- struct ata_device *dev = &ap->device[i]; -- if (ata_dev_present(dev)) { -- dev->pio_mode = xfer_mode; -- dev->xfer_mode = xfer_mode; -- dev->xfer_shift = ATA_SHIFT_PIO; -- if (ap->ops->set_piomode) -- ap->ops->set_piomode(ap, dev); -- } -- } -+ adev->pio_mode = xfer_mode; -+ adev->xfer_mode = xfer_mode; -+ adev->xfer_shift = ATA_SHIFT_PIO; -+ if (ap->ops->set_piomode) -+ ap->ops->set_piomode(ap, adev); - - return 0; - } - --static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, -- unsigned int xfer_shift) -+static void ata_host_set_dma(struct ata_port *ap, struct ata_device *adev, -+ u8 xfer_mode, unsigned int xfer_shift) - { -- int i; -- -- for (i = 0; i < ATA_MAX_DEVICES; i++) { -- struct ata_device *dev = &ap->device[i]; -- if (ata_dev_present(dev)) { -- dev->dma_mode = xfer_mode; -- dev->xfer_mode = xfer_mode; -- dev->xfer_shift = xfer_shift; -- if (ap->ops->set_dmamode) -- ap->ops->set_dmamode(ap, dev); -- } -+ if (ata_dev_present(adev)) { -+ adev->dma_mode = xfer_mode; -+ adev->xfer_mode = xfer_mode; -+ adev->xfer_shift = xfer_shift; -+ if (ap->ops->set_dmamode) -+ ap->ops->set_dmamode(ap, adev); - } - } - -@@ -1886,32 +1964,64 @@ - */ - static void ata_set_mode(struct ata_port *ap) - { -- unsigned int xfer_shift; -- u8 xfer_mode; -+ unsigned int xfer_shift[ATA_MAX_DEVICES]; -+ u8 xfer_mode[ATA_MAX_DEVICES]; - int rc; -+ int i; -+ int used_dma = 0; /* Track if DMA was used for this setup */ - -- /* step 1: always set host PIO timings */ -- rc = ata_host_set_pio(ap); -- if (rc) -- goto err_out; -+ /* We need to set timings individually for each device */ - -- /* step 2: choose the best data xfer mode */ -- xfer_mode = xfer_shift = 0; -- rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift); -- if (rc) -- goto err_out; -+ /* Compute the timings first so that when we ask the device to do -+ speed configuration it can see all the intended device state in -+ full */ -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *adev = &ap->device[i]; -+ /* Choose the best data xfer mode */ -+ xfer_mode[i] = xfer_shift[i] = 0; -+ rc = ata_choose_xfer_mode(ap, adev, &xfer_mode[i], &xfer_shift[i]); -+ if (rc) -+ goto err_out; -+ -+ } -+ -+ /* Now set the mode tables we have computed */ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *adev = &ap->device[i]; -+ /* step 1: always set host PIO timings */ -+ rc = ata_host_set_pio(ap, adev); -+ if (rc) -+ goto err_out; - -- /* step 3: if that xfer mode isn't PIO, set host DMA timings */ -- if (xfer_shift != ATA_SHIFT_PIO) -- ata_host_set_dma(ap, xfer_mode, xfer_shift); -- -- /* step 4: update devices' xfer mode */ -- ata_dev_set_mode(ap, &ap->device[0]); -- ata_dev_set_mode(ap, &ap->device[1]); -+ /* step 2: if that xfer mode isn't PIO, set host DMA timings */ -+ if (xfer_shift[i] != ATA_SHIFT_PIO) { -+ ata_host_set_dma(ap, adev, xfer_mode[i], xfer_shift[i]); -+ used_dma = 1; -+ } -+ -+ /* In some cases the DMA mode will cause the driver to -+ update the pio mode to match chip limits. */ -+ -+ /* step 3: update devices' xfer mode */ -+ ata_dev_set_mode(ap, adev); -+ } - - if (ap->flags & ATA_FLAG_PORT_DISABLED) - return; - -+ /* -+ * Record simplex status. If we selected DMA then the other -+ * host channels are not permitted to do so. -+ */ -+ -+ if (used_dma && (ap->host_set->host_set_flags & ATA_HOST_SIMPLEX)) -+ ap->host_set->simplex_claimed = 1; -+ -+ /* -+ * Chip specific finalisation -+ */ -+ - if (ap->ops->post_set_mode) - ap->ops->post_set_mode(ap); - -@@ -2200,132 +2310,126 @@ - } - - static const char * const ata_dma_blacklist [] = { -- "WDC AC11000H", -- "WDC AC22100H", -- "WDC AC32500H", -- "WDC AC33100H", -- "WDC AC31600H", -- "WDC AC32100H", -- "WDC AC23200L", -- "Compaq CRD-8241B", -- "CRD-8400B", -- "CRD-8480B", -- "CRD-8482B", -- "CRD-84", -- "SanDisk SDP3B", -- "SanDisk SDP3B-64", -- "SANYO CD-ROM CRD", -- "HITACHI CDR-8", -- "HITACHI CDR-8335", -- "HITACHI CDR-8435", -- "Toshiba CD-ROM XM-6202B", -- "TOSHIBA CD-ROM XM-1702BC", -- "CD-532E-A", -- "E-IDE CD-ROM CR-840", -- "CD-ROM Drive/F5A", -- "WPI CDD-820", -- "SAMSUNG CD-ROM SC-148C", -- "SAMSUNG CD-ROM SC", -- "SanDisk SDP3B-64", -- "ATAPI CD-ROM DRIVE 40X MAXIMUM", -- "_NEC DV5800A", -+ "WDC AC11000H", NULL, -+ "WDC AC22100H", NULL, -+ "WDC AC32500H", NULL, -+ "WDC AC33100H", NULL, -+ "WDC AC31600H", NULL, -+ "WDC AC32100H", "24.09P07", -+ "WDC AC23200L", "21.10N21", -+ "Compaq CRD-8241B", NULL, -+ "CRD-8400B", NULL, -+ "CRD-8480B", NULL, -+ "CRD-8482B", NULL, -+ "CRD-84", NULL, -+ "SanDisk SDP3B", NULL, -+ "SanDisk SDP3B-64", NULL, -+ "SANYO CD-ROM CRD", NULL, -+ "HITACHI CDR-8", NULL, -+ "HITACHI CDR-8335", NULL, -+ "HITACHI CDR-8435", NULL, -+ "Toshiba CD-ROM XM-6202B", NULL, -+ "TOSHIBA CD-ROM XM-1702BC", NULL, -+ "CD-532E-A", NULL, -+ "E-IDE CD-ROM CR-840", NULL, -+ "CD-ROM Drive/F5A", NULL, -+ "WPI CDD-820", NULL, -+ "SAMSUNG CD-ROM SC-148C", NULL, -+ "SAMSUNG CD-ROM SC", NULL, -+ "SanDisk SDP3B-64", NULL, -+ "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL, -+ "_NEC DV5800A", NULL, -+ "SAMSUNG CD-ROM SN-124", "N001" - }; - --static int ata_dma_blacklisted(const struct ata_device *dev) -+static int ata_strim(char *s, size_t len) - { -- unsigned char model_num[40]; -- char *s; -- unsigned int len; -- int i; -- -- ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, -- sizeof(model_num)); -- s = &model_num[0]; -- len = strnlen(s, sizeof(model_num)); -+ len = strnlen(s, len); - - /* ATAPI specifies that empty space is blank-filled; remove blanks */ - while ((len > 0) && (s[len - 1] == ' ')) { - len--; - s[len] = 0; - } -+ return len; -+} - -- for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++) -- if (!strncmp(ata_dma_blacklist[i], s, len)) -- return 1; -+static int ata_dma_blacklisted(const struct ata_device *dev) -+{ -+ unsigned char model_num[40]; -+ unsigned char model_rev[16]; -+ unsigned int nlen, rlen; -+ int i; - -+ ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, -+ sizeof(model_num)); -+ ata_dev_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS, -+ sizeof(model_rev)); -+ nlen = ata_strim(model_num, sizeof(model_num)); -+ rlen = ata_strim(model_rev, sizeof(model_rev)); -+ -+ for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) { -+ if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) { -+ if (ata_dma_blacklist[i+1] == NULL) -+ return 1; -+ if (!strncmp(ata_dma_blacklist[i], model_rev, rlen)) -+ return 1; -+ } -+ } - return 0; - } - --static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift) -+static unsigned int ata_get_mode_mask(const struct ata_port *ap, struct ata_device *adev, int shift) - { -- const struct ata_device *master, *slave; - unsigned int mask; -+ struct ata_host_set *hs = ap->host_set; -+ -+ if (!ata_dev_present(adev)) -+ return 0xFF; /* Drive isn't limiting anything */ -+ -+ if (shift == ATA_SHIFT_PIO) { -+ u16 tmp_mode = ata_pio_modes(adev); -+ mask = ap->pio_mask; -+ mask &= tmp_mode; -+ } - -- master = &ap->device[0]; -- slave = &ap->device[1]; -+ /* -+ * Enforce simplex rules if host is simplex -+ */ - -- assert (ata_dev_present(master) || ata_dev_present(slave)); -+ if (hs->host_set_flags & ATA_HOST_SIMPLEX) { -+ if (hs->simplex_claimed) { -+ if (shift != ATA_SHIFT_PIO) -+ return 0; -+ } -+ } - - if (shift == ATA_SHIFT_UDMA) { - mask = ap->udma_mask; -- if (ata_dev_present(master)) { -- mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); -- if (ata_dma_blacklisted(master)) { -- mask = 0; -- ata_pr_blacklisted(ap, master); -- } -- } -- if (ata_dev_present(slave)) { -- mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff); -- if (ata_dma_blacklisted(slave)) { -- mask = 0; -- ata_pr_blacklisted(ap, slave); -- } -+ mask &= (adev->id[ATA_ID_UDMA_MODES] & 0xff); -+ if (ata_dma_blacklisted(adev)) { -+ mask = 0; -+ ata_pr_blacklisted(ap, adev); - } -+ /* 40 pin cable enforcement */ -+ if (ap->cbl == ATA_CBL_PATA40) -+ mask &= ~ATA_UDMA_MASK_40C; - } - else if (shift == ATA_SHIFT_MWDMA) { - mask = ap->mwdma_mask; -- if (ata_dev_present(master)) { -- mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07); -- if (ata_dma_blacklisted(master)) { -- mask = 0; -- ata_pr_blacklisted(ap, master); -- } -- } -- if (ata_dev_present(slave)) { -- mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07); -- if (ata_dma_blacklisted(slave)) { -- mask = 0; -- ata_pr_blacklisted(ap, slave); -- } -- } -- } -- else if (shift == ATA_SHIFT_PIO) { -- mask = ap->pio_mask; -- if (ata_dev_present(master)) { -- /* spec doesn't return explicit support for -- * PIO0-2, so we fake it -- */ -- u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03; -- tmp_mode <<= 3; -- tmp_mode |= 0x7; -- mask &= tmp_mode; -- } -- if (ata_dev_present(slave)) { -- /* spec doesn't return explicit support for -- * PIO0-2, so we fake it -- */ -- u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03; -- tmp_mode <<= 3; -- tmp_mode |= 0x7; -- mask &= tmp_mode; -+ mask &= (adev->id[ATA_ID_MWDMA_MODES] & 0x07); -+ if (ata_dma_blacklisted(adev)) { -+ mask = 0; -+ ata_pr_blacklisted(ap, adev); - } -- } -- else { -- mask = 0xffffffff; /* shut up compiler warning */ -- BUG(); -- } -- -+ } else if (shift != ATA_SHIFT_PIO) -+ panic("gmm:bad shift"); /* BUG confuses the compiler */ -+ /* -+ * Allow the controller to see the proposed mode and -+ * device data to do any custom filtering rules. -+ */ -+ if(ap->ops->mode_filter) -+ mask = ap->ops->mode_filter(ap, adev, mask, shift); - return mask; - } - -@@ -2345,6 +2449,7 @@ - /** - * ata_choose_xfer_mode - attempt to find best transfer mode - * @ap: Port for which an xfer mode will be selected -+ * @adev: ATA device for which xfer mode is being selected - * @xfer_mode_out: (output) SET FEATURES - XFER MODE code - * @xfer_shift_out: (output) bit shift that selects this mode - * -@@ -2359,6 +2464,7 @@ - */ - - static int ata_choose_xfer_mode(const struct ata_port *ap, -+ struct ata_device *adev, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out) - { -@@ -2367,7 +2473,7 @@ - - for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) { - shift = xfer_mode_classes[i].shift; -- mask = ata_get_mode_mask(ap, shift); -+ mask = ata_get_mode_mask(ap, adev, shift); - - x = fgb(mask); - if (x >= 0) { -@@ -3000,6 +3106,7 @@ - /** - * ata_mmio_data_xfer - Transfer data by MMIO - * @ap: port to read/write -+ * @adev: device to target - * @buf: data buffer - * @buflen: buffer length - * @write_data: read/write -@@ -3010,8 +3117,8 @@ - * Inherited from caller. - */ - --static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, -- unsigned int buflen, int write_data) -+void ata_mmio_data_xfer(struct ata_port *ap, struct ata_device *adev, -+ unsigned char *buf, unsigned int buflen, int write_data) - { - unsigned int i; - unsigned int words = buflen >> 1; -@@ -3045,6 +3152,7 @@ - /** - * ata_pio_data_xfer - Transfer data by PIO - * @ap: port to read/write -+ * @adev: device to target - * @buf: data buffer - * @buflen: buffer length - * @write_data: read/write -@@ -3055,11 +3163,11 @@ - * Inherited from caller. - */ - --static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, -- unsigned int buflen, int write_data) -+void ata_pio_data_xfer(struct ata_port *ap, struct ata_device *adev, -+ unsigned char *buf, unsigned int buflen, int write_data) - { - unsigned int words = buflen >> 1; -- -+ - /* Transfer multiple of 2 bytes */ - if (write_data) - outsw(ap->ioaddr.data_addr, buf, words); -@@ -3082,36 +3190,55 @@ - } - - /** -- * ata_data_xfer - Transfer data from/to the data register. -+ * ata_pio_data_xfer_noirq - Transfer data from/to the data register. - * @ap: port to read/write -+ * @adev: device to target - * @buf: data buffer - * @buflen: buffer length - * @do_write: read/write - * -- * Transfer data from/to the device data register. -+ * Transfer data from/to the device data register. This variant -+ * ensures local IRQs do not interrupt the data stream and this -+ * is needed for some controllers. - * - * LOCKING: - * Inherited from caller. - */ - --static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, -- unsigned int buflen, int do_write) -+void ata_pio_data_xfer_noirq(struct ata_port *ap, struct ata_device *adev, -+ unsigned char *buf, unsigned int buflen, int do_write) - { - /* Make the crap hardware pay the costs not the good stuff */ -- if (unlikely(ap->flags & ATA_FLAG_IRQ_MASK)) { -- unsigned long flags; -- local_irq_save(flags); -- if (ap->flags & ATA_FLAG_MMIO) -- ata_mmio_data_xfer(ap, buf, buflen, do_write); -- else -- ata_pio_data_xfer(ap, buf, buflen, do_write); -- local_irq_restore(flags); -- } else { -- if (ap->flags & ATA_FLAG_MMIO) -- ata_mmio_data_xfer(ap, buf, buflen, do_write); -- else -- ata_pio_data_xfer(ap, buf, buflen, do_write); -- } -+ unsigned long flags; -+ local_irq_save(flags); -+ ata_pio_data_xfer(ap, adev, buf, buflen, do_write); -+ local_irq_restore(flags); -+} -+ -+/** -+ * ata_mmio_data_xfer_noirq - Transfer data from/to the data register. -+ * @ap: address to read/write -+ * @adev: device to target -+ * @buf: data buffer -+ * @buflen: buffer length -+ * @do_write: read/write -+ * -+ * Transfer data from/to the device data register. This variant -+ * ensures local IRQs do not interrupt the data stream and this -+ * is needed for some controllers. -+ * -+ * LOCKING: -+ * Inherited from caller. -+ */ -+ -+void ata_mmio_data_xfer_noirq(struct ata_port *ap, struct ata_device *adev, -+ unsigned char *buf, unsigned int buflen, int do_write) -+{ -+ /* Make the crap hardware pay the costs not the good stuff */ -+ unsigned long flags; -+ local_irq_save(flags); -+ ata_mmio_data_xfer(ap, adev, buf, buflen, do_write); -+ local_irq_restore(flags); - } - - /** -@@ -3157,7 +3284,7 @@ - - /* do the actual data transfer */ - do_write = (qc->tf.flags & ATA_TFLAG_WRITE); -- ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write); -+ ap->ops->data_xfer(ap, qc->dev, buf, ATA_SECT_SIZE, do_write); - - kunmap(page); - } -@@ -3204,7 +3331,7 @@ - ap->id, bytes); - - for (i = 0; i < words; i++) -- ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write); -+ ap->ops->data_xfer(ap, qc->dev, (unsigned char*)pad_buf, 2, do_write); - - ap->hsm_task_state = HSM_ST_LAST; - return; -@@ -3239,7 +3366,7 @@ - DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); - - /* do the actual data transfer */ -- ata_data_xfer(ap, buf, count, do_write); -+ ap->ops->data_xfer(ap, qc->dev, buf, count, do_write); - - kunmap(page); - -@@ -3948,14 +4075,15 @@ - - void ata_bmdma_irq_clear(struct ata_port *ap) - { -- if (ap->flags & ATA_FLAG_MMIO) { -- void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; -- writeb(readb(mmio), mmio); -- } else { -- unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; -- outb(inb(addr), addr); -- } -- -+ if (ap->ioaddr.bmdma_addr) { -+ if (ap->flags & ATA_FLAG_MMIO) { -+ void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; -+ writeb(readb(mmio), mmio); -+ } else { -+ unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; -+ outb(inb(addr), addr); -+ } -+ } - } - - -@@ -4194,12 +4322,12 @@ - */ - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags &= ~ATA_FLAG_NOINTR; -- ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); -+ ap->ops->data_xfer(ap, qc->dev, qc->cdb, ap->cdb_len, 1); - if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) - ap->ops->bmdma_start(qc); /* initiate bmdma */ - spin_unlock_irqrestore(&ap->host_set->lock, flags); - } else { -- ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); -+ ap->ops->data_xfer(ap, qc->dev, qc->cdb, ap->cdb_len, 1); - - /* PIO commands are handled by polling */ - ap->hsm_task_state = HSM_ST; -@@ -4505,7 +4633,7 @@ - * Number of ports registered. Zero on error (no ports registered). - */ - --int ata_device_add(const struct ata_probe_ent *ent) -+int ata_device_add(struct ata_probe_ent *ent) - { - unsigned int count = 0, i; - struct device *dev = ent->dev; -@@ -4525,6 +4653,9 @@ - host_set->mmio_base = ent->mmio_base; - host_set->private_data = ent->private_data; - host_set->ops = ent->port_ops; -+ host_set->host_set_flags = ent->host_set_flags; -+ -+ ent->host_set = host_set; - - /* register each port bound to this device */ - for (i = 0; i < ent->n_ports; i++) { -@@ -4536,6 +4667,14 @@ - goto err_out; - - host_set->ports[i] = ap; -+ -+ /* Tidy up if we have no bus master base -+ Not sure this is the right spot to do it */ -+ if (ap->ioaddr.bmdma_addr == 0) { -+ ap->udma_mask = 0; -+ ap->mwdma_mask = 0; -+ } -+ - xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | - (ap->mwdma_mask << ATA_SHIFT_MWDMA) | - (ap->pio_mask << ATA_SHIFT_PIO); -@@ -4552,6 +4691,7 @@ - ent->irq); - - ata_chk_status(ap); -+ /* This last call probably should be conditional on bmdma */ - host_set->ops->irq_clear(ap); - count++; - } -@@ -4605,7 +4745,8 @@ - ata_scsi_scan_host(ap); - } - -- dev_set_drvdata(dev, host_set); -+ if(dev) -+ dev_set_drvdata(dev, host_set); - - VPRINTK("EXIT, returning %u\n", ent->n_ports); - return ent->n_ports; /* success */ -@@ -4779,6 +4920,7 @@ - { - struct ata_probe_ent *probe_ent = - ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); -+ unsigned long bmdma; - int p = 0; - - if (!probe_ent) -@@ -4793,7 +4935,13 @@ - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = - pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; -- probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); -+ bmdma = pci_resource_start(pdev, 4); -+ -+ if (bmdma) { -+ if (inb(bmdma + 2) & 0x80) -+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; -+ probe_ent->port[p].bmdma_addr = bmdma; -+ } - ata_std_ports(&probe_ent->port[p]); - p++; - } -@@ -4803,7 +4951,14 @@ - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = - pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; -- probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; -+ bmdma = pci_resource_start(pdev, 4); -+ -+ if (bmdma) { -+ bmdma += 8; -+ if(inb(bmdma + 2) & 0x80) -+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; -+ probe_ent->port[p].bmdma_addr = bmdma; -+ } - ata_std_ports(&probe_ent->port[p]); - p++; - } -@@ -4815,6 +4970,7 @@ - static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num) - { - struct ata_probe_ent *probe_ent; -+ unsigned long bmdma; - - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); - if (!probe_ent) -@@ -4840,7 +4996,13 @@ - probe_ent->port[0].ctl_addr = 0x376; - break; - } -- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num; -+ bmdma = pci_resource_start(pdev, 4); -+ if(bmdma != 0) { -+ bmdma += 8 * port_num; -+ probe_ent->port[0].bmdma_addr = bmdma; -+ if (inb(bmdma + 2) & 0x80) -+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; -+ } - ata_std_ports(&probe_ent->port[0]); - return probe_ent; - } -@@ -5081,6 +5243,33 @@ - pci_set_master(pdev); - return 0; - } -+ -+/** -+ * ata_pci_clear_simplex - attempt to kick device out of simplex -+ * @pdev: PCI device -+ * -+ * Some PCI ATA devices report simplex mode but in fact can be told to -+ * enter non simplex mode. This implements the neccessary logic to -+ * perform the task on such devices. Calling it on other devices will -+ * have -undefined- behaviour. -+ */ -+ -+int ata_pci_clear_simplex(struct pci_dev *pdev) -+{ -+ unsigned long bmdma = pci_resource_start(pdev, 4); -+ u8 simplex; -+ -+ if (bmdma == 0) -+ return -ENOENT; -+ -+ simplex = inb(bmdma + 0x02); -+ outb(simplex & 0x60, bmdma + 0x02); -+ simplex = inb(bmdma + 0x02); -+ if (simplex & 0x80) -+ return -EOPNOTSUPP; -+ return 0; -+} -+ - #endif /* CONFIG_PCI */ - - -@@ -5158,6 +5347,10 @@ - EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); - EXPORT_SYMBOL_GPL(ata_bmdma_status); - EXPORT_SYMBOL_GPL(ata_bmdma_stop); -+EXPORT_SYMBOL_GPL(ata_mmio_data_xfer); -+EXPORT_SYMBOL_GPL(ata_pio_data_xfer); -+EXPORT_SYMBOL_GPL(ata_mmio_data_xfer_noirq); -+EXPORT_SYMBOL_GPL(ata_pio_data_xfer_noirq); - EXPORT_SYMBOL_GPL(ata_port_probe); - EXPORT_SYMBOL_GPL(sata_phy_reset); - EXPORT_SYMBOL_GPL(__sata_phy_reset); -@@ -5175,6 +5368,7 @@ - EXPORT_SYMBOL_GPL(ata_dev_config); - EXPORT_SYMBOL_GPL(ata_scsi_simulate); - -+EXPORT_SYMBOL_GPL(ata_dev_pair); - EXPORT_SYMBOL_GPL(ata_pio_need_iordy); - EXPORT_SYMBOL_GPL(ata_timing_compute); - EXPORT_SYMBOL_GPL(ata_timing_merge); -@@ -5187,6 +5381,8 @@ - EXPORT_SYMBOL_GPL(ata_pci_remove_one); - EXPORT_SYMBOL_GPL(ata_pci_device_suspend); - EXPORT_SYMBOL_GPL(ata_pci_device_resume); -+EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); -+ - #endif /* CONFIG_PCI */ - - EXPORT_SYMBOL_GPL(ata_device_suspend); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/Makefile linux-2.6.16-rc4/drivers/scsi/Makefile ---- linux.vanilla-2.6.16-rc4/drivers/scsi/Makefile 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/Makefile 2006-02-17 18:20:44.000000000 +0000 -@@ -139,6 +139,42 @@ - obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o - obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o - -+obj-$(CONFIG_SCSI_PATA_ALI) += libata.o pata_ali.o -+obj-$(CONFIG_SCSI_PATA_AMD) += libata.o pata_amd.o -+obj-$(CONFIG_SCSI_PATA_ARTOP) += libata.o pata_artop.o -+obj-$(CONFIG_SCSI_PATA_ATIIXP) += libata.o pata_atiixp.o -+obj-$(CONFIG_SCSI_PATA_CMD64X) += libata.o pata_cmd64x.o -+obj-$(CONFIG_SCSI_PATA_CS5520) += libata.o pata_cs5520.o -+obj-$(CONFIG_SCSI_PATA_CS5530) += libata.o pata_cs5530.o -+obj-$(CONFIG_SCSI_PATA_CS5535) += libata.o pata_cs5535.o -+obj-$(CONFIG_SCSI_PATA_CYPRESS) += libata.o pata_cypress.o -+obj-$(CONFIG_SCSI_PATA_EFAR) += libata.o pata_efar.o -+obj-$(CONFIG_SCSI_PATA_ISAPNP) += libata.o pata_isapnp.o -+obj-$(CONFIG_SCSI_PATA_HPT37X) += libata.o pata_hpt37x.o -+obj-$(CONFIG_SCSI_PATA_HPT3X2N) += libata.o pata_hpt3x2n.o -+obj-$(CONFIG_SCSI_PATA_HPT3X3) += libata.o pata_hpt34x.o -+obj-$(CONFIG_SCSI_PATA_IT8172) += libata.o pata_it8172.o -+obj-$(CONFIG_SCSI_PATA_IT821X) += libata.o pata_it821x.o -+obj-$(CONFIG_SCSI_PATA_MPIIX) += libata.o pata_mpiix.o -+obj-$(CONFIG_SCSI_PATA_NETCELL) += libata.o pata_netcell.o -+obj-$(CONFIG_SCSI_PATA_NS87410) += libata.o pata_ns87410.o -+obj-$(CONFIG_SCSI_PATA_OLDPIIX) += libata.o pata_oldpiix.o -+obj-$(CONFIG_SCSI_PATA_OPTI) += libata.o pata_opti.o -+obj-$(CONFIG_SCSI_PATA_PCMCIA) += libata.o pata_pcmcia.o -+obj-$(CONFIG_SCSI_PATA_PDC_OLD) += libata.o pata_pdc202xx_old.o -+obj-$(CONFIG_SCSI_PATA_QDI) += libata.o pata_qdi.o -+obj-$(CONFIG_SCSI_PATA_RADISYS) += libata.o pata_radisys.o -+obj-$(CONFIG_SCSI_PATA_RZ1000) += libata.o pata_rz1000.o -+obj-$(CONFIG_SCSI_PATA_SERVERWORKS) += libata.o pata_serverworks.o -+obj-$(CONFIG_SCSI_PATA_SC1200) += libata.o pata_sc1200.o -+obj-$(CONFIG_SCSI_PATA_SIL680) += libata.o pata_sil680.o -+obj-$(CONFIG_SCSI_PATA_SIS) += libata.o pata_sis.o -+obj-$(CONFIG_SCSI_PATA_TRIFLEX) += libata.o pata_triflex.o -+obj-$(CONFIG_SCSI_PATA_VIA) += libata.o pata_via.o -+obj-$(CONFIG_SCSI_PATA_WINBOND) += libata.o pata_sl82c105.o -+obj-$(CONFIG_SCSI_ATA_GENERIC) += libata.o ata_generic.o -+obj-$(CONFIG_SCSI_PATA_LEGACY) += libata.o pata_legacy.o -+ - obj-$(CONFIG_ARM) += arm/ - - obj-$(CONFIG_CHR_DEV_ST) += st.o -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ali.c linux-2.6.16-rc4/drivers/scsi/pata_ali.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ali.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_ali.c 2006-02-20 12:28:04.000000000 +0000 -@@ -0,0 +1,606 @@ -+/* -+ * ata-ali.c - ALI 15x3 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * TODO -+ * MWDMA timings -+ * -+ * based in part upon -+ * linux/drivers/ide/pci/alim15x3.c Version 0.17 2003/01/02 -+ * -+ * Copyright (C) 1998-2000 Michel Aubry, Maintainer -+ * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer -+ * Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer -+ * -+ * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) -+ * May be copied or modified under the terms of the GNU General Public License -+ * Copyright (C) 2002 Alan Cox <alan@redhat.com> -+ * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> -+ * -+ * Documentation -+ * Chipset documentation available under NDA only -+ * -+ * TODO -+ * Cannot have ATAPI on both master & slave for rev < c2 but -+ * otherwise should do atapi DMA. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "ali" -+#define DRV_VERSION "0.2.2" -+ -+/** -+ * ali_c2_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection for C2 and later revisions -+ */ -+ -+static int ali_c2_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 ata66; -+ -+ /* Certain laptops use short but suitable cables and don't -+ implement the detect logic */ -+ -+ /* Fujitsu P2000 */ -+ if (pdev->subsystem_vendor == 0x10CF && pdev->subsystem_device == 0x10AF) -+ return ATA_CBL_PATA80; -+ -+ /* Host view cable detect 0x4A bit 0 primary bit 1 secondary -+ Bit set for 40 pin */ -+ pci_read_config_byte(pdev, 0x4A, &ata66); -+ if (ata66 & (1 << ap->hard_port_no)) -+ return ATA_CBL_PATA40; -+ else -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * ali_early_phy_reset - reset for eary chip -+ * @ap: ATA port -+ * -+ * Handle the reset callback for the later chips with cable detect -+ */ -+ -+static void ali_c2_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ali_c2_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * ali_early_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection for older chipsets. This turns out to be -+ * rather easy to implement -+ */ -+ -+static int ali_early_cable_detect(struct ata_port *ap) { -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * ali_early_phy_reset - reset for eary chip -+ * @ap: ATA port -+ * -+ * Handle the reset callback for the early (pre cable detect) chips. -+ */ -+ -+static void ali_early_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ali_early_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * ali_20_filter - filter for earlier ALI DMA -+ * @ap: ALi ATA port -+ * @adev: attached device -+ * -+ * Ensure that we do not do DMA on CD devices. We may be able to -+ * fix that later on. Also ensure we do not do UDMA on WDC drives -+ */ -+ -+static unsigned int ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ char model_num[40]; -+ /* No DMA on CD for now */ -+ if (adev->class != ATA_DEV_ATA && shift != ATA_SHIFT_PIO) -+ return 0; -+ -+ if (shift != ATA_SHIFT_UDMA) -+ return mask; -+ -+ ata_dev_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num)); -+ if (strstr(model_num, "WDC")) -+ return 0; -+ return mask; -+} -+ -+/** -+ * ali_fifo_control - FIFO manager -+ * @ap: ALi channel to control -+ * @adev: device for FIFO control -+ * @on: 0 for off 1 for on -+ * -+ * Enable or disable the FIFO on a given device. Because of the way the -+ * ALi FIFO works it provides a boost on ATA disk but can be confused by -+ * ATAPI and we must therefore manage it. -+ */ -+ -+static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int on) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int pio_fifo = 0x54 + ap->hard_port_no; -+ u8 fifo; -+ int shift = 4 * adev->devno; -+ -+ /* Bits 3:2 (7:6 for slave) control the PIO. 00 is off 01 -+ is on. The FIFO must not be used for ATAPI. We preserve -+ BIOS set thresholds */ -+ pci_read_config_byte(pdev, pio_fifo, &fifo); -+ fifo &= ~(0x0C << shift); -+ if (on) -+ fifo |= (0x04 << shift); -+ pci_write_config_byte(pdev, pio_fifo, fifo); -+} -+ -+/** -+ * ali_program_modes - load mode registers -+ * @ap: ALi channel to load -+ * @adev: Device the timing is for -+ * @cmd: Command timing -+ * @data: Data timing -+ * @udma: UDMA timing or zero for off -+ * -+ * Loads the timing registers for cmd/data and disable UDMA if -+ * udma is zero. If udma is set then load and enable the UDMA -+ * timing but do not touch the command/data timing. -+ */ -+ -+static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, u8 cmd, u8 data, u8 ultra) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int cbt = 0x59 + 4 * ap->hard_port_no; /* Command timing */ -+ int drwt = 0x5A + 4 * ap->hard_port_no + adev->devno; /* R/W timing */ -+ int udmat = 0x56 + ap->hard_port_no; /* UDMA timing */ -+ int shift = 4 * adev->devno; -+ u8 udma; -+ -+ if (ultra == 0) { -+ /* FIXME: We ought to set up pcas not rely on the BIOS */ -+ /* Load the command block timing register */ -+ pci_write_config_byte(pdev, cbt, cmd); -+ -+ /* Load the data transfer timing register */ -+ pci_write_config_byte(pdev, drwt, data); -+ } -+ -+ /* Set up the UDMA enable */ -+ pci_read_config_byte(pdev, udmat, &udma); -+ udma &= ~(0x0F << shift); -+ udma |= ultra << shift; -+ pci_write_config_byte(pdev, udmat, udma); -+} -+ -+/** -+ * ali_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the ALi registers for PIO mode. FIXME: add timings for -+ * PIO5. -+ */ -+ -+static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ int pio = adev->pio_mode - XFER_PIO_0; -+ int cmdpio = pio; -+ -+ /* These values are from the BIOS programming guide */ -+ static u8 cmd_block_timing[5] = { 0x0A, 0x03, 0x01, 0x33, 0x31 }; -+ static u8 data_block_timing[5] = { 0x88, 0x58, 0x44, 0x33, 0x31 }; -+ -+ if (adev->class != ATA_DEV_ATA) -+ ali_fifo_control(ap, adev, 0); -+ -+ /* Command timing is shared, so pick the best we can use */ -+ if (pair) -+ cmdpio = min(pair->pio_mode, adev->pio_mode) - XFER_PIO_0; -+ -+ ali_program_modes(ap, adev, cmd_block_timing[cmdpio], -+ data_block_timing[pio], 0); -+ -+ if (adev->class == ATA_DEV_ATA) -+ ali_fifo_control(ap, adev, 1); -+ -+} -+ -+/** -+ * ali_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * FIXME: MWDMA timings -+ */ -+ -+static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD }; -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ ali_program_modes(ap, adev, 0, 0, udma_timing[adev->dma_mode - XFER_UDMA_0]); -+ } else { -+ /* MWDMA is not yet supported */ -+ /* ali_program_modes(ap, adev, cmd, data, 0); */ -+ } -+} -+ -+/** -+ * ali_lock_sectors - Keep older devices to 255 sector mode -+ * @ap: ATA port -+ * @adev: Device -+ * -+ * Called during the bus probe for each device that is found. We use -+ * this call to lock the sector count of the device to 255 or less on -+ * older ALi controllers. If we didn't do this then large I/O's would -+ * require LBA48 commands which the older ALi requires are issued by -+ * slower PIO methods -+ */ -+ -+static void ali_lock_sectors(struct ata_port *ap, struct ata_device *adev) -+{ -+ if(ap->host->max_sectors > 255) { -+ ap->host->max_sectors = 255; -+ ap->host->hostt->max_sectors = 255; -+ } -+ adev->flags |= ATA_DFLAG_LOCK_SECTORS; -+} -+ -+static struct scsi_host_template ali_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ /* Keep LBA28 counts so large I/O's don't turn LBA48 and PIO -+ with older controllers. Not locked so will grow on C5 or later */ -+ .max_sectors = 255, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+/* -+ * Port operations for PIO only ALi -+ */ -+ -+static struct ata_port_operations ali_early_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ali_set_piomode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = ali_early_phy_reset, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Port operations for DMA capable ALi without cable -+ * detect -+ */ -+static struct ata_port_operations ali_20_port_ops = { -+ .port_disable = ata_port_disable, -+ -+ .set_piomode = ali_set_piomode, -+ .set_dmamode = ali_set_dmamode, -+ .mode_filter = ali_20_filter, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ .dev_config = ali_lock_sectors, -+ -+ .phy_reset = ali_early_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Port operations for DMA capable ALi with cable detect -+ */ -+static struct ata_port_operations ali_c2_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ali_set_piomode, -+ .set_dmamode = ali_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ .dev_config = ali_lock_sectors, -+ -+ .phy_reset = ali_c2_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Port operations for DMA capable ALi with cable detect and LBA48 -+ */ -+static struct ata_port_operations ali_c5_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ali_set_piomode, -+ .set_dmamode = ali_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = ali_c2_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * ali_init_one - discovery callback -+ * @pdev: PCI device ID -+ * @id: PCI table info -+ * -+ * An ALi IDE interface has been discovered. Figure out what revision -+ * and perform configuration work before handing it to the ATA layer -+ */ -+ -+static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info_early = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &ali_early_port_ops -+ }; -+ /* Revision 0x20 added DMA */ -+ static struct ata_port_info info_20 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &ali_20_port_ops -+ }; -+ /* Revision 0x20 with support logic added UDMA */ -+ static struct ata_port_info info_20_udma = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, /* UDMA33 */ -+ .port_ops = &ali_20_port_ops -+ }; -+ /* Revision 0xC2 adds UDMA66 */ -+ static struct ata_port_info info_c2 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &ali_c2_port_ops -+ }; -+ /* Revision 0xC3 is UDMA100 */ -+ static struct ata_port_info info_c3 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &ali_c2_port_ops -+ }; -+ /* Revision 0xC4 is UDMA133 */ -+ static struct ata_port_info info_c4 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &ali_c2_port_ops -+ }; -+ /* Revision 0xC5 is UDMA133 with LBA48 DMA */ -+ static struct ata_port_info info_c5 = { -+ .sht = &ali_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &ali_c5_port_ops -+ }; -+ -+ static struct ata_port_info *port_info[2]; -+ u8 rev, tmp; -+ struct pci_dev *north, *isa_bridge; -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); -+ -+ /* -+ * The chipset revision selects the driver operations and -+ * mode data. -+ */ -+ -+ if (rev < 0x20) { -+ port_info[0] = port_info[1] = &info_early; -+ } else if (rev < 0xC2) { -+ /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */ -+ pci_read_config_byte(pdev, 0x4B, &tmp); -+ /* Clear CD-ROM DMA write bit */ -+ tmp &= 0x7F; -+ pci_write_config_byte(pdev, 0x4B, tmp); -+ port_info[0] = port_info[1] = &info_20; -+ } else if (rev == 0xC2) { -+ port_info[0] = port_info[1] = &info_c2; -+ } else if (rev == 0xC3) { -+ port_info[0] = port_info[1] = &info_c3; -+ } else if (rev == 0xC4) { -+ port_info[0] = port_info[1] = &info_c4; -+ } else -+ port_info[0] = port_info[1] = &info_c5; -+ -+ if (rev >= 0xC2) { -+ /* Enable cable detection logic */ -+ pci_read_config_byte(pdev, 0x4B, &tmp); -+ pci_write_config_byte(pdev, 0x4B, tmp | 0x08); -+ } -+ -+ north = pci_get_slot(pdev->bus, PCI_DEVFN(0,0)); -+ isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); -+ -+ if (north && north->vendor == PCI_VENDOR_ID_AL) { -+ /* Configure the ALi bridge logic. For non ALi rely on BIOS. -+ Set the south bridge enable bit */ -+ pci_read_config_byte(isa_bridge, 0x79, &tmp); -+ if (rev == 0xC2) -+ pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04); -+ else if (rev > 0xC2) -+ pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02); -+ } -+ -+ if (rev >= 0x20) { -+ if (rev < 0xC2) { -+ /* Are we paired with a UDMA capable chip */ -+ pci_read_config_byte(isa_bridge, 0x5E, &tmp); -+ if ((tmp & 0x1E) == 0x12) -+ port_info[0] = port_info[1] = &info_20_udma; -+ } -+ /* -+ * CD_ROM DMA on (0x53 bit 0). Enable this even if we want -+ * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control -+ * via 0x54/55. -+ */ -+ pci_read_config_byte(pdev, 0x53, &tmp); -+ if (rev == 0x20) -+ tmp &= ~0x02; -+ tmp |= 0x01; -+ pci_write_config_byte(pdev, 0x53, tmp); -+ } -+ -+ pci_dev_put(isa_bridge); -+ pci_dev_put(north); -+ -+ ata_pci_clear_simplex(pdev); -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static struct pci_device_id ali[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229), }, -+ { 0, }, -+}; -+ -+static struct pci_driver ali_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = ali, -+ .probe = ali_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init ali_init(void) -+{ -+ return pci_register_driver(&ali_pci_driver); -+} -+ -+ -+static void __exit ali_exit(void) -+{ -+ pci_unregister_driver(&ali_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ALi PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, ali); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(ali_init); -+module_exit(ali_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_amd.c linux-2.6.16-rc4/drivers/scsi/pata_amd.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_amd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_amd.c 2006-02-16 15:37:39.000000000 +0000 -@@ -0,0 +1,650 @@ -+/* -+ * pata_amd.c - AMD PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based on pata-sil680. Errata information is taken from data sheets -+ * and the amd74xx.c driver by Vojtech Pavlik. Nvidia SATA devices are -+ * claimed by sata-nv.c. -+ * -+ * TODO: -+ * Nvidia support here or seperated ? -+ * Debug cable detect -+ * Variable system clock when/if it makes sense -+ * Power management on ports -+ * -+ * -+ * Documentation publically available. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_amd" -+#define DRV_VERSION "0.1.3" -+ -+/** -+ * timing_setup - shared timing computation and load -+ * @ap: ATA port being set up -+ * @adev: drive being configured -+ * @offset: port offset -+ * @speed: target speed -+ * @clock: clock multiplier (number of times 33MHz for this part) -+ * -+ * Perform the actual timing set up for Nvidia or AMD PATA devices. -+ * The actual devices vary so they all call into this helper function -+ * providing the clock multipler and offset (because AMD and Nvidia put -+ * the ports at different locations). -+ */ -+ -+static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offset, int speed, int clock) -+{ -+ static const unsigned char amd_cyc2udma[] = { -+ 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 -+ }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct ata_device *peer = ata_dev_pair(ap, adev); -+ int dn = ap->hard_port_no * 2 + adev->devno; -+ struct ata_timing at, apeer; -+ int T, UT; -+ const int amd_clock = 33333; /* KHz. */ -+ u8 t; -+ -+ T = 1000000000 / amd_clock; -+ UT = T / min_t(int, max_t(int, clock, 1), 2); -+ -+ if (ata_timing_compute(adev, speed, &at, T, UT) < 0) { -+ dev_printk(KERN_ERR, &pdev->dev, "unknown mode %d.\n", speed); -+ return; -+ } -+ -+ if (peer) { -+ /* This may be over conservative */ -+ if (peer->dma_mode) { -+ ata_timing_compute(peer, peer->dma_mode, &apeer, T, UT); -+ ata_timing_merge(&apeer, &at, &at, ATA_TIMING_8BIT); -+ } -+ ata_timing_compute(peer, peer->pio_mode, &apeer, T, UT); -+ ata_timing_merge(&apeer, &at, &at, ATA_TIMING_8BIT); -+ } -+ -+ if (speed == XFER_UDMA_5 && amd_clock <= 33333) at.udma = 1; -+ if (speed == XFER_UDMA_6 && amd_clock <= 33333) at.udma = 15; -+ -+ /* -+ * Now do the setup work -+ */ -+ -+ /* Configure the address set up timing */ -+ pci_read_config_byte(pdev, offset + 0x0C, &t); -+ t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(at.setup, 1, 4) - 1) << ((3 - dn) << 1)); -+ pci_write_config_byte(pdev, offset + 0x0C , t); -+ -+ /* Configure the 8bit I/O timing */ -+ pci_write_config_byte(pdev, offset + 0x0E + (1 - (dn >> 1)), -+ ((FIT(at.act8b, 1, 16) - 1) << 4) | (FIT(at.rec8b, 1, 16) - 1)); -+ -+ /* Drive timing */ -+ pci_write_config_byte(pdev, offset + 0x08 + (3 - dn), -+ ((FIT(at.active, 1, 16) - 1) << 4) | (FIT(at.recover, 1, 16) - 1)); -+ -+ switch (clock) { -+ case 1: -+ t = at.udma ? (0xc0 | (FIT(at.udma, 2, 5) - 2)) : 0x03; -+ break; -+ -+ case 2: -+ t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 2, 10)]) : 0x03; -+ break; -+ -+ case 3: -+ t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 10)]) : 0x03; -+ break; -+ -+ case 4: -+ t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 15)]) : 0x03; -+ break; -+ -+ default: -+ return; -+ } -+ -+ /* UDMA timing */ -+ pci_write_config_byte(pdev, offset + 0x10 + (3 - dn), t); -+} -+ -+/** -+ * amd_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. The BIOS stores this in PCI config -+ * space for us. -+ */ -+ -+static int amd_cable_detect(struct ata_port *ap) { -+ static u32 bitmask[2] = {0x00030000, 0x00C00000}; -+ u32 ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_dword(pdev, 0x42, &ata66); -+ if (ata66 & bitmask[ap->hard_port_no]) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+ -+} -+ -+static void amd_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits amd_enable_bits[] = { -+ { 0x40, 1, 0x02, 0x02 }, -+ { 0x40, 1, 0x01, 0x01 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = amd_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * amd33_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the AMD registers for PIO mode. -+ */ -+ -+static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 1); -+} -+ -+static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 2); -+} -+ -+static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 3); -+} -+ -+static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->pio_mode, 4); -+} -+ -+/** -+ * amd33_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the AMD and Nvidia -+ * chipset. -+ */ -+ -+static void amd33_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 1); -+} -+ -+static void amd66_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 2); -+} -+ -+static void amd100_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 3); -+} -+ -+static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x40, adev->dma_mode, 4); -+} -+ -+ -+/** -+ * nv_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. The BIOS stores this in PCI config -+ * space for us. -+ */ -+ -+static int nv_cable_detect(struct ata_port *ap) { -+ static u32 bitmask[2] = {0x00030000, 0x00C00000}; -+ u32 ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_dword(pdev, 0x52, &ata66); -+ if (ata66 & bitmask[ap->hard_port_no]) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+ -+} -+ -+static void nv_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = nv_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * nv100_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the AMD registers for PIO mode. -+ */ -+ -+static void nv100_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->pio_mode, 3); -+} -+ -+static void nv133_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->pio_mode, 4); -+} -+ -+/** -+ * nv100_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the AMD and Nvidia -+ * chipset. -+ */ -+ -+static void nv100_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->dma_mode, 3); -+} -+ -+static void nv133_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ timing_setup(ap, adev, 0x50, adev->dma_mode, 4); -+} -+ -+static struct scsi_host_template amd_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations amd33_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd33_set_piomode, -+ .set_dmamode = amd33_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations amd66_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd66_set_piomode, -+ .set_dmamode = amd66_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations amd100_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd100_set_piomode, -+ .set_dmamode = amd100_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations amd133_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = amd133_set_piomode, -+ .set_dmamode = amd133_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = amd_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations nv100_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = nv100_set_piomode, -+ .set_dmamode = nv100_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = nv_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations nv133_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = nv133_set_piomode, -+ .set_dmamode = nv133_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = nv_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info[10] = { -+ { /* 0: AMD 7401 */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, /* No SWDMA */ -+ .udma_mask = 0x07, /* UDMA 33 */ -+ .port_ops = &amd33_port_ops -+ }, -+ { /* 1: Early AMD7409 - no swdma */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, /* UDMA 66 */ -+ .port_ops = &amd66_port_ops -+ }, -+ { /* 2: AMD 7409, no swdma errata */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, /* UDMA 66 */ -+ .port_ops = &amd66_port_ops -+ }, -+ { /* 3: AMD 7411 */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &amd100_port_ops -+ }, -+ { /* 4: AMD 7441 */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &amd100_port_ops -+ }, -+ { /* 5: AMD 8111*/ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, /* UDMA 133, no swdma */ -+ .port_ops = &amd133_port_ops -+ }, -+ { /* 6: AMD 8111 UDMA 100 (Serenade) */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100, no swdma */ -+ .port_ops = &amd133_port_ops -+ }, -+ { /* 7: Nvidia Nforce */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &nv100_port_ops -+ }, -+ { /* 8: Nvidia Nforce2 and later */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, /* UDMA 133, no swdma */ -+ .port_ops = &nv133_port_ops -+ }, -+ { /* 9: AMD CS5536 (Geode companion) */ -+ .sht = &amd_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* UDMA 100 */ -+ .port_ops = &amd100_port_ops -+ } -+ }; -+ static struct ata_port_info *port_info[2]; -+ static int printed_version; -+ int type = id->driver_data; -+ u8 rev; -+ u8 fifo; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); -+ pci_read_config_byte(pdev, 0x41, &fifo); -+ -+ /* Check for AMD7409 without swdma errata and if found adjust type */ -+ if (type == 1 && rev > 0x7) -+ type = 2; -+ -+ /* Check for AMD7411 */ -+ if (type == 3) -+ /* FIFO is broken */ -+ pci_write_config_byte(pdev, 0x41, fifo & 0x0F); -+ else -+ pci_write_config_byte(pdev, 0x41, fifo | 0xF0); -+ -+ /* Serenade ? */ -+ if (type == 5 && pdev->subsystem_vendor == PCI_VENDOR_ID_AMD && -+ pdev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) -+ type = 6; /* UDMA 100 only */ -+ -+ if (type < 3) -+ ata_pci_clear_simplex(pdev); -+ -+ /* And fire it up */ -+ -+ port_info[0] = port_info[1] = &info[type]; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id amd[] = { -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, -+ { 0, }, -+}; -+ -+static struct pci_driver amd_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = amd, -+ .probe = amd_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init amd_init(void) -+{ -+ return pci_register_driver(&amd_pci_driver); -+} -+ -+static void __exit amd_exit(void) -+{ -+ pci_unregister_driver(&amd_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for AMD PATA IDE"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, amd); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(amd_init); -+module_exit(amd_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_artop.c linux-2.6.16-rc4/drivers/scsi/pata_artop.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_artop.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_artop.c 2006-02-07 13:41:48.000000000 +0000 -@@ -0,0 +1,497 @@ -+/* -+ * pata_artop.c - ARTOP ATA controller driver -+ * -+ * (C) 2006 Red Hat <alan@redhat.com> -+ * -+ * Based in part on drivers/ide/pci/aec62xx.c -+ * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> -+ * 865/865R fixes for Macintosh card version from a patch to the old -+ * driver by Thibaut VARENE <varenet@parisc-linux.org> -+ * -+ * TODO -+ * 850 serialization once the core supports it -+ * Investigate no_dsc on 850R -+ * Clock detect -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_artop" -+#define DRV_VERSION "0.2" -+ -+/* -+ * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we -+ * get PCI bus speed functionality we leave this as 0. Its a variable -+ * for when we get the functionality and also for folks wanting to -+ * test stuff. -+ */ -+ -+static int clock = 0; -+ -+/** -+ * artop6210_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ const struct pci_bits artop_enable_bits[] = { -+ { 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4AU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * artop6260_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * The ARTOP hardware reports the cable detect bits in register 0x49. -+ * Nothing complicated needed here. -+ */ -+ -+static int artop6260_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 tmp; -+ -+ pci_read_config_byte(pdev, 0x49, &tmp); -+ if (tmp & (1 >> ap->hard_port_no)) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * artop6260_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ const struct pci_bits artop_enable_bits[] = { -+ { 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4AU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ /* Odd numbered device ids are the units with enable bits (the -R cards) */ -+ if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = artop6260_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * artop6210_load_piomode - Load a set of PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device -+ * @pio: PIO mode -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * is used both to set PIO timings in PIO mode and also to set the -+ * matching PIO clocking for UDMA, as well as the MWDMA timings. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_load_piomode(struct ata_port *ap, struct ata_device *adev, unsigned int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ const u16 timing[2][5] = { -+ { 0x0000, 0x000A, 0x0008, 0x0303, 0x0301 }, -+ { 0x0700, 0x070A, 0x0708, 0x0403, 0x0401 } -+ -+ }; -+ /* Load the PIO timing active/recovery bits */ -+ pci_write_config_word(pdev, 0x40 + 2 * dn, timing[clock][pio]); -+} -+ -+/** -+ * artop6210_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * -+ * Set PIO mode for device, in host controller PCI config space. For -+ * ARTOP we must also clear the UDMA bits if we are not doing UDMA. In -+ * the event UDMA is used the later call to set_dmamode will set the -+ * bits as required. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ u8 ultra; -+ -+ artop6210_load_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+ -+ /* Clear the UDMA mode bits (set_dmamode will redo this if needed) */ -+ pci_read_config_byte(pdev, 0x54, &ultra); -+ ultra &= ~(3 << (2 * dn)); -+ pci_write_config_byte(pdev, 0x54, ultra); -+} -+ -+/** -+ * artop6260_load_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * @pio: PIO mode -+ * -+ * Set PIO mode for device, in host controller PCI config space. The -+ * ARTOP6260 and relatives store the timing data differently. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_load_piomode (struct ata_port *ap, struct ata_device *adev, unsigned int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ const u8 timing[2][5] = { -+ { 0x00, 0x0A, 0x08, 0x33, 0x31 }, -+ { 0x70, 0x7A, 0x78, 0x43, 0x41 } -+ -+ }; -+ /* Load the PIO timing active/recovery bits */ -+ pci_write_config_byte(pdev, 0x40 + dn, timing[clock][pio]); -+} -+ -+/** -+ * artop6260_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * -+ * Set PIO mode for device, in host controller PCI config space. For -+ * ARTOP we must also clear the UDMA bits if we are not doing UDMA. In -+ * the event UDMA is used the later call to set_dmamode will set the -+ * bits as required. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 ultra; -+ -+ artop6260_load_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+ -+ /* Clear the UDMA mode bits (set_dmamode will redo this if needed) */ -+ pci_read_config_byte(pdev, 0x44 + ap->hard_port_no, &ultra); -+ ultra &= ~(7 << (4 * adev->devno)); /* One nibble per drive */ -+ pci_write_config_byte(pdev, 0x44 + ap->hard_port_no, ultra); -+} -+ -+/** -+ * artop6210_set_dmamode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set DMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6210_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = adev->devno + 2 * ap->hard_port_no; -+ u8 ultra; -+ -+ if (adev->dma_mode == XFER_MW_DMA_0) -+ pio = 1; -+ else -+ pio = 4; -+ -+ /* Load the PIO timing active/recovery bits */ -+ artop6210_load_piomode(ap, adev, pio); -+ -+ pci_read_config_byte(pdev, 0x54, &ultra); -+ ultra &= ~(3 << (2 * dn)); -+ -+ /* Add ultra DMA bits if in UDMA mode */ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ u8 mode = (adev->dma_mode - XFER_UDMA_0) + 1 - clock; -+ if (mode == 0) -+ mode = 1; -+ ultra |= (mode << (2 * dn)); -+ } -+ pci_write_config_byte(pdev, 0x54, ultra); -+} -+ -+/** -+ * artop6260_set_dmamode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring -+ * -+ * Set DMA mode for device, in host controller PCI config space. The -+ * ARTOP6260 and relatives store the timing data differently. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void artop6260_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 ultra; -+ -+ if (adev->dma_mode == XFER_MW_DMA_0) -+ pio = 1; -+ else -+ pio = 4; -+ -+ /* Load the PIO timing active/recovery bits */ -+ artop6260_load_piomode(ap, adev, pio); -+ -+ /* Add ultra DMA bits if in UDMA mode */ -+ pci_read_config_byte(pdev, 0x44 + ap->hard_port_no, &ultra); -+ ultra &= ~(7 << (4 * adev->devno)); /* One nibble per drive */ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ u8 mode = adev->dma_mode - XFER_UDMA_0 + 1 - clock; -+ if (mode == 0) -+ mode = 1; -+ ultra |= (mode << (4 * adev->devno)); -+ } -+ pci_write_config_byte(pdev, 0x44 + ap->hard_port_no, ultra); -+} -+ -+static struct scsi_host_template artop_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations artop6210_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = artop6210_set_piomode, -+ .set_dmamode = artop6210_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = artop6210_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations artop6260_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = artop6260_set_piomode, -+ .set_dmamode = artop6260_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = artop6260_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * artop_init_one - Register ARTOP ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in artop_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static int printed_version; -+ static struct ata_port_info info_6210 = { -+ .sht = &artop_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA2, -+ .port_ops = &artop6210_ops, -+ }; -+ static struct ata_port_info info_626x = { -+ .sht = &artop_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA4, -+ .port_ops = &artop6260_ops, -+ }; -+ static struct ata_port_info info_626x_fast = { -+ .sht = &artop_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &artop6260_ops, -+ }; -+ struct ata_port_info *port_info[2]; -+ struct ata_port_info *info; -+ int ports = 2; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ if (id->driver_data == 0) { /* 6210 variant */ -+ info = &info_6210; -+ /* BIOS may have left us in UDMA, clear it before libata probe */ -+ pci_write_config_byte(pdev, 0x54, 0); -+ /* For the moment (also lacks dsc) */ -+ printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n"); -+ printk(KERN_WARNING "Secondary ATA ports will not be activated.\n"); -+ ports = 1; -+ } -+ else if (id->driver_data == 1) /* 6260 */ -+ info = &info_626x; -+ else if (id->driver_data == 2) { /* 6260 or 6260 + fast */ -+ unsigned long io = pci_resource_start(pdev, 4); -+ u8 reg; -+ -+ info = &info_626x; -+ if (inb(io) & 0x10) -+ info = &info_626x_fast; -+ /* Mac systems come up with some registers not set as we -+ will need them */ -+ -+ /* Clear reset & test bits */ -+ pci_read_config_byte(pdev, 0x49, ®); -+ pci_write_config_byte(pdev, 0x49, reg & ~ 0x30); -+ -+ /* Enable IRQ output and burst mode */ -+ pci_read_config_byte(pdev, 0x4a, ®); -+ pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80); -+ -+ } -+ port_info[0] = port_info[1] = info; -+ return ata_pci_init_one(pdev, port_info, ports); -+} -+ -+static const struct pci_device_id artop_pci_tbl[] = { -+ { 0x1191, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0x1191, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { 0x1191, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { 0x1191, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { 0x1191, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver artop_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = artop_pci_tbl, -+ .probe = artop_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init artop_init(void) -+{ -+ return pci_register_driver(&artop_pci_driver); -+} -+ -+static void __exit artop_exit(void) -+{ -+ pci_unregister_driver(&artop_pci_driver); -+} -+ -+ -+module_init(artop_init); -+module_exit(artop_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for ARTOP PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, artop_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_atiixp.c linux-2.6.16-rc4/drivers/scsi/pata_atiixp.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_atiixp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_atiixp.c 2006-02-07 13:42:02.000000000 +0000 -@@ -0,0 +1,299 @@ -+/* -+ * pata_atiixp.c - ATI PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based on -+ * -+ * linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004 -+ * -+ * Copyright (C) 2003 ATI Inc. <hyu@ati.com> -+ * Copyright (C) 2004 Bartlomiej Zolnierkiewicz -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_atiixp" -+#define DRV_VERSION "0.1.1" -+ -+enum { -+ ATIIXP_IDE_PIO_TIMING = 0x40, -+ ATIIXP_IDE_MWDMA_TIMING = 0x44, -+ ATIIXP_IDE_PIO_CONTROL = 0x48, -+ ATIIXP_IDE_PIO_MODE = 0x4a, -+ ATIIXP_IDE_UDMA_CONTROL = 0x54, -+ ATIIXP_IDE_UDMA_MODE = 0x56 -+}; -+ -+static void atiixp_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits atiixp_enable_bits[] = { -+ { 0x48, 1, 0x01, 0x00 }, -+ { 0x48, 1, 0x08, 0x00 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * atiixp_set_pio_timing - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called by both the pio and dma setup functions to set the controller -+ * timings for PIO transfers. We must load both the mode number and -+ * timing values into the controller. -+ */ -+ -+static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ static u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ -+ /* Check this is correct - the order is odd in both drivers */ -+ int timing_shift = (16 * ap->hard_port_no) + 8 * (adev->devno ^ 1); -+ u16 pio_mode_data, pio_timing_data; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data); -+ pio_mode_data &= ~(0x7 << (4 * dn)); -+ pio_mode_data |= pio << (4 * dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data); -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data); -+ pio_mode_data &= ~(0xFF << timing_shift); -+ pio_mode_data |= (pio_timings[pio] << timing_shift); -+ pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); -+} -+ -+/** -+ * atiixp_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. We use a shared helper for this -+ * as the DMA setup must also adjust the PIO timing information. -+ */ -+ -+static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * atiixp_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. We use timing tables for most -+ * modes but must tune an appropriate PIO mode to match. -+ */ -+ -+static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dma = adev->dma_mode; -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ int wanted_pio; -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ u16 udma_mode_data; -+ -+ dma -= XFER_UDMA_0; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_UDMA_MODE, &udma_mode_data); -+ udma_mode_data &= ~(0x7 << (4 * dn)); -+ udma_mode_data |= dma << (4 * dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data); -+ } else { -+ u16 mwdma_timing_data; -+ /* Check this is correct - the order is odd in both drivers */ -+ int timing_shift = (16 * ap->hard_port_no) + 8 * (adev->devno ^ 1); -+ -+ dma -= XFER_MW_DMA_0; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, &mwdma_timing_data); -+ mwdma_timing_data &= ~(0xFF << timing_shift); -+ mwdma_timing_data |= (mwdma_timings[dma] << timing_shift); -+ pci_write_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, mwdma_timing_data); -+ } -+ /* -+ * We must now look at the PIO mode situation. We may need to -+ * adjust the PIO mode to keep the timings acceptable -+ */ -+ if (adev->dma_mode >= XFER_MW_DMA_2) -+ wanted_pio = 4; -+ else if (adev->dma_mode == XFER_MW_DMA_1) -+ wanted_pio = 3; -+ else if (adev->dma_mode == XFER_MW_DMA_0) -+ wanted_pio = 0; -+ else BUG(); -+ -+ if (adev->pio_mode != wanted_pio) -+ atiixp_set_pio_timing(ap, adev, wanted_pio); -+} -+ -+/** -+ * atiixp_bmdma_start - DMA start callback -+ * @qc: Command in progress -+ * -+ * When DMA begins we need to ensure that the UDMA control -+ * register for the channel is correctly set. -+ */ -+ -+static void atiixp_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = (2 * ap->hard_port_no) + adev->devno; -+ u16 tmp16; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); -+ if (adev->dma_mode >= XFER_UDMA_0) -+ tmp16 |= (1 << dn); -+ else -+ tmp16 &= ~(1 << dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * atiixp_dma_stop - DMA stop callback -+ * @qc: Command in progress -+ * -+ * DMA has completed. Clear the UDMA flag as the next operations will -+ * be PIO ones not UDMA data transfer. -+ */ -+ -+static void atiixp_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = (2 * ap->hard_port_no) + qc->dev->devno; -+ u16 tmp16; -+ -+ pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); -+ tmp16 &= ~(1 << dn); -+ pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16); -+ ata_bmdma_stop(qc); -+} -+ -+static struct scsi_host_template atiixp_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations atiixp_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = atiixp_set_piomode, -+ .set_dmamode = atiixp_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = atiixp_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = atiixp_bmdma_start, -+ .bmdma_stop = atiixp_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &atiixp_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x06, /* No MWDMA0 support */ -+ .udma_mask = 0x3F, -+ .port_ops = &atiixp_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id atiixp[] = { -+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver atiixp_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = atiixp, -+ .probe = atiixp_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init atiixp_init(void) -+{ -+ return pci_register_driver(&atiixp_pci_driver); -+} -+ -+ -+static void __exit atiixp_exit(void) -+{ -+ pci_unregister_driver(&atiixp_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, atiixp); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(atiixp_init); -+module_exit(atiixp_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cmd64x.c linux-2.6.16-rc4/drivers/scsi/pata_cmd64x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cmd64x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cmd64x.c 2006-02-16 15:34:39.000000000 +0000 -@@ -0,0 +1,486 @@ -+/* -+ * pata_cmd64x.c - ATI PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based upon -+ * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 -+ * -+ * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. -+ * Note, this driver is not used at all on other systems because -+ * there the "BIOS" has done all of the following already. -+ * Due to massive hardware bugs, UltraDMA is only supported -+ * on the 646U2 and not on the 646U. -+ * -+ * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) -+ * Copyright (C) 1998 David S. Miller (davem@redhat.com) -+ * -+ * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> -+ * -+ * TODO -+ * Testing work -+ * Non x86 needs PIO 0 loading before we commence ident -+ * - but this belongs in libata-core -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_cmd64x" -+#define DRV_VERSION "0.1.1" -+ -+/* -+ * CMD64x specific registers definition. -+ */ -+ -+enum { -+ CFR = 0x50, -+ CFR_INTR_CH0 = 0x02, -+ CNTRL = 0x51, -+ CNTRL_DIS_RA0 = 0x40, -+ CNTRL_DIS_RA1 = 0x80, -+ CNTRL_ENA_2ND = 0x08, -+ CMDTIM = 0x52, -+ ARTTIM0 = 0x53, -+ DRWTIM0 = 0x54, -+ ARTTIM1 = 0x55, -+ DRWTIM1 = 0x56, -+ ARTTIM23 = 0x57, -+ ARTTIM23_DIS_RA2 = 0x04, -+ ARTTIM23_DIS_RA3 = 0x08, -+ ARTTIM23_INTR_CH1 = 0x10, -+ ARTTIM2 = 0x57, -+ ARTTIM3 = 0x57, -+ DRWTIM23 = 0x58, -+ DRWTIM2 = 0x58, -+ BRST = 0x59, -+ DRWTIM3 = 0x5b, -+ BMIDECR0 = 0x70, -+ MRDMODE = 0x71, -+ MRDMODE_INTR_CH0 = 0x04, -+ MRDMODE_INTR_CH1 = 0x08, -+ MRDMODE_BLK_CH0 = 0x10, -+ MRDMODE_BLK_CH1 = 0x20, -+ BMIDESR0 = 0x72, -+ UDIDETCR0 = 0x73, -+ DTPR0 = 0x74, -+ BMIDECR1 = 0x78, -+ BMIDECSR = 0x79, -+ BMIDESR1 = 0x7A, -+ UDIDETCR1 = 0x7B, -+ DTPR1 = 0x7C -+}; -+ -+/* Phee Phy Pho Phum */ -+ -+static void cmd64x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+static void cmd648_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 r; -+ -+ /* Check cable detect bits */ -+ pci_read_config_byte(pdev, BMIDECSR, &r); -+ if (r & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA80; -+ else -+ ap->cbl = ATA_CBL_PATA40; -+ -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * cmd64x_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. -+ */ -+ -+static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct ata_timing t; -+ const unsigned long T = 1000000 / 33; -+ const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 }; -+ -+ u8 reg; -+ -+ /* Port layout is not logical so use a table */ -+ const u8 arttim_port[2][2] = { -+ { ARTTIM0, ARTTIM1 }, -+ { ARTTIM23, ARTTIM23 } -+ }; -+ const u8 drwtim_port[2][2] = { -+ { DRWTIM0, DRWTIM1 }, -+ { DRWTIM2, DRWTIM3 } -+ }; -+ -+ int arttim = arttim_port[ap->hard_port_no][adev->devno]; -+ int drwtim = drwtim_port[ap->hard_port_no][adev->devno]; -+ -+ -+ if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) { -+ printk(KERN_ERR DRV_NAME ": mome computation failed.\n"); -+ return; -+ } -+ if (ap->hard_port_no) { -+ /* Slave has shared address setup */ -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ -+ if (pair) { -+ struct ata_timing tp; -+ ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); -+ ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); -+ } -+ } -+ -+ printk(KERN_DEBUG DRV_NAME ": active %d recovery %d setup %d.\n", -+ t.active, t.recover, t.setup); -+ if (t.recover > 16) { -+ t.active += t.recover - 16; -+ t.recover = 16; -+ } -+ if (t.active > 16) -+ t.active = 16; -+ -+ /* Now convert the clocks into values we can actually stuff into -+ the chip */ -+ -+ if (t.recover > 1) -+ t.recover--; -+ else -+ t.recover = 15; -+ -+ if (t.setup > 4) -+ t.setup = 0xC0; -+ else -+ t.setup = setup_data[t.setup]; -+ -+ t.active &= 0x0F; /* 0 = 16 */ -+ -+ /* Load setup timing */ -+ pci_read_config_byte(pdev, arttim, ®); -+ reg &= 0x3F; -+ reg |= t.setup; -+ pci_write_config_byte(pdev, arttim, reg); -+ -+ /* Load active/recovery */ -+ pci_write_config_byte(pdev, drwtim, (t.active << 4) | t.recover); -+} -+ -+/** -+ * cmd64x_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. -+ */ -+ -+static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 regU, regD; -+ -+ int pciU = UDIDETCR0 + 8 * ap->hard_port_no; -+ int pciD = BMIDESR0 + 8 * ap->hard_port_no; -+ int shift = 2 * adev->devno; -+ const u8 udma_data[] = { 0x31, 0x21, 0x11, 0x25, 0x15, 0x05 }; -+ const u8 mwdma_data[] = { 0x30, 0x20, 0x10 }; -+ -+ pci_read_config_byte(pdev, pciD, ®D); -+ pci_read_config_byte(pdev, pciU, ®U); -+ -+ regD &= ~(0x20 << shift); -+ regU &= ~(0x35 << shift); -+ -+ if (adev->dma_mode >= XFER_UDMA_0) -+ regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; -+ else -+ regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; -+ -+ regD |= 0x20 << adev->devno; -+ -+ pci_write_config_byte(pdev, pciU, regU); -+ pci_write_config_byte(pdev, pciD, regD); -+} -+ -+/** -+ * cmd648_dma_stop - DMA stop callback -+ * @qc: Command in progress -+ * -+ * DMA has completed. -+ */ -+ -+static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 dma_intr; -+ int dma_reg = ap->hard_port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; -+ int dma_mask = ap->hard_port_no ? ARTTIM2 : CFR; -+ -+ ata_bmdma_stop(qc); -+ -+ pci_read_config_byte(pdev, dma_reg, &dma_intr); -+ pci_write_config_byte(pdev, dma_reg, dma_intr | dma_mask); -+} -+ -+/** -+ * cmd646r1_dma_stop - DMA stop callback -+ * @qc: Command in progress -+ * -+ * Stub for now while investigating the r1 quirk in the old driver. -+ */ -+ -+static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ ata_bmdma_stop(qc); -+} -+ -+static struct scsi_host_template cmd64x_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cmd64x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cmd64x_set_piomode, -+ .set_dmamode = cmd64x_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = cmd64x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations cmd646r1_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cmd64x_set_piomode, -+ .set_dmamode = cmd64x_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = cmd64x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = cmd646r1_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations cmd648_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cmd64x_set_piomode, -+ .set_dmamode = cmd64x_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = cmd648_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = cmd648_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ u32 class_rev; -+ -+ static struct ata_port_info cmd_info[6] = { -+ { /* CMD 643 - no UDMA */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cmd64x_port_ops -+ }, -+ { /* CMD 646 with broken UDMA */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cmd64x_port_ops -+ }, -+ { /* CMD 646 with working UDMA */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA1, -+ .port_ops = &cmd64x_port_ops -+ }, -+ { /* CMD 646 rev 1 */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cmd646r1_port_ops -+ }, -+ { /* CMD 648 */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA2, -+ .port_ops = &cmd648_port_ops -+ }, -+ { /* CMD 649 */ -+ .sht = &cmd64x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA3, -+ .port_ops = &cmd648_port_ops -+ } -+ }; -+ static struct ata_port_info *port_info[2], *info; -+ u8 mrdmode; -+ -+ info = &cmd_info[id->driver_data]; -+ -+ pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ if (id->driver_data == 0) /* 643 */ -+ ata_pci_clear_simplex(pdev); -+ -+ if (pdev->device == PCI_DEVICE_ID_CMD_646) { -+ /* Does UDMA work ? */ -+ if (class_rev > 4) -+ info = &cmd_info[2]; -+ /* Early rev with other problems ? */ -+ else if (class_rev == 1) -+ info = &cmd_info[3]; -+ } -+ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); -+ pci_read_config_byte(pdev, MRDMODE, &mrdmode); -+ mrdmode &= ~ 0x30; /* IRQ set up */ -+ mrdmode |= 0x02; /* Memory read line enable */ -+ pci_write_config_byte(pdev, MRDMODE, mrdmode); -+ -+ /* Force PIO 0 here.. */ -+ -+ /* PPC specific fixup copied from old driver */ -+#ifdef CONFIG_PPC -+ pci_write_config_byte(pdev, UDIDETCR0, 0xF0); -+#endif -+ -+ port_info[0] = port_info[1] = info; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static struct pci_device_id cmd64x[] = { -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, -+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, -+ { 0, }, -+}; -+ -+static struct pci_driver cmd64x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cmd64x, -+ .probe = cmd64x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cmd64x_init(void) -+{ -+ return pci_register_driver(&cmd64x_pci_driver); -+} -+ -+ -+static void __exit cmd64x_exit(void) -+{ -+ pci_unregister_driver(&cmd64x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cmd64x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cmd64x_init); -+module_exit(cmd64x_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5520.c linux-2.6.16-rc4/drivers/scsi/pata_cs5520.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5520.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cs5520.c 2006-02-20 13:17:11.000000000 +0000 -@@ -0,0 +1,322 @@ -+/* -+ * IDE tuning and bus mastering support for the CS5510/CS5520 -+ * chipsets -+ * -+ * The CS5510/CS5520 are slightly unusual devices. Unlike the -+ * typical IDE controllers they do bus mastering with the drive in -+ * PIO mode and smarter silicon. -+ * -+ * The practical upshot of this is that we must always tune the -+ * drive for the right PIO mode. We must also ignore all the blacklists -+ * and the drive bus mastering DMA information. Also to confuse matters -+ * further we can do DMA on PIO only drives. -+ * -+ * DMA on the 5510 also requires we disable_hlt() during DMA on early -+ * revisions. -+ * -+ * *** This driver is strictly experimental *** -+ * -+ * (c) Copyright Red Hat Inc 2002 -+ * -+ * 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. -+ * -+ * Documentation: -+ * Not publically available. -+ */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "cs5520" -+#define DRV_VERSION "0.4" -+ -+struct pio_clocks -+{ -+ int address; -+ int assert; -+ int recovery; -+}; -+ -+static struct pio_clocks cs5520_pio_clocks[]={ -+ {3, 6, 11}, -+ {2, 5, 6}, -+ {1, 4, 3}, -+ {1, 3, 2}, -+ {1, 2, 1} -+}; -+ -+/** -+ * cs5520_set_timings - program PIO timings -+ * @ap: ATA port -+ * @adev: ATA device -+ * -+ * Program the PIO mode timings for the controller according to the pio -+ * clocking table. -+ */ -+ -+static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int slave = adev->devno; -+ -+ pio -= XFER_PIO_0; -+ -+ /* Channel command timing */ -+ pci_write_config_byte(pdev, 0x62 + ap->hard_port_no, -+ (cs5520_pio_clocks[pio].recovery << 4) | -+ (cs5520_pio_clocks[pio].assert)); -+ /* FIXME: should these use address ? */ -+ /* Read command timing */ -+ pci_write_config_byte(pdev, 0x64 + 4*ap->hard_port_no + slave, -+ (cs5520_pio_clocks[pio].recovery << 4) | -+ (cs5520_pio_clocks[pio].assert)); -+ /* Write command timing */ -+ pci_write_config_byte(pdev, 0x66 + 4*ap->hard_port_no + slave, -+ (cs5520_pio_clocks[pio].recovery << 4) | -+ (cs5520_pio_clocks[pio].assert)); -+} -+ -+/** -+ * cs5520_enable_dma - turn on DMA bits -+ * -+ * Turn on the DMA bits for this disk. Needed because the BIOS probably -+ * has not done the work for us. Belongs in the core SATA code. -+ */ -+ -+static int cs5520_enable_dma(struct ata_port *ap, struct ata_device *adev) -+{ -+ /* Set the DMA enable/disable flag */ -+ u8 reg = inb(ap->ioaddr.bmdma_addr + 0x02); -+ reg |= 1<<(adev->devno + 5); -+ outb(reg, ap->ioaddr.bmdma_addr + 0x02); -+} -+ -+/** -+ * cs5520_set_dmamode - program DMA timings -+ * @ap: ATA port -+ * @adev: ATA device -+ * -+ * Program the DMA mode timings for the controller according to the pio -+ * clocking table. Note that this device sets the DMA timings to PIO -+ * mode values. This may seem bizarre but the 5520 architecture talks -+ * PIO mode to the disk and DMA mode to the controller so the underlying -+ * transfers are PIO timed. -+ */ -+ -+static void cs5520_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static const int dma_xlate[3] = { XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 }; -+ cs5520_set_timings(ap, adev, dma_xlate[adev->dma_mode]); -+ cs5520_enable_dma(ap, adev); -+} -+ -+/** -+ * cs5520_set_piomode - program PIO timings -+ * @ap: ATA port -+ * @adev: ATA device -+ * -+ * Program the PIO mode timings for the controller according to the pio -+ * clocking table. We know pio_mode will equal dma_mode because of the -+ * CS5520 architecture. At least once we turned DMA on and wrote a -+ * mode setter. -+ */ -+ -+static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ cs5520_set_timings(ap, adev, adev->pio_mode); -+} -+ -+static struct scsi_host_template cs5520_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cs5520_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cs5520_set_piomode, -+ .set_dmamode = cs5520_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ u8 pcicfg; -+ static struct ata_probe_ent probe[2]; -+ int ports = 0; -+ -+ pci_read_config_byte(dev, 0x60, &pcicfg); -+ -+ /* Check if the ATA ports are enabled */ -+ if ((pcicfg & 3) == 0) -+ return -ENODEV; -+ -+ if ((pcicfg & 0x40) == 0) { -+ printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n"); -+ pci_write_config_byte(dev, 0x60, pcicfg | 0x40); -+ } -+ -+ /* Perform set up for DMA */ -+ if (pci_enable_device_bars(dev, 1<<2)) { -+ printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); -+ return -ENODEV; -+ } -+ pci_set_master(dev); -+ if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { -+ printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); -+ return -ENODEV; -+ } -+ if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) { -+ printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n"); -+ return -ENODEV; -+ } -+ -+ /* We have to do our own plumbing as the PCI setup for this -+ chipset is non-standard so we can't punt to the libata code */ -+ -+ INIT_LIST_HEAD(&probe[0].node); -+ probe[0].dev = pci_dev_to_dev(dev); -+ probe[0].port_ops = &cs5520_port_ops; -+ probe[0].sht = &cs5520_sht; -+ probe[0].pio_mask = 0x1F; -+ probe[0].mwdma_mask = id->driver_data; -+ probe[0].irq = 14; -+ probe[0].irq_flags = SA_SHIRQ; -+ probe[0].host_flags = ATA_FLAG_SLAVE_POSS; -+ probe[0].legacy_mode = 1; -+ probe[0].n_ports = 1; -+ probe[0].port[0].cmd_addr = 0x1F0; -+ probe[0].port[0].ctl_addr = 0x3F6; -+ probe[0].port[0].altstatus_addr = 0x3F6; -+ probe[0].port[0].bmdma_addr = pci_resource_start(dev, 2); -+ -+ /* The secondary lurks at different addresses but is otherwise -+ the same beastie */ -+ -+ probe[1] = probe[0]; -+ INIT_LIST_HEAD(&probe[1].node); -+ probe[1].irq = 15; -+ probe[1].hard_port_no = 1; -+ probe[1].port[0].cmd_addr = 0x170; -+ probe[1].port[0].ctl_addr = 0x376; -+ probe[1].port[0].altstatus_addr = 0x376; -+ probe[1].port[0].bmdma_addr = pci_resource_start(dev, 2) + 8; -+ -+ /* Let libata fill in the port details */ -+ ata_std_ports(&probe[0].port[0]); -+ ata_std_ports(&probe[1].port[0]); -+ -+ /* Now add the ports that are active */ -+ if (pcicfg & 1) -+ ports += ata_device_add(&probe[0]); -+ if (pcicfg & 2) -+ ports += ata_device_add(&probe[1]); -+ if (ports) -+ return 0; -+ return -ENODEV; -+} -+ -+/** -+ * cs5520_remove_one - device unload -+ * @pdev: PCI device being removed -+ * -+ * Handle an unplug/unload event for a PCI device. Unload the -+ * PCI driver but do not use the default handler as we manage -+ * resources ourself and *MUST NOT* disable the device as it has -+ * other functions. -+ */ -+ -+static void __devexit cs5520_remove_one(struct pci_dev *pdev) -+{ -+ struct device *dev = pci_dev_to_dev(pdev); -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+} -+ -+/* For now keep DMA off. We can set it for all but A rev CS5510 once the -+ core ATA code can handle it */ -+ -+static struct pci_device_id pata_cs5520[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520), }, -+ { 0, }, -+}; -+ -+static struct pci_driver cs5520_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pata_cs5520, -+ .probe = cs5520_init_one, -+ .remove = cs5520_remove_one -+}; -+ -+ -+static int __init cs5520_init(void) -+{ -+ return pci_register_driver(&cs5520_pci_driver); -+} -+ -+static void __exit cs5520_exit(void) -+{ -+ pci_unregister_driver(&cs5520_pci_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Cyrix CS5510/5520"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pata_cs5520); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cs5520_init); -+module_exit(cs5520_exit); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5530.c linux-2.6.16-rc4/drivers/scsi/pata_cs5530.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5530.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cs5530.c 2006-02-21 16:44:52.000000000 +0000 -@@ -0,0 +1,371 @@ -+/* -+ * pata-cs5530.c - CS5530 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon cs5530.c by Mark Lord. -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Loosely based on the piix & svwks drivers. -+ * -+ * Documentation: -+ * Available from AMD web site. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/dmi.h> -+ -+#define DRV_NAME "cs5530" -+#define DRV_VERSION "0.4" -+ -+/** -+ * cs5530_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. This is fairly simple on the CS5530 -+ * chips. -+ */ -+ -+static void cs5530_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static unsigned int cs5530_pio_timings[2][5] = { -+ {0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, -+ {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010} -+ }; -+ unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->hard_port_no; -+ u32 tuning; -+ int format; -+ -+ /* Find out which table to use */ -+ tuning = inl(base + 0x04); -+ format = (tuning & 0x80000000UL) ? 1 : 0; -+ -+ /* Now load the right timing register */ -+ if (adev->devno) -+ base += 0x08; -+ -+ outl(cs5530_pio_timings[format][adev->pio_mode - XFER_PIO_0], base); -+} -+ -+/** -+ * cs5530_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * We cannot mix MWDMA and UDMA without reloading timings each switch -+ * master to slave. We track the last DMA setup in order to minimise -+ * reloads. -+ */ -+ -+static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->hard_port_no; -+ u32 tuning, timing = 0; -+ u8 reg; -+ -+ /* Find out which table to use */ -+ tuning = inl(base + 0x04); -+ -+ switch(adev->dma_mode) { -+ case XFER_UDMA_0: -+ timing = 0x00921250;break; -+ case XFER_UDMA_1: -+ timing = 0x00911140;break; -+ case XFER_UDMA_2: -+ timing = 0x00911030;break; -+ case XFER_MW_DMA_0: -+ timing = 0x00077771;break; -+ case XFER_MW_DMA_1: -+ timing = 0x00012121;break; -+ case XFER_MW_DMA_2: -+ timing = 0x00002020;break; -+ default: -+ BUG(); -+ } -+ /* Merge in the PIO format bit */ -+ timing |= (tuning & 0x80000000UL); -+ if (adev->devno == 0) /* Master */ -+ outl(timing, base + 0x04); -+ else { -+ if (timing & 0x00100000) -+ tuning |= 0x00100000; /* UDMA for both */ -+ else -+ tuning &= ~0x00100000; /* MWDMA for both */ -+ outl(tuning, base + 0x04); -+ outl(timing, base + 0x0C); -+ } -+ -+ /* Set the DMA capable bit in the BMDMA area */ -+ reg = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); -+ reg |= (1 << (5 + adev->devno)); -+ outb(reg, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); -+ -+ /* Remember the last DMA setup we did */ -+ -+ ap->private_data = adev; -+} -+ -+/** -+ * cs5530_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Specifically we have a problem that there is only -+ * one MWDMA/UDMA bit. -+ */ -+ -+static int cs5530_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct ata_device *prev = ap->private_data; -+ -+ /* See if the DMA settings could be wrong */ -+ if (adev->dma_mode != 0 && adev != prev && prev != NULL) { -+ /* Maybe, but do the channels match MWDMA/UDMA ? */ -+ if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) || -+ (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0)) -+ /* Switch the mode bits */ -+ cs5530_set_dmamode(ap, adev); -+ } -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template cs5530_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cs5530_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cs5530_set_piomode, -+ .set_dmamode = cs5530_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = cs5530_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct dmi_system_id __initdata palmax_dmi_table[] = { -+ { -+ .ident = "Palmax PD1100", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Cyrix"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Caddis"), -+ }, -+ }, -+ { } -+}; -+ -+static int cs5530_is_palmax(void) -+{ -+ if (dmi_check_system(palmax_dmi_table)) { -+ printk(KERN_INFO "Palmax PD1100: Disabling DMA on docking port.\n"); -+ return 1; -+ } -+ return 0; -+} -+ -+/** -+ * cs5530_init_one - Initialise a CS5530 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Install a driver for the newly found CS5530 companion chip. Most of -+ * this is just housekeeping. We have to set the chip up correctly and -+ * turn off various bits of emulation magic. -+ */ -+ -+static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ int compiler_warning_pointless_fix; -+ struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; -+ static struct ata_port_info info = { -+ .sht = &cs5530_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &cs5530_port_ops -+ }; -+ /* The docking connector doesn't do UDMA, and it seems not MWDMA */ -+ static struct ata_port_info info_palmax_secondary = { -+ .sht = &cs5530_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .port_ops = &cs5530_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ dev = NULL; -+ while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { -+ switch (dev->device) { -+ case PCI_DEVICE_ID_CYRIX_PCI_MASTER: -+ master_0 = pci_dev_get(dev); -+ break; -+ case PCI_DEVICE_ID_CYRIX_5530_LEGACY: -+ cs5530_0 = pci_dev_get(dev); -+ break; -+ } -+ } -+ if (!master_0) { -+ printk(KERN_ERR DRV_NAME ": unable to locate PCI MASTER function\n"); -+ goto fail_put; -+ } -+ if (!cs5530_0) { -+ printk(KERN_ERR DRV_NAME ": unable to locate CS5530 LEGACY function\n"); -+ goto fail_put; -+ } -+ -+ pci_set_master(cs5530_0); -+ compiler_warning_pointless_fix = pci_set_mwi(cs5530_0); -+ -+ /* -+ * Set PCI CacheLineSize to 16-bytes: -+ * --> Write 0x04 into 8-bit PCI CACHELINESIZE reg of function 0 of the cs5530 -+ * -+ * Note: This value is constant because the 5530 is only a Geode companion -+ */ -+ -+ pci_write_config_byte(cs5530_0, PCI_CACHE_LINE_SIZE, 0x04); -+ -+ /* -+ * Disable trapping of UDMA register accesses (Win98 hack): -+ * --> Write 0x5006 into 16-bit reg at offset 0xd0 of function 0 of the cs5530 -+ */ -+ -+ pci_write_config_word(cs5530_0, 0xd0, 0x5006); -+ -+ /* -+ * Bit-1 at 0x40 enables MemoryWriteAndInvalidate on internal X-bus: -+ * The other settings are what is necessary to get the register -+ * into a sane state for IDE DMA operation. -+ */ -+ -+ pci_write_config_byte(master_0, 0x40, 0x1e); -+ -+ /* -+ * Set max PCI burst size (16-bytes seems to work best): -+ * 16bytes: set bit-1 at 0x41 (reg value of 0x16) -+ * all others: clear bit-1 at 0x41, and do: -+ * 128bytes: OR 0x00 at 0x41 -+ * 256bytes: OR 0x04 at 0x41 -+ * 512bytes: OR 0x08 at 0x41 -+ * 1024bytes: OR 0x0c at 0x41 -+ */ -+ -+ pci_write_config_byte(master_0, 0x41, 0x14); -+ -+ /* -+ * These settings are necessary to get the chip -+ * into a sane state for IDE DMA operation. -+ */ -+ -+ pci_write_config_byte(master_0, 0x42, 0x00); -+ pci_write_config_byte(master_0, 0x43, 0xc1); -+ -+ pci_dev_put(master_0); -+ pci_dev_put(cs5530_0); -+ -+ if (cs5530_is_palmax()) -+ port_info[1] = &info_palmax_secondary; -+ -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+ -+fail_put: -+ if (master_0) -+ pci_dev_put(master_0); -+ if (cs5530_0) -+ pci_dev_put(cs5530_0); -+ return -ENODEV; -+} -+ -+static struct pci_device_id cs5530[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, -+ { 0, }, -+}; -+ -+static struct pci_driver cs5530_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cs5530, -+ .probe = cs5530_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cs5530_init(void) -+{ -+ return pci_register_driver(&cs5530_pci_driver); -+} -+ -+ -+static void __exit cs5530_exit(void) -+{ -+ pci_unregister_driver(&cs5530_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cs5530); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cs5530_init); -+module_exit(cs5530_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5535.c linux-2.6.16-rc4/drivers/scsi/pata_cs5535.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cs5535.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cs5535.c 2006-02-16 15:37:21.000000000 +0000 -@@ -0,0 +1,286 @@ -+/* -+ * pata-cs5535.c - CS5535 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon cs5535.c from AMD <Jens.Altmann@amd.com> as cleaned up and -+ * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de -+ * and Alexander Kiausch <alex.kiausch@t-online.de> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * 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 -+ * -+ * Loosely based on the piix & svwks drivers. -+ * -+ * Documentation: -+ * Available from AMD web site. -+ * TODO -+ * Review errata to see if serializing is neccessary -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <asm/msr.h> -+ -+#define DRV_NAME "cs5535" -+#define DRV_VERSION "0.2.1" -+ -+/* -+ * The Geode (Aka Athlon GX now) uses an internal MSR based -+ * bus system for control. Demented but there you go. -+ */ -+ -+#define MSR_ATAC_BASE 0x51300000 -+#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0) -+#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01) -+#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02) -+#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03) -+#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04) -+#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05) -+#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08) -+#define ATAC_RESET (MSR_ATAC_BASE+0x10) -+#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20) -+#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21) -+#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22) -+#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23) -+#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24) -+ -+#define ATAC_BM0_CMD_PRIM 0x00 -+#define ATAC_BM0_STS_PRIM 0x02 -+#define ATAC_BM0_PRD 0x04 -+ -+#define CS5535_CABLE_DETECT 0x48 -+ -+#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 ) -+ -+/** -+ * cs5535_cable_detect - detect cable type -+ * @ap: Port to detect on -+ * -+ * Perform cable detection for ATA66 capable cable. Return a libata -+ * cable type. -+ */ -+ -+static int cs5535_cable_detect(struct ata_port *ap) -+{ -+ u8 cable; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable); -+ if (cable & 1) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * cs5535_phy_reset - reset/probe -+ * @ap: Port to reset -+ * -+ * Reset and configure a port -+ */ -+ -+static void cs5535_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = cs5535_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * cs5535_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. The CS5535 is pretty clean about all this -+ */ -+ -+static void cs5535_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u16 pio_timings[5] = { -+ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 -+ }; -+ static u16 pio_cmd_timings[5] = { -+ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 -+ }; -+ u32 reg, dummy; -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ -+ int mode = adev->pio_mode - XFER_PIO_0; -+ int cmdmode = mode; -+ -+ /* Command timing has to be for the lowest of the pair of devices */ -+ if (pair) { -+ int pairmode = pair->pio_mode - XFER_PIO_0; -+ cmdmode = min(mode, pairmode); -+ /* Write the other drive timing register if it changed */ -+ if (cmdmode < pairmode) -+ wrmsr(ATAC_CH0D0_PIO + 2 * pair->devno, -+ pio_cmd_timings[cmdmode] << 16 | pio_timings[pairmode], 0); -+ } -+ /* Write the drive timing register */ -+ wrmsr(ATAC_CH0D0_PIO + 2 * adev->devno, -+ pio_cmd_timings[cmdmode] << 16 | pio_timings[mode], 0); -+ -+ /* Set the PIO "format 1" bit in the DMA timing register */ -+ rdmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, dummy); -+ wrmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg | 0x80000000UL, 0); -+} -+ -+/** -+ * cs5535_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ */ -+ -+static void cs5535_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u32 udma_timings[5] = { 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 }; -+ static u32 mwdma_timings[3] = { 0x7F0FFFF3, 0x7F035352, 0x7F024241 }; -+ u32 reg, dummy; -+ int mode = adev->dma_mode; -+ -+ rdmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, dummy); -+ reg &= 0x80000000UL; -+ if (mode >= XFER_UDMA_0) -+ reg |= udma_timings[mode - XFER_UDMA_0]; -+ else -+ reg |= mwdma_timings[mode - XFER_MW_DMA_0]; -+ wrmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, 0); -+} -+ -+static struct scsi_host_template cs5535_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cs5535_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cs5535_set_piomode, -+ .set_dmamode = cs5535_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = cs5535_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * cs5535_init_one - Initialise a CS5530 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Install a driver for the newly found CS5530 companion chip. Most of -+ * this is just housekeeping. We have to set the chip up correctly and -+ * turn off various bits of emulation magic. -+ */ -+ -+static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &cs5535_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &cs5535_port_ops -+ }; -+ struct ata_port_info *ports[1] = { &info }; -+ -+ u32 timings, dummy; -+ -+ /* Check the BIOS set the initial timing clock. If not set the -+ timings for PIO0 */ -+ rdmsr(ATAC_CH0D0_PIO, timings, dummy); -+ if (CS5535_BAD_PIO(timings)) -+ wrmsr(ATAC_CH0D0_PIO, 0xF7F4F7F4UL, 0); -+ rdmsr(ATAC_CH0D1_PIO, timings, dummy); -+ if (CS5535_BAD_PIO(timings)) -+ wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0); -+ return ata_pci_init_one(dev, ports, 1); -+} -+ -+static struct pci_device_id cs5535[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_NS, 0x002D), }, -+ { 0, }, -+}; -+ -+static struct pci_driver cs5535_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cs5535, -+ .probe = cs5535_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cs5535_init(void) -+{ -+ return pci_register_driver(&cs5535_pci_driver); -+} -+ -+ -+static void __exit cs5535_exit(void) -+{ -+ pci_unregister_driver(&cs5535_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch"); -+MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cs5535); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cs5535_init); -+module_exit(cs5535_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cypress.c linux-2.6.16-rc4/drivers/scsi/pata_cypress.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_cypress.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_cypress.c 2006-02-16 15:37:46.000000000 +0000 -@@ -0,0 +1,215 @@ -+/* -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_cypress" -+#define DRV_VERSION "0.1" -+ -+/* here are the offset definitions for the registers */ -+ -+enum { -+ CY82_IDE_CMDREG = 0x04, -+ CY82_IDE_ADDRSETUP = 0x48, -+ CY82_IDE_MASTER_IOR = 0x4C, -+ CY82_IDE_MASTER_IOW = 0x4D, -+ CY82_IDE_SLAVE_IOR = 0x4E, -+ CY82_IDE_SLAVE_IOW = 0x4F, -+ CY82_IDE_MASTER_8BIT = 0x50, -+ CY82_IDE_SLAVE_8BIT = 0x51, -+ -+ CY82_INDEX_PORT = 0x22, -+ CY82_DATA_PORT = 0x23, -+ -+ CY82_INDEX_CTRLREG1 = 0x01, -+ CY82_INDEX_CHANNEL0 = 0x30, -+ CY82_INDEX_CHANNEL1 = 0x31, -+ CY82_INDEX_TIMEOUT = 0x32 -+}; -+ -+/* Phee Phy Pho Phum */ -+ -+static void cy82c693_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * cy82c693_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. -+ */ -+ -+static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct ata_timing t; -+ const unsigned long T = 1000000 / 33; -+ short time_16, time_8; -+ u32 addr; -+ -+ if (ata_timing_compute(adev, adev->pio_mode, &t, T, 1) < 0) { -+ printk(KERN_ERR DRV_NAME ": mome computation failed.\n"); -+ return; -+ } -+ -+ time_16 = FIT(t.recover, 0, 15) | (FIT(t.active, 0, 15) << 4); -+ time_8 = FIT(t.act8b, 0, 15) | (FIT(t.rec8b, 0, 15) << 4); -+ -+ if (adev->devno == 0) { -+ pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); -+ -+ addr &= ~0x0F; /* Mask bits */ -+ addr |= FIT(t.setup, 0, 15); -+ -+ pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); -+ pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_MASTER_IOW, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_MASTER_8BIT, time_8); -+ } else { -+ pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); -+ -+ addr &= ~0xF0; /* Mask bits */ -+ addr |= (FIT(t.setup, 0, 15) << 4); -+ -+ pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); -+ pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOW, time_16); -+ pci_write_config_byte(pdev, CY82_IDE_SLAVE_8BIT, time_8); -+ } -+} -+ -+/** -+ * cy82c693_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. -+ */ -+ -+static void cy82c693_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ int reg = CY82_INDEX_CHANNEL0 + ap->hard_port_no; -+ -+ /* Be afraid, be very afraid. Magic registers in low I/O space */ -+ outb(reg, 0x22); -+ outb(adev->dma_mode - XFER_MW_DMA_0, 0x23); -+ -+ /* 0x50 gives the best behaviour on the Alpha's using this chip */ -+ outb(CY82_INDEX_TIMEOUT, 0x22); -+ outb(0x50, 0x23); -+} -+ -+static struct scsi_host_template cy82c693_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations cy82c693_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = cy82c693_set_piomode, -+ .set_dmamode = cy82c693_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = cy82c693_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &cy82c693_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &cy82c693_port_ops -+ }; -+ static struct ata_port_info *port_info[1] = { &info }; -+ -+ /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. For the -+ moment we don't handle the secondary. FIXME */ -+ -+ if (PCI_FUNC(pdev->devfn) != 1) -+ return -ENODEV; -+ -+ return ata_pci_init_one(pdev, port_info, 1); -+} -+ -+static struct pci_device_id cy82c693[] = { -+ { PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver cy82c693_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = cy82c693, -+ .probe = cy82c693_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init cy82c693_init(void) -+{ -+ return pci_register_driver(&cy82c693_pci_driver); -+} -+ -+ -+static void __exit cy82c693_exit(void) -+{ -+ pci_unregister_driver(&cy82c693_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the CY82C693 PATA controller"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, cy82c693); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(cy82c693_init); -+module_exit(cy82c693_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_efar.c linux-2.6.16-rc4/drivers/scsi/pata_efar.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_efar.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_efar.c 2006-02-16 15:37:53.000000000 +0000 -@@ -0,0 +1,341 @@ -+/* -+ * pata_efar.c - EFAR PIIX clone controller driver -+ * -+ * (C) 2005 Red Hat <alan@redhat.com> -+ * -+ * Some parts based on ata_piix.c by Jeff Garzik and others. -+ * -+ * The EFAR is a PIIX4 clone with UDMA66 support. Unlike the later -+ * Intel ICH controllers the EFAR widened the UDMA mode register bits -+ * and doesn't require the funky clock selection. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_efar" -+#define DRV_VERSION "0.1" -+ -+/** -+ * efar_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Perform cable detection for the EFAR ATA interface. This is -+ * different to the PIIX arrangement -+ */ -+ -+static int efar_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 tmp; -+ -+ pci_read_config_byte(pdev, 0x47, &tmp); -+ if (tmp & (2 >> ap->hard_port_no)) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * efar_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void efar_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ const struct pci_bits efar_enable_bits[] = { -+ { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ -+ { 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = efar_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * efar_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set PIO mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ unsigned int idetm_port= ap->hard_port_no ? 0x42 : 0x40; -+ u16 idetm_data; -+ int control = 0; -+ -+ /* -+ * See Intel Document 298600-004 for the timing programing rules -+ * for PIIX/ICH. The EFAR is a clone so very similar -+ */ -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ if (pio > 2) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */ -+ control |= 2; /* IE enable */ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ -+ pci_read_config_word(dev, idetm_port, &idetm_data); -+ -+ /* Enable PPE, IE and TIME as appropriate */ -+ -+ if (adev->devno == 0) { -+ idetm_data &= 0xCCF0; -+ idetm_data |= control; -+ idetm_data |= (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ } else { -+ int shift = 4 * ap->hard_port_no; -+ u8 slave_data; -+ -+ idetm_data &= 0xCC0F; -+ idetm_data |= (control << 4); -+ -+ /* Slave timing in seperate register */ -+ pci_read_config_byte(dev, 0x44, &slave_data); -+ slave_data &= 0x0F << shift; -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << shift; -+ pci_write_config_byte(dev, 0x44, slave_data); -+ } -+ -+ idetm_data |= 0x4000; /* Ensure SITRE is enabled */ -+ pci_write_config_word(dev, idetm_port, idetm_data); -+} -+ -+/** -+ * efar_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ u8 master_port = ap->hard_port_no ? 0x42 : 0x40; -+ u16 master_data; -+ u8 speed = adev->dma_mode; -+ int devid = adev->devno + 2 * ap->hard_port_no; -+ u8 udma_enable; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ pci_read_config_word(dev, master_port, &master_data); -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ -+ if (speed >= XFER_UDMA_0) { -+ unsigned int udma = adev->dma_mode - XFER_UDMA_0; -+ u16 udma_timing; -+ -+ udma_enable |= (1 << devid); -+ -+ /* Load the UDMA mode number */ -+ pci_read_config_word(dev, 0x4A, &udma_timing); -+ udma_timing &= ~(7 << (4 * devid)); -+ udma_timing |= udma << (4 * devid); -+ pci_write_config_word(dev, 0x4A, udma_timing); -+ } else { -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally along with TIME1. PPE has already -+ * been set when the PIO timing was set. -+ */ -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ unsigned int control; -+ u8 slave_data; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ -+ control = 3; /* IORDY|TIME1 */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO into PIO0 */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ /* Enable DMA timing only */ -+ control |= 8; /* PIO cycles in PIO0 */ -+ -+ if (adev->devno) { /* Slave */ -+ master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ -+ master_data |= control << 4; -+ pci_read_config_byte(dev, 0x44, &slave_data); -+ slave_data &= (0x0F + 0xE1 * ap->hard_port_no); -+ /* Load the matching timing */ -+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); -+ pci_write_config_byte(dev, 0x44, slave_data); -+ } else { /* Master */ -+ master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY -+ and master timing bits */ -+ master_data |= control; -+ master_data |= -+ (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ } -+ udma_enable &= ~(1 << devid); -+ pci_write_config_word(dev, master_port, master_data); -+ } -+ pci_write_config_byte(dev, 0x48, udma_enable); -+} -+ -+static struct scsi_host_template efar_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations efar_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = efar_set_piomode, -+ .set_dmamode = efar_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = efar_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * efar_init_one - Register EFAR ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in efar_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &efar_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .udma_mask = 0x0f, /* UDMA 66 */ -+ .port_ops = &efar_ops, -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id efar_pci_tbl[] = { -+ { 0x1055, 0x9130, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver efar_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = efar_pci_tbl, -+ .probe = efar_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init efar_init(void) -+{ -+ return pci_register_driver(&efar_pci_driver); -+} -+ -+static void __exit efar_exit(void) -+{ -+ pci_unregister_driver(&efar_pci_driver); -+} -+ -+ -+module_init(efar_init); -+module_exit(efar_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for EFAR PIIX clones"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, efar_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt34x.c linux-2.6.16-rc4/drivers/scsi/pata_hpt34x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt34x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt34x.c 2006-02-16 15:38:47.000000000 +0000 -@@ -0,0 +1,206 @@ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt34x" -+#define DRV_VERSION "0.1" -+ -+/** -+ * hpt34x_bus_reset - reset the hpt34x bus -+ * @ap: ATA port to reset -+ * -+ * Perform the housekeeping when doing an ATA bus reeset. We just -+ * need to force the cable type. -+ */ -+ -+static void hpt34x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * hpt34x_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. This is fairly simple on the HPT34x as -+ * all we have to do is clear the MWDMA and UDMA bits then load the -+ * mode number. -+ */ -+ -+static void hpt34x_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 r1, r2; -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ -+ pci_read_config_dword(pdev, 0x44, &r1); -+ pci_read_config_dword(pdev, 0x48, &r2); -+ /* Load the PIO timing number */ -+ r1 &= ~(7 << (3 * dn)); -+ r1 |= (adev->pio_mode - XFER_PIO_0) << (3 * dn); -+ r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */ -+ -+ pci_write_config_dword(pdev, 0x44, r1); -+ pci_write_config_dword(pdev, 0x48, r2); -+} -+ -+/** -+ * hpt34x_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt34x_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 r1, r2; -+ int dn = 2 * ap->hard_port_no + adev->devno; -+ int mode_num = adev->dma_mode & 0x0F; -+ -+ pci_read_config_dword(pdev, 0x44, &r1); -+ pci_read_config_dword(pdev, 0x48, &r2); -+ /* Load the timing number */ -+ r1 &= ~(7 << (3 * dn)); -+ r1 |= (mode_num << (3 * dn)); -+ r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */ -+ -+ if (adev->dma_mode >= XFER_UDMA_0) -+ r2 |= 0x01 << dn; /* Ultra mode */ -+ else -+ r2 |= 0x10 << dn; /* MWDMA */ -+ -+ pci_write_config_dword(pdev, 0x44, r1); -+ pci_write_config_dword(pdev, 0x48, r2); -+} -+ -+static struct scsi_host_template hpt34x_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations hpt34x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt34x_set_piomode, -+ .set_dmamode = hpt34x_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = hpt34x_phy_reset, -+ -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * hpt34x_init_one - Initialise an HPT343/363 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Perform basic initialisation. The chip has a quirk that it won't -+ * function unless it is at XX00. The old ATA driver touched this up -+ * but we leave it for pci quirks to do properly. -+ */ -+ -+static int hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &hpt34x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &hpt34x_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ u16 cmd; -+ -+ /* Initialize the board */ -+ pci_write_config_word(dev, 0x80, 0x00); -+ /* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ if (cmd & PCI_COMMAND_MEMORY) -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); -+ else -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); -+ -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt34x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt34x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt34x, -+ .probe = hpt34x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt34x_init(void) -+{ -+ return pci_register_driver(&hpt34x_pci_driver); -+} -+ -+ -+static void __exit hpt34x_exit(void) -+{ -+ pci_unregister_driver(&hpt34x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT343/363"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt34x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt34x_init); -+module_exit(hpt34x_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt366.c linux-2.6.16-rc4/drivers/scsi/pata_hpt366.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt366.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt366.c 2006-02-16 15:45:36.000000000 +0000 -@@ -0,0 +1,479 @@ -+/* -+ * Libata driver for the highpoint 366 and 368 UDMA66 ATA controllers. -+ * -+ * This driver is heavily based upon: -+ * -+ * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 -+ * -+ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 2001 Sun Microsystems, Inc. -+ * Portions Copyright (C) 2003 Red Hat Inc -+ * -+ * -+ * TODO -+ * Maybe PLL mode -+ * Look into engine reset on timeout errors. Should not be -+ * required. -+ */ -+ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt36x" -+#define DRV_VERSION "0.2" -+ -+struct hpt_clock { -+ u8 xfer_speed; -+ u32 timing; -+}; -+ -+/* key for bus clock timings -+ * bit -+ * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file -+ * register access. -+ * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file -+ * register access. -+ * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. -+ * during task file register access. -+ * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA -+ * xfer. -+ * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task -+ * register access. -+ * 28 UDMA enable -+ * 29 DMA enable -+ * 30 PIO_MST enable. if set, the chip is in bus master mode during -+ * PIO. -+ * 31 FIFO enable. -+ */ -+ -+static struct chipset_bus_clock_list_entry hpt366_40[] = { -+ { XFER_UDMA_4, 0x900fd943 }, -+ { XFER_UDMA_3, 0x900ad943 }, -+ { XFER_UDMA_2, 0x900bd943 }, -+ { XFER_UDMA_1, 0x9008d943 }, -+ { XFER_UDMA_0, 0x9008d943 }, -+ -+ { XFER_MW_DMA_2, 0xa008d943 }, -+ { XFER_MW_DMA_1, 0xa010d955 }, -+ { XFER_MW_DMA_0, 0xa010d9fc }, -+ -+ { XFER_PIO_4, 0xc008d963 }, -+ { XFER_PIO_3, 0xc010d974 }, -+ { XFER_PIO_2, 0xc010d997 }, -+ { XFER_PIO_1, 0xc010d9c7 }, -+ { XFER_PIO_0, 0xc018d9d9 }, -+ { 0, 0x0120d9d9 } -+}; -+ -+static struct chipset_bus_clock_list_entry hpt366_33[] = { -+ { XFER_UDMA_4, 0x90c9a731 }, -+ { XFER_UDMA_3, 0x90cfa731 }, -+ { XFER_UDMA_2, 0x90caa731 }, -+ { XFER_UDMA_1, 0x90cba731 }, -+ { XFER_UDMA_0, 0x90c8a731 }, -+ -+ { XFER_MW_DMA_2, 0xa0c8a731 }, -+ { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */ -+ { XFER_MW_DMA_0, 0xa0c8a797 }, -+ -+ { XFER_PIO_4, 0xc0c8a731 }, -+ { XFER_PIO_3, 0xc0c8a742 }, -+ { XFER_PIO_2, 0xc0d0a753 }, -+ { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */ -+ { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ -+ { 0, 0x0120a7a7 } -+}; -+ -+static struct chipset_bus_clock_list_entry hpt366_25[] = { -+ { XFER_UDMA_4, 0x90c98521 }, -+ { XFER_UDMA_3, 0x90cf8521 }, -+ { XFER_UDMA_2, 0x90cf8521 }, -+ { XFER_UDMA_1, 0x90cb8521 }, -+ { XFER_UDMA_0, 0x90cb8521 }, -+ -+ { XFER_MW_DMA_2, 0xa0ca8521 }, -+ { XFER_MW_DMA_1, 0xa0ca8532 }, -+ { XFER_MW_DMA_0, 0xa0ca8575 }, -+ -+ { XFER_PIO_4, 0xc0ca8521 }, -+ { XFER_PIO_3, 0xc0ca8532 }, -+ { XFER_PIO_2, 0xc0ca8542 }, -+ { XFER_PIO_1, 0xc0d08572 }, -+ { XFER_PIO_0, 0xc0d08585 }, -+ { 0, 0x01208585 } -+}; -+ -+static const char *bad_ata33[] = { -+ "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", -+ "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", -+ "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", -+ "Maxtor 90510D4", -+ "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", -+ "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", -+ "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", -+ NULL -+}; -+ -+static const char *bad_ata66_4[] = { -+ "IBM-DTLA-307075", -+ "IBM-DTLA-307060", -+ "IBM-DTLA-307045", -+ "IBM-DTLA-307030", -+ "IBM-DTLA-307020", -+ "IBM-DTLA-307015", -+ "IBM-DTLA-305040", -+ "IBM-DTLA-305030", -+ "IBM-DTLA-305020", -+ "IC35L010AVER07-0", -+ "IC35L020AVER07-0", -+ "IC35L030AVER07-0", -+ "IC35L040AVER07-0", -+ "IC35L060AVER07-0", -+ "WDC AC310200R", -+ NULL -+}; -+ -+static const char *bad_ata66_3[] = { -+ "WDC AC310200R", -+ NULL -+}; -+ -+static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) -+{ -+ unsigned char model_num[40]; -+ char *s; -+ unsigned int len; -+ int i = 0; -+ -+ ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, -+ sizeof(model_num)); -+ s = &model_num[0]; -+ len = strnlen(s, sizeof(model_num)); -+ -+ /* ATAPI specifies that empty space is blank-filled; remove blanks */ -+ while ((len > 0) && (s[len - 1] == ' ')) { -+ len--; -+ s[len] = 0; -+ } -+ -+ while(list[i] != NULL) { -+ if (!strncmp(list[i], s, len)) { -+ printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", -+ modestr, list[i]); -+ return 1; -+ } -+ i++; -+ } -+ return 0; -+} -+ -+/** -+ * hpt366_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Block UDMA on devices that cause trouble with this controller. -+ */ -+ -+static unsigned int hpt366_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ if (shift != ATA_SHIFT_UDMA) -+ return mask; -+ if (adev->class != ATA_DEV_ATA) -+ return mask; -+ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) -+ return 0; -+ if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3)) -+ return mask & 0x07; -+ if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) -+ return mask & 0x0F; -+ return mask; -+} -+ -+/** -+ * hpt36x_find_mode - reset the hpt36x bus -+ * @ap: ATA port -+ * @speed: transfer mode -+ * -+ * Return the 32bit register programming information for this channel -+ * that matches the speed provided. -+ */ -+ -+static u32 hpt36x_find_mode(struct ata_port *ap, int speed) -+{ -+ struct hpt_clock *clocks = ap->host_set->private_data; -+ -+ while(clocks->xfer_speed) { -+ if (clocks->xfer_speed == speed) -+ return clocks->timing; -+ clocks++; -+ } -+ BUG(); -+} -+ -+/** -+ * hpt36x_phy_reset - reset the hpt36x bus -+ * @ap: ATA port to reset -+ * -+ * Perform the PHY reset handling for the 366/368 -+ */ -+ -+static void hpt36x_phy_reset(struct ata_port *ap) -+{ -+ u8 scr2, ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ if (ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * hpt366_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ if (fast & 0x80) { -+ fast &= ~0x80; -+ pci_write_config_byte(pdev, addr2, fast); -+ } -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt36x_find_mode(ap, adev->pio_mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt366_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ if (fast & 0x80) { -+ fast &= ~0x80; -+ pci_write_config_byte(pdev, addr2, fast); -+ } -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt36x_find_mode(ap, adev->dma_mode); -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+static struct scsi_host_template hpt36x_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+/* -+ * Configuration for HPT366/68 -+ */ -+ -+static struct ata_port_operations hpt366_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt366_set_piomode, -+ .set_dmamode = hpt366_set_dmamode, -+ .mode_filter = hpt366_filter, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = hpt36x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * hpt36x_init_one - Initialise an HPT366/368 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Initialise an HPT36x device. There are some interesting complications -+ * here. Firstly the chip may report 366 and be one of several variants. -+ * Secondly all the timings depend on the clock for the chip which we must -+ * detect and look up -+ * -+ * This is the known chip mappings. It may be missing a couple of later -+ * releases. -+ * -+ * Chip version PCI Rev Notes -+ * HPT366 4 (HPT366) 0 UDMA66 -+ * HPT366 4 (HPT366) 1 UDMA66 -+ * HPT368 4 (HPT366) 2 UDMA66 -+ * HPT37x/30x 4 (HPT366) 3+ Other driver -+ * -+ */ -+ -+static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info_hpt366 = { -+ .sht = &hpt366_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &hpt370_port_ops -+ }; -+ struct ata_port_info *port_info[2] = {&info_hpt366, &info_hpt366}; -+ -+ u8 irqmask; -+ u32 class_rev; -+ u32 reg1; -+ -+ struct hpt_chip *chip_table; -+ int clock_slot; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ /* May be a later chip in disguise. Check */ -+ /* Newer chips are in the HPT36x driver. Ignore them */ -+ if (class_rev > 2) -+ return -ENODEV; -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); -+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); -+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); -+ -+ pci_read_config_byte(dev, 0x51, &drive_fast); -+ if (drive_fast & 0x80) -+ pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); -+ -+ pci_read_config_dword(dev, 0x40, ®1); -+ -+ /* PCI clocking determines the ATA timing values to use */ -+ switch((reg1 & 0x700) { -+ case 5: -+ port->private_data = hpt366_40; -+ break; -+ case 9: -+ port->private_data = hpt366_25; -+ break; -+ default: -+ port->private_data = hpt366_33; -+ break; -+ } -+ port_info[0] = port_info[1] = port; -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt36x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt36x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt36x, -+ .probe = hpt36x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt36x_init(void) -+{ -+ return pci_register_driver(&hpt36x_pci_driver); -+} -+ -+ -+static void __exit hpt36x_exit(void) -+{ -+ pci_unregister_driver(&hpt36x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt36x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt36x_init); -+module_exit(hpt36x_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt37x.c linux-2.6.16-rc4/drivers/scsi/pata_hpt37x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt37x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt37x.c 2006-02-16 15:45:27.000000000 +0000 -@@ -0,0 +1,1232 @@ -+/* -+ * Libata driver for the highpoint 37x and 30x UDMA66 ATA controllers. -+ * -+ * This driver is heavily based upon: -+ * -+ * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 -+ * -+ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 2001 Sun Microsystems, Inc. -+ * Portions Copyright (C) 2003 Red Hat Inc -+ * -+ * TODO -+ * PLL mode -+ * Look into engine reset on timeout errors. Should not be -+ * required. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt37x" -+#define DRV_VERSION "0.2" -+ -+struct hpt_clock { -+ u8 xfer_speed; -+ u32 timing; -+}; -+ -+struct hpt_chip { -+ const char *name; -+ unsigned int base; -+ struct hpt_clock *clocks[4]; -+}; -+ -+/* key for bus clock timings -+ * bit -+ * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file -+ * register access. -+ * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file -+ * register access. -+ * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. -+ * during task file register access. -+ * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA -+ * xfer. -+ * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task -+ * register access. -+ * 28 UDMA enable -+ * 29 DMA enable -+ * 30 PIO_MST enable. if set, the chip is in bus master mode during -+ * PIO. -+ * 31 FIFO enable. -+ */ -+ -+/* from highpoint documentation. these are old values */ -+static struct hpt_clock hpt370_timings_33[] = { -+/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */ -+ { XFER_UDMA_5, 0x16454e31 }, -+ { XFER_UDMA_4, 0x16454e31 }, -+ { XFER_UDMA_3, 0x166d4e31 }, -+ { XFER_UDMA_2, 0x16494e31 }, -+ { XFER_UDMA_1, 0x164d4e31 }, -+ { XFER_UDMA_0, 0x16514e31 }, -+ -+ { XFER_MW_DMA_2, 0x26514e21 }, -+ { XFER_MW_DMA_1, 0x26514e33 }, -+ { XFER_MW_DMA_0, 0x26514e97 }, -+ -+ { XFER_PIO_4, 0x06514e21 }, -+ { XFER_PIO_3, 0x06514e22 }, -+ { XFER_PIO_2, 0x06514e33 }, -+ { XFER_PIO_1, 0x06914e43 }, -+ { XFER_PIO_0, 0x06914e57 }, -+ { 0, 0x06514e57 } -+}; -+ -+static struct hpt_clock hpt370_timings_66[] = { -+ { XFER_UDMA_5, 0x14846231 }, -+ { XFER_UDMA_4, 0x14886231 }, -+ { XFER_UDMA_3, 0x148c6231 }, -+ { XFER_UDMA_2, 0x148c6231 }, -+ { XFER_UDMA_1, 0x14906231 }, -+ { XFER_UDMA_0, 0x14986231 }, -+ -+ { XFER_MW_DMA_2, 0x26514e21 }, -+ { XFER_MW_DMA_1, 0x26514e33 }, -+ { XFER_MW_DMA_0, 0x26514e97 }, -+ -+ { XFER_PIO_4, 0x06514e21 }, -+ { XFER_PIO_3, 0x06514e22 }, -+ { XFER_PIO_2, 0x06514e33 }, -+ { XFER_PIO_1, 0x06914e43 }, -+ { XFER_PIO_0, 0x06914e57 }, -+ { 0, 0x06514e57 } -+}; -+ -+/* these are the current (4 sep 2001) timings from highpoint */ -+static struct hpt_clock hpt370a_timings_33[] = { -+ { XFER_UDMA_5, 0x12446231 }, -+ { XFER_UDMA_4, 0x12446231 }, -+ { XFER_UDMA_3, 0x126c6231 }, -+ { XFER_UDMA_2, 0x12486231 }, -+ { XFER_UDMA_1, 0x124c6233 }, -+ { XFER_UDMA_0, 0x12506297 }, -+ -+ { XFER_MW_DMA_2, 0x22406c31 }, -+ { XFER_MW_DMA_1, 0x22406c33 }, -+ { XFER_MW_DMA_0, 0x22406c97 }, -+ -+ { XFER_PIO_4, 0x06414e31 }, -+ { XFER_PIO_3, 0x06414e42 }, -+ { XFER_PIO_2, 0x06414e53 }, -+ { XFER_PIO_1, 0x06814e93 }, -+ { XFER_PIO_0, 0x06814ea7 }, -+ { 0, 0x06814ea7 } -+}; -+ -+/* 2x 33MHz timings */ -+static struct hpt_clock hpt370a_timings_66[] = { -+ { XFER_UDMA_5, 0x1488e673 }, -+ { XFER_UDMA_4, 0x1488e673 }, -+ { XFER_UDMA_3, 0x1498e673 }, -+ { XFER_UDMA_2, 0x1490e673 }, -+ { XFER_UDMA_1, 0x1498e677 }, -+ { XFER_UDMA_0, 0x14a0e73f }, -+ -+ { XFER_MW_DMA_2, 0x2480fa73 }, -+ { XFER_MW_DMA_1, 0x2480fa77 }, -+ { XFER_MW_DMA_0, 0x2480fb3f }, -+ -+ { XFER_PIO_4, 0x0c82be73 }, -+ { XFER_PIO_3, 0x0c82be95 }, -+ { XFER_PIO_2, 0x0c82beb7 }, -+ { XFER_PIO_1, 0x0d02bf37 }, -+ { XFER_PIO_0, 0x0d02bf5f }, -+ { 0, 0x0d02bf5f } -+}; -+ -+static struct hpt_clock hpt370a_timings_50[] = { -+ { XFER_UDMA_5, 0x12848242 }, -+ { XFER_UDMA_4, 0x12ac8242 }, -+ { XFER_UDMA_3, 0x128c8242 }, -+ { XFER_UDMA_2, 0x120c8242 }, -+ { XFER_UDMA_1, 0x12148254 }, -+ { XFER_UDMA_0, 0x121882ea }, -+ -+ { XFER_MW_DMA_2, 0x22808242 }, -+ { XFER_MW_DMA_1, 0x22808254 }, -+ { XFER_MW_DMA_0, 0x228082ea }, -+ -+ { XFER_PIO_4, 0x0a81f442 }, -+ { XFER_PIO_3, 0x0a81f443 }, -+ { XFER_PIO_2, 0x0a81f454 }, -+ { XFER_PIO_1, 0x0ac1f465 }, -+ { XFER_PIO_0, 0x0ac1f48a }, -+ { 0, 0x0ac1f48a } -+}; -+ -+static struct hpt_clock hpt372_timings_33[] = { -+ { XFER_UDMA_6, 0x1c81dc62 }, -+ { XFER_UDMA_5, 0x1c6ddc62 }, -+ { XFER_UDMA_4, 0x1c8ddc62 }, -+ { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */ -+ { XFER_UDMA_2, 0x1c91dc62 }, -+ { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */ -+ { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */ -+ -+ { XFER_MW_DMA_2, 0x2c829262 }, -+ { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */ -+ { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */ -+ -+ { XFER_PIO_4, 0x0c829c62 }, -+ { XFER_PIO_3, 0x0c829c84 }, -+ { XFER_PIO_2, 0x0c829ca6 }, -+ { XFER_PIO_1, 0x0d029d26 }, -+ { XFER_PIO_0, 0x0d029d5e }, -+ { 0, 0x0d029d5e } -+}; -+ -+static struct hpt_clock hpt372_timings_50[] = { -+ { XFER_UDMA_5, 0x12848242 }, -+ { XFER_UDMA_4, 0x12ac8242 }, -+ { XFER_UDMA_3, 0x128c8242 }, -+ { XFER_UDMA_2, 0x120c8242 }, -+ { XFER_UDMA_1, 0x12148254 }, -+ { XFER_UDMA_0, 0x121882ea }, -+ -+ { XFER_MW_DMA_2, 0x22808242 }, -+ { XFER_MW_DMA_1, 0x22808254 }, -+ { XFER_MW_DMA_0, 0x228082ea }, -+ -+ { XFER_PIO_4, 0x0a81f442 }, -+ { XFER_PIO_3, 0x0a81f443 }, -+ { XFER_PIO_2, 0x0a81f454 }, -+ { XFER_PIO_1, 0x0ac1f465 }, -+ { XFER_PIO_0, 0x0ac1f48a }, -+ { 0, 0x0a81f443 } -+}; -+ -+static struct hpt_clock hpt372_timings_66[] = { -+ { XFER_UDMA_6, 0x1c869c62 }, -+ { XFER_UDMA_5, 0x1cae9c62 }, -+ { XFER_UDMA_4, 0x1c8a9c62 }, -+ { XFER_UDMA_3, 0x1c8e9c62 }, -+ { XFER_UDMA_2, 0x1c929c62 }, -+ { XFER_UDMA_1, 0x1c9a9c62 }, -+ { XFER_UDMA_0, 0x1c829c62 }, -+ -+ { XFER_MW_DMA_2, 0x2c829c62 }, -+ { XFER_MW_DMA_1, 0x2c829c66 }, -+ { XFER_MW_DMA_0, 0x2c829d2e }, -+ -+ { XFER_PIO_4, 0x0c829c62 }, -+ { XFER_PIO_3, 0x0c829c84 }, -+ { XFER_PIO_2, 0x0c829ca6 }, -+ { XFER_PIO_1, 0x0d029d26 }, -+ { XFER_PIO_0, 0x0d029d5e }, -+ { 0, 0x0d029d26 } -+}; -+ -+static struct hpt_clock hpt374_timings_33[] = { -+ { XFER_UDMA_6, 0x12808242 }, -+ { XFER_UDMA_5, 0x12848242 }, -+ { XFER_UDMA_4, 0x12ac8242 }, -+ { XFER_UDMA_3, 0x128c8242 }, -+ { XFER_UDMA_2, 0x120c8242 }, -+ { XFER_UDMA_1, 0x12148254 }, -+ { XFER_UDMA_0, 0x121882ea }, -+ -+ { XFER_MW_DMA_2, 0x22808242 }, -+ { XFER_MW_DMA_1, 0x22808254 }, -+ { XFER_MW_DMA_0, 0x228082ea }, -+ -+ { XFER_PIO_4, 0x0a81f442 }, -+ { XFER_PIO_3, 0x0a81f443 }, -+ { XFER_PIO_2, 0x0a81f454 }, -+ { XFER_PIO_1, 0x0ac1f465 }, -+ { XFER_PIO_0, 0x0ac1f48a }, -+ { 0, 0x06814e93 } -+}; -+ -+static struct hpt_chip hpt370 = { -+ "HPT370", -+ 48, -+ { -+ hpt370_timings_33, -+ NULL, -+ NULL, -+ hpt370_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt370a = { -+ "HPT370A", -+ 48, -+ { -+ hpt370a_timings_33, -+ NULL, -+ hpt370a_timings_50, -+ hpt370a_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt372 = { -+ "HPT372", -+ 55, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt302 = { -+ "HPT302", -+ 66, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt371 = { -+ "HPT371", -+ 66, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt372a = { -+ "HPT372A", -+ 66, -+ { -+ hpt372_timings_33, -+ NULL, -+ hpt372_timings_50, -+ hpt372_timings_66 -+ } -+}; -+ -+static struct hpt_chip hpt374 = { -+ "HPT374", -+ 48, -+ { -+ hpt374_timings_33, -+ NULL, -+ NULL, -+ NULL -+ } -+}; -+ -+/** -+ * hpt37x_find_mode - reset the hpt37x bus -+ * @ap: ATA port -+ * @speed: transfer mode -+ * -+ * Return the 32bit register programming information for this channel -+ * that matches the speed provided. -+ */ -+ -+static u32 hpt37x_find_mode(struct ata_port *ap, int speed) -+{ -+ struct hpt_clock *clocks = ap->host_set->private_data; -+ -+ while(clocks->xfer_speed) { -+ if (clocks->xfer_speed == speed) -+ return clocks->timing; -+ clocks++; -+ } -+ BUG(); -+} -+ -+static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) -+{ -+ unsigned char model_num[40]; -+ char *s; -+ unsigned int len; -+ int i = 0; -+ -+ ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, -+ sizeof(model_num)); -+ s = &model_num[0]; -+ len = strnlen(s, sizeof(model_num)); -+ -+ /* ATAPI specifies that empty space is blank-filled; remove blanks */ -+ while ((len > 0) && (s[len - 1] == ' ')) { -+ len--; -+ s[len] = 0; -+ } -+ -+ while(list[i] != NULL) { -+ if (!strncmp(list[i], s, len)) { -+ printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", -+ modestr, list[i]); -+ return 1; -+ } -+ i++; -+ } -+ return 0; -+} -+ -+static const char *bad_ata33[] = { -+ "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", -+ "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", -+ "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", -+ "Maxtor 90510D4", -+ "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", -+ "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", -+ "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", -+ NULL -+}; -+ -+static const char *bad_ata100_5[] = { -+ "IBM-DTLA-307075", -+ "IBM-DTLA-307060", -+ "IBM-DTLA-307045", -+ "IBM-DTLA-307030", -+ "IBM-DTLA-307020", -+ "IBM-DTLA-307015", -+ "IBM-DTLA-305040", -+ "IBM-DTLA-305030", -+ "IBM-DTLA-305020", -+ "IC35L010AVER07-0", -+ "IC35L020AVER07-0", -+ "IC35L030AVER07-0", -+ "IC35L040AVER07-0", -+ "IC35L060AVER07-0", -+ "WDC AC310200R", -+ NULL -+}; -+ -+/** -+ * hpt370_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Block UDMA on devices that cause trouble with this controller. -+ */ -+ -+static unsigned int hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ if (shift != ATA_SHIFT_UDMA) -+ return mask; -+ if (adev->class != ATA_DEV_ATA) -+ return mask; -+ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) -+ return mask & 0x1F; -+ if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) -+ return mask & 0x1F; -+ return mask; -+} -+ -+/** -+ * hpt370a_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Block UDMA on devices that cause trouble with this controller. -+ */ -+ -+static unsigned int hpt370a_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ if (shift != ATA_SHIFT_UDMA) -+ return mask; -+ if (adev->class != ATA_DEV_ATA) -+ return mask; -+ if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) -+ return mask & 0x1F; -+ return mask; -+} -+ -+/** -+ * hpt37x_phy_reset - reset the hpt37x bus -+ * @ap: ATA port to reset -+ * -+ * Perform the PHY reset handling for the 370/372 and 374 func 0 -+ */ -+ -+static void hpt37x_phy_reset(struct ata_port *ap) -+{ -+ u8 scr2, ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x5B, &scr2); -+ pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); -+ /* Cable register now active */ -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ /* Restore state */ -+ pci_write_config_byte(pdev, 0x5B, scr2); -+ -+ if (ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ /* Reset the state machine */ -+ pci_write_config_byte(pdev, 0x50, 0x37); -+ pci_write_config_byte(pdev, 0x54, 0x37); -+ udelay(100); -+ -+ printk("BUS RESET\n"); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * hpt374_phy_reset - reset the hpt374 -+ * @ap: ATA port to reset -+ * -+ * The 374 cable detect is a little different due to the extra -+ * channels. The function 0 channels work like usual but function 1 -+ * is special -+ */ -+ -+static void hpt374_phy_reset(struct ata_port *ap) -+{ -+ u16 mcr3, mcr6; -+ u8 ata66; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ if (!(PCI_FUNC(pdev->devfn) & 1)) { -+ hpt37x_phy_reset(ap); -+ return; -+ } -+ /* Do the extra channel work */ -+ pci_read_config_word(pdev, 0x52, &mcr3); -+ pci_read_config_word(pdev, 0x56, &mcr6); -+ /* Set bit 15 of 0x52 to enable TCBLID as input -+ Set bit 15 of 0x56 to enable FCBLID as input -+ */ -+ pci_write_config_word(pdev, 0x52, mcr3 | 0x8000); -+ pci_write_config_word(pdev, 0x56, mcr6 | 0x8000); -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ /* Reset TCBLID/FCBLID to output */ -+ pci_write_config_word(pdev, 0x52, mcr3); -+ pci_write_config_word(pdev, 0x56, mcr6); -+ -+ if (ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ /* Reset the state machine */ -+ pci_write_config_byte(pdev, 0x50, 0x37); -+ pci_write_config_byte(pdev, 0x54, 0x37); -+ udelay(100); -+ -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+ -+/** -+ * hpt370_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x02; -+ fast |= 0x01; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->pio_mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt370_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x02; -+ fast |= 0x01; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->dma_mode); -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt370_bmdma_start - DMA engine begin -+ * @qc: ATA command -+ * -+ * The 370 and 370A want us to reset the DMA engine each time we -+ * use it. The 372 and later are fine. -+ */ -+ -+static void hpt370_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ pci_write_config_byte(pdev, 0x50 + 4 * ap->hard_port_no, 0x37); -+ udelay(10); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * hpt370_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Work around the HPT370 DMA engine. -+ */ -+ -+static void hpt370_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 dma_stat = inb(ap->ioaddr.bmdma_addr + 2); -+ u8 dma_cmd; -+ unsigned long bmdma = ap->ioaddr.bmdma_addr; -+ -+ if (dma_stat & 0x01) { -+ udelay(20); -+ dma_stat = inb(bmdma + 2); -+ } -+ if (dma_stat & 0x01) { -+ /* Clear the engine */ -+ pci_write_config_byte(pdev, 0x50 + 4 * ap->hard_port_no, 0x37); -+ udelay(10); -+ /* Stop DMA */ -+ dma_cmd = inb(bmdma ); -+ outb(dma_cmd & 0xFE, bmdma); -+ /* Clear Error */ -+ dma_stat = inb(bmdma + 2); -+ outb(dma_stat | 0x06 , bmdma + 2); -+ /* Clear the engine */ -+ pci_write_config_byte(pdev, 0x50 + 4 * ap->hard_port_no, 0x37); -+ udelay(10); -+ } -+ ata_bmdma_stop(qc); -+} -+ -+/** -+ * hpt372_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->pio_mode); -+ -+ printk("Find mode for %d reports %X\n", adev->pio_mode, mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt372_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt37x_find_mode(ap, adev->dma_mode); -+ printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt37x_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Clean up after the HPT372 and later DMA engine -+ */ -+ -+static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int mscreg = 0x50 + 2 * ap->hard_port_no; -+ u8 bwsr_stat, msc_stat; -+ -+ pci_read_config_byte(pdev, 0x6A, &bwsr_stat); -+ pci_read_config_byte(pdev, mscreg, &msc_stat); -+ if (bwsr_stat & (1 << ap->hard_port_no)) -+ pci_write_config_byte(pdev, mscreg, msc_stat | 0x30); -+ ata_bmdma_stop(qc); -+} -+ -+ -+static struct scsi_host_template hpt37x_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+/* -+ * Configuration for HPT370 -+ */ -+ -+static struct ata_port_operations hpt370_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt370_set_piomode, -+ .set_dmamode = hpt370_set_dmamode, -+ .mode_filter = hpt370_filter, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = hpt37x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = hpt370_bmdma_start, -+ .bmdma_stop = hpt370_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Configuration for HPT370A. Close to 370 but less filters -+ */ -+ -+static struct ata_port_operations hpt370a_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt370_set_piomode, -+ .set_dmamode = hpt370_set_dmamode, -+ .mode_filter = hpt370a_filter, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = hpt37x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = hpt370_bmdma_start, -+ .bmdma_stop = hpt370_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Configuration for HPT372, HPT371, HPT302. Slightly different PIO -+ * and DMA mode setting functionality. -+ */ -+ -+static struct ata_port_operations hpt372_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt372_set_piomode, -+ .set_dmamode = hpt372_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = hpt37x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = hpt37x_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Configuration for HPT374. Mode setting works like 372 and friends -+ * but we have a different cable detection procedure. -+ */ -+ -+static struct ata_port_operations hpt374_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt372_set_piomode, -+ .set_dmamode = hpt372_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = hpt374_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = hpt37x_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * htp37x_clock_slot - Turn timing to PC clock entry -+ * @freq: Reported frequency timing -+ * @base: Base timing -+ * -+ * Turn the timing data intoa clock slot (0 for 33, 1 for 40, 2 for 50 -+ * and 3 for 66Mhz) -+ */ -+ -+static int hpt37x_clock_slot(unsigned int freq, unsigned int base) -+{ -+ unsigned int f = (base * freq) / 192; /* Mhz */ -+ if (f < 40) -+ return 0; /* 33Mhz slot */ -+ if (f < 45) -+ return 1; /* 40Mhz slot */ -+ if (f < 55) -+ return 2; /* 50Mhz slot */ -+ return 3; /* 60Mhz slot */ -+} -+ -+/** -+ * hpt37x_calibrate_dpll - Calibrate the DPLL loop -+ * @dev: PCI device -+ * -+ * Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this -+ * succeeds -+ */ -+ -+static int hpt37x_calibrate_dpll(struct pci_dev *dev) -+{ -+ u8 reg5b; -+ u32 reg5c; -+ int tries; -+ -+ for(tries = 0; tries < 0x5000; tries++) { -+ udelay(50); -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ if (reg5b & 0x80) { -+ /* See if it stays set */ -+ for(tries = 0; tries < 0x1000; tries ++) { -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ /* Failed ? */ -+ if ((reg5b & 0x80) == 0) -+ return 0; -+ } -+ /* Turn off tuning, we have the DPLL set */ -+ pci_read_config_dword(dev, 0x5c, ®5c); -+ pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); -+ return 1; -+ } -+ } -+ /* Never went stable */ -+ return 0; -+} -+/** -+ * hpt37x_init_one - Initialise an HPT37X/302 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Initialise an HPT37x device. There are some interesting complications -+ * here. Firstly the chip may report 366 and be one of several variants. -+ * Secondly all the timings depend on the clock for the chip which we must -+ * detect and look up -+ * -+ * This is the known chip mappings. It may be missing a couple of later -+ * releases. -+ * -+ * Chip version PCI Rev Notes -+ * HPT366 4 (HPT366) 0 Other driver -+ * HPT366 4 (HPT366) 1 Other driver -+ * HPT368 4 (HPT366) 2 Other driver -+ * HPT370 4 (HPT366) 3 UDMA100 -+ * HPT370A 4 (HPT366) 4 UDMA100 -+ * HPT372 4 (HPT366) 5 UDMA133 (1) -+ * HPT372N 4 (HPT366) 6 Other driver -+ * HPT372A 5 (HPT372) 1 UDMA133 (1) -+ * HPT372N 5 (HPT372) 2 Other driver -+ * HPT302 6 (HPT302) 1 UDMA133 -+ * HPT302N 6 (HPT302) 2 Other driver -+ * HPT371 7 (HPT371) * UDMA133 -+ * HPT374 8 (HPT374) * UDMA133 4 channel -+ * HPT372N 9 (HPT372N) * Other driver -+ * -+ * (1) UDMA133 support depends on the bus clock -+ */ -+ -+static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ /* HPT370 - UDMA100 */ -+ static struct ata_port_info info_hpt370 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &hpt370_port_ops -+ }; -+ /* HPT370A - UDMA100 */ -+ static struct ata_port_info info_hpt370a = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &hpt370a_port_ops -+ }; -+ /* HPT371, 372 and friends - UDMA133 */ -+ static struct ata_port_info info_hpt372 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &hpt372_port_ops -+ }; -+ /* HPT371, 372 and friends - UDMA100 at 50MHz clock */ -+ static struct ata_port_info info_hpt372_50 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &hpt372_port_ops -+ }; -+ /* HPT374 - UDMA133 */ -+ static struct ata_port_info info_hpt374 = { -+ .sht = &hpt37x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &hpt374_port_ops -+ }; -+ -+ struct ata_port_info *port_info[2]; -+ struct ata_port_info *port; -+ -+ u8 irqmask; -+ u32 class_rev; -+ u32 freq; -+ -+ int MHz[4] = { 33, 40, 50, 66 }; -+ struct hpt_chip *chip_table; -+ int clock_slot; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ if (dev->device == PCI_DEVICE_ID_TTI_HPT366) { -+ /* May be a later chip in disguise. Check */ -+ /* Older chips are in the HPT366 driver. Ignore them */ -+ if (class_rev < 3) -+ return -ENODEV; -+ /* N series chips have their own driver. Ignore */ -+ if (class_rev == 6) -+ return -ENODEV; -+ -+ switch(class_rev) { -+ case 3: -+ port = &info_hpt370; -+ chip_table = &hpt370; -+ break; -+ case 4: -+ port = &info_hpt370a; -+ chip_table = &hpt370a; -+ break; -+ case 5: -+ port = &info_hpt372; -+ chip_table = &hpt372; -+ break; -+ default: -+ printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype please report (%d).\n", class_rev); -+ return -ENODEV; -+ } -+ } else { -+ switch(dev->device) { -+ case PCI_DEVICE_ID_TTI_HPT372: -+ /* 372N if rev >= 2*/ -+ if (class_rev >= 2) -+ return -ENODEV; -+ port = &info_hpt372; -+ chip_table = &hpt372a; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT302: -+ /* 302N if rev > 1 */ -+ if (class_rev > 1) -+ return -ENODEV; -+ port = &info_hpt372; -+ /* Check this */ -+ chip_table = &hpt302; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT371: -+ port = &info_hpt372; -+ chip_table = &hpt371; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT374: -+ chip_table = &hpt374; -+ port = &info_hpt374; -+ break; -+ default: -+ printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device); -+ return -ENODEV; -+ } -+ } -+ /* Ok so this is a chip we support */ -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); -+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); -+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); -+ -+ pci_read_config_byte(dev, 0x5A, &irqmask); -+ irqmask &= ~0x10; -+ pci_write_config_byte(dev, 0x5a, irqmask); -+ -+ /* -+ * default to pci clock. make sure MA15/16 are set to output -+ * to prevent drives having problems with 40-pin cables. Needed -+ * for some drives such as IBM-DTLA which will not enter ready -+ * state on reset when PDIAG is a input. -+ */ -+ -+ pci_write_config_byte(dev, 0x5b, 0x23); -+ -+ pci_read_config_dword(dev, 0x70, &freq); -+ if ((freq >> 12) != 0xABCDE) { -+ int i; -+ u8 sr; -+ u32 total = 0; -+ -+ printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n"); -+ -+ /* This is the process the HPT371 BIOS is reported to use */ -+ for(i = 0; i < 128; i++) { -+ pci_read_config_byte(dev, 0x78, &sr); -+ total += sr; -+ udelay(15); -+ } -+ freq = total / 128; -+ } -+ freq &= 0x1FF; -+ -+ /* -+ * Turn the frequency check into a band and then find a timing -+ * table to match it. -+ */ -+ -+ clock_slot = hpt37x_clock_slot(freq, chip_table->base); -+ if (chip_table->clocks[clock_slot] == NULL) { -+ /* -+ * We need to try PLL mode instead -+ */ -+ unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192; -+ unsigned int f_high = f_low + 2; -+ int adjust; -+ -+ for(adjust = 0; adjust < 8; adjust++) { -+ if (hpt37x_calibrate_dpll(dev)) -+ break; -+ /* See if it'll settle at a fractionally different clock */ -+ if ((adjust & 3) == 3) { -+ f_low --; -+ f_high ++; -+ } -+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); -+ } -+ if (adjust == 8) { -+ printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); -+ return -ENODEV; -+ } -+ /* Check if this works for all cases */ -+ port->private_data = hpt370_timings_66; -+ -+ printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]); -+ } else { -+ port->private_data = chip_table->clocks[clock_slot]; -+ /* -+ * Perform a final fixup. The 371 and 372 clock determines -+ * if UDMA133 is available. -+ */ -+ -+ if (clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */ -+ printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n"); -+ if (port == &info_hpt372) -+ port = &info_hpt372_50; -+ else BUG(); -+ } -+ printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); -+ } -+ port_info[0] = port_info[1] = port; -+ /* Now kick off ATA set up */ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt37x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt37x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt37x, -+ .probe = hpt37x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt37x_init(void) -+{ -+ return pci_register_driver(&hpt37x_pci_driver); -+} -+ -+ -+static void __exit hpt37x_exit(void) -+{ -+ pci_unregister_driver(&hpt37x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt37x); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt37x_init); -+module_exit(hpt37x_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c linux-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_hpt3x2n.c 2006-02-16 15:36:58.000000000 +0000 -@@ -0,0 +1,580 @@ -+/* -+ * Libata driver for the highpoint 372N and 302N UDMA66 ATA controllers. -+ * -+ * This driver is heavily based upon: -+ * -+ * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 -+ * -+ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 2001 Sun Microsystems, Inc. -+ * Portions Copyright (C) 2003 Red Hat Inc -+ * -+ * -+ * TODO -+ * 371N -+ * Work out best PLL policy -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "hpt3x2n" -+#define DRV_VERSION "0.1" -+ -+enum { -+ HPT_PCI_FAST = (1 << 31), -+ PCI66 = (1 << 1), -+ USE_DPLL = (1 << 0) -+}; -+ -+struct hpt_clock { -+ u8 xfer_speed; -+ u32 timing; -+}; -+ -+struct hpt_chip { -+ const char *name; -+ struct hpt_clock *clocks[3]; -+}; -+ -+/* key for bus clock timings -+ * bit -+ * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW -+ * DMA. cycles = value + 1 -+ * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file -+ * register access. -+ * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file -+ * register access. -+ * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. -+ * during task file register access. -+ * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA -+ * xfer. -+ * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task -+ * register access. -+ * 28 UDMA enable -+ * 29 DMA enable -+ * 30 PIO_MST enable. if set, the chip is in bus master mode during -+ * PIO. -+ * 31 FIFO enable. -+ */ -+ -+/* 66MHz DPLL clocks */ -+ -+static struct hpt_clock hpt3x2n_clocks[] = { -+ { XFER_UDMA_7, 0x1c869c62 }, -+ { XFER_UDMA_6, 0x1c869c62 }, -+ { XFER_UDMA_5, 0x1c8a9c62 }, -+ { XFER_UDMA_4, 0x1c8a9c62 }, -+ { XFER_UDMA_3, 0x1c8e9c62 }, -+ { XFER_UDMA_2, 0x1c929c62 }, -+ { XFER_UDMA_1, 0x1c9a9c62 }, -+ { XFER_UDMA_0, 0x1c829c62 }, -+ -+ { XFER_MW_DMA_2, 0x2c829c62 }, -+ { XFER_MW_DMA_1, 0x2c829c66 }, -+ { XFER_MW_DMA_0, 0x2c829d2c }, -+ -+ { XFER_PIO_4, 0x0c829c62 }, -+ { XFER_PIO_3, 0x0c829c84 }, -+ { XFER_PIO_2, 0x0c829ca6 }, -+ { XFER_PIO_1, 0x0d029d26 }, -+ { XFER_PIO_0, 0x0d029d5e }, -+ { 0, 0x0d029d5e } -+}; -+ -+/** -+ * hpt3x2n_find_mode - reset the hpt3x2n bus -+ * @ap: ATA port -+ * @speed: transfer mode -+ * -+ * Return the 32bit register programming information for this channel -+ * that matches the speed provided. For the moment the clocks table -+ * is hard coded but easy to change. This will be needed if we use -+ * different DPLLs -+ */ -+ -+static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) -+{ -+ struct hpt_clock *clocks = hpt3x2n_clocks; -+ -+ while(clocks->xfer_speed) { -+ if (clocks->xfer_speed == speed) -+ return clocks->timing; -+ clocks++; -+ } -+ BUG(); -+} -+ -+/** -+ * hpt3x2n_phy_reset - reset the hpt3x2n bus -+ * @ap: ATA port to reset -+ * -+ * Perform the PHY reset handling for the 3x2N -+ */ -+ -+static void hpt3x2n_phy_reset(struct ata_port *ap) -+{ -+ u8 scr2, ata66; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x5B, &scr2); -+ pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); -+ /* Cable register now active */ -+ pci_read_config_byte(pdev, 0x5A, &ata66); -+ /* Restore state */ -+ pci_write_config_byte(pdev, 0x5B, scr2); -+ -+ if (ata66 & (1 << ap->hard_port_no)) -+ ap->cbl = ATA_CBL_PATA40; -+ else -+ ap->cbl = ATA_CBL_PATA80; -+ -+ /* Reset the state machine */ -+ pci_write_config_byte(pdev, 0x50, 0x37); -+ pci_write_config_byte(pdev, 0x54, 0x37); -+ udelay(100); -+ -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+/** -+ * hpt3x2n_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Perform PIO mode setup. -+ */ -+ -+static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt3x2n_find_mode(ap, adev->pio_mode); -+ mode &= ~0x8000000; /* No FIFO in PIO */ -+ mode &= ~0x30070000; /* Leave config bits alone */ -+ reg &= 0x30070000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt3x2n_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * Set up the channel for MWDMA or UDMA modes. Much the same as with -+ * PIO, load the mode number and then set MWDMA or UDMA flag. -+ */ -+ -+static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 addr1, addr2; -+ u32 reg; -+ u32 mode; -+ u8 fast; -+ -+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->hard_port_no); -+ addr2 = 0x51 + 4 * ap->hard_port_no; -+ -+ /* Fast interrupt prediction disable, hold off interrupt disable */ -+ pci_read_config_byte(pdev, addr2, &fast); -+ fast &= ~0x07; -+ pci_write_config_byte(pdev, addr2, fast); -+ -+ pci_read_config_dword(pdev, addr1, ®); -+ mode = hpt3x2n_find_mode(ap, adev->dma_mode); -+ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ -+ mode &= ~0xC0000000; /* Leave config bits alone */ -+ reg &= 0xC0000000; /* Strip timing bits */ -+ pci_write_config_dword(pdev, addr1, reg | mode); -+} -+ -+/** -+ * hpt3x2n_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Clean up after the HPT3x2n and later DMA engine -+ */ -+ -+static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int mscreg = 0x50 + 2 * ap->hard_port_no; -+ u8 bwsr_stat, msc_stat; -+ -+ pci_read_config_byte(pdev, 0x6A, &bwsr_stat); -+ pci_read_config_byte(pdev, mscreg, &msc_stat); -+ if (bwsr_stat & (1 << ap->hard_port_no)) -+ pci_write_config_byte(pdev, mscreg, msc_stat | 0x30); -+ ata_bmdma_stop(qc); -+} -+ -+/** -+ * hpt3x2n_set_clock - clock control -+ * @ap: ATA port -+ * @source: 0x21 or 0x23 for PLL or PCI sourced clock -+ * -+ * Switch the ATA bus clock between the PLL and PCI clock sources -+ * while correctly isolating the bus and resetting internal logic -+ * -+ * We must use the DPLL for -+ * - writing -+ * - second channel UDMA7 (SATA ports) or higher -+ * - 66MHz PCI -+ * -+ * or we will underclock the device and get reduced performance. -+ */ -+ -+static void hpt3x2n_set_clock(struct ata_port *ap, int source) -+{ -+ unsigned long bmdma = ap->ioaddr.bmdma_addr; -+ -+ /* Tristate the bus */ -+ outb(0x80, bmdma+0x73); -+ outb(0x80, bmdma+0x77); -+ -+ /* Switch clock and reset channels */ -+ outb(source, bmdma+0x7B); -+ outb(0xC0, bmdma+0x79); -+ -+ /* Reset state machines */ -+ outb(0x37, bmdma+0x70); -+ outb(0x37, bmdma+0x74); -+ -+ /* Complete reset */ -+ outb(0x00, bmdma+0x79); -+ -+ /* Reconnect channels to bus */ -+ outb(0x00, bmdma+0x73); -+ outb(0x00, bmdma+0x77); -+} -+ -+/* Check if our partner interface is busy */ -+ -+static int hpt3x2n_pair_idle(struct ata_port *ap) -+{ -+ struct ata_host_set *host = ap->host_set; -+ struct ata_port *pair = host->ports[ap->hard_port_no ^ 1]; -+ -+ if (pair->hsm_task_state == HSM_ST_IDLE) -+ return 1; -+ return 0; -+} -+ -+static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) -+{ -+ long flags = (long)ap->host_set->private_data; -+ /* See if we should use the DPLL */ -+ if (reading == 0) -+ return USE_DPLL; /* Needed for write */ -+ if (flags & PCI66) -+ return USE_DPLL; /* Needed at 66Mhz */ -+ return 0; -+} -+ -+static int hpt3x2n_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_taskfile *tf = &qc->tf; -+ struct ata_port *ap = qc->ap; -+ int flags = (long)ap->host_set->private_data; -+ -+ if (hpt3x2n_pair_idle(ap)) { -+ int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE)); -+ if ((flags & USE_DPLL) != dpll) { -+ if (dpll == 1) -+ hpt3x2n_set_clock(ap, 0x21); -+ else -+ hpt3x2n_set_clock(ap, 0x23); -+ } -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template hpt3x2n_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+/* -+ * Configuration for HPT3x2n. -+ */ -+ -+static struct ata_port_operations hpt3x2n_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = hpt3x2n_set_piomode, -+ .set_dmamode = hpt3x2n_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = hpt3x2n_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = hpt3x2n_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = hpt3x2n_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * hpt3xn_calibrate_dpll - Calibrate the DPLL loop -+ * @dev: PCI device -+ * -+ * Perform a calibration cycle on the HPT3xN DPLL. Returns 1 if this -+ * succeeds -+ */ -+ -+static int hpt3xn_calibrate_dpll(struct pci_dev *dev) -+{ -+ u8 reg5b; -+ u32 reg5c; -+ int tries; -+ -+ for(tries = 0; tries < 0x5000; tries++) { -+ udelay(50); -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ if (reg5b & 0x80) { -+ /* See if it stays set */ -+ for(tries = 0; tries < 0x1000; tries ++) { -+ pci_read_config_byte(dev, 0x5b, ®5b); -+ /* Failed ? */ -+ if ((reg5b & 0x80) == 0) -+ return 0; -+ } -+ /* Turn off tuning, we have the DPLL set */ -+ pci_read_config_dword(dev, 0x5c, ®5c); -+ pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); -+ return 1; -+ } -+ } -+ /* Never went stable */ -+ return 0; -+} -+ -+static int hpt3x2n_pci_clock(struct pci_dev *pdev) -+{ -+ unsigned long freq; -+ u32 fcnt; -+ -+ pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt); -+ if ((fcnt >> 12) != 0xABCDE) { -+ printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); -+ return 33; /* Not BIOS set */ -+ } -+ fcnt &= 0x1FF; -+ -+ freq = (fcnt * 77) / 192; -+ -+ /* Clamp to bands */ -+ if (freq < 40) -+ return 33; -+ if (freq < 45) -+ return 40; -+ if (freq < 55) -+ return 50; -+ return 66; -+} -+ -+/** -+ * hpt3x2n_init_one - Initialise an HPT37X/302 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Initialise an HPT3x2n device. There are some interesting complications -+ * here. Firstly the chip may report 366 and be one of several variants. -+ * Secondly all the timings depend on the clock for the chip which we must -+ * detect and look up -+ * -+ * This is the known chip mappings. It may be missing a couple of later -+ * releases. -+ * -+ * Chip version PCI Rev Notes -+ * HPT372 4 (HPT366) 5 Other driver -+ * HPT372N 4 (HPT366) 6 UDMA133 -+ * HPT372 5 (HPT372) 1 Other driver -+ * HPT372N 5 (HPT372) 2 UDMA133 -+ * HPT302 6 (HPT302) * Other driver -+ * HPT302N 6 (HPT302) > 1 UDMA133 -+ * HPT371 7 (HPT371) * Other driver -+ * HPT371N 7 (HPT371) > 1 UDMA133 -+ * HPT374 8 (HPT374) * Other driver -+ * HPT372N 9 (HPT372N) * UDMA133 -+ * -+ * (1) UDMA133 support depends on the bus clock -+ * -+ * To pin down HPT371N -+ */ -+ -+static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ /* HPT372N and friends - UDMA133 */ -+ static struct ata_port_info info = { -+ .sht = &hpt3x2n_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &hpt3x2n_port_ops -+ }; -+ struct ata_port_info *port_info[2]; -+ struct ata_port_info *port = &info; -+ -+ u8 irqmask; -+ u32 class_rev; -+ -+ unsigned int pci_mhz; -+ unsigned int f_low, f_high; -+ int adjust; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xFF; -+ -+ switch(dev->device) { -+ case PCI_DEVICE_ID_TTI_HPT366: -+ if (class_rev < 6) -+ return -ENODEV; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT372: -+ /* 372N if rev >= 1*/ -+ if (class_rev == 0) -+ return -ENODEV; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT302: -+ if (class_rev < 2) -+ return -ENODEV; -+ break; -+ case PCI_DEVICE_ID_TTI_HPT372N: -+ break; -+ default: -+ printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); -+ return -ENODEV; -+ } -+ -+ /* Ok so this is a chip we support */ -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); -+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); -+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); -+ -+ pci_read_config_byte(dev, 0x5A, &irqmask); -+ irqmask &= ~0x10; -+ pci_write_config_byte(dev, 0x5a, irqmask); -+ -+ /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or -+ 50 for UDMA100. Right now we always use 66 */ -+ -+ pci_mhz = hpt3x2n_pci_clock(dev); -+ -+ f_low = (pci_mhz * 48) / 66; /* PCI Mhz for 66Mhz DPLL */ -+ f_high = f_low + 2; /* Tolerance */ -+ -+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); -+ /* PLL clock */ -+ pci_write_config_byte(dev, 0x5B, 0x21); -+ -+ /* Unlike the 37x we don't try jiggling the frequency */ -+ for(adjust = 0; adjust < 8; adjust++) { -+ if (hpt3xn_calibrate_dpll(dev)) -+ break; -+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); -+ } -+ if (adjust == 8) -+ printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n"); -+ -+ /* Set our private data up. We only need a few flags so we use -+ it directly */ -+ port->private_data = NULL; -+ if (pci_mhz > 60) -+ port->private_data = (void *)PCI66; -+ -+ /* Now kick off ATA set up */ -+ port_info[0] = port_info[1] = port; -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id hpt3x2n[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N), }, -+ { 0, }, -+}; -+ -+static struct pci_driver hpt3x2n_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = hpt3x2n, -+ .probe = hpt3x2n_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init hpt3x2n_init(void) -+{ -+ return pci_register_driver(&hpt3x2n_pci_driver); -+} -+ -+ -+static void __exit hpt3x2n_exit(void) -+{ -+ pci_unregister_driver(&hpt3x2n_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, hpt3x2n); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(hpt3x2n_init); -+module_exit(hpt3x2n_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_isapnp.c linux-2.6.16-rc4/drivers/scsi/pata_isapnp.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_isapnp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_isapnp.c 2006-01-21 16:52:31.000000000 +0000 -@@ -0,0 +1,151 @@ -+ -+/* -+ * pata-isapnp.c - ISA PnP PATA controller driver. -+ * Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * Based in part on ide-pnp.c by Andrey Panin <pazke@donpac.ru> -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/isapnp.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/ata.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_isapnp" -+#define DRV_VERSION "0.1" -+ -+static struct scsi_host_template isapnp_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations isapnp_port_ops = { -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * isapnp_init_one - attach an isapnp interface -+ * @idev: PnP device -+ * @dev_id: matching detect line -+ * -+ * Register an ISA bus IDE interface. Such interfaces are PIO 0 and -+ * non shared IRQ. -+ */ -+ -+static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id) -+{ -+ struct ata_probe_ent ae; -+ -+ if (pnp_port_valid(idev, 0) == 0) -+ return -ENODEV; -+ if (pnp_port_valid(idev, 1) == 0) -+ return -ENODEV; -+ -+ /* FIXME: Should selected polled PIO here not fail */ -+ if (pnp_irq_valid(idev, 0) == 0) -+ return -ENODEV; -+ -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = &idev->dev; -+ ae.port_ops = &isapnp_port_ops; -+ ae.sht = &isapnp_sht; -+ ae.n_ports = 1; -+ ae.pio_mask = 1; /* ISA so PIO 0 cycles */ -+ ae.irq = pnp_irq(idev, 0); -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = pnp_port_start(idev, 0); -+ ae.port[0].altstatus_addr = pnp_port_start(idev, 1); -+ ae.port[0].ctl_addr = pnp_port_start(idev, 1); -+ ata_std_ports(&ae.port[0]); -+ -+ if (ata_device_add(&ae) == 0) -+ return -ENODEV; -+ return 0; -+} -+ -+/** -+ * isapnp_remove_one - unplug an isapnp interface -+ * @idev: PnP device -+ * -+ * Remove a previously configured PnP ATA port. Called only on module -+ * unload events as the core does not currently deal with ISAPnP docking. -+ */ -+ -+static void isapnp_remove_one(struct pnp_dev *idev) -+{ -+ struct device *dev = &idev->dev; -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+} -+ -+static struct pnp_device_id isapnp_devices[] = { -+ /* Generic ESDI/IDE/ATA compatible hard disk controller */ -+ {.id = "PNP0600", .driver_data = 0}, -+ {.id = ""} -+}; -+ -+static struct pnp_driver isapnp_driver = { -+ .name = DRV_NAME, -+ .id_table = isapnp_devices, -+ .probe = isapnp_init_one, -+ .remove = isapnp_remove_one, -+}; -+ -+static int __init isapnp_init(void) -+{ -+ return pnp_register_driver(&isapnp_driver); -+} -+ -+static void __exit isapnp_exit(void) -+{ -+ pnp_unregister_driver(&isapnp_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ISA PnP ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(isapnp_init); -+module_exit(isapnp_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it8172.c linux-2.6.16-rc4/drivers/scsi/pata_it8172.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it8172.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_it8172.c 2006-02-16 15:39:11.000000000 +0000 -@@ -0,0 +1,280 @@ -+/* -+ * pata_it8172.c - IT8172 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based heavily on -+ * -+ * BRIEF MODULE DESCRIPTION -+ * IT8172 IDE controller support -+ * -+ * Copyright 2000 MontaVista Software Inc. -+ * Author: MontaVista Software, Inc. -+ * stevel@mvista.com or source@mvista.com -+ * -+ * 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 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 AUTHOR 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. -+ * -+ * 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. -+ * -+ * TODO -+ * Check for errata -+ * See if we really need to force native mode -+ * PIO timings (also lacking in original) -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "it8172" -+#define DRV_VERSION "0.1.1" -+ -+static void it8172_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits it8172_enable_bits[] = { -+ { 0x00, 0, 0x00, 0x00 }, -+ { 0x40, 1, 0x00, 0x01 } -+ }; -+ -+ if (ap->hard_port_no && !pci_test_config_bits(pdev, &it8172_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * it8172_set_pio_timing - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called by both the pio and dma setup functions to set the controller -+ * timings for PIO transfers. We must load both the mode number and -+ * timing values into the controller. -+ */ -+ -+static void it8172_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 reg40; -+ -+ pci_read_config_word(pdev, 0x40, ®40); -+ -+ /* -+ * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 -+ * are being left at the default values of 8 PCI clocks (242 nsec -+ * for a 33 MHz clock). These can be safely shortened at higher -+ * PIO modes. The DIOR/DIOW pulse width and recovery times only -+ * apply to PIO modes, not to the DMA modes. -+ */ -+ -+ /* -+ * Enable port 0x44. The IT8172G spec is confused; it calls -+ * this register the "Slave IDE Timing Register", but in fact, -+ * it controls timing for both master and slave drives. -+ */ -+ -+ reg40 |= 0x4000; -+ if (adev->devno) { -+ reg40 |= 0xC006; -+ if (pio > 1) -+ /* Enable prefetch and IORDY sample-point */ -+ reg40 |= 0x0060; -+ } else { -+ reg40 |= 0xC060; -+ if (pio > 1) -+ /* Enable prefetch and IORDY sample-point */ -+ reg40 |= 0x0006; -+ } -+ /* Write back the enables */ -+ pci_write_config_word(pdev, 0x40, reg40); -+} -+ -+/** -+ * it8172_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. We use a shared helper for this -+ * as the DMA setup must also adjust the PIO timing information. -+ */ -+ -+static void it8172_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ it8172_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * it8172_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. We must tune an appropriate PIO -+ * mode to match. -+ */ -+ -+static void it8172_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int dn = (2 * ap->hard_port_no) + adev->devno; -+ u8 reg48, reg4a; -+ int pio; -+ -+ static int pio_map[] = { 1, 3, 4}; -+ /* -+ * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec -+ * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA -+ * transfers on some drives, even though both numbers meet the minimum -+ * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively. -+ * So the faster times are just commented out here. The good news is -+ * that the slower cycle time has very little affect on transfer -+ * performance. -+ */ -+ -+ pci_read_config_byte(pdev, 0x48, ®48); -+ pci_read_config_byte(pdev, 0x4A, ®4a); -+ -+ reg4a &= ~(3 << (4 * dn)); -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ reg48 |= 1 << dn; -+#ifdef UDMA_TIMING_SET -+ reg4a |= ((adev->dma_mode - XFER_UDMA_0) << (4 * dn)); -+#endif -+ pio = 4; -+ } else { -+ pio = pio_map[adev->dma_mode - XFER_MW_DMA_0]; -+ reg48 &= ~ (1 << dn); -+ } -+ pci_write_config_byte(pdev, 0x48, reg48); -+ pci_write_config_byte(pdev, 0x4A, reg4a); -+ it8172_set_pio_timing(ap, adev, pio); -+ -+} -+ -+static struct scsi_host_template it8172_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations it8172_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = it8172_set_piomode, -+ .set_dmamode = it8172_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = it8172_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &it8172_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x06, /* No MWDMA0 support */ -+ .udma_mask = 0x7, -+ .port_ops = &it8172_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if ((!(PCI_FUNC(dev->devfn) & 1) || -+ (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))) -+ return -ENODEV; /* IT8172 is more than an IDE controller */ -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id it8172[] = { -+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver it8172_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = it8172, -+ .probe = it8172_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init it8172_init(void) -+{ -+ return pci_register_driver(&it8172_pci_driver); -+} -+ -+ -+static void __exit it8172_exit(void) -+{ -+ pci_unregister_driver(&it8172_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for ITE IT8172"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, it8172); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(it8172_init); -+module_exit(it8172_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it821x.c linux-2.6.16-rc4/drivers/scsi/pata_it821x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_it821x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_it821x.c 2006-02-20 12:27:55.000000000 +0000 -@@ -0,0 +1,743 @@ -+/* -+ * ata-it821x.c - IT821x PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * it821x.c -+ * -+ * linux/drivers/ide/pci/it821x.c Version 0.09 December 2004 -+ * -+ * Copyright (C) 2004 Red Hat <alan@redhat.com> -+ * -+ * May be copied or modified under the terms of the GNU General Public License -+ * Based in part on the ITE vendor provided SCSI driver. -+ * -+ * Documentation available from -+ * http://www.ite.com.tw/pc/IT8212F_V04.pdf -+ * Some other documents are NDA. -+ * -+ * The ITE8212 isn't exactly a standard IDE controller. It has two -+ * modes. In pass through mode then it is an IDE controller. In its smart -+ * mode its actually quite a capable hardware raid controller disguised -+ * as an IDE controller. Smart mode only understands DMA read/write and -+ * identify, none of the fancier commands apply. The IT8211 is identical -+ * in other respects but lacks the raid mode. -+ * -+ * Errata: -+ * o Rev 0x10 also requires master/slave hold the same DMA timings and -+ * cannot do ATAPI MWDMA. -+ * o The identify data for raid volumes lacks CHS info (technically ok) -+ * but also fails to set the LBA28 and other bits. We fix these in -+ * the IDE probe quirk code. -+ * o If you write LBA48 sized I/O's (ie > 256 sector) in smart mode -+ * raid then the controller firmware dies -+ * o Smart mode without RAID doesn't clear all the necessary identify -+ * bits to reduce the command set to the one used -+ * -+ * This has a few impacts on the driver -+ * - In pass through mode we do all the work you would expect -+ * - In smart mode the clocking set up is done by the controller generally -+ * but we must watch the other limits and filter. -+ * - There are a few extra vendor commands that actually talk to the -+ * controller but only work PIO with no IRQ. -+ * -+ * Vendor areas of the identify block in smart mode are used for the -+ * timing and policy set up. Each HDD in raid mode also has a serial -+ * block on the disk. The hardware extra commands are get/set chip status, -+ * rebuild, get rebuild status. -+ * -+ * In Linux the driver supports pass through mode as if the device was -+ * just another IDE controller. If the smart mode is running then -+ * volumes are managed by the controller firmware and each IDE "disk" -+ * is a raid volume. Even more cute - the controller can do automated -+ * hotplug and rebuild. -+ * -+ * The pass through controller itself is a little demented. It has a -+ * flaw that it has a single set of PIO/MWDMA timings per channel so -+ * non UDMA devices restrict each others performance. It also has a -+ * single clock source per channel so mixed UDMA100/133 performance -+ * isn't perfect and we have to pick a clock. Thankfully none of this -+ * matters in smart mode. ATAPI DMA is not currently supported. -+ * -+ * It seems the smart mode is a win for RAID1/RAID10 but otherwise not. -+ * -+ * TODO -+ * - ATAPI and other speed filtering -+ * - Command filter in smart mode -+ * - RAID configuration ioctls -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+ -+#define DRV_NAME "it821x" -+#define DRV_VERSION "0.2.1" -+ -+struct it821x_dev -+{ -+ unsigned int smart:1, /* Are we in smart raid mode */ -+ timing10:1; /* Rev 0x10 */ -+ u8 clock_mode; /* 0, ATA_50 or ATA_66 */ -+ u8 want[2][2]; /* Mode/Pri log for master slave */ -+ /* We need these for switching the clock when DMA goes on/off -+ The high byte is the 66Mhz timing */ -+ u16 pio[2]; /* Cached PIO values */ -+ u16 mwdma[2]; /* Cached MWDMA values */ -+ u16 udma[2]; /* Cached UDMA values (per drive) */ -+ u16 last_device; /* Master or slave loaded ? */ -+}; -+ -+#define ATA_66 0 -+#define ATA_50 1 -+#define ATA_ANY 2 -+ -+#define UDMA_OFF 0 -+#define MWDMA_OFF 0 -+ -+/* -+ * We allow users to force the card into non raid mode without -+ * flashing the alternative BIOS. This is also neccessary right now -+ * for embedded platforms that cannot run a PC BIOS but are using this -+ * device. -+ */ -+ -+static int it8212_noraid; -+ -+ -+/** -+ * it821x_phy_reset - probe/reset -+ * @ap: ATA port -+ * -+ * Set the cable type and trigger a probe -+ */ -+ -+static void it821x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * it821x_program - program the PIO/MWDMA registers -+ * @ap: ATA port -+ * @adev: Device to program -+ * @timing: Timing value (66Mhz in top 8bits, 50 in the low 8) -+ * -+ * Program the PIO/MWDMA timing for this channel according to the -+ * current clock. These share the same register so are managed by -+ * the DMA start/stop sequence as with the old driver. -+ */ -+ -+static void it821x_program(struct ata_port *ap, struct ata_device *adev, u16 timing) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev = ap->private_data; -+ int channel = ap->hard_port_no; -+ u8 conf; -+ -+ /* Program PIO/MWDMA timing bits */ -+ if (itdev->clock_mode == ATA_66) -+ conf = timing >> 8; -+ else -+ conf = timing & 0xFF; -+ pci_write_config_byte(pdev, 0x54 + 4 * channel, conf); -+} -+ -+ -+/** -+ * it821x_program_udma - program the UDMA registers -+ * @ap: ATA port -+ * @adev: ATA device to update -+ * @timing: Timing bits. Top 8 are for 66Mhz bottom for 50Mhz -+ * -+ * Program the UDMA timing for this drive according to the -+ * current clock. Handles the dual clocks and also knows about -+ * the errata on the 0x10 revision. The UDMA errata is partly handled -+ * here and partly in start_dma. -+ */ -+ -+static void it821x_program_udma(struct ata_port *ap, struct ata_device *adev, u16 timing) -+{ -+ struct it821x_dev *itdev = ap->private_data; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int channel = ap->hard_port_no; -+ int unit = adev->devno; -+ u8 conf; -+ -+ /* Program UDMA timing bits */ -+ if (itdev->clock_mode == ATA_66) -+ conf = timing >> 8; -+ else -+ conf = timing & 0xFF; -+ if (itdev->timing10 == 0) -+ pci_write_config_byte(pdev, 0x56 + 4 * channel + unit, conf); -+ else { -+ /* Early revision must be programmed for both together */ -+ pci_write_config_byte(pdev, 0x56 + 4 * channel, conf); -+ pci_write_config_byte(pdev, 0x56 + 4 * channel + 1, conf); -+ } -+} -+ -+/** -+ * it821x_clock_strategy -+ * @ap: ATA interface -+ * @adev: ATA device being updated -+ * -+ * Select between the 50 and 66Mhz base clocks to get the best -+ * results for this interface. -+ */ -+ -+static void it821x_clock_strategy(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev = ap->private_data; -+ u8 unit = adev->devno; -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ -+ int clock, altclock; -+ u8 v; -+ int sel = 0; -+ -+ /* Look for the most wanted clocking */ -+ if (itdev->want[0][0] > itdev->want[1][0]) { -+ clock = itdev->want[0][1]; -+ altclock = itdev->want[1][1]; -+ } else { -+ clock = itdev->want[1][1]; -+ altclock = itdev->want[0][1]; -+ } -+ -+ /* Master doesn't care does the slave ? */ -+ if (clock == ATA_ANY) -+ clock = altclock; -+ -+ /* Nobody cares - keep the same clock */ -+ if (clock == ATA_ANY) -+ return; -+ /* No change */ -+ if (clock == itdev->clock_mode) -+ return; -+ -+ /* Load this into the controller ? */ -+ if (clock == ATA_66) -+ itdev->clock_mode = ATA_66; -+ else { -+ itdev->clock_mode = ATA_50; -+ sel = 1; -+ } -+ pci_read_config_byte(pdev, 0x50, &v); -+ v &= ~(1 << (1 + ap->hard_port_no)); -+ v |= sel << (1 + ap->hard_port_no); -+ pci_write_config_byte(pdev, 0x50, v); -+ -+ /* -+ * Reprogram the UDMA/PIO of the pair drive for the switch -+ * MWDMA will be dealt with by the dma switcher -+ */ -+ if (pair && itdev->udma[1-unit] != UDMA_OFF) { -+ it821x_program_udma(ap, pair, itdev->udma[1-unit]); -+ it821x_program(ap, pair, itdev->pio[1-unit]); -+ } -+ /* -+ * Reprogram the UDMA/PIO of our drive for the switch. -+ * MWDMA will be dealt with by the dma switcher -+ */ -+ if (itdev->udma[unit] != UDMA_OFF) { -+ it821x_program_udma(ap, adev, itdev->udma[unit]); -+ it821x_program(ap, adev, itdev->pio[unit]); -+ } -+} -+ -+/** -+ * it821x_passthru_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Configure for PIO mode. This is complicated as the register is -+ * shared by PIO and MWDMA and for both channels. -+ */ -+ -+static void it821x_passthru_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ /* Spec says 89 ref driver uses 88 */ -+ static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; -+ static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; -+ -+ struct it821x_dev *itdev = ap->private_data; -+ int unit = adev->devno; -+ int mode_wanted = adev->pio_mode - XFER_PIO_0; -+ -+ /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ -+ itdev->want[unit][1] = pio_want[mode_wanted]; -+ itdev->want[unit][0] = 1; /* PIO is lowest priority */ -+ itdev->pio[unit] = pio[mode_wanted]; -+ it821x_clock_strategy(ap, adev); -+ it821x_program(ap, adev, itdev->pio[unit]); -+} -+ -+/** -+ * it821x_passthru_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Set up the DMA modes. The actions taken depend heavily on the mode -+ * to use. If UDMA is used as is hopefully the usual case then the -+ * timing register is private and we need only consider the clock. If -+ * we are using MWDMA then we have to manage the setting ourself as -+ * we switch devices and mode. -+ */ -+ -+static void it821x_passthru_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u16 dma[] = { 0x8866, 0x3222, 0x3121 }; -+ static u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY }; -+ static u16 udma[] = { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 }; -+ static u8 udma_want[] = { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev = ap->private_data; -+ int channel = ap->hard_port_no; -+ int unit = adev->devno; -+ u8 conf; -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ int mode_wanted = adev->dma_mode - XFER_UDMA_0; -+ -+ itdev->want[unit][1] = udma_want[mode_wanted]; -+ itdev->want[unit][0] = 3; /* UDMA is high priority */ -+ itdev->mwdma[unit] = MWDMA_OFF; -+ itdev->udma[unit] = udma[mode_wanted]; -+ if (mode_wanted >= 5) -+ itdev->udma[unit] |= 0x8080; /* UDMA 5/6 select on */ -+ -+ /* UDMA on. Again revision 0x10 must do the pair */ -+ pci_read_config_byte(pdev, 0x50, &conf); -+ if (itdev->timing10) -+ conf &= channel ? 0x9F: 0xE7; -+ else -+ conf &= ~ (1 << (3 + 2 * channel + unit)); -+ pci_write_config_byte(pdev, 0x50, conf); -+ it821x_clock_strategy(ap, adev); -+ it821x_program_udma(ap, adev, itdev->udma[unit]); -+ } else { -+ int mode_wanted = adev->dma_mode - XFER_UDMA_0; -+ -+ itdev->want[unit][1] = mwdma_want[mode_wanted]; -+ itdev->want[unit][0] = 2; /* MWDMA is low priority */ -+ itdev->mwdma[unit] = dma[mode_wanted]; -+ itdev->udma[unit] = UDMA_OFF; -+ -+ /* UDMA bits off - Revision 0x10 do them in pairs */ -+ pci_read_config_byte(pdev, 0x50, &conf); -+ if (itdev->timing10) -+ conf |= channel ? 0x60: 0x18; -+ else -+ conf |= 1 << (3 + 2 * channel + unit); -+ pci_write_config_byte(pdev, 0x50, conf); -+ it821x_clock_strategy(ap, adev); -+ } -+} -+ -+/** -+ * it821x_passthru_dma_start - DMA start callback -+ * @qc: Command in progress -+ * -+ * Usually drivers set the DMA timing at the point the set_dmamode call -+ * is made. IT821x however requires we load new timings on the -+ * transitions in some cases. -+ */ -+ -+static void it821x_passthru_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct it821x_dev *itdev = ap->private_data; -+ int unit = adev->devno; -+ -+ if (itdev->mwdma[unit] != MWDMA_OFF) -+ it821x_program(ap, adev, itdev->mwdma[unit]); -+ else if (itdev->udma[unit] != UDMA_OFF && itdev->timing10) -+ it821x_program_udma(ap, adev, itdev->udma[unit]); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * it821x_passthru_dma_stop - DMA stop callback -+ * @qc: ATA command -+ * -+ * We loaded new timings in dma_start, as a result we need to restore -+ * the PIO timings in dma_stop so that the next command issue gets the -+ * right clock values. -+ */ -+ -+static void it821x_passthru_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct it821x_dev *itdev = ap->private_data; -+ int unit = adev->devno; -+ -+ ata_bmdma_stop(qc); -+ if (itdev->mwdma[unit] != MWDMA_OFF) -+ it821x_program(ap, adev, itdev->pio[unit]); -+} -+ -+ -+/** -+ * it821x_passthru_dev_select - Select master/slave -+ * @ap: ATA port -+ * @device: Device number (not pointer) -+ * -+ * Device selection hook. If neccessary perform clock switching -+ */ -+ -+void it821x_passthru_dev_select(struct ata_port *ap, unsigned int device) -+{ -+ struct it821x_dev *itdev = ap->private_data; -+ if (itdev && device != itdev->last_device) { -+ struct ata_device *adev = &ap->device[device]; -+ it821x_program(ap, adev, itdev->pio[adev->devno]); -+ itdev->last_device = device; -+ } -+} -+ -+/** -+ * it821x_passthru_qc_issue_prot - wrap qc issue prot -+ * @qc: command -+ * -+ * Wrap the command issue sequence for the IT821x. We need to -+ * perform out own device selection timing loads before the -+ * usual happenings kick off -+ */ -+ -+static int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ it821x_passthru_dev_select(qc->ap, qc->dev->devno); -+ return ata_qc_issue_prot(qc); -+} -+ -+/** -+ * it821x_smart_set_mode - mode setting -+ * @ap: interface to set up -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. -+ * The BIOS configured everything. Our job is not to fiddle. We -+ * read the dma enabled bits from the PCI configuration of the device -+ * and respect them. -+ */ -+ -+static void it821x_smart_set_mode(struct ata_port *ap) -+{ -+ int dma_enabled; -+ int i; -+ -+ /* Bits 5 and 6 indicate if DMA is active on master/slave */ -+ dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ /* We don't really care */ -+ dev->pio_mode = XFER_PIO_0; -+ dev->dma_mode = XFER_MW_DMA_0; -+ /* We do need the right mode information for DMA or PIO -+ and this comes from the current configuration flags */ -+ if (dma_enabled & (1 << (5 + i))) { -+ dev->xfer_mode = XFER_MW_DMA_0; -+ dev->xfer_shift = ATA_SHIFT_MWDMA; -+ dev->flags &= ~ATA_DFLAG_PIO; -+ } else { -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ /* Keep sector count safe (LBA48 counts blow the -+ brains of the firmware) */ -+ -+ /* Do we need a dev_config method ? */ -+ dev->flags |= ATA_DFLAG_LOCK_SECTORS; -+ } -+ } -+} -+ -+/** -+ * it821x_check_atapi_dma - ATAPI DMA handler -+ * @qc: Command we are about to issue -+ * -+ * Decide if this ATAPI command can be issued by DMA on this -+ * controller. Return 0 if it can be. -+ */ -+ -+static int it821x_check_atapi_dma(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct it821x_dev *itdev = ap->private_data; -+ -+ /* No ATAPI DMA in smart mode */ -+ if (itdev->smart) -+ return -EOPNOTSUPP; -+ /* No ATAPI DMA on rev 10 */ -+ if (itdev->timing10) -+ return -EOPNOTSUPP; -+ /* Cool */ -+ return 0; -+} -+ -+ -+/** -+ * it821x_port_start - port setup -+ * @ap: ATA port being set up -+ * -+ * The it821x needs to maintain private data structures and also to -+ * use the standard PCI interface which lacks support for this -+ * functionality. We instead set up the private data on the port -+ * start hook, and tear it down on port stop -+ */ -+ -+static int it821x_port_start(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct it821x_dev *itdev; -+ u8 conf; -+ -+ int ret = ata_port_start(ap); -+ if (ret < 0) -+ return ret; -+ -+ ap->private_data = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL); -+ if (ap->private_data == NULL) { -+ ata_port_stop(ap); -+ return -ENOMEM; -+ } -+ -+ itdev = ap->private_data; -+ memset(itdev, 0, sizeof(struct it821x_dev)); -+ -+ pci_read_config_byte(pdev, 0x50, &conf); -+ -+ if (conf & 1) { -+ itdev->smart = 1; -+ /* Long I/O's although allowed in LBA48 space cause the -+ onboard firmware to enter the twighlight zone */ -+ /* No ATAPI DMA in this mode either */ -+ } -+ /* Pull the current clocks from 0x50 */ -+ if (conf & (1 << (1 + ap->hard_port_no))) -+ itdev->clock_mode = ATA_50; -+ else -+ itdev->clock_mode = ATA_66; -+ -+ itdev->want[0][1] = ATA_ANY; -+ itdev->want[1][1] = ATA_ANY; -+ itdev->last_device = -1; -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &conf); -+ if (conf == 0x10) { -+ itdev->timing10 = 1; -+ /* Need to disable ATAPI DMA for this case */ -+ if (!itdev->smart) -+ printk(KERN_WARNING DRV_NAME": Revision 0x10, workarounds activated.\n"); -+ } -+ -+ return 0; -+} -+ -+/** -+ * it821x_port_stop - port shutdown -+ * @ap: ATA port being removed -+ * -+ * Release the private objects we added in it821x_port_start -+ */ -+ -+static void it821x_port_stop(struct ata_port *ap) { -+ kfree(ap->private_data); -+ ap->private_data = NULL; /* We want an OOPS if we reuse this -+ too late! */ -+ ata_port_stop(ap); -+} -+ -+static struct scsi_host_template it821x_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ /* 255 sectors to begin with. This is locked in smart mode but not -+ in pass through */ -+ .max_sectors = 255, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations it821x_smart_port_ops = { -+ .set_mode = it821x_smart_set_mode, -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .check_atapi_dma= it821x_check_atapi_dma, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = it821x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = it821x_port_start, -+ .port_stop = it821x_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations it821x_passthru_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = it821x_passthru_set_piomode, -+ .set_dmamode = it821x_passthru_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .check_atapi_dma= it821x_check_atapi_dma, -+ .dev_select = it821x_passthru_dev_select, -+ -+ .phy_reset = it821x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = it821x_passthru_bmdma_start, -+ .bmdma_stop = it821x_passthru_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = it821x_passthru_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ .irq_handler = ata_interrupt, -+ .port_start = it821x_port_start, -+ .port_stop = it821x_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static void __devinit it821x_disable_raid(struct pci_dev *pdev) -+{ -+ /* Reset local CPU, and set BIOS not ready */ -+ pci_write_config_byte(pdev, 0x5E, 0x01); -+ -+ /* Set to bypass mode, and reset PCI bus */ -+ pci_write_config_byte(pdev, 0x50, 0x00); -+ pci_write_config_word(pdev, PCI_COMMAND, -+ PCI_COMMAND_PARITY | PCI_COMMAND_IO | -+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); -+ pci_write_config_word(pdev, 0x40, 0xA0F3); -+ -+ pci_write_config_dword(pdev,0x4C, 0x02040204); -+ pci_write_config_byte(pdev, 0x42, 0x36); -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0); -+} -+ -+ -+static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ u8 conf; -+ -+ static struct ata_port_info info_smart = { -+ .sht = &it821x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &it821x_smart_port_ops -+ }; -+ static struct ata_port_info info_passthru = { -+ .sht = &it821x_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &it821x_passthru_port_ops -+ }; -+ static struct ata_port_info *port_info[2]; -+ -+ static char *mode[2] = { "pass through", "smart" }; -+ -+ /* Force the card into bypass mode if so requested */ -+ if (it8212_noraid) { -+ printk(KERN_INFO DRV_NAME ": forcing bypass mode.\n"); -+ it821x_disable_raid(pdev); -+ } -+ pci_read_config_byte(pdev, 0x50, &conf); -+ conf &= 1; -+ -+ printk(KERN_INFO DRV_NAME ": controller in %s mode.\n", mode[conf]); -+ if (conf == 0) -+ port_info[0] = port_info[1] = &info_passthru; -+ else -+ port_info[0] = port_info[1] = &info_smart; -+ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static struct pci_device_id it821x[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212), }, -+ { 0, }, -+}; -+ -+static struct pci_driver it821x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = it821x, -+ .probe = it821x_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init it821x_init(void) -+{ -+ return pci_register_driver(&it821x_pci_driver); -+} -+ -+ -+static void __exit it821x_exit(void) -+{ -+ pci_unregister_driver(&it821x_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for the IT8211/IT8212 IDE RAID controller"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, it821x); -+MODULE_VERSION(DRV_VERSION); -+ -+ -+module_param_named(noraid, it8212_noraid, int, S_IRUGO); -+MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode"); -+ -+module_init(it821x_init); -+module_exit(it821x_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_legacy.c linux-2.6.16-rc4/drivers/scsi/pata_legacy.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_legacy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_legacy.c 2006-02-16 15:33:52.000000000 +0000 -@@ -0,0 +1,672 @@ -+ -+/* -+ * pata-legacy.c - Legacy port PATA/SATA controller driver. -+ * Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * An ATA driver for the legacy ATA ports. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/ata.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "legacy" -+#define DRV_VERSION "0.3.1" -+ -+#define NR_HOST 6 -+ -+static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; -+static int legacy_irq[NR_HOST] = { 15, 14, 11, 10, 8, 12 }; -+ -+static struct ata_host_set *legacy_host[NR_HOST]; -+static int nr_legacy_host; -+static int legacy_all; -+static int ht6560a; -+static int ht6560b; -+static int opti82c611a; -+ -+/** -+ * legacy_set_mode - mode setting -+ * @ap: IDE interface -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. -+ * -+ * The BIOS configured everything. Our job is not to fiddle. Just use -+ * whatever PIO the hardware is using and leave it at that. When we -+ * get some kind of nice user driven API for control then we can -+ * expand on this as per hdparm in the base kernel. -+ */ -+ -+static void legacy_set_mode(struct ata_port *ap) -+{ -+ int i; -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ dev->pio_mode = XFER_PIO_0; -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ } -+} -+ -+static struct scsi_host_template legacy_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations legacy_port_ops = { -+ .set_mode = legacy_set_mode, -+ -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer_noirq, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Promise 20230C and 20620 support -+ * -+ * This controller supports PIO0 to PIO2. We set PIO timings conservatively to -+ * allow for 50MHz Vesa Local Bus. The 20620 DMA support is weird being DMA to -+ * controller and PIO'd to the host and not supported. -+ */ -+ -+static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ int tries = 5; -+ int pio = adev->pio_mode - XFER_PIO_0; -+ u8 rt; -+ -+ do -+ { -+ inb(0x1F5); -+ outb(inb(0x1F2) | 0x80, 0x1F2); -+ inb(0x1F2); -+ inb(0x3F6); -+ inb(0x3F6); -+ inb(0x1F2); -+ inb(0x1F2); -+ } -+ while((inb(0x1F2) & 0x80) && --tries); -+ -+ outb(inb(0x1F4) & 0x07, 0x1F4); -+ -+ rt = inb(0x1F3); -+ rt &= 0x07 << (3 * adev->devno); -+ rt |= (3 * pio) << (3 * adev->devno); -+ -+ udelay(100); -+ outb(inb(0x1F2) | 0x01, 0x1F2); -+ udelay(100); -+ inb(0x1F5); -+ -+} -+ -+static void pdc_data_xfer_vlb(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) -+{ -+ int slop = buflen & 3; -+ unsigned long flags; -+ -+ if (ata_id_has_dword_io(adev->id)) { -+ local_irq_save(flags); -+ -+ /* Perform the 32bit I/O synchronization sequence */ -+ inb(ap->ioaddr.nsect_addr); -+ inb(ap->ioaddr.nsect_addr); -+ inb(ap->ioaddr.nsect_addr); -+ -+ /* Now the data */ -+ -+ if (write_data) -+ outsl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ else -+ insl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ -+ if (unlikely(slop)) { -+ u32 pad; -+ if (write_data) { -+ memcpy(&pad, buf + buflen - slop, slop); -+ outl(le32_to_cpu(pad), ap->ioaddr.data_addr); -+ } else { -+ pad = cpu_to_le16(inl(ap->ioaddr.data_addr)); -+ memcpy(buf + buflen - slop, &pad, slop); -+ } -+ } -+ local_irq_restore(flags); -+ } -+ else -+ ata_pio_data_xfer_noirq(ap, adev, buf, buflen, write_data); -+} -+ -+static struct ata_port_operations pdc20230_port_ops = { -+ .set_piomode = pdc20230_set_piomode, -+ -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = pdc_data_xfer_vlb, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Holtek 6560A support -+ * -+ * This controller supports PIO0 to PIO2 (no IORDY even though higher timings -+ * can be loaded). -+ */ -+ -+static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ u8 active, recover; -+ struct ata_timing t; -+ -+ /* Get the timing data in cycles. For now play safe at 50Mhz */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); -+ -+ active = FIT(t.active, 2, 15); -+ recover = FIT(t.recover, 4, 15); -+ -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ -+ outb(recover << 4 | active, ap->ioaddr.device_addr); -+ inb(ap->ioaddr.status_addr); -+} -+ -+static struct ata_port_operations ht6560a_port_ops = { -+ .set_piomode = ht6560a_set_piomode, -+ -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, /* Check vlb/noirq */ -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Holtek 6560B support -+ * -+ * This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO setting -+ * unless we see an ATAPI device in which case we force it off. -+ * -+ * FIXME: need to implement 2nd channel support. -+ */ -+ -+static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ u8 active, recover; -+ struct ata_timing t; -+ -+ /* Get the timing data in cycles. For now play safe at 50Mhz */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); -+ -+ active = FIT(t.active, 2, 15); -+ recover = FIT(t.recover, 2, 16); -+ recover &= 0x15; -+ -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ inb(0x3E6); -+ -+ outb(recover << 4 | active, ap->ioaddr.device_addr); -+ -+ if (adev->class != ATA_DEV_ATA) { -+ u8 rconf = inb(0x3E6); -+ if (rconf & 0x24) { -+ rconf &= ~ 0x24; -+ outb(rconf, 0x3E6); -+ } -+ } -+ inb(ap->ioaddr.status_addr); -+} -+ -+static struct ata_port_operations ht6560b_port_ops = { -+ .set_piomode = ht6560b_set_piomode, -+ -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, /* FIXME: Check 32bit and noirq */ -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/* -+ * Opti 82C611A -+ * -+ * This controller supports PIO0 to PIO3. -+ */ -+ -+static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ u8 active, recover, setup; -+ struct ata_timing t; -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ int clock; -+ int khz[4] = { 50000, 40000, 33000, 25000 }; -+ u8 rc; -+ -+ /* Enter configuration mode */ -+ inb(ap->ioaddr.error_addr); -+ inb(ap->ioaddr.error_addr); -+ -+ /* Read VLB clock strapping */ -+ clock = 1000000000 / khz[inb(ap->ioaddr.lbah_addr) & 0x03]; -+ -+ /* Get the timing data in cycles */ -+ ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000); -+ -+ /* Setup timing is shared */ -+ if (pair) { -+ struct ata_timing tp; -+ ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000); -+ -+ ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); -+ } -+ -+ active = FIT(t.active, 2, 17) - 2; -+ recover = FIT(t.recover, 1, 16) - 1; -+ setup = FIT(t.setup, 1, 4) - 1; -+ -+ /* Select the right timing bank for write timing */ -+ rc = inb(ap->ioaddr.lbal_addr); -+ rc &= 0x7F; -+ rc |= (adev->devno << 7); -+ outb(rc, ap->ioaddr.lbal_addr); -+ -+ /* Write the timings */ -+ outb(active << 4 | recover, ap->ioaddr.error_addr); -+ -+ /* Select the right bank for read timings, also -+ load the shared timings for address */ -+ rc = inb(ap->ioaddr.device_addr); -+ rc &= 0xC0; -+ rc |= adev->devno; /* Index select */ -+ rc |= (setup << 4) | 0x04; -+ outb(rc, ap->ioaddr.device_addr); -+ -+ /* Load the read timings */ -+ outb(active << 4 | recover, ap->ioaddr.data_addr); -+ -+ /* Ensure the timing register mode is right */ -+ rc = inb (ap->ioaddr.lbal_addr); -+ rc &= 0x73; -+ rc |= 0x84; -+ outb(rc, ap->ioaddr.lbal_addr); -+ -+ /* Exit command mode */ -+ outb(0x82, ap->ioaddr.nsect_addr); -+} -+ -+static struct ata_port_operations opti82c611a_port_ops = { -+ .set_piomode = opti82c611a_set_piomode, -+ -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * legacy_init_one - attach a legacy interface -+ * @io: I/O port start -+ * @ctrl: control port -+ * @irq: interrupt line -+ * -+ * Register an ISA bus IDE interface. Such interfaces are PIO and we -+ * assume do not support IRQ sharing. -+ */ -+ -+static __init int legacy_init_one(unsigned long io, unsigned long ctrl, int irq) -+{ -+ struct ata_probe_ent ae; -+ int ret; -+ struct ata_port_operations *ops = &legacy_port_ops; -+ int pio_mask = 0x1F; -+ -+ if (request_region(io, 8, "pata_legacy") == NULL) -+ return -EBUSY; -+ if (request_region(ctrl, 1, "pata_legacy") == NULL) { -+ release_region(io, 8); -+ return -EBUSY; -+ } -+ -+ if (ht6560a == 1 && (io == 0x1F0 || io == 0x170)) { -+ ops = &ht6560a_port_ops; -+ pio_mask = 0x07; -+ } -+ if (ht6560b == 1 && (io == 0x1F0 || io == 0x170)) { -+ ops = &ht6560b_port_ops; -+ pio_mask = 0x1F; -+ } -+ if (opti82c611a == 1 && (io == 0x1F0 || io == 0x170)) { -+ ops = &opti82c611a_port_ops; -+ pio_mask = 0x0F; -+ } -+ else if (io == 0x1F0) { -+ /* Probes */ -+ inb(0x1F5); -+ outb(inb(0x1F2) | 0x80, 0x1F2); -+ inb(0x1F2); -+ inb(0x3F6); -+ inb(0x3F6); -+ inb(0x1F2); -+ inb(0x1F2); -+ -+ if ((inb(0x1F2) & 0x80) == 0) { -+ /* PDC20230 or 20630 ? */ -+ printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller detected.\n"); -+ pio_mask = 0x07; -+ ops = &pdc20230_port_ops; -+ udelay(100); -+ inb(0x1F5); -+ } else { -+ outb(0x55, 0x1F2); -+ inb(0x1F2); -+ inb(0x1F2); -+ if (inb(0x1F2) == 0x00) { -+ printk(KERN_INFO "PDC20230-B VLB ATA controller detected.\n"); -+ } -+ } -+ } -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = NULL; -+ ae.port_ops = ops; -+ ae.sht = &legacy_sht; -+ ae.n_ports = 1; -+ ae.pio_mask = pio_mask; -+ ae.irq = irq; -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = io; -+ ae.port[0].altstatus_addr = ctrl; -+ ae.port[0].ctl_addr = ctrl; -+ ata_std_ports(&ae.port[0]); -+ -+ ret = ata_device_add(&ae); -+ if (ret == 0) -+ return -ENODEV; -+ -+ legacy_host[nr_legacy_host++] = ae.host_set; -+ return 0; -+} -+ -+/** -+ * legacy_check_special_cases - ATA special cases -+ * @p: PCI device to check -+ * @master: set this if we find an ATA master -+ * @master: set this if we find an ATA secondary -+ * -+ * A small number of vendors implemented early PCI ATA interfaces on bridge logic -+ * without the ATA interface being PCI visible. Where we have a matching PCI driver -+ * we must skip the relevant device here. If we don't know about it then the legacy -+ * driver is the right driver anyway. -+ */ -+ -+static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *secondary) -+{ -+ /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */ -+ if (p->vendor == 0x1078 && p->device == 0x0000) { -+ *primary = *secondary = 1; -+ return; -+ } -+ /* Cyrix CS5520 pre SFF MWDMA ATA on the bridge */ -+ if (p->vendor == 0x1078 && p->device == 0x0002) { -+ *primary = *secondary = 1; -+ return; -+ } -+ /* Intel MPIIX - PIO ATA on non PCI side of bridge */ -+ if (p->vendor == 0x8086 && p->device == 0x1234) { -+ u16 r; -+ pci_read_config_word(p, 0x6C, &r); -+ if (r & 0x8000) { /* ATA port enabled */ -+ if (r & 0x4000) -+ *secondary = 1; -+ else -+ *primary = 1; -+ } -+ return; -+ } -+} -+ -+/** -+ * legacy_init - attach legacy interfaces -+ * -+ * Attach legacy IDE interfaces by scanning the usual IRQ/port suspects. -+ * Right now we do not scan the ide0 and ide1 address but should do so -+ * for non PCI systems or systems with no PCI IDE legacy mode devices. -+ * If you fix that note there are special cases to consider like VLB -+ * drivers and CS5510/20. -+ */ -+ -+static __init int legacy_init(void) -+{ -+ int i; -+ int ct = 0; -+ int primary = 0; -+ int secondary = 0; -+ int last_port = NR_HOST; -+ -+ struct pci_dev *p = NULL; -+ -+ for_each_pci_dev(p) { -+ int r; -+ /* Check for any overlap of the system ATA mappings. Native mode controllers -+ stuck on these addresses or some devices in 'raid' mode won't be found by -+ the storage class test */ -+ for (r = 0; r < 6; r++) { -+ if (pci_resource_start(p, r) == 0x1f0) -+ primary = 1; -+ if (pci_resource_start(p, r) == 0x170) -+ secondary = 1; -+ } -+ /* Check for special cases */ -+ legacy_check_special_cases(p, &primary, &secondary); -+ -+ /* If PCI bus is present then don't probe for tertiary legacy ports */ -+ if (legacy_all == 0) -+ last_port = 2; -+ } -+ -+ -+ for (i = 0; i < last_port; i++) { -+ /* Skip primary if we have seen a PCI one */ -+ if (i == 0 && primary == 1) -+ continue; -+ /* Skip secondary if we have seen a PCI one */ -+ if (i == 1 && secondary == 1) -+ continue; -+ if (legacy_init_one(legacy_port[i], -+ legacy_port[i] + 0x0206, -+ legacy_irq[i]) == 0) -+ ct++; -+ } -+ if (ct != 0) -+ return 0; -+ return -ENODEV; -+} -+ -+static __exit void legacy_exit(void) -+{ -+ int i; -+ -+ for (i = 0; i < nr_legacy_host; i++) { -+ struct ata_port *ap =legacy_host[i]->ports[0]; -+ unsigned long io = ap->ioaddr.cmd_addr; -+ unsigned long ctrl = ap->ioaddr.ctl_addr; -+ ata_host_set_remove(legacy_host[i]); -+ release_region(io, 8); -+ release_region(ctrl, 1); -+ } -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for legacy ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+/** -+ * legacy_probe_all - setup argument handler -+ * @unused: unused -+ * -+ * Called when the probe_all argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_probe_all(char *unused) -+{ -+ legacy_all = 1; -+ return 1; -+} -+ -+__setup("probe-all", legacy_probe_all); -+ -+/** -+ * legacy_ht6560a - setup argument handler -+ * @unused: unused -+ * -+ * Called when the ht6560a argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_ht6560a(char *unused) -+{ -+ ht6560a = 1; -+ return 1; -+} -+ -+__setup("ht6560a", legacy_ht6560a); -+ -+/** -+ * legacy_ht6560b - setup argument handler -+ * @unused: unused -+ * -+ * Called when the ht6560b argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_ht6560b(char *unused) -+{ -+ ht6560b = 1; -+ return 1; -+} -+ -+__setup("ht6560b", legacy_ht6560b); -+ -+/** -+ * legacy_ht6560a - setup argument handler -+ * @unused: unused -+ * -+ * Called when the ht6560a argument is passed to this driver. This indicates -+ * that we should check all the legacy ATA addresses even if PCI is present. Should -+ * only ever be needed on very strange PCI/legacy combinations -+ */ -+ -+static int __init legacy_opti82c611a(char *unused) -+{ -+ opti82c611a = 1; -+ return 1; -+} -+ -+__setup("opti82c611a", legacy_opti82c611a); -+ -+module_init(legacy_init); -+module_exit(legacy_exit); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_mpiix.c linux-2.6.16-rc4/drivers/scsi/pata_mpiix.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_mpiix.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_mpiix.c 2006-02-16 15:38:41.000000000 +0000 -@@ -0,0 +1,303 @@ -+/* -+ * pata_mpiix.c - Intel MPIIX PATA for new ATA layer -+ * (C) 2005-2006 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * The MPIIX is different enough to the PIIX4 and friends that we give it -+ * a separate driver. The old ide/pci code handles this by just not tuning -+ * MPIIX at all. -+ * -+ * The MPIIX also differs in another important way from the majority of PIIX -+ * devices. The chip is a bridge (pardon the pun) between the old world of -+ * ISA IDE and PCI IDE. Although the ATA timings are PCI configured the actual -+ * IDE controller is not decoded in PCI space and the chip does not claim to -+ * be IDE class PCI. This requires slightly non-standard probe logic compared -+ * with PCI IDE and also that we do not disable the device when our driver is -+ * unloaded (as it has many other functions). -+ * -+ * The driver conciously keeps this logic internally to avoid pushing quirky -+ * PATA history into the clean libata layer. -+ * -+ * Thinkpad specific note: If you boot an MPIIX using thinkpad with a PCMCIA -+ * hard disk present this driver will not detect it. This is not a bug. In this -+ * configuration the secondary port of the MPIIX is disabled and the addresses -+ * are decoded by the PCMCIA bridge and therefore are for a generic IDE driver -+ * to operate. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_mpiix" -+#define DRV_VERSION "0.4" -+ -+/** -+ * mpiix_phy_reset - probe reset -+ * @ap: ATA port -+ * -+ * Perform the ATA probe and bus reset sequence plus specific handling -+ * for this hardware. The MPIIX has the enable bits in a different place -+ * to PIIX4 and friends. As a pure PIO device it has no cable detect -+ */ -+ -+static void mpiix_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits mpiix_enable_bits[] = { -+ { 0x6D, 1, 0x80, 0x80 }, -+ { 0x6F, 1, 0x80, 0x80 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * mpiix_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. The MPIIX allows us to program the -+ * IORDY sample point (2-5 clocks), recovery 1-4 clocks and whether -+ * prefetching or iordy are used. -+ * -+ * This would get very ugly because we can only program timing for one -+ * device at a time, the other gets PIO0. Fortunately libata calls -+ * our qc_issue_prot command before a command is issued so we can -+ * flip the timings back and forth to reduce the pain. -+ */ -+ -+static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ int control = 0; -+ int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 idetim; -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ pci_read_config_word(pdev, 0x6C, &idetim); -+ /* Mask the IORDY/TIME/PPE0 bank for this device */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable for disk */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IORDY */ -+ if (pio > 0) -+ control |= 1; /* This drive is on the fast timing bank */ -+ -+ /* Mask out timing and clear both TIME bank selects */ -+ idetim &= 0xCCEE; -+ idetim &= ~(0x07 << (2 * adev->devno)); -+ idetim |= (control << (2 * adev->devno)); -+ -+ idetim |= (timings[pio][0] << 12) | (timings[pio][1] << 8); -+ pci_write_config_word(pdev, 0x6C, idetim); -+ -+ /* We use ap->private_data as a pointer to the device currently -+ loaded for timing */ -+ ap->private_data = adev; -+} -+ -+/** -+ * mpiix_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Our logic also clears TIME0/TIME1 for the other device so -+ * that, even if we get this wrong, cycles to the other device will -+ * be made PIO0. -+ */ -+ -+static int mpiix_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ /* If modes have been configured and the channel data is not loaded -+ then load it. We have to check if pio_mode is set as the core code -+ does not set adev->pio_mode to XFER_PIO_0 while probing as would be -+ logical */ -+ -+ if (adev->pio_mode && adev != ap->private_data) -+ mpiix_set_piomode(ap, adev); -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template mpiix_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations mpiix_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = mpiix_set_piomode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = mpiix_phy_reset, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = mpiix_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ /* Single threaded by the PCI probe logic */ -+ static struct ata_probe_ent probe[2]; -+ static int printed_version; -+ u16 idetim; -+ int enabled; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); -+ -+ /* MPIIX has many functions which can be turned on or off according -+ to other devices present. Make sure IDE is enabled before we try -+ and use it */ -+ -+ pci_read_config_word(dev, 0x6C, &idetim); -+ if (!(idetim & 0x8000)) -+ return -ENODEV; -+ -+ /* We do our own plumbing to avoid leaking special cases for whacko -+ ancient hardware into the core code. There are two issues to -+ worry about. #1 The chip is a bridge so if in legacy mode and -+ without BARs set fools the setup. #2 If you pci_disable_device -+ the MPIIX your box goes castors up */ -+ -+ INIT_LIST_HEAD(&probe[0].node); -+ probe[0].dev = pci_dev_to_dev(dev); -+ probe[0].port_ops = &mpiix_port_ops; -+ probe[0].sht = &mpiix_sht; -+ probe[0].pio_mask = 0x1F; -+ probe[0].irq = 14; -+ probe[0].irq_flags = SA_SHIRQ; -+ probe[0].host_flags = ATA_FLAG_SLAVE_POSS; -+ probe[0].legacy_mode = 1; -+ probe[0].hard_port_no = 0; -+ probe[0].n_ports = 1; -+ probe[0].port[0].cmd_addr = 0x1F0; -+ probe[0].port[0].ctl_addr = 0x3F6; -+ probe[0].port[0].altstatus_addr = 0x3F6; -+ -+ /* The secondary lurks at different addresses but is otherwise -+ the same beastie */ -+ -+ INIT_LIST_HEAD(&probe[1].node); -+ probe[1] = probe[0]; -+ probe[1].irq = 15; -+ probe[1].hard_port_no = 1; -+ probe[1].port[0].cmd_addr = 0x170; -+ probe[1].port[0].ctl_addr = 0x376; -+ probe[1].port[0].altstatus_addr = 0x376; -+ -+ /* Let libata fill in the port details */ -+ ata_std_ports(&probe[0].port[0]); -+ ata_std_ports(&probe[1].port[0]); -+ -+ /* Now add the port that is active */ -+ enabled = (idetim & 0x4000) ? 1 : 0; -+ -+ if (ata_device_add(&probe[enabled])) -+ return 0; -+ return -ENODEV; -+} -+ -+/** -+ * mpiix_remove_one - device unload -+ * @pdev: PCI device being removed -+ * -+ * Handle an unplug/unload event for a PCI device. Unload the -+ * PCI driver but do not use the default handler as we *MUST NOT* -+ * disable the device as it has other functions. -+ */ -+ -+static void __devexit mpiix_remove_one(struct pci_dev *pdev) -+{ -+ struct device *dev = pci_dev_to_dev(pdev); -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+} -+ -+ -+ -+static const struct pci_device_id mpiix[] = { -+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -+ { 0, }, -+}; -+ -+static struct pci_driver mpiix_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = mpiix, -+ .probe = mpiix_init_one, -+ .remove = mpiix_remove_one -+}; -+ -+static int __init mpiix_init(void) -+{ -+ return pci_register_driver(&mpiix_pci_driver); -+} -+ -+ -+static void __exit mpiix_exit(void) -+{ -+ pci_unregister_driver(&mpiix_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Intel MPIIX"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, mpiix); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(mpiix_init); -+module_exit(mpiix_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_netcell.c linux-2.6.16-rc4/drivers/scsi/pata_netcell.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_netcell.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_netcell.c 2006-02-08 14:05:57.000000000 +0000 -@@ -0,0 +1,176 @@ -+/* -+ * pata_netcell.c - Netcell PATA driver -+ * -+ * (c) 2006 Red Hat <alan@redhat.com> -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_netcell" -+#define DRV_VERSION "0.1" -+ -+/** -+ * netcell_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Cables are handled by the RAID controller. Report 80 pin. -+ */ -+ -+static int netcell_cable_detect(struct ata_port *ap) -+{ -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * netcell_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void netcell_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = netcell_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/* No PIO or DMA methods needed for this device */ -+ -+static struct scsi_host_template netcell_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ /* Special handling needed if you have sector or LBA48 limits */ -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ /* Use standard CHS mapping rules */ -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations netcell_ops = { -+ .port_disable = ata_port_disable, -+ -+ /* Task file is PCI ATA format, use helpers */ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = netcell_phy_reset, -+ -+ /* BMDMA handling is PCI ATA format, use helpers */ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, /* In -ac only right now */ -+ -+ /* Timeout handling. Special recovery hooks here */ -+ .eng_timeout = ata_eng_timeout, -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ /* Generic PATA PCI ATA helpers */ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * netcell_init_one - Register Netcell ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in netcell_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &netcell_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ /* Actually we don't really care about these as the -+ firmware deals with it */ -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = 0x3f, /* UDMA 133 */ -+ .port_ops = &netcell_ops, -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ /* Any chip specific setup/optimisation/messages here */ -+ ata_pci_clear_simplex(pdev); -+ -+ /* And let the library code do the work */ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id netcell_pci_tbl[] = { -+ { 0x169C, 0x0044, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver netcell_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = netcell_pci_tbl, -+ .probe = netcell_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init netcell_init(void) -+{ -+ return pci_register_driver(&netcell_pci_driver); -+} -+ -+static void __exit netcell_exit(void) -+{ -+ pci_unregister_driver(&netcell_pci_driver); -+} -+ -+ -+module_init(netcell_init); -+module_exit(netcell_exit); -+ -+MODULE_AUTHOR(""); -+MODULE_DESCRIPTION("SCSI low-level driver for Netcell PATA RAID"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, netcell_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ns87410.c linux-2.6.16-rc4/drivers/scsi/pata_ns87410.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_ns87410.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_ns87410.c 2006-02-15 15:05:43.000000000 +0000 -@@ -0,0 +1,213 @@ -+/* -+ * pata_ns87410.c - National Semiconductor 87410 PATA for new ATA layer -+ * (C) 2006 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_ns87410" -+#define DRV_VERSION "0.1" -+ -+/** -+ * ns87410_phy_reset - probe reset -+ * @ap: ATA port -+ * -+ * Perform the ATA probe and bus reset sequence plus specific handling -+ * for this hardware. The MPIIX has the enable bits in a different place -+ * to PIIX4 and friends. As a pure PIO device it has no cable detect -+ */ -+ -+static void ns87410_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits ns87410_enable_bits[] = { -+ { 0x43, 1, 0x08, 0x08 }, -+ { 0x47, 1, 0x08, 0x08 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * ns87410_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program timing data. This is kept per channel not per device, -+ * and only affects the data port. -+ */ -+ -+static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x40 + 4 * ap->hard_port_no; -+ u8 idetcr, idefr; -+ struct ata_timing at; -+ -+ static const u8 activebits[15] = { -+ 0, 1, 2, 3, 4, -+ 5, 5, 6, 6, 6, -+ 6, 7, 7, 7, 7 -+ }; -+ -+ static const u8 recoverbits[12] = { -+ 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 7, 7 -+ }; -+ -+ pci_read_config_byte(pdev, port + 3, &idefr); -+ -+ if (ata_pio_need_iordy(adev)) -+ idefr |= 0x04; /* IORDY enable */ -+ else -+ idefr &= ~0x04; -+ -+ if (ata_timing_compute(adev, adev->pio_mode, &at, 30303, 1) < 0) { -+ dev_printk(KERN_ERR, &pdev->dev, "unknown mode %d.\n", adev->pio_mode); -+ return; -+ } -+ -+ at.active = FIT(at.active, 2, 16) - 2; -+ at.setup = FIT(at.setup, 1, 4) - 1; -+ at.recover = FIT(at.recover, 1, 12) - 1; -+ -+ idetcr = (at.setup << 6) | (recoverbits[at.recover] << 3) | activebits[at.active]; -+ -+ pci_write_config_byte(pdev, port, idetcr); -+ pci_write_config_byte(pdev, port + 3, idefr); -+ /* We use ap->private_data as a pointer to the device currently -+ loaded for timing */ -+ ap->private_data = adev; -+} -+ -+/** -+ * ns87410_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Our logic also clears TIME0/TIME1 for the other device so -+ * that, even if we get this wrong, cycles to the other device will -+ * be made PIO0. -+ */ -+ -+static int ns87410_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ /* If modes have been configured and the channel data is not loaded -+ then load it. We have to check if pio_mode is set as the core code -+ does not set adev->pio_mode to XFER_PIO_0 while probing as would be -+ logical */ -+ -+ if (adev->pio_mode && adev != ap->private_data) -+ ns87410_set_piomode(ap, adev); -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template ns87410_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations ns87410_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = ns87410_set_piomode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = ns87410_phy_reset, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ns87410_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &ns87410_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x0F, -+ .port_ops = &ns87410_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = {&info, &info}; -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static const struct pci_device_id ns87410[] = { -+ { PCI_DEVICE(0x100B, 0xD001), }, -+ { 0, }, -+}; -+ -+static struct pci_driver ns87410_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = ns87410, -+ .probe = ns87410_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init ns87410_init(void) -+{ -+ return pci_register_driver(&ns87410_pci_driver); -+} -+ -+ -+static void __exit ns87410_exit(void) -+{ -+ pci_unregister_driver(&ns87410_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Nat Semi 87410"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, ns87410); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(ns87410_init); -+module_exit(ns87410_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_oldpiix.c linux-2.6.16-rc4/drivers/scsi/pata_oldpiix.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_oldpiix.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_oldpiix.c 2006-01-21 16:55:29.000000000 +0000 -@@ -0,0 +1,327 @@ -+/* -+ * pata_oldpiix.c - Intel PATA/SATA controllers -+ * -+ * (C) 2005 Red Hat <alan@redhat.com> -+ * -+ * Some parts based on ata_piix.c by Jeff Garzik and others. -+ * -+ * Early PIIX differs significantly from the later PIIX as it lacks -+ * SITRE and the slave timing registers. This means that you have to -+ * set timing per channel, or be clever. Libata tells us whenever it -+ * does drive selection and we use this to reload the timings. -+ * -+ * Because of these behaviour differences PIIX gets its own driver module. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_oldpiix" -+#define DRV_VERSION "0.3" -+ -+/** -+ * oldpiix_pata_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void oldpiix_pata_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits oldpiix_enable_bits[] = { -+ { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ -+ { 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * oldpiix_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set PIO mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void oldpiix_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ unsigned int idetm_port= ap->hard_port_no ? 0x42 : 0x40; -+ u16 idetm_data; -+ int control = 0; -+ -+ /* -+ * See Intel Document 298600-004 for the timing programing rules -+ * for PIIX/ICH. Note that the early PIIX does not have the slave -+ * timing port at 0x44. -+ */ -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ if (pio > 2) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IE IORDY */ -+ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ -+ pci_read_config_word(dev, idetm_port, &idetm_data); -+ -+ /* Enable PPE, IE and TIME as appropriate. Clear the other -+ drive timing bits */ -+ if (adev->devno == 0) { -+ idetm_data &= 0xCCE0; -+ idetm_data |= control; -+ } else { -+ idetm_data &= 0xCC0E; -+ idetm_data |= (control << 4); -+ } -+ idetm_data |= (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ pci_write_config_word(dev, idetm_port, idetm_data); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * oldpiix_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * @isich: True if the device is an ICH and has IOCFG registers -+ * -+ * Set MWDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void oldpiix_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ u8 idetm_port = ap->hard_port_no ? 0x42 : 0x40; -+ u16 idetm_data; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 0 }, -+ { 2, 1 }, -+ { 2, 3 }, }; -+ -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally along with TIME1. PPE has already -+ * been set when the PIO timing was set. -+ */ -+ -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ unsigned int control; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ -+ pci_read_config_word(dev, idetm_port, &idetm_data); -+ -+ control = 3; /* IORDY|TIME0 */ -+ /* Intel specifies that the PPE functionality is for disk only */ -+ if (adev->class == ATA_DEV_ATA) -+ control |= 4; /* PPE enable */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO into PIO0 */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ /* Enable DMA timing only */ -+ control |= 8; /* PIO cycles in PIO0 */ -+ -+ /* Mask out the relevant control and timing bits we will load. Also -+ clear the other drive TIME register as a precaution */ -+ if (adev->devno == 0) { -+ idetm_data &= 0xCCE0; -+ idetm_data |= control; -+ } else { -+ idetm_data &= 0xCC0E; -+ idetm_data |= (control << 4); -+ } -+ idetm_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8); -+ pci_write_config_word(dev, idetm_port, idetm_data); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * oldpiix_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Our logic also clears TIME0/TIME1 for the other device so -+ * that, even if we get this wrong, cycles to the other device will -+ * be made PIO0. -+ */ -+ -+static int oldpiix_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ if (adev != ap->private_data) { -+ if (adev->dma_mode) -+ oldpiix_set_dmamode(ap, adev); -+ else if (adev->pio_mode) -+ oldpiix_set_piomode(ap, adev); -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+ -+static struct scsi_host_template oldpiix_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations oldpiix_pata_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = oldpiix_set_piomode, -+ .set_dmamode = oldpiix_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = oldpiix_pata_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = oldpiix_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * oldpiix_init_one - Register PIIX ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in oldpiix_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. We probe for combined mode (sigh), -+ * and then hand over control to libata, for it to do the rest. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &oldpiix_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .port_ops = &oldpiix_pata_ops, -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id oldpiix_pci_tbl[] = { -+ { 0x8086, 0x1230, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver oldpiix_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = oldpiix_pci_tbl, -+ .probe = oldpiix_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init oldpiix_init(void) -+{ -+ return pci_register_driver(&oldpiix_pci_driver); -+} -+ -+static void __exit oldpiix_exit(void) -+{ -+ pci_unregister_driver(&oldpiix_pci_driver); -+} -+ -+ -+module_init(oldpiix_init); -+module_exit(oldpiix_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for early PIIX series controllers"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, oldpiix_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_opti.c linux-2.6.16-rc4/drivers/scsi/pata_opti.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_opti.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_opti.c 2006-02-16 15:38:28.000000000 +0000 -@@ -0,0 +1,268 @@ -+/* -+ * pata_opti.c - ATI PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based on -+ * linux/drivers/ide/pci/opti621.c Version 0.7 Sept 10, 2002 -+ * -+ * Copyright (C) 1996-1998 Linus Torvalds & authors (see below) -+ * -+ * Authors: -+ * Jaromir Koutek <miri@punknet.cz>, -+ * Jan Harkes <jaharkes@cwi.nl>, -+ * Mark Lord <mlord@pobox.com> -+ * Some parts of code are from ali14xx.c and from rz1000.c. -+ * -+ * Also consulted the FreeBSD prototype driver by Kevin Day to try -+ * and resolve some confusions. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_opti" -+#define DRV_VERSION "0.1.2" -+ -+enum { -+ READ_REG = 0, /* index of Read cycle timing register */ -+ WRITE_REG = 1, /* index of Write cycle timing register */ -+ CNTRL_REG = 3, /* index of Control register */ -+ STRAP_REG = 5, /* index of Strap register */ -+ MISC_REG = 6 /* index of Miscellaneous register */ -+}; -+ -+/** -+ * opti_phy_reset - probe reset -+ * @ap: ATA port -+ * -+ * Perform the ATA probe and bus reset sequence plus specific handling -+ * for this hardware. The Opti needs little handling - we have no UDMA66 -+ * capability that needs cable detection. All we must do is check the port -+ * is enabled. -+ */ -+ -+static void opti_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static const struct pci_bits opti_enable_bits[] = { -+ { 0x45, 1, 0x80, 0x00 }, -+ { 0x45, 1, 0x08, 0x00 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * opti_write_reg - control register setup -+ * @ap: ATA port -+ * @value: value -+ * @reg: control register number -+ * -+ * The Opti uses magic 'trapdoor' register accesses to do configuration -+ * rather than using PCI space as other controllers do. The double inw -+ * on the error register activates configuration mode. We can then write -+ * the control register -+ */ -+ -+static void opti_write_reg(struct ata_port *ap, u8 val, int reg) -+{ -+ unsigned long regio = ap->ioaddr.cmd_addr; -+ inw(regio + 1); -+ inw(regio + 1); -+ outb(3, regio + 2); -+ outb(val, regio + reg); -+ outb(0x83, regio + 2); -+} -+ -+#if 0 -+/** -+ * opti_read_reg - control register read -+ * @ap: ATA port -+ * @reg: control register number -+ * -+ * The Opti uses magic 'trapdoor' register accesses to do configuration -+ * rather than using PCI space as other controllers do. The double inw -+ * on the error register activates configuration mode. We can then read -+ * the control register -+ */ -+ -+static u8 opti_read_reg(struct ata_port *ap, int reg) -+{ -+ unsigned long regio = ap->ioaddr.cmd_addr; -+ u8 ret; -+ inw(regio + 1); -+ inw(regio + 1); -+ outb(3, regio + 2); -+ ret = inb(regio + reg); -+ outb(0x83, regio + 2); -+} -+#endif -+ -+/** -+ * opti_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. Timing numbers are taken from -+ * the FreeBSD driver then pre computed to keep the code clean. There -+ * are two tables depending on the hardware clock speed. -+ */ -+ -+static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ int clock; -+ int pio = adev->pio_mode - XFER_PIO_0; -+ unsigned long regio = ap->ioaddr.cmd_addr; -+ u8 addr; -+ -+ /* Address table precomputed with prefetch off and a DCLK of 2 */ -+ static const u8 addr_timing[2][5] = { -+ { 0x30, 0x20, 0x20, 0x10, 0x10 }, -+ { 0x20, 0x20, 0x10, 0x10, 0x10 } -+ }; -+ static const u8 data_rec_timing[2][5] = { -+ { 0x6B, 0x56, 0x42, 0x32, 0x31 }, -+ { 0x58, 0x44, 0x32, 0x22, 0x21 } -+ }; -+ -+ outb(0xff, regio + 5); -+ clock = inw(regio + 5) & 1; -+ -+ /* -+ * As with many controllers the address setup time is shared -+ * and must suit both devices if present. -+ */ -+ -+ addr = addr_timing[clock][pio]; -+ if (pair) { -+ /* Hardware constraint */ -+ u8 pair_addr = addr_timing[clock][pair->pio_mode - XFER_PIO_0]; -+ if (pair_addr > addr) -+ addr = pair_addr; -+ } -+ -+ /* Commence primary programming sequence */ -+ opti_write_reg(ap, adev->devno, MISC_REG); -+ opti_write_reg(ap, data_rec_timing[clock][pio], READ_REG); -+ opti_write_reg(ap, data_rec_timing[clock][pio], WRITE_REG); -+ opti_write_reg(ap, addr, MISC_REG); -+ -+ /* Programming sequence complete, override strapping */ -+ opti_write_reg(ap, 0x85, CNTRL_REG); -+} -+ -+static struct scsi_host_template opti_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations opti_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = opti_set_piomode, -+/* .set_dmamode = opti_set_dmamode, */ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = opti_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &opti_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &opti_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ static int printed_version; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static const struct pci_device_id opti[] = { -+ { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { 0, }, -+}; -+ -+static struct pci_driver opti_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = opti, -+ .probe = opti_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init opti_init(void) -+{ -+ return pci_register_driver(&opti_pci_driver); -+} -+ -+ -+static void __exit opti_exit(void) -+{ -+ pci_unregister_driver(&opti_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Opti 621/621X"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, opti); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(opti_init); -+module_exit(opti_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pcmcia.c linux-2.6.16-rc4/drivers/scsi/pata_pcmcia.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_pcmcia.c 2006-02-20 17:26:30.000000000 +0000 -@@ -0,0 +1,406 @@ -+/* -+ * pata-pcmcia.c - PCMCIA PATA controller driver. -+ * Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved. -+ * -+ * Heavily based upon ide-cs.c -+ * The initial developer of the original code is David A. Hinds -+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds -+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/ata.h> -+#include <linux/libata.h> -+ -+#include <pcmcia/cs_types.h> -+#include <pcmcia/cs.h> -+#include <pcmcia/cistpl.h> -+#include <pcmcia/ds.h> -+#include <pcmcia/cisreg.h> -+#include <pcmcia/ciscode.h> -+ -+ -+#define DRV_NAME "pata_pcmcia" -+#define DRV_VERSION "0.1" -+ -+/* -+ * Private data structure to glue stuff together -+ */ -+ -+struct ata_pcmcia_info { -+ dev_link_t link; -+ int ndev; -+ dev_node_t node; -+}; -+ -+static struct scsi_host_template pcmcia_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations pcmcia_port_ops = { -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+#define CS_CHECK(fn, ret) \ -+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -+ -+/** -+ * pcmcia_init_one - attach an pcmcia interface -+ * @pdev: pcmcia device -+ * -+ * Register a PCMCIA IDE interface. Such interfaces are PIO 0 and -+ * non shared IRQ. -+ */ -+ -+static int pcmcia_init_one(struct pcmcia_device *pdev) -+{ -+ struct ata_probe_ent ae; -+ dev_link_t *link; -+ struct ata_pcmcia_info *info; -+ client_handle_t handle; -+ tuple_t tuple; -+ struct { -+ unsigned short buf[128]; -+ cisparse_t parse; -+ config_info_t conf; -+ cistpl_cftable_entry_t dflt; -+ } *stk = NULL; -+ cistpl_cftable_entry_t *cfg; -+ int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM; -+ unsigned long io_base, ctl_base; -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (info == NULL) -+ return -ENOMEM; -+ -+ link = &info->link; -+ link->priv = info; -+ -+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; -+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; -+ link->io.IOAddrLines = 3; -+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; -+ link->irq.IRQInfo1 = IRQ_LEVEL_ID; -+ link->conf.Attributes = CONF_ENABLE_IRQ; -+ link->conf.Vcc = 50; -+ link->conf.IntType = INT_MEMORY_AND_IO; -+ -+ link->handle = pdev; -+ pdev->instance = link; -+ -+ handle = link->handle; -+ -+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -+ -+ stk = kzalloc(sizeof(*stk), GFP_KERNEL); -+ if (!stk) -+ goto out1; -+ -+ cfg = &stk->parse.cftable_entry; -+ -+ tuple.TupleData = (cisdata_t *)&stk->buf; -+ tuple.TupleOffset = 0; -+ tuple.TupleDataMax = 255; -+ tuple.Attributes = 0; -+ tuple.DesiredTuple = CISTPL_CONFIG; -+ -+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); -+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); -+ CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse)); -+ link->conf.ConfigBase = stk->parse.config.base; -+ link->conf.Present = stk->parse.config.rmask[0]; -+ -+ tuple.DesiredTuple = CISTPL_MANFID; -+ if (!pcmcia_get_first_tuple(handle, &tuple) && !pcmcia_get_tuple_data(handle, &tuple) && !pcmcia_parse_tuple(handle, &tuple, &stk->parse)) -+ is_kme = ((stk->parse.manfid.manf == MANFID_KME) && ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); -+ -+ /* Configure card */ -+ link->state |= DEV_CONFIG; -+ -+ /* Not sure if this is right... look up the current Vcc */ -+ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf)); -+ link->conf.Vcc = stk->conf.Vcc; -+ -+ pass = io_base = ctl_base = 0; -+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; -+ tuple.Attributes = 0; -+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); -+ -+ while (1) { -+ if (pcmcia_get_tuple_data(handle, &tuple) != 0) -+ goto next_entry; -+ if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) -+ goto next_entry; -+ /* Check for matching Vcc, unless we're desperate */ -+ if (!pass) { -+ if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { -+ if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) -+ goto next_entry; -+ } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { -+ if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) -+ goto next_entry; -+ } -+ } -+ -+ if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) -+ link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; -+ else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) -+ link->conf.Vpp1 = link->conf.Vpp2 = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; -+ -+ if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { -+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; -+ link->conf.ConfigIndex = cfg->index; -+ link->io.BasePort1 = io->win[0].base; -+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; -+ if (!(io->flags & CISTPL_IO_16BIT)) -+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; -+ if (io->nwin == 2) { -+ link->io.NumPorts1 = 8; -+ link->io.BasePort2 = io->win[1].base; -+ link->io.NumPorts2 = (is_kme) ? 2 : 1; -+ if (pcmcia_request_io(link->handle, &link->io) != 0) -+ goto next_entry; -+ io_base = link->io.BasePort1; -+ ctl_base = link->io.BasePort2; -+ } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { -+ link->io.NumPorts1 = io->win[0].len; -+ link->io.NumPorts2 = 0; -+ if (pcmcia_request_io(link->handle, &link->io) != 0) -+ goto next_entry; -+ io_base = link->io.BasePort1; -+ ctl_base = link->io.BasePort1 + 0x0e; -+ } else goto next_entry; -+ /* If we've got this far, we're done */ -+ break; -+ } -+next_entry: -+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT) -+ memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); -+ if (pass) { -+ CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); -+ } else if (pcmcia_get_next_tuple(handle, &tuple) != 0) { -+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); -+ memset(&stk->dflt, 0, sizeof(stk->dflt)); -+ pass++; -+ } -+ } -+ -+ if (is_kme) -+ outb(0x81, ctl_base + 0x01); -+ -+ /* FIXME: Could be more ports at base + 0x10 but we only deal with -+ one right now */ -+ -+ if (link->io.NumPorts1 >= 0x20) -+ printk(KERN_WARNING DRV_NAME ": second channel not yet supported.\n"); -+ -+ /* -+ * Having done the PCMCIA plumbing the ATA side is relatively -+ * sane. -+ */ -+ -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = &pdev->dev; -+ ae.port_ops = &pcmcia_port_ops; -+ ae.sht = &pcmcia_sht; -+ ae.n_ports = 1; -+ ae.pio_mask = 1; /* ISA so PIO 0 cycles */ -+ ae.irq = link->irq.AssignedIRQ; -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = io_base; -+ ae.port[0].altstatus_addr = ctl_base; -+ ae.port[0].ctl_addr = ctl_base; -+ ata_std_ports(&ae.port[0]); -+ -+ if (ata_device_add(&ae) == 0) -+ goto failed; -+ -+ info->ndev = 1; -+ link->dev = &info->node; -+ link->state &= ~DEV_CONFIG_PENDING; -+ kfree(stk); -+ return 0; -+ -+cs_failed: -+ cs_error(link->handle, last_fn, last_ret); -+failed: -+ kfree(stk); -+ info->ndev = 0; -+ link->dev = NULL; -+ -+ pcmcia_release_configuration(link->handle); -+ pcmcia_release_io(link->handle, &link->io); -+ pcmcia_release_irq(link->handle, &link->irq); -+ -+ link->state &= ~DEV_CONFIG; -+out1: -+ kfree(info); -+ return ret; -+} -+ -+/** -+ * pcmcia_remove_one - unplug an pcmcia interface -+ * @pdev: pcmcia device -+ * -+ * A PCMCIA ATA device has been unplugged. Perform the needed -+ * cleanup. Also called on module unload for any active devices. -+ */ -+ -+void pcmcia_remove_one(struct pcmcia_device *pdev) -+{ -+ dev_link_t *link = dev_to_instance(pdev); -+ struct ata_pcmcia_info *info = link->priv; -+ struct device *dev = &pdev->dev; -+ -+ if (link->state & DEV_CONFIG) { -+ if (info->ndev) { -+ struct ata_host_set *host_set = dev_get_drvdata(dev); -+ ata_host_set_remove(host_set); -+ dev_set_drvdata(dev, NULL); -+ } -+ info->ndev = 0; -+ link->dev = NULL; -+ -+ pcmcia_release_configuration(link->handle); -+ pcmcia_release_io(link->handle, &link->io); -+ pcmcia_release_irq(link->handle, &link->irq); -+ link->state &= ~DEV_CONFIG; -+ } -+ kfree(link->priv); -+} -+ -+static int pcmcia_suspend(struct pcmcia_device *dev) -+{ -+ dev_link_t *link = dev_to_instance(dev); -+ -+ link->state |= DEV_SUSPEND; -+ if (link->state & DEV_CONFIG) -+ pcmcia_release_configuration(link->handle); -+ -+ return 0; -+} -+ -+static int pcmcia_resume(struct pcmcia_device *dev) -+{ -+ dev_link_t *link = dev_to_instance(dev); -+ -+ link->state &= ~DEV_SUSPEND; -+ if (DEV_OK(link)) -+ pcmcia_request_configuration(link->handle, &link->conf); -+ -+ return 0; -+} -+ -+static struct pcmcia_device_id pcmcia_devices[] = { -+ PCMCIA_DEVICE_FUNC_ID(4), -+ PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */ -+ PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), -+ PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), -+ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ -+ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), -+ PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ -+ PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */ -+ PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), -+ PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */ -+ PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), -+ PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74), -+ PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), -+ PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728), -+ PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), -+ PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), -+ PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf), -+ PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), -+ PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), -+ PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), -+ PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), -+ PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), -+ PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), -+ PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), -+ PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), -+ PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), -+ PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), -+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), -+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), -+ PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), -+ PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), -+ PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), -+ PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), -+ PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), -+ PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), -+ PCMCIA_DEVICE_NULL, -+}; -+ -+MODULE_DEVICE_TABLE(pcmcia, pcmcia_devices); -+ -+static struct pcmcia_driver pcmcia_driver = { -+ .owner = THIS_MODULE, -+ .drv = { -+ .name = DRV_NAME, -+ }, -+ .id_table = pcmcia_devices, -+ .probe = pcmcia_init_one, -+ .remove = pcmcia_remove_one, -+ .suspend = pcmcia_suspend, -+ .resume = pcmcia_resume, -+}; -+ -+static int __init pcmcia_init(void) -+{ -+ return pcmcia_register_driver(&pcmcia_driver); -+} -+ -+static void __exit pcmcia_exit(void) -+{ -+ pcmcia_unregister_driver(&pcmcia_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for PCMCIA ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(pcmcia_init); -+module_exit(pcmcia_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc2027x.c linux-2.6.16-rc4/drivers/scsi/pata_pdc2027x.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc2027x.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_pdc2027x.c 2006-01-21 16:56:47.000000000 +0000 -@@ -0,0 +1,857 @@ -+/* -+ * Promise PATA TX2/TX4/TX2000/133 IDE driver for pdc20268 to pdc20277. -+ * -+ * 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. -+ * -+ * Ported to libata by: -+ * Albert Lee <albertcc@tw.ibm.com> IBM Corporation -+ * -+ * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> -+ * Portions Copyright (C) 1999 Promise Technology, Inc. -+ * -+ * Author: Frank Tiernan (frankt@promise.com) -+ * Released under terms of General Public License -+ * -+ * -+ * libata documentation is available via 'make {ps|pdf}docs', -+ * as Documentation/DocBook/libata.* -+ * -+ * Hardware information only available under NDA. -+ * -+ */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <scsi/scsi.h> -+#include <scsi/scsi_host.h> -+#include <scsi/scsi_cmnd.h> -+#include <linux/libata.h> -+#include <asm/io.h> -+ -+#define DRV_NAME "pata_pdc2027x" -+#define DRV_VERSION "0.73" -+#undef PDC_DEBUG -+ -+#ifdef PDC_DEBUG -+#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) -+#else -+#define PDPRINTK(fmt, args...) -+#endif -+ -+enum { -+ PDC_UDMA_100 = 0, -+ PDC_UDMA_133 = 1, -+ -+ PDC_100_MHZ = 100000000, -+ PDC_133_MHZ = 133333333, -+ -+ PDC_SYS_CTL = 0x1100, -+ PDC_ATA_CTL = 0x1104, -+ PDC_GLOBAL_CTL = 0x1108, -+ PDC_CTCR0 = 0x110C, -+ PDC_CTCR1 = 0x1110, -+ PDC_BYTE_COUNT = 0x1120, -+ PDC_PLL_CTL = 0x1202, -+}; -+ -+static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -+static void pdc2027x_remove_one(struct pci_dev *pdev); -+static void pdc2027x_phy_reset(struct ata_port *ap); -+static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev); -+static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev); -+static void pdc2027x_post_set_mode(struct ata_port *ap); -+static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc); -+ -+/* -+ * ATA Timing Tables based on 133MHz controller clock. -+ * These tables are only used when the controller is in 133MHz clock. -+ * If the controller is in 100MHz clock, the ASIC hardware will -+ * set the timing registers automatically when "set feature" command -+ * is issued to the device. However, if the controller clock is 133MHz, -+ * the following tables must be used. -+ */ -+static struct pdc2027x_pio_timing { -+ u8 value0, value1, value2; -+} pdc2027x_pio_timing_tbl [] = { -+ { 0xfb, 0x2b, 0xac }, /* PIO mode 0 */ -+ { 0x46, 0x29, 0xa4 }, /* PIO mode 1 */ -+ { 0x23, 0x26, 0x64 }, /* PIO mode 2 */ -+ { 0x27, 0x0d, 0x35 }, /* PIO mode 3, IORDY on, Prefetch off */ -+ { 0x23, 0x09, 0x25 }, /* PIO mode 4, IORDY on, Prefetch off */ -+}; -+ -+static struct pdc2027x_mdma_timing { -+ u8 value0, value1; -+} pdc2027x_mdma_timing_tbl [] = { -+ { 0xdf, 0x5f }, /* MDMA mode 0 */ -+ { 0x6b, 0x27 }, /* MDMA mode 1 */ -+ { 0x69, 0x25 }, /* MDMA mode 2 */ -+}; -+ -+static struct pdc2027x_udma_timing { -+ u8 value0, value1, value2; -+} pdc2027x_udma_timing_tbl [] = { -+ { 0x4a, 0x0f, 0xd5 }, /* UDMA mode 0 */ -+ { 0x3a, 0x0a, 0xd0 }, /* UDMA mode 1 */ -+ { 0x2a, 0x07, 0xcd }, /* UDMA mode 2 */ -+ { 0x1a, 0x05, 0xcd }, /* UDMA mode 3 */ -+ { 0x1a, 0x03, 0xcd }, /* UDMA mode 4 */ -+ { 0x1a, 0x02, 0xcb }, /* UDMA mode 5 */ -+ { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ -+}; -+ -+static const struct pci_device_id pdc2027x_pci_tbl[] = { -+#ifdef ATA_ENABLE_PATA -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, -+#endif -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver pdc2027x_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pdc2027x_pci_tbl, -+ .probe = pdc2027x_init_one, -+ .remove = __devexit_p(pdc2027x_remove_one), -+}; -+ -+static struct scsi_host_template pdc2027x_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+}; -+ -+static struct ata_port_operations pdc2027x_pata100_ops = { -+ .port_disable = ata_port_disable, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = pdc2027x_phy_reset, -+ -+ .check_atapi_dma = pdc2027x_check_atapi_dma, -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_mmio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static struct ata_port_operations pdc2027x_pata133_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = pdc2027x_set_piomode, -+ .set_dmamode = pdc2027x_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = pdc2027x_phy_reset, -+ .post_set_mode = pdc2027x_post_set_mode, -+ -+ .check_atapi_dma = pdc2027x_check_atapi_dma, -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_mmio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static struct ata_port_info pdc2027x_port_info[] = { -+ /* PDC_UDMA_100 */ -+ { -+ .sht = &pdc2027x_sht, -+ .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | -+ ATA_FLAG_SRST | ATA_FLAG_MMIO, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA5, /* udma0-5 */ -+ .port_ops = &pdc2027x_pata100_ops, -+ }, -+ /* PDC_UDMA_133 */ -+ { -+ .sht = &pdc2027x_sht, -+ .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | -+ ATA_FLAG_SRST | ATA_FLAG_MMIO, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma0-2 */ -+ .udma_mask = ATA_UDMA6, /* udma0-6 */ -+ .port_ops = &pdc2027x_pata133_ops, -+ }, -+}; -+ -+MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Albert Lee"); -+MODULE_DESCRIPTION("libata driver module for Promise PDC20268 to PDC20277"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl); -+ -+/** -+ * port_mmio - Get the MMIO address of PDC2027x extended registers -+ * @ap: Port -+ * @offset: offset from mmio base -+ */ -+static inline void* port_mmio(struct ata_port *ap, unsigned int offset) -+{ -+ return ap->host_set->mmio_base + ap->port_no * 0x100 + offset; -+} -+ -+/** -+ * dev_mmio - Get the MMIO address of PDC2027x extended registers -+ * @ap: Port -+ * @adev: device -+ * @offset: offset from mmio base -+ */ -+static inline void* dev_mmio(struct ata_port *ap, struct ata_device *adev, unsigned int offset) -+{ -+ u8 adj = (adev->devno) ? 0x08 : 0x00; -+ return port_mmio(ap, offset) + adj; -+} -+ -+/** -+ * pdc2027x_pata_cbl_detect - Probe host controller cable detect info -+ * @ap: Port for which cable detect info is desired -+ * -+ * Read 80c cable indicator from Promise extended register. -+ * This register is latched when the system is reset. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_cbl_detect(struct ata_port *ap) -+{ -+ u32 cgcr; -+ -+ /* check cable detect results */ -+ cgcr = readl(port_mmio(ap, PDC_GLOBAL_CTL)); -+ if (cgcr & (1 << 26)) -+ goto cbl40; -+ -+ PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no); -+ -+ ap->cbl = ATA_CBL_PATA80; -+ return; -+ -+cbl40: -+ printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no); -+ ap->cbl = ATA_CBL_PATA40; -+ ap->udma_mask &= ATA_UDMA_MASK_40C; -+} -+ -+/** -+ * pdc2027x_port_enabled - Check PDC ATA control register to see whether the port is enabled. -+ * @ap: Port to check -+ */ -+static inline int pdc2027x_port_enabled(struct ata_port *ap) -+{ -+ return readb(port_mmio(ap, PDC_ATA_CTL)) & 0x02; -+} -+ -+/** -+ * pdc2027x_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * Probe PATA phy. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_phy_reset(struct ata_port *ap) -+{ -+ /* Check whether port enabled */ -+ if (!pdc2027x_port_enabled(ap)) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ -+ pdc2027x_cbl_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * pdc2027x_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port to configure -+ * @adev: um -+ * @pio: PIO mode, 0 - 4 -+ * -+ * Set PIO mode for device. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ u32 ctcr0, ctcr1; -+ -+ PDPRINTK("adev->pio_mode[%X]\n", adev->pio_mode); -+ -+ /* Sanity check */ -+ if (pio > 4) { -+ printk(KERN_ERR DRV_NAME ": Unknown pio mode [%d] ignored\n", pio); -+ return; -+ -+ } -+ -+ /* Set the PIO timing registers using value table for 133MHz */ -+ PDPRINTK("Set pio regs... \n"); -+ -+ ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0)); -+ ctcr0 &= 0xffff0000; -+ ctcr0 |= pdc2027x_pio_timing_tbl[pio].value0 | -+ (pdc2027x_pio_timing_tbl[pio].value1 << 8); -+ writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0)); -+ -+ ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1)); -+ ctcr1 &= 0x00ffffff; -+ ctcr1 |= (pdc2027x_pio_timing_tbl[pio].value2 << 24); -+ writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1)); -+ -+ PDPRINTK("Set pio regs done\n"); -+ -+ PDPRINTK("Set to pio mode[%u] \n", pio); -+} -+ -+/** -+ * pdc2027x_set_dmamode - Initialize host controller PATA UDMA timings -+ * @ap: Port to configure -+ * @adev: um -+ * @udma: udma mode, XFER_UDMA_0 to XFER_UDMA_6 -+ * -+ * Set UDMA mode for device. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int dma_mode = adev->dma_mode; -+ u32 ctcr0, ctcr1; -+ -+ if ((dma_mode >= XFER_UDMA_0) && -+ (dma_mode <= XFER_UDMA_6)) { -+ /* Set the UDMA timing registers with value table for 133MHz */ -+ unsigned int udma_mode = dma_mode & 0x07; -+ -+ if (dma_mode == XFER_UDMA_2) { -+ /* -+ * Turn off tHOLD. -+ * If tHOLD is '1', the hardware will add half clock for data hold time. -+ * This code segment seems to be no effect. tHOLD will be overwritten below. -+ */ -+ ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1)); -+ writel(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1)); -+ } -+ -+ PDPRINTK("Set udma regs... \n"); -+ -+ ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1)); -+ ctcr1 &= 0xff000000; -+ ctcr1 |= pdc2027x_udma_timing_tbl[udma_mode].value0 | -+ (pdc2027x_udma_timing_tbl[udma_mode].value1 << 8) | -+ (pdc2027x_udma_timing_tbl[udma_mode].value2 << 16); -+ writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1)); -+ -+ PDPRINTK("Set udma regs done\n"); -+ -+ PDPRINTK("Set to udma mode[%u] \n", udma_mode); -+ -+ } else if ((dma_mode >= XFER_MW_DMA_0) && -+ (dma_mode <= XFER_MW_DMA_2)) { -+ /* Set the MDMA timing registers with value table for 133MHz */ -+ unsigned int mdma_mode = dma_mode & 0x07; -+ -+ PDPRINTK("Set mdma regs... \n"); -+ ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0)); -+ -+ ctcr0 &= 0x0000ffff; -+ ctcr0 |= (pdc2027x_mdma_timing_tbl[mdma_mode].value0 << 16) | -+ (pdc2027x_mdma_timing_tbl[mdma_mode].value1 << 24); -+ -+ writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0)); -+ PDPRINTK("Set mdma regs done\n"); -+ -+ PDPRINTK("Set to mdma mode[%u] \n", mdma_mode); -+ } else { -+ printk(KERN_ERR DRV_NAME ": Unknown dma mode [%u] ignored\n", dma_mode); -+ } -+} -+ -+/** -+ * pdc2027x_post_set_mode - Set the timing registers back to correct values. -+ * @ap: Port to configure -+ * -+ * The pdc2027x hardware will look at "SET FEATURES" and change the timing registers -+ * automatically. The values set by the hardware might be incorrect, under 133Mhz PLL. -+ * This function overwrites the possibly incorrect values set by the hardware to be correct. -+ */ -+static void pdc2027x_post_set_mode(struct ata_port *ap) -+{ -+ int i; -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ -+ if (ata_dev_present(dev)) { -+ -+ pdc2027x_set_piomode(ap, dev); -+ -+ /* -+ * Enable prefetch if the device support PIO only. -+ */ -+ if (dev->xfer_shift == ATA_SHIFT_PIO) { -+ u32 ctcr1 = readl(dev_mmio(ap, dev, PDC_CTCR1)); -+ ctcr1 |= (1 << 25); -+ writel(ctcr1, dev_mmio(ap, dev, PDC_CTCR1)); -+ -+ PDPRINTK("Turn on prefetch\n"); -+ } else { -+ pdc2027x_set_dmamode(ap, dev); -+ } -+ } -+ } -+} -+ -+/** -+ * pdc2027x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command -+ * @qc: Metadata associated with taskfile to check -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ * -+ * RETURNS: 0 when ATAPI DMA can be used -+ * 1 otherwise -+ */ -+static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc) -+{ -+ struct scsi_cmnd *cmd = qc->scsicmd; -+ u8 *scsicmd = cmd->cmnd; -+ int rc = 1; /* atapi dma off by default */ -+ -+ /* -+ * This workaround is from Promise's GPL driver. -+ * If ATAPI DMA is used for commands not in the -+ * following white list, say MODE_SENSE and REQUEST_SENSE, -+ * pdc2027x might hit the irq lost problem. -+ */ -+ switch (scsicmd[0]) { -+ case READ_10: -+ case WRITE_10: -+ case READ_12: -+ case WRITE_12: -+ case READ_6: -+ case WRITE_6: -+ case 0xad: /* READ_DVD_STRUCTURE */ -+ case 0xbe: /* READ_CD */ -+ /* ATAPI DMA is ok */ -+ rc = 0; -+ break; -+ default: -+ ; -+ } -+ -+ return rc; -+} -+ -+/** -+ * pdc_read_counter - Read the ctr counter -+ * @probe_ent: for the port address -+ */ -+ -+static long pdc_read_counter(struct ata_probe_ent *probe_ent) -+{ -+ long counter; -+ int retry = 1; -+ u32 bccrl, bccrh, bccrlv, bccrhv; -+ -+retry: -+ bccrl = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff; -+ bccrh = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; -+ rmb(); -+ -+ /* Read the counter values again for verification */ -+ bccrlv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff; -+ bccrhv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; -+ rmb(); -+ -+ counter = (bccrh << 15) | bccrl; -+ -+ PDPRINTK("bccrh [%X] bccrl [%X]\n", bccrh, bccrl); -+ PDPRINTK("bccrhv[%X] bccrlv[%X]\n", bccrhv, bccrlv); -+ -+ /* -+ * The 30-bit decreasing counter are read by 2 pieces. -+ * Incorrect value may be read when both bccrh and bccrl are changing. -+ * Ex. When 7900 decrease to 78FF, wrong value 7800 might be read. -+ */ -+ if (retry && !(bccrh == bccrhv && bccrl >= bccrlv)) { -+ retry--; -+ PDPRINTK("rereading counter\n"); -+ goto retry; -+ } -+ -+ return counter; -+} -+ -+/** -+ * adjust_pll - Adjust the PLL input clock in Hz. -+ * -+ * @pdc_controller: controller specific information -+ * @probe_ent: For the port address -+ * @pll_clock: The input of PLL in HZ -+ */ -+static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx) -+{ -+ -+ u16 pll_ctl; -+ long pll_clock_khz = pll_clock / 1000; -+ long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ; -+ long ratio = pout_required / pll_clock_khz; -+ int F, R; -+ -+ /* Sanity check */ -+ if (unlikely(pll_clock_khz < 5000L || pll_clock_khz > 70000L)) { -+ printk(KERN_ERR DRV_NAME ": Invalid PLL input clock %ldkHz, give up!\n", pll_clock_khz); -+ return; -+ } -+ -+#ifdef PDC_DEBUG -+ PDPRINTK("pout_required is %ld\n", pout_required); -+ -+ /* Show the current clock value of PLL control register -+ * (maybe already configured by the firmware) -+ */ -+ pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL); -+ -+ PDPRINTK("pll_ctl[%X]\n", pll_ctl); -+#endif -+ -+ /* -+ * Calculate the ratio of F, R and OD -+ * POUT = (F + 2) / (( R + 2) * NO) -+ */ -+ if (ratio < 8600L) { /* 8.6x */ -+ /* Using NO = 0x01, R = 0x0D */ -+ R = 0x0d; -+ } else if (ratio < 12900L) { /* 12.9x */ -+ /* Using NO = 0x01, R = 0x08 */ -+ R = 0x08; -+ } else if (ratio < 16100L) { /* 16.1x */ -+ /* Using NO = 0x01, R = 0x06 */ -+ R = 0x06; -+ } else if (ratio < 64000L) { /* 64x */ -+ R = 0x00; -+ } else { -+ /* Invalid ratio */ -+ printk(KERN_ERR DRV_NAME ": Invalid ratio %ld, give up!\n", ratio); -+ return; -+ } -+ -+ F = (ratio * (R+2)) / 1000 - 2; -+ -+ if (unlikely(F < 0 || F > 127)) { -+ /* Invalid F */ -+ printk(KERN_ERR DRV_NAME ": F[%d] invalid!\n", F); -+ return; -+ } -+ -+ PDPRINTK("F[%d] R[%d] ratio*1000[%ld]\n", F, R, ratio); -+ -+ pll_ctl = (R << 8) | F; -+ -+ PDPRINTK("Writing pll_ctl[%X]\n", pll_ctl); -+ -+ writew(pll_ctl, probe_ent->mmio_base + PDC_PLL_CTL); -+ readw(probe_ent->mmio_base + PDC_PLL_CTL); /* flush */ -+ -+ /* Wait the PLL circuit to be stable */ -+ mdelay(30); -+ -+#ifdef PDC_DEBUG -+ /* -+ * Show the current clock value of PLL control register -+ * (maybe configured by the firmware) -+ */ -+ pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL); -+ -+ PDPRINTK("pll_ctl[%X]\n", pll_ctl); -+#endif -+ -+ return; -+} -+ -+/** -+ * detect_pll_input_clock - Detect the PLL input clock in Hz. -+ * @probe_ent: for the port address -+ * Ex. 16949000 on 33MHz PCI bus for pdc20275. -+ * Half of the PCI clock. -+ */ -+static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent) -+{ -+ u32 scr; -+ long start_count, end_count; -+ long pll_clock; -+ -+ /* Read current counter value */ -+ start_count = pdc_read_counter(probe_ent); -+ -+ /* Start the test mode */ -+ scr = readl(probe_ent->mmio_base + PDC_SYS_CTL); -+ PDPRINTK("scr[%X]\n", scr); -+ writel(scr | (0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL); -+ readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */ -+ -+ /* Let the counter run for 100 ms. */ -+ mdelay(100); -+ -+ /* Read the counter values again */ -+ end_count = pdc_read_counter(probe_ent); -+ -+ /* Stop the test mode */ -+ scr = readl(probe_ent->mmio_base + PDC_SYS_CTL); -+ PDPRINTK("scr[%X]\n", scr); -+ writel(scr & ~(0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL); -+ readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */ -+ -+ /* calculate the input clock in Hz */ -+ pll_clock = (start_count - end_count) * 10; -+ -+ PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count); -+ PDPRINTK("PLL input clock[%ld]Hz\n", pll_clock); -+ -+ return pll_clock; -+} -+ -+/** -+ * pdc_hardware_init - Initialize the hardware. -+ * @pdev: instance of pci_dev found -+ * @pdc_controller: controller specific information -+ * @pe: for the port address -+ */ -+static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, unsigned int board_idx) -+{ -+ long pll_clock; -+ -+ /* -+ * Detect PLL input clock rate. -+ * On some system, where PCI bus is running at non-standard clock rate. -+ * Ex. 25MHz or 40MHz, we have to adjust the cycle_time. -+ * The pdc20275 controller employs PLL circuit to help correct timing registers setting. -+ */ -+ pll_clock = pdc_detect_pll_input_clock(pe); -+ -+ if (pll_clock < 0) /* counter overflow? Try again. */ -+ pll_clock = pdc_detect_pll_input_clock(pe); -+ -+ dev_printk(KERN_INFO, &pdev->dev, "PLL input clock %ld kHz\n", pll_clock/1000); -+ -+ /* Adjust PLL control register */ -+ pdc_adjust_pll(pe, pll_clock, board_idx); -+ -+ return 0; -+} -+ -+/** -+ * pdc_ata_setup_port - setup the mmio address -+ * @port: ata ioports to setup -+ * @base: base address -+ */ -+static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base) -+{ -+ port->cmd_addr = -+ port->data_addr = base; -+ port->feature_addr = -+ port->error_addr = base + 0x05; -+ port->nsect_addr = base + 0x0a; -+ port->lbal_addr = base + 0x0f; -+ port->lbam_addr = base + 0x10; -+ port->lbah_addr = base + 0x15; -+ port->device_addr = base + 0x1a; -+ port->command_addr = -+ port->status_addr = base + 0x1f; -+ port->altstatus_addr = -+ port->ctl_addr = base + 0x81a; -+} -+ -+/** -+ * pdc2027x_init_one - PCI probe function -+ * Called when an instance of PCI adapter is inserted. -+ * This function checks whether the hardware is supported, -+ * initialize hardware and register an instance of ata_host_set to -+ * libata by providing struct ata_probe_ent and ata_device_add(). -+ * (implements struct pci_driver.probe() ) -+ * -+ * @pdev: instance of pci_dev found -+ * @ent: matching entry in the id_tbl[] -+ */ -+static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ unsigned int board_idx = (unsigned int) ent->driver_data; -+ -+ struct ata_probe_ent *probe_ent = NULL; -+ unsigned long base; -+ void *mmio_base; -+ int rc; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -+ -+ rc = pci_enable_device(pdev); -+ if (rc) -+ return rc; -+ -+ rc = pci_request_regions(pdev, DRV_NAME); -+ if (rc) -+ goto err_out; -+ -+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); -+ if (rc) -+ goto err_out_regions; -+ -+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); -+ if (rc) -+ goto err_out_regions; -+ -+ /* Prepare the probe entry */ -+ probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); -+ if (probe_ent == NULL) { -+ rc = -ENOMEM; -+ goto err_out_regions; -+ } -+ -+ memset(probe_ent, 0, sizeof(*probe_ent)); -+ probe_ent->dev = pci_dev_to_dev(pdev); -+ INIT_LIST_HEAD(&probe_ent->node); -+ -+ mmio_base = ioremap(pci_resource_start(pdev, 5), -+ pci_resource_len(pdev, 5)); -+ -+ if (mmio_base == NULL) { -+ rc = -ENOMEM; -+ goto err_out_free_ent; -+ } -+ -+ base = (unsigned long) mmio_base; -+ -+ probe_ent->sht = pdc2027x_port_info[board_idx].sht; -+ probe_ent->host_flags = pdc2027x_port_info[board_idx].host_flags; -+ probe_ent->pio_mask = pdc2027x_port_info[board_idx].pio_mask; -+ probe_ent->mwdma_mask = pdc2027x_port_info[board_idx].mwdma_mask; -+ probe_ent->udma_mask = pdc2027x_port_info[board_idx].udma_mask; -+ probe_ent->port_ops = pdc2027x_port_info[board_idx].port_ops; -+ -+ probe_ent->irq = pdev->irq; -+ probe_ent->irq_flags = SA_SHIRQ; -+ probe_ent->mmio_base = mmio_base; -+ -+ pdc_ata_setup_port(&probe_ent->port[0], base + 0x17c0); -+ probe_ent->port[0].bmdma_addr = base + 0x1000; -+ pdc_ata_setup_port(&probe_ent->port[1], base + 0x15c0); -+ probe_ent->port[1].bmdma_addr = base + 0x1008; -+ -+ probe_ent->n_ports = 2; -+ -+ pci_set_master(pdev); -+ //pci_enable_intx(pdev); -+ -+ /* initialize adapter */ -+ if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0) -+ goto err_out_free_ent; -+ -+ ata_device_add(probe_ent); -+ kfree(probe_ent); -+ -+ return 0; -+ -+err_out_free_ent: -+ kfree(probe_ent); -+err_out_regions: -+ pci_release_regions(pdev); -+err_out: -+ pci_disable_device(pdev); -+ return rc; -+} -+ -+/** -+ * pdc2027x_remove_one - Called to remove a single instance of the -+ * adapter. -+ * -+ * @dev: The PCI device to remove. -+ * FIXME: module load/unload not working yet -+ */ -+static void __devexit pdc2027x_remove_one(struct pci_dev *pdev) -+{ -+ ata_pci_remove_one(pdev); -+} -+ -+/** -+ * pdc2027x_init - Called after this module is loaded into the kernel. -+ */ -+static int __init pdc2027x_init(void) -+{ -+ return pci_register_driver(&pdc2027x_pci_driver); -+} -+ -+/** -+ * pdc2027x_exit - Called before this module unloaded from the kernel -+ */ -+static void __exit pdc2027x_exit(void) -+{ -+ pci_unregister_driver(&pdc2027x_pci_driver); -+} -+ -+module_init(pdc2027x_init); -+module_exit(pdc2027x_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c linux-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_pdc202xx_old.c 2006-02-20 13:19:57.000000000 +0000 -@@ -0,0 +1,428 @@ -+/* -+ * pata_pdc202xx_old.c - SL82C105 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based in part on linux/drivers/ide/pci/pdc202xx_old.c -+ * -+ * Initial revision -+ * -+ * TODO: -+ * Channel interlock/reset on both required ? -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_pdc202xx_old" -+#define DRV_VERSION "0.1.2" -+ -+static void pdc2024x_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+static void pdc2026x_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 cis; -+ -+ pci_read_config_word(pdev, 0x50, &cis); -+ if (cis & (1 << (10 + ap->hard_port_no))) -+ ap->cbl = ATA_CBL_PATA80; -+ else -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * pdc_configure_piomode - set chip PIO timing -+ * @ap: ATA interface -+ * @adev: ATA device -+ * @pio: PIO mode -+ * -+ * Called to do the PIO mode setup. Our timing registers are shared -+ * so a configure_dmamode call will undo any work we do here and vice -+ * versa -+ */ -+ -+static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x60 + 4 * ap->hard_port_no + 2 * adev->devno; -+ static u16 pio_timing[5] = { -+ 0x0913, 0x050C , 0x0308, 0x0206, 0x0104 -+ }; -+ u8 r_ap, r_bp; -+ -+ /* FIFO, IORDY ? */ -+ pci_read_config_byte(pdev, port, &r_ap); -+ pci_read_config_byte(pdev, port + 1, &r_bp); -+ r_ap &= ~0x0F; -+ r_bp &= ~0x07; -+ r_ap |= (pio_timing[pio] >> 8); -+ r_bp |= (pio_timing[pio] & 0xFF); -+ pci_write_config_byte(pdev, port, r_ap); -+ pci_write_config_byte(pdev, port + 1, r_bp); -+} -+ -+/** -+ * pdc_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. Our timing registers are shared -+ * but we want to set the PIO timing by default. -+ */ -+ -+static void pdc_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ pdc_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * pdc_configure_dmamode - set DMA mode in chip -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Load DMA cycle times into the chip ready for a DMA transfer -+ * to occur. -+ */ -+ -+static void pdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x60 + 4 * ap->hard_port_no + 2 * adev->devno; -+ static u8 udma_timing[6][2] = { -+ { 0x60, 0x03 }, /* 33 Mhz Clock */ -+ { 0x40, 0x02 }, -+ { 0x20, 0x01 }, -+ { 0x40, 0x02 }, /* 66 Mhz Clock */ -+ { 0x20, 0x01 }, -+ { 0x20, 0x01 } -+ }; -+ u8 r_bp, r_cp; -+ -+ pci_read_config_byte(pdev, port + 1, &r_bp); -+ pci_read_config_byte(pdev, port + 2, &r_cp); -+ -+ r_bp &= ~0xF0; -+ r_cp &= ~0x0F; -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ int speed = adev->dma_mode - XFER_UDMA_0; -+ r_bp |= udma_timing[speed][0]; -+ r_cp |= udma_timing[speed][1]; -+ -+ } else { -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ r_bp |= 0x60; -+ r_cp |= (5 - speed); -+ } -+ pci_write_config_byte(pdev, port + 1, r_bp); -+ pci_write_config_byte(pdev, port + 2, r_cp); -+ -+} -+ -+/** -+ * pdc2026x_reset_engine - Reset the DMA engine -+ * @ap: ATA interface -+ * -+ * Reset the 2026x DMA engine. This is not something we want to do, -+ * and we need to figure out how to serialize this across dual channel -+ * devices if it is neccessary. -+ * -+ * FIXME: Do we need to reset the other interface too ? -+ */ -+ -+static void pdc2026x_reset_engine(struct ata_port *ap) -+{ -+ unsigned long ctrl = ap->host_set->ports[0]->ioaddr.bmdma_addr + 0x1F; -+ -+ u8 val = inb(ctrl); -+ outb(val | 0x10, ctrl); -+ mdelay(100); -+ outb(val & ~0x10, ctrl); -+ mdelay(2000); /* Check - seems to be overkill, plus if needed -+ redo locking */ -+ /* Need to fix up speed info at this point */ -+} -+ -+/** -+ * pdc2026x_bmdma_start - DMA engine begin -+ * @qc: ATA command -+ * -+ * In UDMA3 or higher we have to clock switch for the duration of the -+ * DMA transfer sequence. -+ */ -+ -+static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ int sel66 = ap->hard_port_no ? 0x08: 0x02; -+ /* The clock bits are in the same register for both channels */ -+ unsigned long clock = ap->host_set->ports[0]->ioaddr.bmdma_addr + 0x11; -+ -+ /* Check we keep host_set level locking here */ -+ if (adev->dma_mode >= XFER_UDMA_2) -+ outb(inb(clock) | sel66, clock); -+ else -+ outb(inb(clock) & ~sel66, clock); -+ /* The DMA clocks may have been trashed by a reset. FIXME: make conditional -+ and move to qc_issue ? */ -+ pdc_set_dmamode(ap, qc->dev); -+ /* Activate DMA */ -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * pdc2026x_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * After a DMA completes we need to put the clock back to 33MHz for -+ * PIO timings. -+ */ -+ -+static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ int sel66 = ap->hard_port_no ? 0x08: 0x02; -+ /* The clock bits are in the same register for both channels */ -+ unsigned long clock = ap->host_set->ports[0]->ioaddr.bmdma_addr + 0x11; -+ -+ /* FIXME: Review LBA48 code in ide/pci driver */ -+ ata_bmdma_stop(qc); -+ /* Check we keep host_set level locking here */ -+ /* Flip back to 33Mhz for PIO */ -+ if (adev->dma_mode >= XFER_UDMA_2) -+ outb(inb(clock) & ~sel66, clock); -+} -+ -+/** -+ * pdc2026x_eng_timeout - command timeout -+ * @qc: command that timed out -+ * -+ * When the PDC2026x times out hit the controller over the head -+ * with a hammer before continuing. The reset unfortunately also -+ * resets the timing registers so we must reprogram these. -+ */ -+ -+static void pdc2026x_eng_timeout(struct ata_port *ap) -+{ -+ int i; -+ -+ /* Perform libata side housekeeping */ -+ ata_eng_timeout(ap); -+ -+ /* Reset the controller */ -+ pdc2026x_reset_engine(ap); -+ -+ /* Reprogram the device timings */ -+ for (i = 0; i < 2; i++) { -+ struct ata_device *adev = &ap->device[i]; -+ if (ata_dev_present(adev)) { -+ pdc_set_piomode(ap, adev); -+ if (adev->dma_mode) -+ pdc_set_dmamode(ap, adev); -+ } -+ } -+} -+ -+/** -+ * pdc2026x_dev_config - device setup hook -+ * @ap: ATA port -+ * @adev: newly found device -+ * -+ * Perform chip specific early setup. We need to lock the transfer -+ * sizes to 8bit to avoid making the state engine on the 2026x cards -+ * barf. -+ */ -+ -+static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev) -+{ -+ /* We cannot blindly set 256 as the core code may already -+ have picked a lower limit */ -+ -+ if(ap->host->max_sectors > 256) { -+ ap->host->max_sectors = 256; -+ ap->host->hostt->max_sectors = 256; -+ } -+ adev->flags |= ATA_DFLAG_LOCK_SECTORS; -+} -+ -+static struct scsi_host_template pdc_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations pdc2024x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = pdc_set_piomode, -+ .set_dmamode = pdc_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = pdc2024x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations pdc2026x_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = pdc_set_piomode, -+ .set_dmamode = pdc_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ .dev_config = pdc2026x_dev_config, -+ -+ .phy_reset = pdc2026x_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = pdc2026x_bmdma_start, -+ .bmdma_stop = pdc2026x_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = pdc2026x_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info[3] = { -+ { -+ .sht = &pdc_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA2, -+ .port_ops = &pdc2024x_port_ops -+ }, -+ { -+ .sht = &pdc_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA4, -+ .port_ops = &pdc2026x_port_ops -+ }, -+ { -+ .sht = &pdc_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &pdc2026x_port_ops -+ } -+ -+ }; -+ static struct ata_port_info *port_info[2]; -+ -+ port_info[0] = port_info[1] = &info[id->driver_data]; -+ -+ if (dev->device == PCI_DEVICE_ID_PROMISE_20265) { -+ struct pci_dev *bridge = dev->bus->self; -+ /* Don't grab anything behind a Promise I2O RAID */ -+ if (bridge && bridge->vendor == PCI_VENDOR_ID_INTEL) { -+ if( bridge->device == PCI_DEVICE_ID_INTEL_I960) -+ return -ENODEV; -+ if( bridge->device == PCI_DEVICE_ID_INTEL_I960RM) -+ return -ENODEV; -+ } -+ } -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static struct pci_device_id pdc[] = { -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { 0, }, -+}; -+ -+static struct pci_driver pdc_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pdc, -+ .probe = pdc_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init pdc_init(void) -+{ -+ return pci_register_driver(&pdc_pci_driver); -+} -+ -+ -+static void __exit pdc_exit(void) -+{ -+ pci_unregister_driver(&pdc_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pdc); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(pdc_init); -+module_exit(pdc_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_qdi.c linux-2.6.16-rc4/drivers/scsi/pata_qdi.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_qdi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_qdi.c 2006-02-15 15:08:22.000000000 +0000 -@@ -0,0 +1,370 @@ -+/* -+ * pata_qdi.c - QDI VLB ATA controllers -+ * (C) 2006 Red Hat <alan@redhat.com> -+ * -+ * This driver mostly exists as a proof of concept for non PCI devices under libata. -+ * While the QDI6580 was 'neat' in 1993 it is no longer terribly useful. -+ * -+ * Tuning code written from the documentation at -+ * http://www.ryston.cz/petr/vlb/qd6500.html -+ * http://www.ryston.cz/petr/vlb/qd6580.html -+ * -+ * Probe code based on drivers/ide/legacy/qd65xx.c -+ * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by -+ * Samuel Thibault <samuel.thibault@fnac.net> -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_qdi" -+#define DRV_VERSION "0.2" -+ -+#define NR_HOST 4 /* Two 6580s */ -+ -+struct qdi_data { -+ unsigned long timing; -+ u8 clock[2]; -+ u8 last; -+ int fast; -+ -+}; -+ -+static struct ata_host_set *qdi_host[NR_HOST]; -+static struct qdi_data qdi_data[NR_HOST]; -+static int nr_qdi_host = 0; -+ -+static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_timing t; -+ struct qdi_data *qdi = ap->host_set->private_data; -+ int active, recovery; -+ u8 timing; -+ -+ /* Get the timing data in cycles */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); -+ -+ if (qdi->fast) { -+ active = 8 - FIT(t.active, 1, 8); -+ recovery = 18 - FIT(t.recover, 3, 18); -+ } else { -+ active = 9 - FIT(t.active, 2, 9); -+ recovery = 15 - FIT(t.recover, 0, 15); -+ } -+ timing = (recovery << 4) | active | 0x08; -+ -+ qdi->clock[adev->devno] = timing; -+ -+ outb(timing, qdi->timing); -+} -+ -+static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct ata_timing t; -+ struct qdi_data *qdi = ap->host_set->private_data; -+ int active, recovery; -+ u8 timing; -+ -+ /* Get the timing data in cycles */ -+ ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); -+ -+ if (qdi->fast) { -+ active = 8 - FIT(t.active, 1, 8); -+ recovery = 18 - FIT(t.recover, 3, 18); -+ } else { -+ active = 9 - FIT(t.active, 2, 9); -+ recovery = 15 - FIT(t.recover, 0, 15); -+ } -+ timing = (recovery << 4) | active | 0x08; -+ -+ qdi->clock[adev->devno] = timing; -+ -+ outb(timing, qdi->timing); -+ -+ /* Clear the FIFO */ -+ if (adev->class != ATA_DEV_ATA) -+ outb(0x5F, (qdi->timing & 0xFFF0) + 3); -+} -+ -+/** -+ * qdi_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings. -+ */ -+ -+static int qdi_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct qdi_data *qdi = ap->host_set->private_data; -+ -+ if (qdi->clock[adev->devno] != qdi->last) { -+ if (adev->pio_mode) { -+ qdi->last = qdi->clock[adev->devno]; -+ outb(qdi->clock[adev->devno], qdi->timing); -+ } -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+static void qdi_data_xfer(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) -+{ -+ int slop = buflen & 3; -+ -+ if (ata_id_has_dword_io(adev->id)) { -+ if (write_data) -+ outsl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ else -+ insl(ap->ioaddr.data_addr, buf, buflen >> 2); -+ -+ if (unlikely(slop)) { -+ u32 pad; -+ if (write_data) { -+ memcpy(&pad, buf + buflen - slop, slop); -+ outl(le32_to_cpu(pad), ap->ioaddr.data_addr); -+ } else { -+ pad = cpu_to_le16(inl(ap->ioaddr.data_addr)); -+ memcpy(buf + buflen - slop, &pad, slop); -+ } -+ } -+ } else -+ ata_pio_data_xfer(ap, adev, buf, buflen, write_data); -+} -+ -+static struct scsi_host_template qdi_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations qdi6500_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = qdi6500_set_piomode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = qdi_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = qdi_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations qdi6580_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = qdi6580_set_piomode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = qdi_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = qdi_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * qdi_init_one - attach a qdi interface -+ * @type: Type to display -+ * @io: I/O port start -+ * @irq: interrupt line -+ * @fast: True if on a > 33Mhz VLB -+ * -+ * Register an ISA bus IDE interface. Such interfaces are PIO and we -+ * assume do not support IRQ sharing. -+ */ -+ -+static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast) -+{ -+ struct ata_probe_ent ae; -+ int ret; -+ -+ unsigned long ctrl = io + 0x206; -+ -+ /* -+ * Fill in a probe structure first of all -+ */ -+ -+ memset(&ae, 0, sizeof(struct ata_probe_ent)); -+ INIT_LIST_HEAD(&ae.node); -+ ae.dev = NULL; -+ -+ if (type == 6580) { -+ ae.port_ops = &qdi6580_port_ops; -+ ae.pio_mask = 0x1F; -+ } else { -+ ae.port_ops = &qdi6500_port_ops; -+ ae.pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */ -+ } -+ -+ ae.sht = &qdi_sht; -+ ae.n_ports = 1; -+ ae.irq = irq; -+ ae.irq_flags = 0; -+ ae.host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IRQ_MASK; -+ ae.port[0].cmd_addr = io; -+ ae.port[0].altstatus_addr = ctrl; -+ ae.port[0].ctl_addr = ctrl; -+ ata_std_ports(&ae.port[0]); -+ -+ /* -+ * Hook in a private data structure per channel -+ */ -+ ae.private_data = &qdi_data[nr_qdi_host]; -+ -+ qdi_data[nr_qdi_host].timing = port; -+ qdi_data[nr_qdi_host].fast = fast; -+ -+ printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io); -+ ret = ata_device_add(&ae); -+ if (ret == 0) -+ return -ENODEV; -+ -+ qdi_host[nr_qdi_host++] = ae.host_set; -+ return 0; -+} -+ -+/** -+ * qdi_init - attach qdi interfaces -+ * -+ * Attach qdi IDE interfaces by scanning the ports it may occupy. -+ */ -+ -+static __init int qdi_init(void) -+{ -+ unsigned long flags; -+ unsigned long qd_port[2] = { 0x30, 0xB0 }; -+ unsigned long ide_port[2] = { 0x170, 0x1F0 }; -+ int ide_irq[2] = { 14, 15 }; -+ int ct = 0; -+ int i; -+ -+ /* -+ * Check each possible QD65xx base address -+ */ -+ -+ for (i = 0; i < 2; i++) { -+ unsigned long port = qd_port[i]; -+ u8 r, res; -+ -+ -+ if (request_region(port, 2, "pata_qdi")) { -+ /* Check for a card */ -+ local_irq_save(flags); -+ r = inb_p(port); -+ outb_p(0x19, port); -+ res = inb_p(port); -+ outb_p(r, port); -+ local_irq_restore(flags); -+ -+ /* Fail */ -+ if (res == 0x19) -+ { -+ release_region(port, 2); -+ continue; -+ } -+ -+ /* Passes the presence test */ -+ r = inb_p(port + 1); /* Check port agrees with port set */ -+ if ((r & 2) >> 1 != i) { -+ release_region(port, 2); -+ continue; -+ } -+ -+ /* Check card type */ -+ if ((r & 0xF0) == 0xC0) { -+ /* QD6500: single channel */ -+ if (r & 8) { -+ /* Disabled ? */ -+ release_region(port, 2); -+ continue; -+ } -+ ct += qdi_init_one(port, 6500, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04); -+ } -+ if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) { -+ /* QD6580: dual channel */ -+ if (!request_region(port + 2 , 2, "pata_qdi")) -+ { -+ release_region(port, 2); -+ continue; -+ } -+ res = inb(port + 3); -+ if (res & 1) { -+ /* Single channel mode */ -+ ct += qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04); -+ } else { -+ /* Dual channel mode */ -+ ct += qdi_init_one(port, 6580, 0x1F0, 14, r & 0x04); -+ ct += qdi_init_one(port + 2, 6580, 0x170, 15, r & 0x04); -+ } -+ } -+ } -+ } -+ if (ct != 0) -+ return 0; -+ return -ENODEV; -+} -+ -+static __exit void qdi_exit(void) -+{ -+ int i; -+ -+ for (i = 0; i < nr_qdi_host; i++) { -+ ata_host_set_remove(qdi_host[i]); -+ /* Free the control resource. The 6580 dual channel has the resources -+ * claimed as a pair of 2 byte resources so we need no special cases... -+ */ -+ release_region(qdi_data[i].timing, 2); -+ } -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for qdi ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(qdi_init); -+module_exit(qdi_exit); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_radisys.c linux-2.6.16-rc4/drivers/scsi/pata_radisys.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_radisys.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_radisys.c 2006-02-17 15:31:12.000000000 +0000 -@@ -0,0 +1,321 @@ -+/* -+ * pata_radisys.c - Intel PATA/SATA controllers -+ * -+ * (C) 2006 Red Hat <alan@redhat.com> -+ * -+ * Some parts based on ata_piix.c by Jeff Garzik and others. -+ * -+ * A PIIX relative, this device has a single ATA channel and no -+ * slave timings, SITRE or PPE. In that sense it is a close relative -+ * of the original PIIX. It does however support UDMA 33/66 per channel -+ * although no other modes/timings. Also lacking is 32bit I/O on the ATA -+ * port. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_radisys" -+#define DRV_VERSION "0.2" -+ -+/** -+ * radisys_pata_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void radisys_pata_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA80; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * radisys_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: um -+ * -+ * Set PIO mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void radisys_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ unsigned int pio = adev->pio_mode - XFER_PIO_0; -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ u16 idetm_data; -+ int control = 0; -+ -+ /* -+ * See Intel Document 298600-004 for the timing programing rules -+ * for PIIX/ICH. Note that the early PIIX does not have the slave -+ * timing port at 0x44. The Radisys is a relative of the PIIX -+ * but not the same so be careful. -+ */ -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, /* Check me */ -+ { 0, 0 }, -+ { 1, 1 }, -+ { 2, 2 }, -+ { 3, 3 }, }; -+ -+ if (pio > 0) -+ control |= 1; /* TIME1 enable */ -+ if (ata_pio_need_iordy(adev)) -+ control |= 2; /* IE IORDY */ -+ -+ pci_read_config_word(dev, 0x40, &idetm_data); -+ -+ /* Enable IE and TIME as appropriate. Clear the other -+ drive timing bits */ -+ idetm_data &= 0xCCCC; -+ idetm_data |= (control << (4 * adev->devno)); -+ idetm_data |= (timings[pio][0] << 12) | -+ (timings[pio][1] << 8); -+ pci_write_config_word(dev, 0x40, idetm_data); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * radisys_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * @isich: True if the device is an ICH and has IOCFG registers -+ * -+ * Set MWDMA mode for device, in host controller PCI config space. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); -+ u16 idetm_data; -+ u8 udma_enable; -+ -+ static const /* ISP RTC */ -+ u8 timings[][2] = { { 0, 0 }, -+ { 0, 0 }, -+ { 1, 1 }, -+ { 2, 2 }, -+ { 3, 3 }, }; -+ -+ /* -+ * MWDMA is driven by the PIO timings. We must also enable -+ * IORDY unconditionally. -+ */ -+ -+ pci_read_config_word(dev, 0x40, &idetm_data); -+ pci_read_config_byte(dev, 0x48, &udma_enable); -+ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; -+ const unsigned int needed_pio[3] = { -+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 -+ }; -+ int pio = needed_pio[mwdma] - XFER_PIO_0; -+ int control = 3; /* IORDY|TIME0 */ -+ -+ /* If the drive MWDMA is faster than it can do PIO then -+ we must force PIO0 for PIO cycles. */ -+ -+ if (adev->pio_mode < needed_pio[mwdma]) -+ control = 1; -+ -+ /* Mask out the relevant control and timing bits we will load. Also -+ clear the other drive TIME register as a precaution */ -+ -+ idetm_data &= 0xCCCC; -+ idetm_data |= control << (4 * adev->devno); -+ idetm_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8); -+ -+ udma_enable &= ~(1 << adev->devno); -+ } else { -+ u8 udma_mode; -+ -+ /* UDMA66 on. It isn't clear from the documentation whether -+ UDMA 33 and 66 are switchable via register 0x4A */ -+ -+ pci_read_config_byte(dev, 0x4A, &udma_mode); -+ -+ if (adev->xfer_mode == XFER_UDMA_2) -+ udma_mode &= ~ (1 << adev->devno); -+ else /* UDMA 4 */ -+ udma_mode |= (1 << adev->devno); -+ -+ pci_write_config_byte(dev, 0x4A, udma_mode); -+ -+ udma_enable |= (1 << adev->devno); -+ } -+ pci_write_config_word(dev, 0x40, idetm_data); -+ pci_write_config_byte(dev, 0x48, udma_enable); -+ -+ /* Track which port is configured */ -+ ap->private_data = adev; -+} -+ -+/** -+ * radisys_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Our logic also clears TIME0/TIME1 for the other device so -+ * that, even if we get this wrong, cycles to the other device will -+ * be made PIO0. -+ */ -+ -+static int radisys_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ -+ if (adev != ap->private_data) { -+ /* UDMA timing is not shared */ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ if (adev->dma_mode) -+ radisys_set_dmamode(ap, adev); -+ else if (adev->pio_mode) -+ radisys_set_piomode(ap, adev); -+ } -+ } -+ return ata_qc_issue_prot(qc); -+} -+ -+ -+static struct scsi_host_template radisys_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations radisys_pata_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = radisys_set_piomode, -+ .set_dmamode = radisys_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = radisys_pata_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = radisys_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+ -+/** -+ * radisys_init_one - Register PIIX ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in radisys_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. We probe for combined mode (sigh), -+ * and then hand over control to libata, for it to do the rest. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info info = { -+ .sht = &radisys_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, /* mwdma1-2 */ -+ .udma_mask = 0x14, /* UDMA33/66 only */ -+ .port_ops = &radisys_pata_ops, -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id radisys_pci_tbl[] = { -+ { 0x1331, 0x8201, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver radisys_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = radisys_pci_tbl, -+ .probe = radisys_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init radisys_init(void) -+{ -+ return pci_register_driver(&radisys_pci_driver); -+} -+ -+static void __exit radisys_exit(void) -+{ -+ pci_unregister_driver(&radisys_pci_driver); -+} -+ -+ -+module_init(radisys_init); -+module_exit(radisys_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for Radisys R82600 controllers"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, radisys_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_rz1000.c linux-2.6.16-rc4/drivers/scsi/pata_rz1000.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_rz1000.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_rz1000.c 2006-02-16 15:38:18.000000000 +0000 -@@ -0,0 +1,183 @@ -+/* -+ * RZ1000/1001 driver based upon -+ * -+ * linux/drivers/ide/pci/rz1000.c Version 0.06 January 12, 2003 -+ * Copyright (C) 1995-1998 Linus Torvalds & author (see below) -+ * Principal Author: mlord@pobox.com (Mark Lord) -+ * -+ * See linux/MAINTAINERS for address of current maintainer. -+ * -+ * This file provides support for disabling the buggy read-ahead -+ * mode of the RZ1000 IDE chipset, commonly used on Intel motherboards. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "rz1000" -+#define DRV_VERSION "0.01" -+ -+static void rz1000_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * rz1000_set_mode - mode setting function -+ * @ap: ATA interface -+ * -+ * Use a non standard set_mode function. We don't want to be tuned. We -+ * would prefer to be BIOS generic but for the fact our hardware is -+ * whacked out. -+ */ -+ -+static void rz1000_set_mode(struct ata_port *ap) -+{ -+ int i; -+ -+ for (i = 0; i < ATA_MAX_DEVICES; i++) { -+ struct ata_device *dev = &ap->device[i]; -+ if (ata_dev_present(dev)) { -+ /* We don't really care */ -+ dev->pio_mode = XFER_PIO_0; -+ dev->xfer_mode = XFER_PIO_0; -+ dev->xfer_shift = ATA_SHIFT_PIO; -+ dev->flags |= ATA_DFLAG_PIO; -+ } -+ } -+} -+ -+ -+static struct scsi_host_template rz1000_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations rz1000_port_ops = { -+ .set_mode = rz1000_set_mode, -+ -+ .port_disable = ata_port_disable, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = rz1000_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * rz1000_init_one - Register RZ1000 ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in rz1000_pci_tbl matching with @pdev -+ * -+ * Configure an RZ1000 interface. This doesn't require much special -+ * handling except that we *MUST* kill the chipset readahead or the -+ * user may experience data corruption. -+ */ -+ -+static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ struct ata_port_info *port_info[2]; -+ u16 reg; -+ static struct ata_port_info info = { -+ .sht = &rz1000_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &rz1000_port_ops -+ }; -+ -+ if (!printed_version++) -+ printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); -+ -+ /* Be exceptionally paranoid as we must be sure to apply the fix */ -+ if (pci_read_config_word(pdev, 0x40, ®) != 0) -+ goto fail; -+ reg &= 0xDFFF; -+ if (pci_write_config_word(pdev, 0x40, reg) != 0) -+ goto fail; -+ printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n"); -+ -+ port_info[0] = &info; -+ port_info[1] = &info; -+ return ata_pci_init_one(pdev, port_info, 2); -+fail: -+ printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n"); -+ /* Not safe to use so skip */ -+ return -ENODEV; -+} -+ -+static struct pci_device_id pata_rz1000[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), }, -+ { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), }, -+ { 0, }, -+}; -+ -+static struct pci_driver rz1000_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = pata_rz1000, -+ .probe = rz1000_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+ -+static int __init rz1000_init(void) -+{ -+ return pci_register_driver(&rz1000_pci_driver); -+} -+ -+static void __exit rz1000_exit(void) -+{ -+ pci_unregister_driver(&rz1000_pci_driver); -+} -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for RZ1000 PCI ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, pata_rz1000); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(rz1000_init); -+module_exit(rz1000_exit); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sc1200.c linux-2.6.16-rc4/drivers/scsi/pata_sc1200.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sc1200.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sc1200.c 2006-02-16 15:46:11.000000000 +0000 -@@ -0,0 +1,286 @@ -+/* -+ * New ATA layer SC1200 driver Alan Cox <alan@redhat.com> -+ * -+ * TODO: Mode selection filtering -+ * TODO: Can't enable second channel until ATA core has serialize -+ * TODO: Needs custom DMA cleanup code -+ * -+ * Based very heavily on -+ * -+ * linux/drivers/ide/pci/sc1200.c Version 0.91 28-Jan-2003 -+ * -+ * Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com> -+ * May be copied or modified under the terms of the GNU General Public License -+ * -+ * Development of this chipset driver was funded -+ * by the nice folks at National Semiconductor. -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "sc1200" -+#define DRV_VERSION "0.2" -+ -+#define SC1200_REV_A 0x00 -+#define SC1200_REV_B1 0x01 -+#define SC1200_REV_B3 0x02 -+#define SC1200_REV_C1 0x03 -+#define SC1200_REV_D1 0x04 -+ -+/** -+ * sc1200_clock - PCI clock -+ * -+ * Return the PCI bus clocking for the SC1200 chipset configuration -+ * in use. We return 0 for 33MHz 1 for 48MHz and 2 for 66Mhz -+ */ -+ -+static int sc1200_clock(void) -+{ -+ /* Magic registers that give us the chipset data */ -+ u8 chip_id = inb(0x903C); -+ u8 silicon_rev = inb(0x903D); -+ u16 pci_clock; -+ -+ if (chip_id == 0x04 && silicon_rev < SC1200_REV_B1) -+ return 0; /* 33 MHz mode */ -+ -+ /* Clock generator configuration 0x901E its 8/9 are the PCI clocking -+ 0/3 is 33Mhz 1 is 48 2 is 66 */ -+ -+ pci_clock = inw(0x901E); -+ pci_clock >>= 8; -+ pci_clock &= 0x03; -+ if (pci_clock == 3) -+ pci_clock = 0; -+ return pci_clock; -+} -+ -+/** -+ * sc1200_set_piomode - PIO setup -+ * @ap: ATA interface -+ * @adev: device on the interface -+ * -+ * Set our PIO requirements. This is fairly simple on the SC1200 -+ */ -+ -+static void sc1200_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u32 pio_timings[4][5] = { -+ {0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, // format0 33Mhz -+ {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}, // format1, 33Mhz -+ {0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021}, // format1, 48Mhz -+ {0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131} // format1, 66Mhz -+ }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 format; -+ unsigned int reg = 0x40 + 0x10 * ap->hard_port_no; -+ int mode = adev->pio_mode - XFER_PIO_0; -+ -+ pci_read_config_dword(pdev, reg + 4, &format); -+ format >>= 31; -+ format += sc1200_clock(); -+ pci_write_config_dword(pdev, reg + 8 * adev->devno, -+ pio_timings[format][mode]); -+} -+ -+/** -+ * sc1200_set_dmamode - DMA timing setup -+ * @ap: ATA interface -+ * @adev: Device being configured -+ * -+ * We cannot mix MWDMA and UDMA without reloading timings each switch -+ * master to slave. -+ */ -+ -+static void sc1200_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u32 udma_timing[3][3] = { -+ { 0x00921250, 0x00911140, 0x00911030 }, -+ { 0x00932470, 0x00922260, 0x00922140 }, -+ { 0x009436A1, 0x00933481, 0x00923261 } -+ }; -+ -+ static u32 mwdma_timing[3][3] = { -+ { 0x00077771, 0x00012121, 0x00002020 }, -+ { 0x000BBBB2, 0x00024241, 0x00013131 }, -+ { 0x000FFFF3, 0x00035352, 0x00015151 } -+ }; -+ -+ int clock = sc1200_clock(); -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned int reg = 0x40 + 0x10 * ap->hard_port_no; -+ int mode = adev->dma_mode; -+ u32 format; -+ -+ if (mode >= XFER_UDMA_0) -+ format = udma_timing[clock][mode - XFER_UDMA_0]; -+ else -+ format = mwdma_timing[clock][mode - XFER_MW_DMA_0]; -+ -+ if (adev->devno == 0) { -+ u32 timings; -+ -+ pci_read_config_dword(pdev, reg + 4, &timings); -+ timings &= 0x80000000UL; -+ timings |= format; -+ pci_write_config_dword(pdev, reg + 4, timings); -+ } else -+ pci_write_config_dword(pdev, reg + 12, format); -+} -+ -+/** -+ * sc1200_qc_issue_prot - command issue -+ * @qc: command pending -+ * -+ * Called when the libata layer is about to issue a command. We wrap -+ * this interface so that we can load the correct ATA timings if -+ * neccessary. Specifically we have a problem that there is only -+ * one MWDMA/UDMA bit. -+ */ -+ -+static int sc1200_qc_issue_prot(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ struct ata_device *adev = qc->dev; -+ struct ata_device *prev = ap->private_data; -+ -+ /* See if the DMA settings could be wrong */ -+ if (adev->dma_mode != 0 && adev != prev && prev != NULL) { -+ /* Maybe, but do the channels match MWDMA/UDMA ? */ -+ if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) || -+ (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0)) -+ /* Switch the mode bits */ -+ sc1200_set_dmamode(ap, adev); -+ } -+ -+ return ata_qc_issue_prot(qc); -+} -+ -+static struct scsi_host_template sc1200_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations sc1200_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sc1200_set_piomode, -+ .set_dmamode = sc1200_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = sc1200_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * sc1200_init_one - Initialise an SC1200 -+ * @dev: PCI device -+ * @id: Entry in match table -+ * -+ * Just throw the needed data at the libata helper and it does all -+ * our work. -+ */ -+ -+static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &sc1200_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &sc1200_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ -+ /* Can't enable port 2 yet, see top comments */ -+ return ata_pci_init_one(dev, port_info, 1); -+} -+ -+static struct pci_device_id sc1200[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), }, -+ { 0, }, -+}; -+ -+static struct pci_driver sc1200_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sc1200, -+ .probe = sc1200_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init sc1200_init(void) -+{ -+ return pci_register_driver(&sc1200_pci_driver); -+} -+ -+ -+static void __exit sc1200_exit(void) -+{ -+ pci_unregister_driver(&sc1200_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox, Mark Lord"); -+MODULE_DESCRIPTION("low-level driver for the NS/AMD SC1200"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sc1200); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(sc1200_init); -+module_exit(sc1200_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_serverworks.c linux-2.6.16-rc4/drivers/scsi/pata_serverworks.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_serverworks.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_serverworks.c 2006-02-16 15:37:31.000000000 +0000 -@@ -0,0 +1,586 @@ -+/* -+ * ata-serverworks.c - Serverworks PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * serverworks.c -+ * -+ * Copyright (C) 1998-2000 Michel Aubry -+ * Copyright (C) 1998-2000 Andrzej Krzysztofowicz -+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> -+ * Portions copyright (c) 2001 Sun Microsystems -+ * -+ * -+ * RCC/ServerWorks IDE driver for Linux -+ * -+ * OSB4: `Open South Bridge' IDE Interface (fn 1) -+ * supports UDMA mode 2 (33 MB/s) -+ * -+ * CSB5: `Champion South Bridge' IDE Interface (fn 1) -+ * all revisions support UDMA mode 4 (66 MB/s) -+ * revision A2.0 and up support UDMA mode 5 (100 MB/s) -+ * -+ * *** The CSB5 does not provide ANY register *** -+ * *** to detect 80-conductor cable presence. *** -+ * -+ * CSB6: `Champion South Bridge' IDE Interface (optional: third channel) -+ * -+ * Documentation: -+ * Available under NDA only. Errata info very hard to get. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "serverworks" -+#define DRV_VERSION "0.1.1" -+ -+#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ -+#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ -+ -+/* Seagate Barracuda ATA IV Family drives in UDMA mode 5 -+ * can overrun their FIFOs when used with the CSB5 */ -+ -+static const char *csb_bad_ata100[] = { -+ "ST320011A", -+ "ST340016A", -+ "ST360021A", -+ "ST380021A", -+ NULL -+}; -+ -+/** -+ * dell_cable - Dell serverworks cable detection -+ * @ap: ATA port to do cable detect -+ * -+ * Dell hide the 40/80 pin select for their interfaces in the top two -+ * bits of the subsystem ID. -+ */ -+ -+static int dell_cable(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ if (pdev->subsystem_device & (1 << (ap->hard_port_no + 14))) -+ return ATA_CBL_PATA80; -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * sun_cable - Sun Cobalt 'Alpine' cable detection -+ * @ap: ATA port to do cable select -+ * -+ * Cobalt CSB5 IDE hides the 40/80pin in the top two bits of the -+ * subsystem ID the same as dell. We could use one function but we may -+ * need to extend the Dell one in future -+ */ -+ -+static int sun_cable(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ if (pdev->subsystem_device & (1 << (ap->hard_port_no + 14))) -+ return ATA_CBL_PATA80; -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * osb4_cable - OSB4 cable detect -+ * @ap: ATA port to check -+ * -+ * The OSB4 isn't UDMA66 capable so this is easy -+ */ -+ -+static int osb4_cable(struct ata_port *ap) { -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * csb4_cable - CSB5/6 cable detect -+ * @ap: ATA port to check -+ * -+ * Serverworks default arrangement is to use the drive side detection -+ * only. -+ */ -+ -+static int csb_cable(struct ata_port *ap) { -+ return ATA_CBL_PATA80; -+} -+ -+struct sv_cable_table { -+ int device; -+ int subvendor; -+ int (*cable_detect)(struct ata_port *ap); -+}; -+ -+/* -+ * Note that we don't copy the old serverworks code because the old -+ * code contains obvious mistakes -+ */ -+ -+static struct sv_cable_table cable_detect[] = { -+ { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_DELL, dell_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_VENDOR_ID_DELL, dell_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_SUN, sun_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_OSB4, PCI_ANY_ID, osb4_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, csb_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, csb_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, csb_cable }, -+ { PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, csb_cable }, -+ { } -+}; -+ -+/** -+ * serverworks_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection according to the device and subvendor -+ * identifications -+ */ -+ -+static int serverworks_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct sv_cable_table *cb = cable_detect; -+ -+ while(cb->device) { -+ if (cb->device == pdev->device && -+ (cb->subvendor == pdev->subsystem_vendor || -+ cb->subvendor == PCI_ANY_ID)) { -+ return cb->cable_detect(ap); -+ } -+ cb++; -+ } -+ BUG(); -+} -+ -+static void serverworks_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = serverworks_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * serverworks_is_csb - Check for CSB or OSB -+ * @pdev: PCI device to check -+ * -+ * Returns true if the device being checked is known to be a CSB -+ * series device. -+ */ -+ -+static u8 serverworks_is_csb(struct pci_dev *pdev) -+{ -+ switch (pdev->device) { -+ case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: -+ case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE: -+ case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2: -+ case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE: -+ return 1; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+/** -+ * serverworks_osb4_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Filter the offered modes for the device to apply controller -+ * specific rules. OSB4 requires no UDMA for disks due to a FIFO -+ * bug we hit. -+ */ -+ -+static unsigned int serverworks_osb4_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ if (shift != ATA_SHIFT_UDMA) -+ return mask; -+ if (adev->class == ATA_DEV_ATA) -+ return 0; -+ return mask; -+} -+ -+ -+/** -+ * serverworks_csb_filter - mode selection filter -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Check the blacklist and disable UDMA5 if matched -+ */ -+ -+static unsigned int serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned int mask, int shift) -+{ -+ const char *p; -+ char model_num[40]; -+ int len, i; -+ -+ /* Disk, UDMA */ -+ if (shift != ATA_SHIFT_UDMA) -+ return mask; -+ if (adev->class != ATA_DEV_ATA) -+ return mask; -+ -+ /* Actually do need to check */ -+ ata_dev_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num)); -+ /* Precuationary - why not do this in the libata core ?? */ -+ -+ len = strlen(model_num); -+ while ((len > 0) && (model_num[len - 1] == ' ')) { -+ len--; -+ model_num[len] = 0; -+ } -+ -+ for(i = 0; (p = csb_bad_ata100[i]) != NULL; i++) { -+ if (!strncmp(p, model_num, len)) -+ return mask & 0x1F; -+ } -+ return mask; -+} -+ -+ -+/** -+ * serverworks_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the OSB4/CSB5 timing registers for PIO. The PIO register -+ * load is done as a simple lookup. -+ */ -+static void serverworks_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 pio_mode[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; -+ int offset = 1 + 2 * ap->hard_port_no - adev->devno; -+ int devbits = (2 * ap->hard_port_no + adev->devno) * 4; -+ u16 csb5_pio; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int pio = adev->pio_mode - XFER_PIO_0; -+ -+ pci_write_config_byte(pdev, 0x40 + offset, pio_mode[pio]); -+ -+ /* The OSB4 just requires the timing but the CSB series want the -+ mode number as well */ -+ if (serverworks_is_csb(pdev)) { -+ pci_read_config_word(pdev, 0x4A, &csb5_pio); -+ csb5_pio &= ~(0x0F << devbits); -+ pci_write_config_byte(pdev, 0x4A, csb5_pio | (pio << devbits)); -+ } -+} -+ -+/** -+ * serverworks_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the serverworks OSB4/CSB5 -+ * chipset. The MWDMA mode values are pulled from a lookup table -+ * while the chipset uses mode number for UDMA. -+ */ -+ -+static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 dma_mode[] = { 0x77, 0x21, 0x20 }; -+ int offset = 1 + 2 * ap->hard_port_no - adev->devno; -+ int devbits = (2 * ap->hard_port_no + adev->devno); -+ u8 ultra; -+ u8 ultra_cfg; -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ pci_read_config_byte(pdev, 0x54, &ultra_cfg); -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ pci_write_config_byte(pdev, 0x44 + offset, 0x20); -+ -+ pci_read_config_byte(pdev, 0x56 + ap->hard_port_no, &ultra); -+ ultra &= ~(0x0F << (ap->hard_port_no * 4)); -+ ultra |= (adev->dma_mode - XFER_UDMA_0) -+ << (ap->hard_port_no * 4); -+ pci_write_config_byte(pdev, 0x56 + ap->hard_port_no, ultra); -+ -+ ultra_cfg |= (1 << devbits); -+ } else { -+ pci_write_config_byte(pdev, 0x44 + offset, -+ dma_mode[adev->dma_mode - XFER_MW_DMA_0]); -+ ultra_cfg &= ~(1 << devbits); -+ } -+ pci_write_config_byte(pdev, 0x54, ultra_cfg); -+} -+ -+static struct scsi_host_template serverworks_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations serverworks_osb4_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = serverworks_set_piomode, -+ .set_dmamode = serverworks_set_dmamode, -+ .mode_filter = serverworks_osb4_filter, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = serverworks_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations serverworks_csb_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = serverworks_set_piomode, -+ .set_dmamode = serverworks_set_dmamode, -+ .mode_filter = serverworks_csb_filter, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = serverworks_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int serverworks_fixup_osb4(struct pci_dev *pdev) -+{ -+ u32 reg; -+ struct pci_dev *isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, -+ PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); -+ if (isa_dev) { -+ pci_read_config_dword(isa_dev, 0x64, ®); -+ reg &= ~0x00002000; /* disable 600ns interrupt mask */ -+ if (!(reg & 0x00004000)) -+ printk(KERN_DEBUG DRV_NAME ": UDMA not BIOS enabled.\n"); -+ reg |= 0x00004000; /* enable UDMA/33 support */ -+ pci_write_config_dword(isa_dev, 0x64, reg); -+ pci_dev_put(isa_dev); -+ return 0; -+ } -+ printk(KERN_WARNING "ata_serverworks: Unable to find bridge.\n"); -+ return -ENODEV; -+} -+ -+static int serverworks_fixup_csb(struct pci_dev *pdev) -+{ -+ u8 rev; -+ u8 btr; -+ -+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); -+ -+ /* Third Channel Test */ -+ if (!(PCI_FUNC(pdev->devfn) & 1)) { -+ struct pci_dev * findev = NULL; -+ u32 reg4c = 0; -+ findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, -+ PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL); -+ if (findev) { -+ pci_read_config_dword(findev, 0x4C, ®4c); -+ reg4c &= ~0x000007FF; -+ reg4c |= 0x00000040; -+ reg4c |= 0x00000020; -+ pci_write_config_dword(findev, 0x4C, reg4c); -+ pci_dev_put(findev); -+ } -+ } else { -+ struct pci_dev * findev = NULL; -+ u8 reg41 = 0; -+ -+ findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, -+ PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL); -+ if (findev) { -+ pci_read_config_byte(findev, 0x41, ®41); -+ reg41 &= ~0x40; -+ pci_write_config_byte(findev, 0x41, reg41); -+ pci_dev_put(findev); -+ } -+ } -+ /* setup the UDMA Control register -+ * -+ * 1. clear bit 6 to enable DMA -+ * 2. enable DMA modes with bits 0-1 -+ * 00 : legacy -+ * 01 : udma2 -+ * 10 : udma2/udma4 -+ * 11 : udma2/udma4/udma5 -+ */ -+ pci_read_config_byte(pdev, 0x5A, &btr); -+ btr &= ~0x40; -+ if (!(PCI_FUNC(pdev->devfn) & 1)) -+ btr |= 0x2; -+ else -+ btr |= (rev >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2; -+ pci_write_config_byte(pdev, 0x5A, btr); -+ -+ return btr; -+} -+ -+static void serverworks_fixup_ht1000(struct pci_dev *pdev) -+{ -+ u8 btr; -+ /* Setup HT1000 SouthBridge Controller - Single Channel Only */ -+ pci_read_config_byte(pdev, 0x5A, &btr); -+ btr &= ~0x40; -+ btr |= 0x3; -+ pci_write_config_byte(pdev, 0x5A, btr); -+} -+ -+ -+static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ int ports = 2; -+ static struct ata_port_info info[4] = { -+ { /* OSB4 */ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x07, -+ .port_ops = &serverworks_osb4_port_ops -+ }, { /* OSB4 no UDMA */ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x00, -+ .port_ops = &serverworks_osb4_port_ops -+ }, { /* CSB5 */ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &serverworks_csb_port_ops -+ }, { /* CSB5 - later revisions*/ -+ .sht = &serverworks_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &serverworks_csb_port_ops -+ } -+ }; -+ static struct ata_port_info *port_info[2]; -+ struct ata_port_info *devinfo = &info[id->driver_data]; -+ -+ /* Force master latency timer to 64 PCI clocks */ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); -+ -+ /* OSB4 : South Bridge and IDE */ -+ if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { -+ /* Select non UDMA capable OSB4 if we can't do fixups */ -+ if ( serverworks_fixup_osb4(pdev) < 0) -+ devinfo = &info[1]; -+ } -+ /* setup CSB5/CSB6 : South Bridge and IDE option RAID */ -+ else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) || -+ (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || -+ (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { -+ -+ /* If the returned btr is the newer revision then -+ select the right info block */ -+ if (serverworks_fixup_csb(pdev) == 3) -+ devinfo = &info[3]; -+ -+ /* Is this the 3rd channel CSB6 IDE ? */ -+ if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) -+ ports = 1; -+ } -+ /* setup HT1000E */ -+ else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) -+ serverworks_fixup_ht1000(pdev); -+ -+ if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) -+ ata_pci_clear_simplex(pdev); -+ -+ port_info[0] = port_info[1] = devinfo; -+ return ata_pci_init_one(pdev, port_info, ports); -+} -+ -+static struct pci_device_id serverworks[] = { -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -+ { 0, }, -+}; -+ -+static struct pci_driver serverworks_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = serverworks, -+ .probe = serverworks_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init serverworks_init(void) -+{ -+ return pci_register_driver(&serverworks_pci_driver); -+} -+ -+ -+static void __exit serverworks_exit(void) -+{ -+ pci_unregister_driver(&serverworks_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, serverworks); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(serverworks_init); -+module_exit(serverworks_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sil680.c linux-2.6.16-rc4/drivers/scsi/pata_sil680.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sil680.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sil680.c 2006-02-16 15:28:00.000000000 +0000 -@@ -0,0 +1,368 @@ -+/* -+ * pata_sil680.c - SIL680 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003 -+ * -+ * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> -+ * Copyright (C) 2003 Red Hat <alan@redhat.com> -+ * -+ * May be copied or modified under the terms of the GNU General Public License -+ * -+ * Documentation publically available. -+ * -+ * If you have strange problems with nVidia chipset systems please -+ * see the SI support documentation and update your system BIOS -+ * if neccessary -+ * -+ * TODO -+ * If we know all our devices are LBA28 (or LBA28 sized) we could use -+ * the command fifo mode. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_sil680" -+#define DRV_VERSION "0.2.1" -+ -+/** -+ * sil680_selreg - return register base -+ * @hwif: interface -+ * @r: config offset -+ * -+ * Turn a config register offset into the right address in either -+ * PCI space or MMIO space to access the control register in question -+ * Thankfully this is a configuration operation so isnt performance -+ * criticial. -+ */ -+ -+static unsigned long sil680_selreg(struct ata_port *ap, int r) -+{ -+ unsigned long base = 0xA0 + r; -+ base += (ap->hard_port_no << 4); -+ return base; -+} -+ -+/** -+ * sil680_seldev - return register base -+ * @hwif: interface -+ * @r: config offset -+ * -+ * Turn a config register offset into the right address in either -+ * PCI space or MMIO space to access the control register in question -+ * including accounting for the unit shift. -+ */ -+ -+static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r) -+{ -+ unsigned long base = 0xA0 + r; -+ base += (ap->hard_port_no << 4); -+ base |= adev->devno ? 2 : 0; -+ return base; -+} -+ -+ -+/** -+ * sil680_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. The SIL680 stores this in PCI config -+ * space for us. -+ */ -+ -+static int sil680_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned long addr = sil680_selreg(ap, 0); -+ u8 ata66; -+ pci_read_config_byte(pdev, addr, &ata66); -+ if (ata66 & 1) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * sil680_bus_reset - reset the SIL680 bus -+ * @ap: ATA port to reset -+ * -+ * Perform the SIL680 housekeeping when doing an ATA bus reset -+ */ -+ -+static void sil680_bus_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned long addr = sil680_selreg(ap, 0); -+ u8 reset; -+ -+ pci_read_config_byte(pdev, addr, &reset); -+ pci_write_config_byte(pdev, addr, reset | 0x03); -+ udelay(25); -+ pci_write_config_byte(pdev, addr, reset); -+ ata_bus_reset(ap); -+} -+ -+static void sil680_phy_reset(struct ata_port *ap) -+{ -+ ap->cbl = sil680_cable_detect(ap); -+ sil680_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * sil680_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the SIL680 registers for PIO mode. Note that the task speed -+ * registers are shared between the devices so we must pick the lowest -+ * mode for command work. -+ */ -+ -+static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 }; -+ static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 }; -+ -+ unsigned long tfaddr = sil680_selreg(ap, 0x02); -+ unsigned long addr = sil680_seldev(ap, adev, 0x04); -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int pio = adev->pio_mode - XFER_PIO_0; -+ int lowest_pio = pio; -+ u16 reg; -+ -+ struct ata_device *pair = ata_dev_pair(ap, adev); -+ -+ if (pair != NULL) { -+ if (adev->pio_mode > pair->pio_mode) -+ lowest_pio = pair->pio_mode - XFER_PIO_0; -+ } -+ -+ pci_write_config_word(pdev, addr, speed_p[pio]); -+ pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]); -+ -+ pci_read_config_word(pdev, tfaddr-2, ®); -+ reg &= ~0x0200; /* Clear IORDY */ -+ if (ata_pio_need_iordy(adev)) -+ reg |= 0x0200; /* Enable IORDY */ -+ pci_write_config_word(pdev, tfaddr-2, reg); -+} -+ -+/** -+ * sil680_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Program the MWDMA/UDMA modes for the sil680 k -+ * chipset. The MWDMA mode values are pulled from a lookup table -+ * while the chipset uses mode number for UDMA. -+ */ -+ -+static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ static u8 ultra_table[2][7] = { -+ { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */ -+ { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */ -+ }; -+ static u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 }; -+ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ unsigned long ma = sil680_seldev(ap, adev, 0x08); -+ unsigned long ua = sil680_seldev(ap, adev, 0x0C); -+ unsigned long addr_mask = 0x80 + 4 * ap->hard_port_no; -+ int port_shift = adev->devno * 4; -+ u8 scsc, mode; -+ u16 multi, ultra; -+ -+ pci_read_config_byte(pdev, 0x8A, &scsc); -+ pci_read_config_byte(pdev, addr_mask, &mode); -+ pci_read_config_word(pdev, ma, &multi); -+ pci_read_config_word(pdev, ua, &ultra); -+ -+ /* Mask timing bits */ -+ ultra &= ~0x3F; -+ mode &= ~(0x03 << port_shift); -+ -+ /* Extract scsc */ -+ scsc = (scsc & 0x30) ? 1: 0; -+ -+ if (adev->dma_mode >= XFER_UDMA_0) { -+ multi = 0x10C1; -+ ultra |= ultra_table[scsc][adev->dma_mode - XFER_UDMA_0]; -+ mode |= (0x03 << port_shift); -+ } else { -+ multi = dma_table[adev->dma_mode - XFER_MW_DMA_0]; -+ mode |= (0x02 << port_shift); -+ } -+ pci_write_config_byte(pdev, addr_mask, mode); -+ pci_write_config_word(pdev, ma, multi); -+ pci_write_config_word(pdev, ua, ultra); -+} -+ -+static struct scsi_host_template sil680_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations sil680_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sil680_set_piomode, -+ .set_dmamode = sil680_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = sil680_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &sil680_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7f, -+ .port_ops = &sil680_port_ops -+ }; -+ static struct ata_port_info info_slow = { -+ .sht = &sil680_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &sil680_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = {&info, &info}; -+ static int printed_version; -+ u32 class_rev = 0; -+ u8 tmpbyte = 0; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -+ -+ pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); -+ class_rev &= 0xff; -+ /* FIXME: double check */ -+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); -+ -+ pci_write_config_byte(pdev, 0x80, 0x00); -+ pci_write_config_byte(pdev, 0x84, 0x00); -+ pci_read_config_byte(pdev, 0x8A, &tmpbyte); -+ switch(tmpbyte & 0x30) { -+ case 0x00: -+ /* 133 clock attempt to force it on */ -+ pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10); -+ case 0x30: -+ /* if clocking is disabled */ -+ /* 133 clock attempt to force it on */ -+ pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20); -+ case 0x10: -+ /* 133 already */ -+ break; -+ case 0x20: -+ /* BIOS set PCI x2 clocking */ -+ break; -+ } -+ -+ pci_read_config_byte(pdev, 0x8A, &tmpbyte); -+ if ((tmpbyte & 0x30) == 0) -+ port_info[0] = port_info[1] = &info_slow; -+ -+ pci_write_config_byte(pdev, 0xA1, 0x72); -+ pci_write_config_word(pdev, 0xA2, 0x328A); -+ pci_write_config_dword(pdev, 0xA4, 0x62DD62DD); -+ pci_write_config_dword(pdev, 0xA8, 0x43924392); -+ pci_write_config_dword(pdev, 0xAC, 0x40094009); -+ pci_write_config_byte(pdev, 0xB1, 0x72); -+ pci_write_config_word(pdev, 0xB2, 0x328A); -+ pci_write_config_dword(pdev, 0xB4, 0x62DD62DD); -+ pci_write_config_dword(pdev, 0xB8, 0x43924392); -+ pci_write_config_dword(pdev, 0xBC, 0x40094009); -+ -+ switch(tmpbyte & 0x30) { -+ case 0x00: printk(KERN_INFO "sil680: 100MHz clock.\n");break; -+ case 0x10: printk(KERN_INFO "sil680: 133MHz clock.\n");break; -+ case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break; -+ /* This last case is _NOT_ ok */ -+ case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n"); -+ return -EIO; -+ } -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id sil680[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), }, -+ { 0, }, -+}; -+ -+static struct pci_driver sil680_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sil680, -+ .probe = sil680_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init sil680_init(void) -+{ -+ return pci_register_driver(&sil680_pci_driver); -+} -+ -+ -+static void __exit sil680_exit(void) -+{ -+ pci_unregister_driver(&sil680_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for SI680 PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sil680); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(sil680_init); -+module_exit(sil680_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sis.c linux-2.6.16-rc4/drivers/scsi/pata_sis.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sis.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sis.c 2006-02-16 15:36:13.000000000 +0000 -@@ -0,0 +1,982 @@ -+/* -+ * pata_sis.c - SiS ATA driver -+ * -+ * (C) 2005 Red Hat <alan@redhat.com> -+ * -+ * Based upon linux/drivers/ide/pci/sis5513.c -+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> -+ * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer -+ * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> -+ * SiS Taiwan : for direct support and hardware. -+ * Daniela Engert : for initial ATA100 advices and numerous others. -+ * John Fremlin, Manfred Spraul, Dave Morgan, Peter Kjellerstedt : -+ * for checking code correctness, providing patches. -+ * Original tests and design on the SiS620 chipset. -+ * ATA100 tests and design on the SiS735 chipset. -+ * ATA16/33 support from specs -+ * ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw> -+ * -+ * -+ * TODO -+ * Check MWDMA on drives that don't support MWDMA speed pio cycles ? -+ * More Testing -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+#include <linux/ata.h> -+ -+#define DRV_NAME "pata_sis" -+#define DRV_VERSION "0.1" -+ -+struct sis_chipset { -+ u16 device; /* PCI host ID */ -+ struct ata_port_info *info; /* Info block */ -+ /* Probably add family, cable detect type etc here to clean -+ up code later */ -+}; -+ -+/** -+ * sis_133_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Perform cable detection for the later UDMA133 capable -+ * SiS chipset. -+ */ -+ -+static int sis_133_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 tmp; -+ -+ pci_read_config_word(pdev, 0x50 + 2 * ap->hard_port_no, &tmp); -+ if (tmp & 0x8000) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * sis_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sis_enable_bits[] = { -+ { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = sis_133_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * sis_66_cable_detect - check for 40/80 pin -+ * @ap: Port -+ * -+ * Perform cable detection on the UDMA66, UDMA100 and early UDMA133 -+ * SiS IDE controllers. -+ */ -+ -+static int sis_66_cable_detect(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 tmp; -+ -+ pci_read_config_byte(pdev, 0x48, &tmp); -+ tmp >>= ap->hard_port_no; -+ if (tmp & 0x10) -+ return ATA_CBL_PATA40; -+ return ATA_CBL_PATA80; -+} -+ -+/** -+ * sis_66_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_66_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sis_enable_bits[] = { -+ { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = sis_66_cable_detect(ap); -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * sis_old_phy_reset - Probe specified port on PATA host controller -+ * @ap: Port to probe -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_old_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sis_enable_bits[] = { -+ { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ -+ { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ -+ }; -+ -+ if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * sis_set_fifo - Set RWP fifo bits for this device -+ * @ap: Port -+ * @adev: Device -+ * -+ * SIS chipsets implement prefetch/postwrite bits for each device -+ * on both channels. This functionality is not ATAPI compatible and -+ * must be configured according to the class of device present -+ */ -+ -+static void sis_set_fifo(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u8 reg4b; -+ u8 mask = 0x11; -+ -+ mask <<= (2 * ap->hard_port_no); -+ mask <<= adev->devno; -+ -+ pci_read_config_byte(pdev, 0x4B, ®4b); -+ reg4b &= ~mask; -+ -+ /* Enable for ATA (disk) only */ -+ if (adev->class == ATA_DEV_ATA) -+ reg4b |= mask; -+ pci_write_config_byte(pdev, 0x4B, reg4b); -+} -+ -+/** -+ * sis_old_set_piomode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring for. -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * function handles PIO set up for all chips that are pre ATA100 and -+ * also early ATA100 devices. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u8 t1, t2; -+ int speed = adev->pio_mode - XFER_PIO_0; -+ -+ const u8 active[] = { 0x00, 0x07, 0x04, 0x03, 0x01 }; -+ const u8 recovery[] = { 0x00, 0x06, 0x04, 0x03, 0x03 }; -+ -+ sis_set_fifo(ap, adev); -+ -+ pci_read_config_byte(pdev, port, &t1); -+ pci_read_config_byte(pdev, port + 1, &t2); -+ -+ t1 &= ~0x0F; /* Clear active/recovery timings */ -+ t2 &= ~0x07; -+ -+ t1 |= active[speed]; -+ t2 |= recovery[speed]; -+ -+ pci_write_config_byte(pdev, port, t1); -+ pci_write_config_byte(pdev, port + 1, t2); -+} -+ -+/** -+ * sis_100_set_pioode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring for. -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * function handles PIO set up for ATA100 devices and early ATA133. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ int speed = adev->pio_mode - XFER_PIO_0; -+ -+ const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 }; -+ -+ sis_set_fifo(ap, adev); -+ -+ pci_write_config_byte(pdev, port, actrec[speed]); -+} -+ -+/** -+ * sis_133_set_pioode - Initialize host controller PATA PIO timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device we are configuring for. -+ * -+ * Set PIO mode for device, in host controller PCI config space. This -+ * function handles PIO set up for the later ATA133 devices. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_set_piomode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int port = 0x40; -+ u32 t1; -+ u32 reg54; -+ int speed = adev->pio_mode - XFER_PIO_0; -+ -+ const u32 timing100[] = { -+ 0x28269000, /* Recovery << 24 | Act << 16 | Ini << 12 */ -+ 0x0C266000, -+ 0x04263000, -+ 0x0C0A3000, -+ 0x05093000 -+ }; -+ const u32 timing133[] = { -+ 0x1E1C6000, /* Recovery << 24 | Act << 16 | Ini << 12 */ -+ 0x091C4000, -+ 0x031C2000, -+ 0x09072000, -+ 0x04062000 -+ }; -+ -+ sis_set_fifo(ap, adev); -+ -+ pci_read_config_dword(pdev, 0x54, ®54); -+ if (reg54 & 0x40000000) -+ port = 0x70; -+ port += 8 * ap->hard_port_no + 4 * adev->devno; -+ -+ pci_read_config_dword(pdev, port, &t1); -+ t1 &= 0xC0C00FFF; /* Mask out timing */ -+ -+ if (t1 & 0x08) /* 100 or 133 ? */ -+ t1 |= timing133[speed]; -+ else -+ t1 |= timing100[speed]; -+ pci_write_config_byte(pdev, port, t1); -+} -+ -+/** -+ * sis_old_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles pre UDMA and UDMA33 devices. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; -+ const u16 udma_bits[] = { -+ 0xE000, 0xC000, 0xA000 -+ }; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ /* bits 3-0 hold recovery timing bits 8-10 active timing and -+ the higer bits are dependant on the device */ -+ timing &= ~ 0x870F; -+ timing |= mwdma_bits[speed]; -+ pci_write_config_word(pdev, drive_pci, timing); -+ } else { -+ /* Bit 15 is UDMA on/off, bit 13-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x6000; -+ timing |= udma_bits[speed]; -+ } -+} -+ -+/** -+ * sis_66_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles UDMA66 and early UDMA100 devices. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; -+ const u16 udma_bits[] = { 0xF000, 0xD000, 0xB000, 0xA000, 0x9000}; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ /* bits 3-0 hold recovery timing bits 8-10 active timing and -+ the higer bits are dependant on the device, bit 15 udma */ -+ timing &= ~ 0x870F; -+ timing |= mwdma_bits[speed]; -+ } else { -+ /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x6000; -+ timing |= udma_bits[speed]; -+ } -+ pci_write_config_word(pdev, drive_pci, timing); -+} -+ -+/** -+ * sis_100_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles UDMA66 and early UDMA100 devices. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 udma_bits[] = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ -+ } else { -+ /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x0F00; -+ timing |= udma_bits[speed]; -+ } -+ pci_write_config_word(pdev, drive_pci, timing); -+} -+ -+/** -+ * sis_133_early_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles early SiS 961 bridges. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int drive_pci = 0x40 + 4 * ap->hard_port_no + 2 * adev->devno; -+ u16 timing; -+ -+ const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; -+ -+ pci_read_config_word(pdev, drive_pci, &timing); -+ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ -+ } else { -+ /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ -+ speed = adev->dma_mode - XFER_UDMA_0; -+ timing &= ~0x0F00; -+ timing |= udma_bits[speed]; -+ } -+ pci_write_config_word(pdev, drive_pci, timing); -+} -+ -+/** -+ * sis_133_set_dmamode - Initialize host controller PATA DMA timings -+ * @ap: Port whose timings we are configuring -+ * @adev: Device to program -+ * -+ * Set UDMA/MWDMA mode for device, in host controller PCI config space. -+ * Handles early SiS 961 bridges. Supports MWDMA as well unlike -+ * the old ide/pci driver. -+ * -+ * LOCKING: -+ * None (inherited from caller). -+ */ -+ -+static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ int speed = adev->dma_mode - XFER_MW_DMA_0; -+ int port = 0x40; -+ u32 t1; -+ u32 reg54; -+ -+ /* bits 4- cycle time 8 - cvs time */ -+ const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 }; -+ const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 }; -+ -+ pci_read_config_dword(pdev, 0x54, ®54); -+ if (reg54 & 0x40000000) -+ port = 0x70; -+ port += 8 * ap->hard_port_no + 4 * adev->devno; -+ -+ pci_read_config_dword(pdev, port, &t1); -+ -+ if (adev->dma_mode < XFER_UDMA_0) { -+ t1 &= ~0x00000004; -+ /* FIXME: need data sheet to add MWDMA here. Also lacking on -+ ide/pci driver */ -+ } else { -+ speed = adev->dma_mode - XFER_UDMA_0; -+ /* if & 8 no UDMA133 - need info for ... */ -+ t1 &= ~0x00000FF0; -+ t1 |= 0x00000004; -+ if (t1 & 0x08) -+ t1 |= timing_u133[speed]; -+ else -+ t1 |= timing_u100[speed]; -+ } -+ pci_write_config_dword(pdev, port, t1); -+} -+ -+static struct scsi_host_template sis_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static const struct ata_port_operations sis_133_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_133_set_piomode, -+ .set_dmamode = sis_133_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = sis_133_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_133_early_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_100_set_piomode, -+ .set_dmamode = sis_133_early_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = sis_66_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_100_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_100_set_piomode, -+ .set_dmamode = sis_100_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = sis_66_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_66_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_old_set_piomode, -+ .set_dmamode = sis_66_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = sis_66_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static const struct ata_port_operations sis_old_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sis_old_set_piomode, -+ .set_dmamode = sis_old_set_dmamode, -+ -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = sis_old_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .eng_timeout = ata_eng_timeout, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop, -+}; -+ -+static struct ata_port_info sis_info = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, -+ .udma_mask = 0, -+ .port_ops = &sis_old_ops, -+}; -+static struct ata_port_info sis_info33 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .mwdma_mask = 0x07, -+ .udma_mask = ATA_UDMA2, /* UDMA 33 */ -+ .port_ops = &sis_old_ops, -+}; -+static struct ata_port_info sis_info66 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA4, /* UDMA 66 */ -+ .port_ops = &sis_66_ops, -+}; -+static struct ata_port_info sis_info100 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA5, -+ .port_ops = &sis_100_ops, -+}; -+static struct ata_port_info sis_info100_early = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .udma_mask = ATA_UDMA5, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .port_ops = &sis_66_ops, -+}; -+static struct ata_port_info sis_info133 = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &sis_133_ops, -+}; -+static struct ata_port_info sis_info133_early = { -+ .sht = &sis_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, /* pio0-4 */ -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &sis_133_early_ops, -+}; -+ -+ -+static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis) -+{ -+ u16 regw; -+ u8 reg; -+ -+ if (sis->info == &sis_info133) { -+ pci_read_config_word(pdev, 0x50, ®w); -+ if (regw & 0x08) -+ pci_write_config_word(pdev, 0x50, regw & ~0x08); -+ pci_read_config_word(pdev, 0x52, ®w); -+ if (regw & 0x08) -+ pci_write_config_word(pdev, 0x52, regw & ~0x08); -+ return; -+ } -+ -+ if (sis->info == &sis_info133_early || sis->info == &sis_info100) { -+ /* Fix up latency */ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); -+ /* Set compatibility bit */ -+ pci_read_config_byte(pdev, 0x49, ®); -+ if (!(reg & 0x01)) -+ pci_write_config_byte(pdev, 0x49, reg | 0x01); -+ return; -+ } -+ -+ if (sis->info == &sis_info66 || sis->info == &sis_info100_early) { -+ /* Fix up latency */ -+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); -+ /* Set compatibility bit */ -+ pci_read_config_byte(pdev, 0x52, ®); -+ if (!(reg & 0x04)) -+ pci_write_config_byte(pdev, 0x52, reg | 0x04); -+ return; -+ } -+ -+ if (sis->info == &sis_info33) { -+ pci_read_config_byte(pdev, PCI_CLASS_PROG, ®); -+ if (( reg & 0x0F ) != 0x00) -+ pci_write_config_byte(pdev, PCI_CLASS_PROG, reg & 0xF0); -+ /* Fall through to ATA16 fixup below */ -+ } -+ -+ if (sis->info == &sis_info || sis->info == &sis_info33) { -+ /* force per drive recovery and active timings -+ needed on ATA_33 and below chips */ -+ pci_read_config_byte(pdev, 0x52, ®); -+ if (!(reg & 0x08)) -+ pci_write_config_byte(pdev, 0x52, reg|0x08); -+ return; -+ } -+ -+ BUG(); -+} -+ -+/** -+ * sis_init_one - Register SiS ATA PCI device with kernel services -+ * @pdev: PCI device to register -+ * @ent: Entry in sis_pci_tbl matching with @pdev -+ * -+ * Called from kernel PCI layer. We probe for combined mode (sigh), -+ * and then hand over control to libata, for it to do the rest. -+ * -+ * LOCKING: -+ * Inherited from PCI layer (may sleep). -+ * -+ * RETURNS: -+ * Zero on success, or -ERRNO value. -+ */ -+ -+static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ static int printed_version; -+ static struct ata_port_info *port_info[2]; -+ struct ata_port_info *port; -+ struct pci_dev *host; -+ struct sis_chipset *chipset = NULL; -+ -+ static struct sis_chipset sis_chipsets[] = { -+ { 0x0745, &sis_info100 }, -+ { 0x0735, &sis_info100 }, -+ { 0x0733, &sis_info100 }, -+ { 0x0635, &sis_info100 }, -+ { 0x0633, &sis_info100 }, -+ -+ { 0x0730, &sis_info100_early }, /* 100 with ATA 66 layout */ -+ { 0x0550, &sis_info100_early }, /* 100 with ATA 66 layout */ -+ -+ { 0x0640, &sis_info66 }, -+ { 0x0630, &sis_info66 }, -+ { 0x0620, &sis_info66 }, -+ { 0x0540, &sis_info66 }, -+ { 0x0530, &sis_info66 }, -+ -+ { 0x5600, &sis_info33 }, -+ { 0x5598, &sis_info33 }, -+ { 0x5597, &sis_info33 }, -+ { 0x5591, &sis_info33 }, -+ { 0x5582, &sis_info33 }, -+ { 0x5581, &sis_info33 }, -+ -+ { 0x5596, &sis_info }, -+ { 0x5571, &sis_info }, -+ { 0x5517, &sis_info }, -+ { 0x5511, &sis_info }, -+ -+ {0} -+ }; -+ static struct sis_chipset sis133_early = { -+ 0x0, &sis_info133_early -+ }; -+ static struct sis_chipset sis133 = { -+ 0x0, &sis_info133 -+ }; -+ static struct sis_chipset sis100_early = { -+ 0x0, &sis_info100_early -+ }; -+ static struct sis_chipset sis100 = { -+ 0x0, &sis_info100 -+ }; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, -+ "version " DRV_VERSION "\n"); -+ -+ /* We have to find the bridge first */ -+ -+ for (chipset = &sis_chipsets[0]; chipset->device; chipset++) { -+ host = pci_get_device(0x1039, chipset->device, NULL); -+ if (host != NULL) { -+ if (chipset->device == 0x630) { /* SIS630 */ -+ u8 host_rev; -+ pci_read_config_byte(host, PCI_REVISION_ID, &host_rev); -+ if (host_rev >= 0x30) /* 630 ET */ -+ chipset = &sis100_early; -+ } -+ break; -+ } -+ } -+ -+ /* Look for concealed bridges */ -+ if (host == NULL) { -+ /* Second check */ -+ u32 idemisc; -+ u16 trueid; -+ -+ /* Disable ID masking and register remapping then -+ see what the real ID is */ -+ -+ pci_read_config_dword(pdev, 0x54, &idemisc); -+ pci_write_config_dword(pdev, 0x54, idemisc & 0x7fffffff); -+ pci_read_config_word(pdev, PCI_DEVICE_ID, &trueid); -+ pci_write_config_dword(pdev, 0x54, idemisc); -+ -+ switch(trueid) { -+ case 0x5518: /* SIS 962/963 */ -+ chipset = &sis133; -+ if ((idemisc & 0x40000000) == 0) { -+ pci_write_config_dword(pdev, 0x54, idemisc | 0x40000000); -+ printk(KERN_INFO "SIS5513: Switching to 5513 register mapping\n"); -+ } -+ break; -+ case 0x0180: /* SIS 965/965L */ -+ chipset = &sis133; -+ break; -+ case 0x1180: /* SIS 966/966L */ -+ chipset = &sis133; -+ break; -+ } -+ } -+ -+ /* Further check */ -+ if (chipset == NULL) { -+ struct pci_dev *lpc_bridge; -+ u16 trueid; -+ u8 prefctl; -+ u8 idecfg; -+ u8 sbrev; -+ -+ /* Try the second unmasking technique */ -+ pci_read_config_byte(pdev, 0x4a, &idecfg); -+ pci_write_config_byte(pdev, 0x4a, idecfg | 0x10); -+ pci_read_config_word(pdev, PCI_DEVICE_ID, &trueid); -+ pci_write_config_byte(pdev, 0x4a, idecfg); -+ -+ switch(trueid) { -+ case 0x5517: -+ lpc_bridge = pci_get_slot(0x00, 0x10); /* Bus 0 Dev 2 Fn 0 */ -+ if (lpc_bridge == NULL) -+ break; -+ pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev); -+ pci_read_config_byte(pdev, 0x49, &prefctl); -+ pci_dev_put(lpc_bridge); -+ -+ if (sbrev == 0x10 && (prefctl & 0x80)) { -+ chipset = &sis133_early; -+ break; -+ } -+ chipset = &sis100; -+ break; -+ } -+ } -+ pci_dev_put(host); -+ -+ /* No chipset info, no support */ -+ if (chipset == NULL) -+ return -ENODEV; -+ -+ port = chipset->info; -+ port->private_data = chipset; -+ -+ sis_fixup(pdev, chipset); -+ -+ port_info[0] = port_info[1] = port; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id sis_pci_tbl[] = { -+ { 0x1039, 0x5513, PCI_ANY_ID, PCI_ANY_ID, }, -+ { 0x1039, 0x5518, PCI_ANY_ID, PCI_ANY_ID, }, -+ { } /* terminate list */ -+}; -+ -+static struct pci_driver sis_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sis_pci_tbl, -+ .probe = sis_init_one, -+ .remove = ata_pci_remove_one, -+}; -+ -+static int __init sis_init(void) -+{ -+ return pci_register_driver(&sis_pci_driver); -+} -+ -+static void __exit sis_exit(void) -+{ -+ pci_unregister_driver(&sis_pci_driver); -+} -+ -+ -+module_init(sis_init); -+module_exit(sis_exit); -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("SCSI low-level driver for SiS ATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sis_pci_tbl); -+MODULE_VERSION(DRV_VERSION); -+ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sl82c105.c linux-2.6.16-rc4/drivers/scsi/pata_sl82c105.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_sl82c105.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_sl82c105.c 2006-02-16 15:36:32.000000000 +0000 -@@ -0,0 +1,376 @@ -+/* -+ * pata_sl82c105.c - SL82C105 PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Based in part on linux/drivers/ide/pci/sl82c105.c -+ * SL82C105/Winbond 553 IDE driver -+ * -+ * and in part on the documentation and errata sheet -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_sl82c105" -+#define DRV_VERSION "0.1.1" -+ -+enum { -+ /* -+ * SL82C105 PCI config register 0x40 bits. -+ */ -+ CTRL_IDE_IRQB = (1 << 30), -+ CTRL_IDE_IRQA = (1 << 28), -+ CTRL_LEGIRQ = (1 << 11), -+ CTRL_P1F16 = (1 << 5), -+ CTRL_P1EN = (1 << 4), -+ CTRL_P0F16 = (1 << 1), -+ CTRL_P0EN = (1 << 0) -+}; -+ -+static void sl82c105_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits sl82c105_enable_bits[] = { -+ { 0x40, 1, 0x01, 0x01 }, -+ { 0x40, 1, 0x10, 0x10 } -+ }; -+ -+ if (ap->hard_port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ dev_printk(KERN_INFO, &pdev->dev, "port disabled. ignoring.\n"); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+ -+/** -+ * sl82c105_configure_piomode - set chip PIO timing -+ * @ap: ATA interface -+ * @adev: ATA device -+ * @pio: PIO mode -+ * -+ * Called to do the PIO mode setup. Our timing registers are shared -+ * so a configure_dmamode call will undo any work we do here and vice -+ * versa -+ */ -+ -+static void sl82c105_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static u16 pio_timing[5] = { -+ 0x50D, 0x407, 0x304, 0x242, 0x240 -+ }; -+ u16 dummy; -+ int timing = 0x44 + 8 * ap->hard_port_no + 4 * adev->devno; -+ -+ pci_write_config_word(pdev, timing, pio_timing[pio]); -+ /* Can we lose this oddity of the old driver */ -+ pci_read_config_word(pdev, timing, &dummy); -+} -+ -+/** -+ * sl82c105_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the PIO mode setup. Our timing registers are shared -+ * but we want to set the PIO timing by default. -+ */ -+ -+static void sl82c105_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ sl82c105_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); -+} -+ -+/** -+ * sl82c105_configure_dmamode - set DMA mode in chip -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Load DMA cycle times into the chip ready for a DMA transfer -+ * to occur. -+ */ -+ -+static void sl82c105_configure_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static u16 dma_timing[3] = { -+ 0x707, 0x201, 0x200 -+ }; -+ u16 dummy; -+ int timing = 0x44 + 8 * ap->hard_port_no + 4 * adev->devno; -+ int dma = adev->dma_mode - XFER_MW_DMA_0; -+ -+ pci_write_config_word(pdev, timing, dma_timing[dma]); -+ /* Can we lose this oddity of the old driver */ -+ pci_read_config_word(pdev, timing, &dummy); -+} -+ -+/** -+ * sl82c105_set_dmamode - set initial DMA mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Called to do the DMA mode setup. This replaces the PIO timings -+ * for the device in question. Set appropriate PIO timings not DMA -+ * timings at this point. -+ */ -+ -+static void sl82c105_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ switch(adev->dma_mode) { -+ case XFER_MW_DMA_0: -+ sl82c105_configure_piomode(ap, adev, 1); -+ break; -+ case XFER_MW_DMA_1: -+ sl82c105_configure_piomode(ap, adev, 3); -+ break; -+ case XFER_MW_DMA_2: -+ sl82c105_configure_piomode(ap, adev, 3); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+/** -+ * sl82c105_reset_engine - Reset the DMA engine -+ * @ap: ATA interface -+ * -+ * The sl82c105 has some serious problems with the DMA engine -+ * when transfers don't run as expected or ATAPI is used. The -+ * recommended fix is to reset the engine each use using a chip -+ * test register. -+ */ -+ -+static void sl82c105_reset_engine(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u16 val; -+ -+ pci_read_config_word(pdev, 0x7E, &val); -+ pci_write_config_word(pdev, 0x7E, val | 4); -+ pci_write_config_word(pdev, 0x7E, val & ~4); -+} -+ -+/** -+ * sl82c105_bmdma_start - DMA engine begin -+ * @qc: ATA command -+ * -+ * Reset the DMA engine each use as recommended by the errata -+ * document. -+ * -+ * FIXME: if we switch clock at BMDMA start/end we might get better -+ * PIO performance on DMA capable devices. -+ */ -+ -+static void sl82c105_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ -+ sl82c105_reset_engine(ap); -+ -+ /* Set the clocks for DMA */ -+ sl82c105_configure_dmamode(ap, qc->dev); -+ /* Activate DMA */ -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * sl82c105_bmdma_end - DMA engine stop -+ * @qc: ATA command -+ * -+ * Reset the DMA engine each use as recommended by the errata -+ * document. -+ * -+ * This function is also called to turn off DMA when a timeout occurs -+ * during DMA operation. In both cases we need to reset the engine, -+ * so no actual eng_timeout handler is required. -+ * -+ * We assume bmdma_stop is always called if bmdma_start as called. If -+ * not then we may need to wrap qc_issue. -+ */ -+ -+static void sl82c105_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ struct ata_port *ap = qc->ap; -+ -+ ata_bmdma_stop(qc); -+ sl82c105_reset_engine(ap); -+ -+ /* This will redo the initial setup of the DMA device to matching -+ PIO timings */ -+ sl82c105_set_dmamode(ap, qc->dev); -+} -+ -+static struct scsi_host_template sl82c105_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations sl82c105_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = sl82c105_set_piomode, -+ .set_dmamode = sl82c105_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = sl82c105_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = sl82c105_bmdma_start, -+ .bmdma_stop = sl82c105_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * sl82c105_bridge_revision - find bridge version -+ * @pdev: PCI device for the ATA function -+ * -+ * Locates the PCI bridge associated with the ATA function and -+ * providing it is a Winbond 553 reports the revision. If it cannot -+ * find a revision or the right device it returns -1 -+ */ -+ -+static int sl82c105_bridge_revision(struct pci_dev *pdev) -+{ -+ struct pci_dev *bridge; -+ u8 rev; -+ -+ /* -+ * The bridge should be part of the same device, but function 0. -+ */ -+ bridge = pci_get_slot(pdev->bus, -+ PCI_DEVFN(PCI_SLOT(pdev->devfn), 0)); -+ if (!bridge) -+ return -1; -+ -+ /* -+ * Make sure it is a Winbond 553 and is an ISA bridge. -+ */ -+ if (bridge->vendor != PCI_VENDOR_ID_WINBOND || -+ bridge->device != PCI_DEVICE_ID_WINBOND_83C553 || -+ bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) { -+ pci_dev_put(bridge); -+ return -1; -+ } -+ /* -+ * We need to find function 0's revision, not function 1 -+ */ -+ pci_read_config_byte(bridge, PCI_REVISION_ID, &rev); -+ -+ pci_dev_put(bridge); -+ return rev; -+} -+ -+ -+static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info_dma = { -+ .sht = &sl82c105_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &sl82c105_port_ops -+ }; -+ static struct ata_port_info info_early = { -+ .sht = &sl82c105_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .port_ops = &sl82c105_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info_early, &info_early }; -+ u32 val; -+ int rev; -+ -+ rev = sl82c105_bridge_revision(dev); -+ -+ if (rev == -1) -+ dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Unable to find bridge, disabling DMA.\n"); -+ else if (rev <= 5) -+ dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Early bridge revision, no DMA available.\n"); -+ else { -+ port_info[0] = &info_dma; -+ port_info[1] = &info_dma; -+ } -+ -+ pci_read_config_dword(dev, 0x40, &val); -+ val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; -+ pci_write_config_dword(dev, 0x40, val); -+ -+ -+ return ata_pci_init_one(dev, port_info, 1); /* For now */ -+} -+ -+static struct pci_device_id sl82c105[] = { -+ { PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver sl82c105_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = sl82c105, -+ .probe = sl82c105_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init sl82c105_init(void) -+{ -+ return pci_register_driver(&sl82c105_pci_driver); -+} -+ -+ -+static void __exit sl82c105_exit(void) -+{ -+ pci_unregister_driver(&sl82c105_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Sl82c105"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, sl82c105); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(sl82c105_init); -+module_exit(sl82c105_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_triflex.c linux-2.6.16-rc4/drivers/scsi/pata_triflex.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_triflex.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_triflex.c 2006-02-16 15:36:23.000000000 +0000 -@@ -0,0 +1,268 @@ -+/* -+ * pata_triflex.c - Compaq PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * based upon -+ * -+ * triflex.c -+ * -+ * IDE Chipset driver for the Compaq TriFlex IDE controller. -+ * -+ * Known to work with the Compaq Workstation 5x00 series. -+ * -+ * Copyright (C) 2002 Hewlett-Packard Development Group, L.P. -+ * Author: Torben Mathiasen <torben.mathiasen@hp.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * 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 -+ * -+ * Loosely based on the piix & svwks drivers. -+ * -+ * Documentation: -+ * Not publically available. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_triflex" -+#define DRV_VERSION "0.2.1" -+ -+static void triflex_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ static struct pci_bits triflex_enable_bits[] = { -+ { 0x80, 1, 0x01, 0x01 }, -+ { 0x80, 1, 0x02, 0x02 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = ATA_CBL_PATA40; -+ ata_port_probe(ap); -+ ata_bus_reset(ap); -+} -+ -+/** -+ * triflex_load_timing - timing configuration -+ * @ap: ATA interface -+ * @adev: Device on the bus -+ * @speed: speed to configure -+ * -+ * The Triflex has one set of timings per device per channel. This -+ * means we must do some switching. As the PIO and DMA timings don't -+ * match we have to do some reloading unlike PIIX devices where tuning -+ * tricks can avoid it. -+ */ -+ -+static void triflex_load_timing(struct ata_port *ap, struct ata_device *adev, int speed) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 timing = 0; -+ u32 triflex_timing, old_triflex_timing; -+ int channel_offset = ap->hard_port_no ? 0x74: 0x70; -+ unsigned int is_slave = (adev->devno != 0); -+ -+ -+ pci_read_config_dword(pdev, channel_offset, &old_triflex_timing); -+ triflex_timing = old_triflex_timing; -+ -+ switch(speed) -+ { -+ case XFER_MW_DMA_2: -+ timing = 0x0103;break; -+ case XFER_MW_DMA_1: -+ timing = 0x0203;break; -+ case XFER_MW_DMA_0: -+ timing = 0x0808;break; -+ case XFER_SW_DMA_2: -+ case XFER_SW_DMA_1: -+ case XFER_SW_DMA_0: -+ timing = 0x0F0F;break; -+ case XFER_PIO_4: -+ timing = 0x0202;break; -+ case XFER_PIO_3: -+ timing = 0x0204;break; -+ case XFER_PIO_2: -+ timing = 0x0404;break; -+ case XFER_PIO_1: -+ timing = 0x0508;break; -+ case XFER_PIO_0: -+ timing = 0x0808;break; -+ default: -+ BUG(); -+ } -+ triflex_timing &= ~ (0xFFFF << (16 * is_slave)); -+ triflex_timing |= (timing << (16 * is_slave)); -+ -+ if (triflex_timing != old_triflex_timing) -+ pci_write_config_dword(pdev, channel_offset, triflex_timing); -+} -+ -+/** -+ * triflex_set_piomode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * Use the timing loader to set up the PIO mode. We have to do this -+ * because DMA start/stop will only be called once DMA occurs. If there -+ * has been no DMA then the PIO timings are still needed. -+ */ -+static void triflex_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ triflex_load_timing(ap, adev, adev->pio_mode); -+} -+ -+/** -+ * triflex_dma_start - DMA start callback -+ * @qc: Command in progress -+ * -+ * Usually drivers set the DMA timing at the point the set_dmamode call -+ * is made. Triflex however requires we load new timings on the -+ * transition or keep matching PIO/DMA pairs (ie MWDMA2/PIO4 etc). -+ * We load the DMA timings just before starting DMA and then restore -+ * the PIO timing when the DMA is finished. -+ */ -+ -+static void triflex_bmdma_start(struct ata_queued_cmd *qc) -+{ -+ triflex_load_timing(qc->ap, qc->dev, qc->dev->dma_mode); -+ ata_bmdma_start(qc); -+} -+ -+/** -+ * triflex_dma_stop - DMA stop callback -+ * @ap: ATA interface -+ * @adev: ATA device -+ * -+ * We loaded new timings in dma_start, as a result we need to restore -+ * the PIO timings in dma_stop so that the next command issue gets the -+ * right clock values. -+ */ -+ -+static void triflex_bmdma_stop(struct ata_queued_cmd *qc) -+{ -+ ata_bmdma_stop(qc); -+ triflex_load_timing(qc->ap, qc->dev, qc->dev->pio_mode); -+} -+ -+static struct scsi_host_template triflex_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations triflex_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = triflex_set_piomode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = triflex_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = triflex_bmdma_start, -+ .bmdma_stop = triflex_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ static struct ata_port_info info = { -+ .sht = &triflex_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &triflex_port_ops -+ }; -+ static struct ata_port_info *port_info[2] = { &info, &info }; -+ static int printed_version; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); -+ -+ return ata_pci_init_one(dev, port_info, 2); -+} -+ -+static const struct pci_device_id triflex[] = { -+ { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -+ { 0, }, -+}; -+ -+static struct pci_driver triflex_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = triflex, -+ .probe = triflex_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init triflex_init(void) -+{ -+ return pci_register_driver(&triflex_pci_driver); -+} -+ -+ -+static void __exit triflex_exit(void) -+{ -+ pci_unregister_driver(&triflex_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for Compaq Triflex"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, triflex); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(triflex_init); -+module_exit(triflex_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pata_via.c linux-2.6.16-rc4/drivers/scsi/pata_via.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pata_via.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-rc4/drivers/scsi/pata_via.c 2006-02-16 15:28:17.000000000 +0000 -@@ -0,0 +1,547 @@ -+/* -+ * pata_via.c - VIA PATA for new ATA layer -+ * (C) 2005 Red Hat Inc -+ * Alan Cox <alan@redhat.com> -+ * -+ * Documentation -+ * Most chipset documentation available under NDA only -+ * -+ * VIA version guide -+ * VIA VT82C561 - early design, uses ata_generic currently -+ * VIA VT82C576 - MWDMA, 33Mhz -+ * VIA VT82C586 - MWDMA, 33Mhz -+ * VIA VT82C586a - Added UDMA to 33Mhz -+ * VIA VT82C586b - UDMA33 -+ * VIA VT82C596a - Nonfunctional UDMA66 -+ * VIA VT82C596b - Working UDMA66 -+ * VIA VT82C686 - Nonfunctional UDMA66 -+ * VIA VT82C686a - Working UDMA66 -+ * VIA VT82C686b - Updated to UDMA100 -+ * VIA VT8231 - UDMA100 -+ * VIA VT8233 - UDMA100 -+ * VIA VT8233a - UDMA133 -+ * VIA VT8233c - UDMA100 -+ * VIA VT8235 - UDMA133 -+ * VIA VT8237 - UDMA133 -+ * -+ * Most registers remain compatible across chips. Others start reserved -+ * and acquire sensible semantics if set to 1 (eg cable detect). A few -+ * exceptions exist, notably around the FIFO settings. -+ * -+ * One additional quirk of the VIA design is that like ALi they use few -+ * PCI IDs for a lot of chips. -+ * -+ * Based heavily on: -+ * -+ * Version 3.38 -+ * -+ * VIA IDE driver for Linux. Supported southbridges: -+ * -+ * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, -+ * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a, -+ * vt8235, vt8237 -+ * -+ * Copyright (c) 2000-2002 Vojtech Pavlik -+ * -+ * Based on the work of: -+ * Michel Aubry -+ * Jeff Garzik -+ * Andre Hedrick -+ -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include <linux/blkdev.h> -+#include <linux/delay.h> -+#include <scsi/scsi_host.h> -+#include <linux/libata.h> -+ -+#define DRV_NAME "pata_via" -+#define DRV_VERSION "0.1.4" -+ -+/* -+ * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx -+ * driver. -+ */ -+ -+enum { -+ VIA_UDMA = 0x007, -+ VIA_UDMA_NONE = 0x000, -+ VIA_UDMA_33 = 0x001, -+ VIA_UDMA_66 = 0x002, -+ VIA_UDMA_100 = 0x003, -+ VIA_UDMA_133 = 0x004, -+ VIA_BAD_PREQ = 0x010, /* Crashes if PREQ# till DDACK# set */ -+ VIA_BAD_CLK66 = 0x020, /* 66 MHz clock doesn't work correctly */ -+ VIA_SET_FIFO = 0x040, /* Needs to have FIFO split set */ -+ VIA_NO_UNMASK = 0x080, /* Doesn't work with IRQ unmasking on */ -+ VIA_BAD_ID = 0x100, /* Has wrong vendor ID (0x1107) */ -+ VIA_BAD_AST = 0x200, /* Don't touch Address Setup Timing */ -+}; -+ -+/* -+ * VIA SouthBridge chips. -+ */ -+ -+static const struct via_isa_bridge { -+ const char *name; -+ u16 id; -+ u8 rev_min; -+ u8 rev_max; -+ u16 flags; -+} via_isa_bridges[] = { -+ { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, -+ { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, -+ { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, -+ { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, -+ { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, -+ { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, -+ { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 }, -+ { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, VIA_UDMA_66 }, -+ { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, -+ { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, VIA_UDMA_66 }, -+ { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, -+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO }, -+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ }, -+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO }, -+ { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO }, -+ { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, -+ { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, -+ { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, -+ { NULL } -+}; -+ -+/** -+ * via_cable_detect - cable detection -+ * @ap: ATA port -+ * -+ * Perform cable detection. Actually for the VIA case the BIOS -+ * already did this for us. We read the values provided by the -+ * BIOS. If you are using an 8235 in a non-PC configuration you -+ * may need to update this code. -+ * -+ * Hotplug also impacts on this. -+ */ -+ -+static int via_cable_detect(struct ata_port *ap) { -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ u32 ata66; -+ pci_read_config_dword(pdev, 0x50, &ata66); -+ /* Check both the drive cable reporting bits, we might not have -+ two drives */ -+ if (ata66 & (0x1010 << (16 * ap->hard_port_no))) -+ return ATA_CBL_PATA80; -+ else -+ return ATA_CBL_PATA40; -+} -+ -+/** -+ * via_phy_reset - reset for eary chip -+ * @ap: ATA port -+ * -+ * Handle the reset callback for the later chips with cable detect -+ */ -+ -+static void via_phy_reset(struct ata_port *ap) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ -+ /* Note: When we add VIA 6410 remember it doesn't have enable bits */ -+ static struct pci_bits via_enable_bits[] = { -+ { 0x40, 1, 0x02, 0x02 }, -+ { 0x40, 1, 0x01, 0x01 } -+ }; -+ -+ if (!pci_test_config_bits(pdev, &via_enable_bits[ap->hard_port_no])) { -+ ata_port_disable(ap); -+ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); -+ return; -+ } -+ ap->cbl = via_cable_detect(ap); -+ ata_bus_reset(ap); -+ ata_port_probe(ap); -+} -+ -+/** -+ * via_do_set_mode - set initial PIO mode data -+ * @ap: ATA interface -+ * @adev: ATA device -+ * @mode: ATA mode being programmed -+ * @tdiv: Clocks per PCI clock -+ * @set_ast: Set to program address setup -+ * @udma_type: UDMA mode/format of registers -+ * -+ * Program the VIA registers for DMA and PIO modes. Uses the ata timing -+ * support in order to compute modes. -+ * -+ * FIXME: Hotplug will require we serialize multiple mode changes -+ * on the two channels. -+ */ -+ -+static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mode, int tdiv, int set_ast, int udma_type) -+{ -+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); -+ struct ata_device *peer = ata_dev_pair(ap, adev); -+ struct ata_timing t, p; -+ static int via_clock = 33000; /* Bus clock in kHZ - ought to be tunable one day */ -+ unsigned long T = 1000000000 / via_clock; -+ unsigned long UT = T/tdiv; -+ int ut; -+ int offset = 3 - (2*ap->hard_port_no) - adev->devno; -+ -+ printk("via_do_set_mode: Mode=%d ast broken=%c udma=%d mul=%d\n", -+ mode, "YN"[set_ast], udma_type, tdiv); -+ /* Calculate the timing values we require */ -+ ata_timing_compute(adev, adev->pio_mode, &t, T, UT); -+ -+ /* We share 8bit timing so we must merge the constraints */ -+ if (peer) { -+ if (peer->pio_mode) { -+ ata_timing_compute(peer, peer->pio_mode, &p, T, UT); -+ ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT); -+ } -+ if (peer->dma_mode) { -+ ata_timing_compute(peer, peer->dma_mode, &p, T, UT); -+ ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT); -+ } -+ } -+ -+ /* Address setup is programmable but breaks on UDMA133 setups */ -+ if (set_ast) { -+ u8 setup; /* 2 bits per drive */ -+ int shift = 2 * offset; -+ -+ pci_read_config_byte(pdev, 0x4C, &setup); -+ setup &= ~(3 << shift); -+ setup |= FIT(t.setup, 1, 4) << shift; -+ pci_write_config_byte(pdev, 0x4C, setup); -+ } -+ -+ /* Load the PIO mode bits */ -+ pci_write_config_byte(pdev, 0x4F - ap->hard_port_no, -+ ((FIT(t.act8b, 1, 16) - 1) << 4) | (FIT(t.rec8b, 1, 16) - 1)); -+ pci_write_config_byte(pdev, 0x48 + offset, -+ ((FIT(t.active, 1, 16) - 1) << 4) | (FIT(t.recover, 1, 16) - 1)); -+ -+ /* Load the UDMA bits according to type */ -+ switch(udma_type) { -+ default: -+ /* BUG() ? */ -+ /* fall through */ -+ case 33: -+ ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 5) - 2)) : 0x03; -+ break; -+ case 66: -+ ut = t.udma ? (0xe8 | (FIT(t.udma, 2, 9) - 2)) : 0x0f; -+ break; -+ case 100: -+ ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; -+ break; -+ case 133: -+ ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; -+ break; -+ } -+ /* Set UDMA unless device is not UDMA capable */ -+ if (udma_type) -+ pci_write_config_byte(pdev, 0x50 + offset, ut); -+} -+ -+static void via_set_piomode(struct ata_port *ap, struct ata_device *adev) -+{ -+ const struct via_isa_bridge *config = ap->host_set->private_data; -+ int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; -+ int mode = config->flags & VIA_UDMA; -+ static u8 tclock[5] = { 1, 1, 2, 3, 4 }; -+ static u8 udma[5] = { 0, 33, 66, 100, 133 }; -+ -+ via_do_set_mode(ap, adev, adev->pio_mode, tclock[mode], set_ast, udma[mode]); -+} -+ -+static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev) -+{ -+ const struct via_isa_bridge *config = ap->host_set->private_data; -+ int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; -+ int mode = config->flags & VIA_UDMA; -+ static u8 tclock[5] = { 1, 1, 2, 3, 4 }; -+ static u8 udma[5] = { 0, 33, 66, 100, 133 }; -+ -+ via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]); -+} -+ -+static struct scsi_host_template via_sht = { -+ .module = THIS_MODULE, -+ .name = DRV_NAME, -+ .ioctl = ata_scsi_ioctl, -+ .queuecommand = ata_scsi_queuecmd, -+ .eh_strategy_handler = ata_scsi_error, -+ .can_queue = ATA_DEF_QUEUE, -+ .this_id = ATA_SHT_THIS_ID, -+ .sg_tablesize = LIBATA_MAX_PRD, -+ .max_sectors = ATA_MAX_SECTORS, -+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, -+ .emulated = ATA_SHT_EMULATED, -+ .use_clustering = ATA_SHT_USE_CLUSTERING, -+ .proc_name = DRV_NAME, -+ .dma_boundary = ATA_DMA_BOUNDARY, -+ .slave_configure = ata_scsi_slave_config, -+ .bios_param = ata_std_bios_param, -+// .ordered_flush = 1, -+}; -+ -+static struct ata_port_operations via_port_ops = { -+ .port_disable = ata_port_disable, -+ .set_piomode = via_set_piomode, -+ .set_dmamode = via_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = via_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+static struct ata_port_operations via_port_ops_noirq = { -+ .port_disable = ata_port_disable, -+ .set_piomode = via_set_piomode, -+ .set_dmamode = via_set_dmamode, -+ .tf_load = ata_tf_load, -+ .tf_read = ata_tf_read, -+ .check_status = ata_check_status, -+ .exec_command = ata_exec_command, -+ .dev_select = ata_std_dev_select, -+ -+ .phy_reset = via_phy_reset, -+ -+ .bmdma_setup = ata_bmdma_setup, -+ .bmdma_start = ata_bmdma_start, -+ .bmdma_stop = ata_bmdma_stop, -+ .bmdma_status = ata_bmdma_status, -+ -+ .qc_prep = ata_qc_prep, -+ .qc_issue = ata_qc_issue_prot, -+ .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer_noirq, -+ -+ .irq_handler = ata_interrupt, -+ .irq_clear = ata_bmdma_irq_clear, -+ -+ .port_start = ata_port_start, -+ .port_stop = ata_port_stop, -+ .host_stop = ata_host_stop -+}; -+ -+/** -+ * via_init_one - discovery callback -+ * @pdev: PCI device ID -+ * @id: PCI table info -+ * -+ * A VIA IDE interface has been discovered. Figure out what revision -+ * and perform configuration work before handing it to the ATA layer -+ */ -+ -+static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ /* Early VIA without UDMA support */ -+ static struct ata_port_info via_mwdma_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &via_port_ops -+ }; -+ /* Ditto with IRQ masking required */ -+ static struct ata_port_info via_mwdma_info_borked = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_IRQ_MASK, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .port_ops = &via_port_ops_noirq, -+ }; -+ /* VIA UDMA 33 devices (and borked 66) */ -+ static struct ata_port_info via_udma33_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x7, -+ .port_ops = &via_port_ops -+ }; -+ /* VIA UDMA 66 devices */ -+ static struct ata_port_info via_udma66_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x1f, -+ .port_ops = &via_port_ops -+ }; -+ /* VIA UDMA 100 devices */ -+ static struct ata_port_info via_udma100_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, -+ .port_ops = &via_port_ops -+ }; -+ /* UDMA133 with bad AST (All current 133) */ -+ static struct ata_port_info via_udma133_info = { -+ .sht = &via_sht, -+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, -+ .pio_mask = 0x1f, -+ .mwdma_mask = 0x07, -+ .udma_mask = 0x3f, /* 0x7F but need to fix north bridge */ -+ .port_ops = &via_port_ops -+ }; -+ struct ata_port_info *port_info[2], *type; -+ struct pci_dev *isa = NULL; -+ const struct via_isa_bridge *config; -+ static int printed_version; -+ u8 t; -+ u8 enable; -+ u32 timing; -+ -+ if (!printed_version++) -+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); -+ -+ /* To find out how the IDE will behave and what features we -+ actually have to look at the bridge not the IDE controller */ -+ for (config = via_isa_bridges; config->id; config++) -+ if ((isa = pci_get_device(PCI_VENDOR_ID_VIA + -+ !!(config->flags & VIA_BAD_ID), -+ config->id, NULL))) { -+ -+ pci_read_config_byte(isa, PCI_REVISION_ID, &t); -+ if (t >= config->rev_min && -+ t <= config->rev_max) -+ break; -+ pci_dev_put(isa); -+ } -+ -+ if (!config->id) { -+ printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n"); -+ return -ENODEV; -+ } -+ -+ /* 0x40 low bits indicate enabled channels */ -+ pci_read_config_byte(pdev, 0x40 , &enable); -+ enable &= 3; -+ if (enable == 0) { -+ pci_dev_put(isa); -+ return -ENODEV; -+ } -+ -+ /* Initialise the FIFO for the enabled channels. */ -+ if (config->flags & VIA_SET_FIFO) { -+ u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20}; -+ u8 fifo; -+ -+ pci_read_config_byte(pdev, 0x43, &fifo); -+ -+ /* Clear PREQ# until DDACK# for errata */ -+ if (config->flags & VIA_BAD_PREQ) -+ fifo &= 0x7F; -+ else -+ fifo &= 0x9f; -+ /* Turn on FIFO for enabled channels */ -+ fifo |= fifo_setting[enable]; -+ pci_write_config_byte(pdev, 0x43, fifo); -+ } -+ /* Clock set up */ -+ switch(config->flags & VIA_UDMA) { -+ case VIA_UDMA_NONE: -+ if (config->flags & VIA_NO_UNMASK) -+ type = &via_mwdma_info_borked; -+ else -+ type = &via_mwdma_info; -+ break; -+ case VIA_UDMA_33: -+ type = &via_udma33_info; -+ break; -+ case VIA_UDMA_66: -+ type = &via_udma66_info; -+ /* The 66 MHz devices require we enable the clock */ -+ pci_read_config_dword(pdev, 0x50, &timing); -+ timing |= 0x80008; -+ pci_write_config_dword(pdev, 0x50, timing); -+ break; -+ case VIA_UDMA_100: -+ type = &via_udma100_info; -+ break; -+ case VIA_UDMA_133: -+ type = &via_udma133_info; -+ break; -+ default: -+ type = NULL; -+ BUG(); -+ break; -+ } -+ -+ if (config->flags & VIA_BAD_CLK66) { -+ /* Disable the 66MHz clock on problem devices */ -+ pci_read_config_dword(pdev, 0x50, &timing); -+ timing &= ~0x80008; -+ pci_write_config_dword(pdev, 0x50, timing); -+ } -+ -+ /* We have established the device type, now fire it up */ -+ type->private_data = (void *)config; -+ -+ port_info[0] = port_info[1] = type; -+ return ata_pci_init_one(pdev, port_info, 2); -+} -+ -+static const struct pci_device_id via[] = { -+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+ { 0, }, -+}; -+ -+static struct pci_driver via_pci_driver = { -+ .name = DRV_NAME, -+ .id_table = via, -+ .probe = via_init_one, -+ .remove = ata_pci_remove_one -+}; -+ -+static int __init via_init(void) -+{ -+ return pci_register_driver(&via_pci_driver); -+} -+ -+ -+static void __exit via_exit(void) -+{ -+ pci_unregister_driver(&via_pci_driver); -+} -+ -+ -+MODULE_AUTHOR("Alan Cox"); -+MODULE_DESCRIPTION("low-level driver for VIA PATA"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(pci, via); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(via_init); -+module_exit(via_exit); -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/pdc_adma.c linux-2.6.16-rc4/drivers/scsi/pdc_adma.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/pdc_adma.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/pdc_adma.c 2006-02-23 13:15:50.480287896 +0000 -@@ -322,7 +322,7 @@ - = (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4); - i += 4; - -- VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", nelem, -+ VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4, - (unsigned long)addr, len); - } - return i; -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_mv.c linux-2.6.16-rc4/drivers/scsi/sata_mv.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_mv.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_mv.c 2006-02-20 11:28:03.000000000 +0000 -@@ -389,6 +389,7 @@ - - .qc_prep = mv_qc_prep, - .qc_issue = mv_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - - .eng_timeout = mv_eng_timeout, - -@@ -416,6 +417,7 @@ - - .qc_prep = mv_qc_prep, - .qc_issue = mv_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - - .eng_timeout = mv_eng_timeout, - -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_nv.c linux-2.6.16-rc4/drivers/scsi/sata_nv.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_nv.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_nv.c 2006-01-21 17:08:58.000000000 +0000 -@@ -258,6 +258,7 @@ - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - .eng_timeout = ata_eng_timeout, -+ .data_xfer = ata_pio_data_xfer, - .irq_handler = nv_interrupt, - .irq_clear = ata_bmdma_irq_clear, - .scr_read = nv_scr_read, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_promise.c linux-2.6.16-rc4/drivers/scsi/sata_promise.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_promise.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_promise.c 2006-02-06 12:36:12.000000000 +0000 -@@ -130,6 +130,7 @@ - .qc_prep = pdc_qc_prep, - .qc_issue = pdc_qc_issue_prot, - .eng_timeout = pdc_eng_timeout, -+ .data_xfer = ata_mmio_data_xfer, - .irq_handler = pdc_interrupt, - .irq_clear = pdc_irq_clear, - -@@ -152,6 +153,7 @@ - - .qc_prep = pdc_qc_prep, - .qc_issue = pdc_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = pdc_eng_timeout, - .irq_handler = pdc_interrupt, - .irq_clear = pdc_irq_clear, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_qstor.c linux-2.6.16-rc4/drivers/scsi/sata_qstor.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_qstor.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_qstor.c 2006-01-21 17:09:57.000000000 +0000 -@@ -158,6 +158,7 @@ - .phy_reset = qs_phy_reset, - .qc_prep = qs_qc_prep, - .qc_issue = qs_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = qs_eng_timeout, - .irq_handler = qs_intr, - .irq_clear = qs_irq_clear, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil24.c linux-2.6.16-rc4/drivers/scsi/sata_sil24.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil24.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_sil24.c 2006-01-21 17:10:52.000000000 +0000 -@@ -309,6 +309,7 @@ - - .qc_prep = sil24_qc_prep, - .qc_issue = sil24_qc_issue, -+ .data_xfer = ata_mmio_data_xfer, - - .eng_timeout = sil24_eng_timeout, - -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil.c linux-2.6.16-rc4/drivers/scsi/sata_sil.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sil.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_sil.c 2006-02-14 17:23:28.000000000 +0000 -@@ -165,6 +165,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sis.c linux-2.6.16-rc4/drivers/scsi/sata_sis.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sis.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_sis.c 2006-01-21 17:11:23.000000000 +0000 -@@ -115,6 +115,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_svw.c linux-2.6.16-rc4/drivers/scsi/sata_svw.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_svw.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_svw.c 2006-02-06 12:30:23.000000000 +0000 -@@ -320,6 +320,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sx4.c linux-2.6.16-rc4/drivers/scsi/sata_sx4.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_sx4.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_sx4.c 2006-01-21 17:12:01.000000000 +0000 -@@ -206,6 +206,7 @@ - .phy_reset = pdc_20621_phy_reset, - .qc_prep = pdc20621_qc_prep, - .qc_issue = pdc20621_qc_issue_prot, -+ .data_xfer = ata_mmio_data_xfer, - .eng_timeout = pdc_eng_timeout, - .irq_handler = pdc20621_interrupt, - .irq_clear = pdc20621_irq_clear, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_uli.c linux-2.6.16-rc4/drivers/scsi/sata_uli.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_uli.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_uli.c 2006-01-21 17:12:24.000000000 +0000 -@@ -106,6 +106,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - - .eng_timeout = ata_eng_timeout, - -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_via.c linux-2.6.16-rc4/drivers/scsi/sata_via.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_via.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_via.c 2006-01-21 17:12:51.000000000 +0000 -@@ -126,6 +126,7 @@ - - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - - .eng_timeout = ata_eng_timeout, - -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/drivers/scsi/sata_vsc.c linux-2.6.16-rc4/drivers/scsi/sata_vsc.c ---- linux.vanilla-2.6.16-rc4/drivers/scsi/sata_vsc.c 2006-02-20 11:22:25.000000000 +0000 -+++ linux-2.6.16-rc4/drivers/scsi/sata_vsc.c 2006-02-20 11:28:11.000000000 +0000 -@@ -280,6 +280,7 @@ - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, -+ .data_xfer = ata_pio_data_xfer, - .eng_timeout = ata_eng_timeout, - .irq_handler = vsc_sata_interrupt, - .irq_clear = ata_bmdma_irq_clear, -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/include/linux/ata.h linux-2.6.16-rc4/include/linux/ata.h ---- linux.vanilla-2.6.16-rc4/include/linux/ata.h 2006-02-20 11:22:26.000000000 +0000 -+++ linux-2.6.16-rc4/include/linux/ata.h 2006-02-15 14:39:41.000000000 +0000 -@@ -134,6 +134,8 @@ - ATA_CMD_PIO_READ_EXT = 0x24, - ATA_CMD_PIO_WRITE = 0x30, - ATA_CMD_PIO_WRITE_EXT = 0x34, -+ ATA_CMD_READ_NATIVE_MAX = 0xF8, -+ ATA_CMD_READ_NATIVE_MAX_EXT = 0x27, - ATA_CMD_READ_MULTI = 0xC4, - ATA_CMD_READ_MULTI_EXT = 0x29, - ATA_CMD_WRITE_MULTI = 0xC5, -@@ -247,18 +249,22 @@ - }; - - #define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) -+#define ata_id_is_cfa(id) ((id)[0] == 0x848A) - #define ata_id_is_sata(id) ((id)[93] == 0) - #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6)) - #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5)) -+#define ata_id_hpa_enabled(id) ((id)[85] & (1 << 10)) - #define ata_id_has_fua(id) ((id)[84] & (1 << 6)) - #define ata_id_has_flush(id) ((id)[83] & (1 << 12)) - #define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13)) - #define ata_id_has_lba48(id) ((id)[83] & (1 << 10)) -+#define ata_id_has_hpa(id) ((id)[82] & (1 << 10)) - #define ata_id_has_wcache(id) ((id)[82] & (1 << 5)) - #define ata_id_has_pm(id) ((id)[82] & (1 << 3)) - #define ata_id_has_lba(id) ((id)[49] & (1 << 9)) - #define ata_id_has_dma(id) ((id)[49] & (1 << 8)) - #define ata_id_removeable(id) ((id)[0] & (1 << 7)) -+#define ata_id_has_dword_io(id) ((id)[50] & (1 << 0)) - #define ata_id_u32(id,n) \ - (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)])) - #define ata_id_u64(id,n) \ -diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc4/include/linux/libata.h linux-2.6.16-rc4/include/linux/libata.h ---- linux.vanilla-2.6.16-rc4/include/linux/libata.h 2006-02-20 11:22:26.000000000 +0000 -+++ linux-2.6.16-rc4/include/linux/libata.h 2006-02-23 13:28:56.634774248 +0000 -@@ -41,7 +41,7 @@ - #undef ATA_VERBOSE_DEBUG /* yet more debugging output */ - #undef ATA_IRQ_TRAP /* define to ack screaming irqs */ - #undef ATA_NDEBUG /* define to disable quick runtime checks */ --#undef ATA_ENABLE_PATA /* define to enable PATA support in some -+#define ATA_ENABLE_PATA /* define to enable PATA support in some - * low-level drivers */ - #undef ATAPI_ENABLE_DMADIR /* enables ATAPI DMADIR bridge support */ - -@@ -101,6 +101,7 @@ - ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ - ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ - ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */ -+ ATA_DFLAG_HPA = (1 << 4), /* device has an HPA */ - - ATA_DEV_UNKNOWN = 0, /* unknown device */ - ATA_DEV_ATA = 1, /* ATA device */ -@@ -133,6 +134,8 @@ - ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ - ATA_QCFLAG_SINGLE = (1 << 4), /* no s/g, just a single buffer */ - ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, -+ -+ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ - - /* various lengths of time */ - ATA_TMOUT_EDD = 5 * HZ, /* heuristic */ -@@ -197,6 +200,7 @@ - - /* forward declarations */ - struct scsi_device; -+struct ata_host_set; - struct ata_port_operations; - struct ata_port; - struct ata_queued_cmd; -@@ -237,8 +241,10 @@ - unsigned long irq; - unsigned int irq_flags; - unsigned long host_flags; -+ unsigned long host_set_flags; - void __iomem *mmio_base; - void *private_data; -+ struct ata_host_set *host_set; /* Return not input value */ - }; - - struct ata_host_set { -@@ -250,6 +256,9 @@ - void *private_data; - const struct ata_port_operations *ops; - struct ata_port * ports[0]; -+ unsigned long host_set_flags; -+ int simplex_claimed; /* Keep seperate in case we -+ ever need to do this locked */ - }; - - struct ata_queued_cmd { -@@ -369,6 +378,7 @@ - - void (*set_piomode) (struct ata_port *, struct ata_device *); - void (*set_dmamode) (struct ata_port *, struct ata_device *); -+ unsigned int (*mode_filter) (const struct ata_port *, struct ata_device *, unsigned int, int); - - void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf); - void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); -@@ -379,12 +389,15 @@ - void (*dev_select)(struct ata_port *ap, unsigned int device); - - void (*phy_reset) (struct ata_port *ap); -+ void (*set_mode) (struct ata_port *ap); - void (*post_set_mode) (struct ata_port *ap); - - int (*check_atapi_dma) (struct ata_queued_cmd *qc); - - void (*bmdma_setup) (struct ata_queued_cmd *qc); - void (*bmdma_start) (struct ata_queued_cmd *qc); -+ -+ void (*data_xfer) (struct ata_port *, struct ata_device *, unsigned char *, unsigned int, int); - - void (*qc_prep) (struct ata_queued_cmd *qc); - int (*qc_issue) (struct ata_queued_cmd *qc); -@@ -443,8 +456,9 @@ - extern void ata_pci_remove_one (struct pci_dev *pdev); - extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state); - extern int ata_pci_device_resume(struct pci_dev *pdev); -+extern int ata_pci_clear_simplex(struct pci_dev *pdev); - #endif /* CONFIG_PCI */ --extern int ata_device_add(const struct ata_probe_ent *ent); -+extern int ata_device_add(struct ata_probe_ent *ent); - extern void ata_host_set_remove(struct ata_host_set *host_set); - extern int ata_scsi_detect(struct scsi_host_template *sht); - extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); -@@ -491,6 +505,15 @@ - extern void ata_bmdma_irq_clear(struct ata_port *ap); - extern void ata_qc_complete(struct ata_queued_cmd *qc); - extern void ata_eng_timeout(struct ata_port *ap); -+extern void ata_mmio_data_xfer(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, -+ unsigned int buflen, int write_data); -+extern void ata_pio_data_xfer(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, -+ unsigned int buflen, int write_data); -+extern void ata_mmio_data_xfer_noirq(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, -+ unsigned int buflen, int do_write); -+extern void ata_pio_data_xfer_noirq(struct ata_port *ap, struct ata_device *adev, unsigned char *buf, -+ unsigned int buflen, int do_write); -+ - extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)); -@@ -498,6 +521,8 @@ - struct block_device *bdev, - sector_t capacity, int geom[]); - extern int ata_scsi_slave_config(struct scsi_device *sdev); -+extern struct ata_device *ata_dev_pair(struct ata_port *ap, -+ struct ata_device *adev); - - /* - * Timing helpers diff --git a/packages/linux/ixp4xx-kernel_2.6.16.bb b/packages/linux/ixp4xx-kernel_2.6.16.bb index ba9a2522f7..66d1c38e42 100644 --- a/packages/linux/ixp4xx-kernel_2.6.16.bb +++ b/packages/linux/ixp4xx-kernel_2.6.16.bb @@ -8,17 +8,16 @@ PR_CONFIG = "1" # Increment the number below (i.e. the digits after PR) when # making changes within this file or for changes to the patches # applied to the kernel. -PR = "r1.${PR_CONFIG}" +PR = "r3.${PR_CONFIG}" include ixp4xx-kernel.inc -# RPSRC = "http://www.rpsys.net/openzaurus/patches" - # IXP4XX_PATCHES - full list of patches to apply IXP4XX_PATCHES = "" -IXP4XX_PATCHES += "file://patch-2.6.16-rc4-ide2;patch=1" +IXP4XX_PATCHES += "file://patch-2.6.16-rc6-ide1;patch=1" IXP4XX_PATCHES += "file://leds-class.patch;patch=1" +IXP4XX_PATCHES += "file://linux-2.6.16-i2c.patch;patch=1" IXP4XX_PATCHES += "file://copypage-xscale.patch;patch=1" # IXP4XX_PATCHES += "file://06-remove-extraversion.patch;patch=1" IXP4XX_PATCHES += "file://10-ixp4xx-fix-irq.patch;patch=1" @@ -26,9 +25,8 @@ IXP4XX_PATCHES += "file://11-mtdpart-redboot-config-byteswap.patch;patch=1" IXP4XX_PATCHES += "file://15-jffs2-endian-config.patch;patch=1" IXP4XX_PATCHES += "file://951-ixp4xx-leds-cpu-activity.patch;patch=1" IXP4XX_PATCHES += "file://40-rtc-class.patch;patch=1" -IXP4XX_PATCHES += "file://45-eeprom-notifier.patch;patch=1" +IXP4XX_PATCHES += "file://45-eeprom-new-notifier.patch;patch=1" IXP4XX_PATCHES += "file://48-setup-byteswap-cmdline.patch;patch=1" -IXP4XX_PATCHES += "file://50-i2c-bus-ixp4xx-hwmon.patch;patch=1" IXP4XX_PATCHES += "file://50-hwmon-ad741x.patch;patch=1" IXP4XX_PATCHES += "file://65-loft-config.patch;patch=1" IXP4XX_PATCHES += "file://75-dsmg600.patch;patch=1" @@ -36,8 +34,8 @@ IXP4XX_PATCHES += "file://83-nas100d-memory-fixup.patch;patch=1" IXP4XX_PATCHES += "file://84-nas100d-cmdline.patch;patch=1" IXP4XX_PATCHES += "file://85-timer.patch;patch=1" IXP4XX_PATCHES += "file://91-maclist.patch;patch=1" -IXP4XX_PATCHES += "file://92-nas100d-maclist.patch;patch=1" -IXP4XX_PATCHES += "file://92-nslu2-maclist.patch;patch=1" +IXP4XX_PATCHES += "file://92-nas100d-mac.patch;patch=1" +IXP4XX_PATCHES += "file://92-nslu2-mac.patch;patch=1" IXP4XX_PATCHES += "file://94-nslu2-setup.patch;patch=1" IXP4XX_PATCHES += "file://94-loft-setup.patch;patch=1" IXP4XX_PATCHES += "file://96-pata-ixp4xx.patch;patch=1" diff --git a/packages/linux/linux-openzaurus-2.6.16/24-hostap_cs_id.diff b/packages/linux/linux-openzaurus-2.6.16/24-hostap_cs_id.diff new file mode 100644 index 0000000000..b90ead9e4f --- /dev/null +++ b/packages/linux/linux-openzaurus-2.6.16/24-hostap_cs_id.diff @@ -0,0 +1,107 @@ +Add more IDs for PCMCIA cards + +From: Pavel Roskin <proski@gnu.org> + +Add string IDs for cards that were covered by 0x0156,0x0002, which is no +longer used in hostap_cs due to conflict with Orinoco cards. + +Also add more IDs for cards that are supported by linux-wlan-ng. Thanks +to Arnold Schulz <arnysch@gmx.net> for providing the list. + +Signed-off-by: Pavel Roskin <proski@gnu.org> +--- + + drivers/net/wireless/hostap/hostap_cs.c | 46 +++++++++++++++++++++++++++++++ + 1 files changed, 46 insertions(+), 0 deletions(-) + +diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c +index 55bed92..9ac1aec 100644 +--- a/drivers/net/wireless/hostap/hostap_cs.c ++++ b/drivers/net/wireless/hostap/hostap_cs.c +@@ -832,9 +832,11 @@ static int hostap_cs_resume(struct pcmci + static struct pcmcia_device_id hostap_cs_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), + PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), ++ PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), + PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), + PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), ++ PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), + PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b), + PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), +@@ -844,7 +846,10 @@ static struct pcmcia_device_id hostap_cs + PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), + PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), + PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), ++ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), ++ PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), + PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), ++ PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), +@@ -862,22 +867,63 @@ static struct pcmcia_device_id hostap_cs + "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", + 0xe6ec52ce, 0x08649af2, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID123( ++ "Belkin", "11Mbps Wireless Notebook Network Adapter", ++ "Version 01.02", 0x3805a391, 0xad4c7744, 0x4b74baa0), ++ PCMCIA_DEVICE_PROD_ID123( + "D", "Link DWL-650 11Mbps WLAN Card", "Version 01.02", + 0x71b18589, 0xb6f1b0ab, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID123( + "Instant Wireless ", " Network PC CARD", "Version 01.02", + 0x11d901af, 0x6e9bd926, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID123( ++ "Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", ++ 0x4b801a17, 0xf222ec2d, 0x630d52b2), ++ PCMCIA_DEVICE_PROD_ID123( ++ "OEM", "PRISM2 IEEE 802.11 PC-Card", "Version 01.02", ++ 0xfea54c90, 0x48f2bdd6, 0x4b74baa0), ++ PCMCIA_DEVICE_PROD_ID123( ++ "Pretec", "CompactWLAN Card 802.11b", "2.5", ++ 0x1cadd3e5, 0xe697636c, 0x7a5bfcf1), ++ PCMCIA_DEVICE_PROD_ID123( + "SMC", "SMC2632W", "Version 01.02", + 0xc4f8b18b, 0x474a1f2a, 0x4b74baa0), ++ PCMCIA_DEVICE_PROD_ID123( ++ "The Linksys Group, Inc.", "Instant Wireless Network PC Card", ++ "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39), ++ PCMCIA_DEVICE_PROD_ID123( ++ "U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02", ++ 0xc7b8df9d, 0x1700d087, 0x4b74baa0), ++ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", ++ 0x78fc06ee, 0xdb9aa842), ++ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", ++ 0x78fc06ee, 0x45a50c1e), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", + 0x2decece3, 0x82067c18), + PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", + 0x54f7c49c, 0x15a75e5b), ++ PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", ++ 0x5261440f, 0xa6405584), ++ PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", ++ 0x5261440f, 0xdf6115f9), ++ PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", ++ 0x71b18589, 0xf144e3ac), ++ PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", ++ 0xfdd73470, 0xe0b6f146), + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", + 0x74c5e40d, 0xdb472a18), ++ PCMCIA_DEVICE_PROD_ID12("LeArtery", ++ "SYNCBYAIR 11Mbps Wireless LAN PC Card", ++ 0x7e3b326a, 0x49893e92), + PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", + 0x0733cc81, 0x0c52f395), ++ PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", ++ 0xa37434e9, 0x9762e8f1), ++ PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", ++ 0x4ac44287, 0x235a6bed), ++ PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", ++ 0x209f40ab, 0xd9715264), ++ PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", ++ 0x209f40ab, 0x46263178), + PCMCIA_DEVICE_PROD_ID12( + "ZoomAir 11Mbps High", "Rate wireless Networking", + 0x273fe3db, 0x32a1eaee), diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-akita b/packages/linux/linux-openzaurus-2.6.16/defconfig-akita index 38281b7cd1..7b9e57436e 100644 --- a/packages/linux/linux-openzaurus-2.6.16/defconfig-akita +++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-akita @@ -1436,42 +1436,42 @@ CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" 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_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_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 # @@ -1491,7 +1491,7 @@ CONFIG_LOG_BUF_SHIFT=14 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1500,7 +1500,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -CONFIG_FORCED_INLINING=y +# CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0 b/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0 index 669efab8b5..80722f4081 100644 --- a/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0 +++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0 @@ -1469,42 +1469,42 @@ CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" 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_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_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 # @@ -1524,7 +1524,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1533,12 +1533,12 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -CONFIG_FORCED_INLINING=y +# CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_LL is not set # CONFIG_DEBUG_ICEDCC is not set # diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-collie b/packages/linux/linux-openzaurus-2.6.16/defconfig-collie index bfc5809f30..0ed5efa9b9 100644 --- a/packages/linux/linux-openzaurus-2.6.16/defconfig-collie +++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-collie @@ -1,20 +1,20 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.14-git3 -# Thu Nov 3 09:37:28 2005 +# Linux kernel version: 2.6.17-rc1 +# Wed Apr 19 21:01:15 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options # CONFIG_EXPERIMENTAL=y -# CONFIG_CLEAN_COMPILE is not set -CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -31,27 +31,28 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=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_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y +CONFIG_DOUBLEFAULT=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -59,24 +60,42 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y # +# Block layer +# +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=m +CONFIG_IOSCHED_CFQ=m +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" + +# # System Type # # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -86,9 +105,11 @@ CONFIG_ARCH_SA1100=y # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91RM9200 is not set # # SA11x0 Implementations @@ -122,6 +143,7 @@ CONFIG_CPU_TLB_V4WB=y # # Processor Features # +CONFIG_KEXEC=y CONFIG_SHARP_LOCOMO=y CONFIG_SHARP_PARAM=y CONFIG_SHARP_SCOOP=y @@ -130,7 +152,6 @@ CONFIG_SHARP_SCOOP=y # Bus support # CONFIG_ISA=y -CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -151,10 +172,12 @@ CONFIG_PCMCIA_SA1100=y # # Kernel Features # -# CONFIG_SMP is not set CONFIG_PREEMPT=y CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 +# CONFIG_AEABI is not set CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_NODES_SHIFT=2 CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set CONFIG_DISCONTIGMEM_MANUAL=y @@ -172,6 +195,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 mem=32M fbcon=rotate:1 dyntick=enable debug" # CONFIG_XIP_KERNEL is not set # @@ -196,12 +220,13 @@ CONFIG_FPE_NWFPE=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -# CONFIG_ARTHUR is not set # # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set CONFIG_APM=y # @@ -212,6 +237,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -228,12 +254,15 @@ CONFIG_SYN_COOKIES=y # 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_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # @@ -245,6 +274,11 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -257,8 +291,11 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_NET_DIVERT 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_NET_CLS_ROUTE is not set # # Network testing @@ -267,7 +304,13 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_IEEE80211 is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_IEEE80211_SOFTMAC is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -282,6 +325,11 @@ CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set # +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -300,6 +348,7 @@ 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 # # RAM/ROM/Flash chip drivers @@ -320,9 +369,7 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set CONFIG_MTD_OBSOLETE_CHIPS=y -# CONFIG_MTD_AMDSTD is not set CONFIG_MTD_SHARP=y -# CONFIG_MTD_JEDEC is not set # # Mapping drivers for chip access @@ -336,7 +383,6 @@ CONFIG_MTD_SHARP=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -352,6 +398,11 @@ CONFIG_MTD_SHARP=y # CONFIG_MTD_NAND is not set # +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# # Parallel port support # # CONFIG_PARPORT is not set @@ -364,7 +415,6 @@ CONFIG_MTD_SHARP=y # # Block devices # -# CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set @@ -374,19 +424,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=m -CONFIG_IOSCHED_CFQ=m -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_ATA_OVER_ETH=m # @@ -413,7 +450,6 @@ CONFIG_ATA_OVER_ETH=m # # IEEE 1394 (FireWire) support # -# CONFIG_IEEE1394 is not set # # I2O device support @@ -429,6 +465,11 @@ CONFIG_NETDEVICES=y CONFIG_TUN=m # +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# # PHY device support # # CONFIG_PHYLIB is not set @@ -438,8 +479,16 @@ CONFIG_TUN=m # CONFIG_NET_ETHERNET=y CONFIG_MII=m +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) @@ -452,16 +501,20 @@ CONFIG_MII=m # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set # # Obsolete Wireless cards support (pre-802.11) # # CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set # CONFIG_PCMCIA_WAVELAN is not set # CONFIG_PCMCIA_NETWAVE is not set @@ -485,6 +538,7 @@ CONFIG_PCMCIA_SPECTRUM=m # CONFIG_PCMCIA_WL3501 is not set CONFIG_HOSTAP=m CONFIG_HOSTAP_FIRMWARE=y +# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set CONFIG_HOSTAP_CS=m CONFIG_NET_WIRELESS=y @@ -512,6 +566,7 @@ CONFIG_PPP_ASYNC=m # CONFIG_PPP_SYNC_TTY is not set CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +# CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -519,7 +574,6 @@ CONFIG_PPP_BSDCOMP=m # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - # # ISDN subsystem # @@ -599,7 +653,6 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set -# CONFIG_SA1100_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -611,11 +664,14 @@ CONFIG_UNIX98_PTYS=y # PCMCIA character devices # # CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # +# CONFIG_TCG_TPM is not set # CONFIG_TELCLOCK is not set # @@ -648,19 +704,28 @@ CONFIG_I2C_ALGOBIT=m # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set -# CONFIG_MAX7310 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 # +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# # Hardware Monitoring support # # CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set # # Misc devices @@ -672,9 +737,25 @@ CONFIG_I2C_ALGOBIT=m # CONFIG_MCP_SA11X0 is not set # -# SoC drivers +# Multi-Function Devices +# + +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_LOCOMO=y + +# +# LED Triggers # -# CONFIG_SOC is not set +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y # # Multimedia devices @@ -688,6 +769,7 @@ CONFIG_VIDEO_DEV=m # # Video Adapters # +# CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_PMS is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5246A is not set @@ -696,6 +778,19 @@ CONFIG_VIDEO_DEV=m # CONFIG_VIDEO_OVCAMCHIP is not set # +# Encoders and Decoders +# +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_CX25840 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# # Radio Adapters # # CONFIG_RADIO_CADET is not set @@ -724,6 +819,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set +CONFIG_FB_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set CONFIG_FB_SA1100=y @@ -754,7 +850,11 @@ CONFIG_FONT_8x8=y # Logo configuration # # CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_LOCOMO=y # # Sound @@ -766,6 +866,7 @@ CONFIG_FONT_8x8=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 is not set # @@ -779,9 +880,11 @@ CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_NET2280 is not set # CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_PXA27X is not set # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set # CONFIG_USB_GADGET_DUALSPEED is not set @@ -793,6 +896,7 @@ CONFIG_USB_GADGET=y # # Real Time Clock # +CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" @@ -810,6 +914,8 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_M48T86 is not set CONFIG_RTC_DRV_SA1100=y # CONFIG_RTC_DRV_TEST is not set @@ -822,12 +928,12 @@ CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y CONFIG_INOTIFY=y @@ -859,10 +965,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -878,10 +983,10 @@ CONFIG_RAMFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y -CONFIG_JFFS2_SUMMARY=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set @@ -913,44 +1018,44 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" -CONFIG_NLS_CODEPAGE_437=m -# 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=m -# 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_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=y +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 # # Profiling support @@ -961,13 +1066,14 @@ CONFIG_NLS_UTF8=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -976,6 +1082,8 @@ CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set +# CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set @@ -991,7 +1099,31 @@ CONFIG_DEBUG_ERRORS=y # # Cryptographic options # -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC 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_DES 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_ARC4=m +# 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_TEST is not set # # Hardware crypto devices @@ -1000,7 +1132,7 @@ CONFIG_DEBUG_ERRORS=y # # Library routines # -# CONFIG_CRC_CCITT is not set +CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle b/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle index c8c74522bd..43cbba6f41 100644 --- a/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle +++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle @@ -1,19 +1,20 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.15 -# Sat Feb 4 16:06:13 2006 +# Linux kernel version: 2.6.17-rc1 +# Wed Apr 19 21:04:42 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -30,27 +31,28 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=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_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y +CONFIG_DOUBLEFAULT=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -58,7 +60,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -66,6 +67,7 @@ CONFIG_KMOD=y # # Block layer # +# CONFIG_BLK_DEV_IO_TRACE is not set # # IO Schedulers @@ -87,12 +89,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set CONFIG_ARCH_PXA=y # CONFIG_ARCH_RPC is not set @@ -106,11 +109,13 @@ CONFIG_ARCH_PXA=y # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91RM9200 is not set # # Intel PXA2xx Implementations # # CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set # CONFIG_MACH_MAINSTONE is not set # CONFIG_ARCH_PXA_IDP is not set CONFIG_PXA_SHARPSL=y @@ -124,6 +129,7 @@ CONFIG_MACH_POODLE=y # CONFIG_MACH_TOSA is not set CONFIG_PXA25x=y # CONFIG_PXA_KEYS is not set +CONFIG_PXA_SSP=y # # Processor Type @@ -140,6 +146,7 @@ CONFIG_CPU_TLB_V4WBI=y # CONFIG_ARM_THUMB=y CONFIG_XSCALE_PMU=y +CONFIG_KEXEC=y CONFIG_SHARP_LOCOMO=y CONFIG_SHARP_PARAM=y CONFIG_SHARP_SCOOP=y @@ -147,7 +154,6 @@ CONFIG_SHARP_SCOOP=y # # Bus support # -CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -168,6 +174,8 @@ CONFIG_PCMCIA_PXA2XX=y # CONFIG_PREEMPT=y CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 +# CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -184,6 +192,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 mem=32M fbcon=rotate:1 dyntick=enable debug" # CONFIG_XIP_KERNEL is not set # @@ -220,7 +229,6 @@ CONFIG_FPE_NWFPE=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -# CONFIG_ARTHUR is not set # # Power management options @@ -238,6 +246,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -256,6 +265,7 @@ CONFIG_SYN_COOKIES=y # 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_DIAG=y CONFIG_INET_TCP_DIAG=y @@ -268,9 +278,11 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IP_VS is not set CONFIG_IPV6=m # CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m +CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y @@ -280,6 +292,7 @@ CONFIG_NETFILTER=y # Core Netfilter Configuration # # CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NETFILTER_XTABLES is not set # # IP: Netfilter Configuration @@ -295,89 +308,13 @@ CONFIG_IP_NF_IRC=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m -CONFIG_IP_NF_MATCH_REALM=m -CONFIG_IP_NF_MATCH_SCTP=m -# CONFIG_IP_NF_MATCH_DCCP is not set -CONFIG_IP_NF_MATCH_COMMENT=m -CONFIG_IP_NF_MATCH_HASHLIMIT=m -# CONFIG_IP_NF_MATCH_STRING is not set -CONFIG_IP_NF_FILTER=m -# CONFIG_IP_NF_TARGET_REJECT is not set -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -# CONFIG_IP_NF_TARGET_NFQUEUE is not set -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -# CONFIG_IP_NF_TARGET_MASQUERADE is not set -# CONFIG_IP_NF_TARGET_REDIRECT is not set -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_NAT_SNMP_BASIC is not set -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_MANGLE=m -# CONFIG_IP_NF_TARGET_TOS is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_DSCP is not set -# CONFIG_IP_NF_TARGET_MARK is not set -# CONFIG_IP_NF_TARGET_CLASSIFY is not set -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=m -# CONFIG_IP_NF_TARGET_NOTRACK is not set -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration (EXPERIMENTAL) # CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -# CONFIG_IP6_NF_TARGET_LOG is not set -# CONFIG_IP6_NF_TARGET_REJECT is not set -# CONFIG_IP6_NF_TARGET_NFQUEUE is not set -CONFIG_IP6_NF_MANGLE=m -# CONFIG_IP6_NF_TARGET_MARK is not set -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_RAW=m # # DCCP Configuration (EXPERIMENTAL) @@ -388,6 +325,11 @@ CONFIG_IP6_NF_RAW=m # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -405,7 +347,6 @@ CONFIG_IP6_NF_RAW=m # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set -CONFIG_NET_CLS_ROUTE=y # # Network testing @@ -456,11 +397,6 @@ CONFIG_IRCOMM=m # # CONFIG_USB_IRDA is not set # CONFIG_SIGMATEL_FIR is not set -# CONFIG_NSC_FIR is not set -# CONFIG_WINBOND_FIR is not set -# CONFIG_SMC_IRCC_FIR is not set -# CONFIG_ALI_FIR is not set -# CONFIG_VIA_FIR is not set CONFIG_PXA_FICP=m CONFIG_BT=m CONFIG_BT_L2CAP=m @@ -493,6 +429,8 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_IEEE80211_SOFTMAC is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -550,6 +488,7 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_RAM is not set CONFIG_MTD_ROM=y # CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access @@ -564,7 +503,6 @@ CONFIG_MTD_SHARP_SL=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -608,7 +546,7 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -745,6 +683,7 @@ CONFIG_MII=m # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set # # Obsolete Wireless cards support (pre-802.11) @@ -773,6 +712,7 @@ CONFIG_PCMCIA_SPECTRUM=m # CONFIG_PCMCIA_WL3501 is not set CONFIG_HOSTAP=m CONFIG_HOSTAP_FIRMWARE=y +# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set CONFIG_HOSTAP_CS=m CONFIG_NET_WIRELESS=y @@ -840,7 +780,6 @@ CONFIG_KEYBOARD_LOCOMO=y # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_CORGI is not set # CONFIG_KEYBOARD_SPITZ is not set -# CONFIG_KEYBOARD_TOSA is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set CONFIG_INPUT_TOUCHSCREEN=y @@ -872,6 +811,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=m CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -894,7 +834,6 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set -CONFIG_SA1100_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -947,15 +886,24 @@ CONFIG_I2C_PXA=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C 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 # +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# # Hardware Monitoring support # # CONFIG_HWMON is not set @@ -966,10 +914,6 @@ CONFIG_I2C_PXA=y # # -# Multimedia Capabilities Port drivers -# - -# # Multi-Function Devices # @@ -978,10 +922,19 @@ CONFIG_I2C_PXA=y # CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -CONFIG_LEDS_TRIGGERS=y -# CONFIG_LEDS_CORGI is not set + +# +# LED drivers +# +CONFIG_LEDS_LOCOMO=y # CONFIG_LEDS_TOSA is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y # # Multimedia devices @@ -995,14 +948,44 @@ CONFIG_VIDEO_DEV=m # # Video Adapters # +# CONFIG_VIDEO_ADV_DEBUG 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_TUNER_3036 is not set -# CONFIG_VIDEO_EM28XX is not set # CONFIG_VIDEO_OVCAMCHIP is not set -# CONFIG_VIDEO_AUDIO_DECODER is not set -# CONFIG_VIDEO_DECODER is not set + +# +# Encoders and Decoders +# +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_CX25840 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# V4L USB devices +# +# CONFIG_VIDEO_EM28XX is not set +CONFIG_USB_DSBR=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +# CONFIG_USB_ET61X251 is not set +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +# CONFIG_USB_W9968CF is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set # # Radio Adapters @@ -1013,6 +996,7 @@ CONFIG_VIDEO_DEV=m # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +CONFIG_USB_DABUSB=m # # Graphics support @@ -1022,6 +1006,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set +CONFIG_FB_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_S1D13XXX is not set @@ -1059,6 +1044,7 @@ CONFIG_BACKLIGHT_DEVICE=y CONFIG_LCD_CLASS_DEVICE=m CONFIG_LCD_DEVICE=y # CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_LOCOMO=y # # Sound @@ -1070,6 +1056,7 @@ CONFIG_LCD_DEVICE=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 @@ -1112,12 +1099,15 @@ CONFIG_USB_STORAGE=m # 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_LIBUSUAL is not set # # USB Input Devices # CONFIG_USB_HID=m CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set # CONFIG_HID_FF is not set # CONFIG_USB_HIDDEV is not set @@ -1137,6 +1127,7 @@ CONFIG_USB_EGALAX=m # CONFIG_USB_YEALINK is not set CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m +# CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set @@ -1147,20 +1138,6 @@ CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m # -# USB Multimedia devices -# -CONFIG_USB_DABUSB=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -# CONFIG_USB_PWC is not set - -# # USB Network Adapters # CONFIG_USB_CATC=m @@ -1221,6 +1198,7 @@ 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_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_HP4X is not set CONFIG_USB_SERIAL_SAFE=m @@ -1266,6 +1244,7 @@ CONFIG_USB_PXA2XX=y # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set # CONFIG_USB_GADGET_DUALSPEED is not set CONFIG_USB_ZERO=m @@ -1283,11 +1262,11 @@ CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set CONFIG_MMC_BLOCK=y CONFIG_MMC_PXA=y -# CONFIG_MMC_WBSD is not set # # Real Time Clock # +CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" @@ -1305,6 +1284,8 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_M48T86 is not set CONFIG_RTC_DRV_SA1100=y # CONFIG_RTC_DRV_TEST is not set @@ -1315,11 +1296,11 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_JBD 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_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -1353,7 +1334,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1430,6 +1411,7 @@ CONFIG_MSDOS_PARTITION=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 # @@ -1438,42 +1420,42 @@ CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" 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_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_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 # @@ -1486,13 +1468,14 @@ CONFIG_OPROFILE=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1501,11 +1484,13 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set +# CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_LL is not set # CONFIG_DEBUG_ICEDCC is not set # @@ -1556,4 +1541,3 @@ CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y - diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz b/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz index 4256287c49..058d7a9ab1 100644 --- a/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz +++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz @@ -1436,42 +1436,42 @@ CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" 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_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_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 # @@ -1491,7 +1491,7 @@ CONFIG_LOG_BUF_SHIFT=14 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1500,7 +1500,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -CONFIG_FORCED_INLINING=y +# CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa b/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa index f1a5c1e1c4..96fc41cdbd 100644 --- a/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa +++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa @@ -1466,46 +1466,46 @@ CONFIG_MSDOS_PARTITION=y # # Native Language Support # -CONFIG_NLS=m +CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" -CONFIG_NLS_CODEPAGE_437=m -# 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=m -# 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_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=y +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 # # Profiling support @@ -1523,7 +1523,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1532,7 +1532,7 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -CONFIG_FORCED_INLINING=y +# CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set diff --git a/packages/linux/linux-openzaurus-2.6.16/hrw-pcmcia-ids-r2.patch b/packages/linux/linux-openzaurus-2.6.16/hrw-pcmcia-ids-r2.patch new file mode 100644 index 0000000000..c7be5b3373 --- /dev/null +++ b/packages/linux/linux-openzaurus-2.6.16/hrw-pcmcia-ids-r2.patch @@ -0,0 +1,35 @@ + +The ident for Seagate 8GB microdrive is +"SEAGATE", "ST1" +hash 0x76dc4190, 0xcfba9599 +manfid 0x0111, 0x0000 + +Signed-off-by: Marcin Juszkiewicz <openembedded@hrw.one.pl> + + drivers/ide/legacy/ide-cs.c | 1 + + 1 file changed, 1 insertion(+) + +Index: linux-2.6.16/drivers/ide/legacy/ide-cs.c +=================================================================== +--- linux-2.6.16.orig/drivers/ide/legacy/ide-cs.c 2006-04-20 12:41:41.000000000 +0200 ++++ linux-2.6.16/drivers/ide/legacy/ide-cs.c 2006-04-20 12:45:19.640621552 +0200 +@@ -444,6 +444,7 @@ + PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), + PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), + PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), ++ PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x76dc4190, 0xcfba9599), /* Seagate 8GB microdrive */ + PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), + PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), + PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), + + +------------------------------------------------------------------------- +With pcmcia-cs -> pcmciautils change some cards which was working with +hostap driver now are bound into orinoco driver. + +This patch made them bound into hostap like it was before. + +Signed-off-by: Marcin Juszkiewicz <openembedded@hrw.one.pl> + +// will add some here + diff --git a/packages/linux/linux-openzaurus_2.6.16.bb b/packages/linux/linux-openzaurus_2.6.16.bb index 1225eb5830..8d1541cb0b 100644 --- a/packages/linux/linux-openzaurus_2.6.16.bb +++ b/packages/linux/linux-openzaurus_2.6.16.bb @@ -1,6 +1,6 @@ include linux-openzaurus.inc -PR = "r5" +PR = "r9" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ @@ -43,6 +43,11 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \ ${RPSRC}/integrator_rtc-r0.patch;patch=1 \ ${RPSRC}/zaurus_keyboard_tweak-r3.patch;patch=1 \ ${RPSRC}/pxafb_tweaks-r0.patch;patch=1 \ + ${RPSRC}/spitz_kbd_fix-r0.patch;patch=1 \ + ${RPSRC}/mmcsd_large_cards-r0.patch;patch=1 \ + ${RPSRC}/fbmem_fix-r1.patch;patch=1 \ + ${RPSRC}/scoop_linkage-r0.patch;patch=1 \ + ${RPSRC}/ssp_cleanup-r0.patch;patch=1 \ ${RPSRC}/alsa/asoc-v0.10rc4.patch;patch=1 \ ${RPSRC}/hx2750_base-r24.patch;patch=1 \ ${RPSRC}/hx2750_bl-r5.patch;patch=1 \ @@ -52,7 +57,7 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \ ${RPSRC}/hx2750_test1-r3.patch;patch=1 \ ${RPSRC}/pxa_timerfix-r0.patch;patch=1 \ ${RPSRC}/input_power-r4.patch;patch=1 \ - ${RPSRC}/jffs2_longfilename-r0.patch;patch=1 \ + ${RPSRC}/jffs2_longfilename-r1.patch;patch=1 \ ${RPSRC}/pxa25x_cpufreq-r0.patch;patch=1 \ ${RPSRC}/misc_fix1-r0.patch;patch=1 \ ${RPSRC}/corgi_bl_cleanup-r3.patch;patch=1 \ @@ -62,11 +67,14 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \ ${RPSRC}/poodle_memsize-r0.patch;patch=1 \ ${RPSRC}/collie_frontlight-r1.patch;patch=1 \ ${RPSRC}/zlib_inflate-r3.patch;patch=1 \ + ${RPSRC}/zaurus_reboot-r0.patch;patch=1 \ + ${RPSRC}/sharpsl_pm_fixes1-r0.patch;patch=1 \ + ${RPSRC}/asoc_fixups-r0.patch;patch=1 \ ${RPSRC}/pm_changes-r1.patch;patch=1 \ ${RPSRC}/sharpsl_pm-do-r2.patch;patch=1 \ ${RPSRC}/usb_pxa27x_udc-r0.patch;patch=1 \ ${RPSRC}/usb_add_epalloc-r1.patch;patch=1 \ - ${DOSRC}/kexec-arm-r2.patch;patch=1 \ + ${DOSRC}/kexec-arm-r2.patch;patch=1 \ ${RPSRC}/pxa_cf_initorder_hack-r1.patch;patch=1 \ ${RPSRC}/mmcsd_no_scr_check-r0.patch;patch=1 \ ${RPSRC}/poodle_ts_hack-r0.patch;patch=1 \ @@ -75,6 +83,8 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \ ${RPSRC}/pxa-linking-bug.patch;patch=1 \ file://serial-add-support-for-non-standard-xtals-to-16c950-driver.patch;patch=1 \ file://connectplus-remove-ide-HACK.patch;patch=1 \ + file://24-hostap_cs_id.diff;patch=1 \ + file://hrw-pcmcia-ids-r2.patch;patch=1 \ file://defconfig-c7x0 \ file://defconfig-ipaq-pxa270 \ file://defconfig-collie \ @@ -113,6 +123,9 @@ SRC_URI_append_tosa = "\ ${DOSRC}/wm97xx-lg7-r0.patch;patch=1 \ ${DOSRC}/tosa-asoc-r0.patch;patch=1 " +SRC_URI_append_poodle = "\ + ${RPSRC}/rp_poodle_hacks-r0.patch;patch=1" + S = "${WORKDIR}/linux-2.6.16" # to get module dependencies working diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb index 217aefb976..92013b8344 100644 --- a/packages/meta/slugos-packages.bb +++ b/packages/meta/slugos-packages.bb @@ -30,7 +30,6 @@ SLUGOS_PACKAGES = "\ binutils \ bison \ bluez-utils-nodbus \ - bogofilter \ boost \ bridge-utils \ bwmon \ @@ -114,7 +113,7 @@ SLUGOS_PACKAGES = "\ netpbm \ nmap \ ntp \ - obexftp openobex-apps ircp \ + openobex-apps ircp \ openldap \ openntpd \ openssh \ @@ -165,7 +164,7 @@ SLUGOS_PACKAGES = "\ SLUGOS_BROKEN_PACKAGES = "\ icecast \ irssi \ - openobex \ + obexftp openobex \ pvrusb2-mci \ setpwc \ watchdog \ @@ -187,6 +186,7 @@ UCLIBC_UNSUPPORTABLE_PACKAGES = "\ # These packages work with glibc, but break on uclibc. UCLIBC_BROKEN_PACKAGES = "\ alsa-utils \ + bogofilter \ " # Packages which build only with glibc (some of these use internal diff --git a/packages/opie-bluetoothmanager/opie-bluetoothmanager.inc b/packages/opie-bluetoothmanager/opie-bluetoothmanager.inc index fbc9a06625..a2fa2e83a1 100644 --- a/packages/opie-bluetoothmanager/opie-bluetoothmanager.inc +++ b/packages/opie-bluetoothmanager/opie-bluetoothmanager.inc @@ -9,8 +9,8 @@ APPNAME = "bluetooth-manager" S = "${WORKDIR}/manager" -EXTRA_QMAKEVARS_POST += " INCLUDEPATH+=${STAGING_INCDIR}/opietooth " -EXTRA_QMAKEVARS_PRE = 'LIBOBEXFTP_INC_DIR=${STAGING_INCDIR}/obexftp' +EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=${STAGING_INCDIR}/opietooth" +EXTRA_QMAKEVARS_PRE += "LIBOBEXFTP_INC_DIR=${STAGING_INCDIR}/obexftp" inherit opie diff --git a/packages/opie-camera/opie-camera.inc b/packages/opie-camera/opie-camera.inc index c57855ac03..9dae4c218c 100644 --- a/packages/opie-camera/opie-camera.inc +++ b/packages/opie-camera/opie-camera.inc @@ -9,7 +9,7 @@ APPTYPE = "binary" S = "${WORKDIR}/camera" -EXTRA_QMAKEVARS_POST=" LIBS+=-L.. " +EXTRA_QMAKEVARS_POST += "LIBS+=-L.." PARALLEL_MAKE = "" inherit opie diff --git a/packages/opie-dagger/opie-dagger.inc b/packages/opie-dagger/opie-dagger.inc index 44213e04ca..705ca26cb6 100644 --- a/packages/opie-dagger/opie-dagger.inc +++ b/packages/opie-dagger/opie-dagger.inc @@ -6,7 +6,7 @@ LICENSE = "GPL" DEPENDS = "libopiecore2 libopieui2 sword" APPNAME = "dagger" -EXTRA_QMAKEVARS_PRE = "LIBSWORD_INC_DIR=${STAGING_INCDIR}/sword" +EXTRA_QMAKEVARS_PRE += "LIBSWORD_INC_DIR=${STAGING_INCDIR}/sword" S = "${WORKDIR}/${APPNAME}" diff --git a/packages/opie-freetype/opie-freetype.inc b/packages/opie-freetype/opie-freetype.inc index 9a75d023a5..8d3fcd7ab2 100644 --- a/packages/opie-freetype/opie-freetype.inc +++ b/packages/opie-freetype/opie-freetype.inc @@ -11,4 +11,4 @@ S = "${WORKDIR}/freetype" inherit opie -EXTRA_QMAKEVARS_POST = "INCLUDEPATH+=${STAGING_INCDIR}/freetype2" +EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=${STAGING_INCDIR}/freetype2" diff --git a/packages/opie-keytabs/opie-keytabs.inc b/packages/opie-keytabs/opie-keytabs.inc index 0bfb8ed750..1f8248b36d 100644 --- a/packages/opie-keytabs/opie-keytabs.inc +++ b/packages/opie-keytabs/opie-keytabs.inc @@ -2,10 +2,7 @@ DESCRIPTION = "Opie keytabs for terminal applications" SECTION = "opie/base" PRIORITY = "optional" LICENSE = "GPL" -DEPENDS = "virtual/libqpe" MAINTAINER = "Team Opie <opie-devel@handhelds.org>" -APPTYPE = "binary" - do_install() { install -d ${D}${palmtopdir}/etc/keytabs/ diff --git a/packages/opie-packagemanager/opie-packagemanager.inc b/packages/opie-packagemanager/opie-packagemanager.inc index 3c3a22161b..0ec6b93fbf 100644 --- a/packages/opie-packagemanager/opie-packagemanager.inc +++ b/packages/opie-packagemanager/opie-packagemanager.inc @@ -3,14 +3,14 @@ SECTION = "opie/settings" PRIORITY = "optional" MAINTAINER = "Team Opie <opie@handhelds.org>" LICENSE = "GPL" -DEPENDS = "libipkg " +DEPENDS = "libipkg" APPNAME = "packagemanager" S = "${WORKDIR}/${APPNAME}" inherit opie -EXTRA_QMAKEVARS_PRE = 'LIBIPK_INC_DIR=${STAGING_INCDIR}/libipkg' +EXTRA_QMAKEVARS_PRE += "LIBIPK_INC_DIR=${STAGING_INCDIR}/libipkg" do_install() { install -d ${D}${palmtopdir}/pics/${APPNAME} diff --git a/packages/pocketcellar/pocketcellar_1.1.bb b/packages/pocketcellar/pocketcellar_1.1.bb index 4b3ef77042..c7d1815e44 100644 --- a/packages/pocketcellar/pocketcellar_1.1.bb +++ b/packages/pocketcellar/pocketcellar_1.1.bb @@ -15,7 +15,7 @@ SRC_URI = "http://www.staikos.net/~staikos/pocketcellar/pocketcellar-${PV}.tar.g inherit palmtop -EXTRA_QMAKEVARS_POST = " DESTDIR=pkg-cellar/home/QtPalmtop/bin/" +EXTRA_QMAKEVARS_POST += " DESTDIR=pkg-cellar/home/QtPalmtop/bin/" do_install() { install -d ${D}${palmtopdir}/bin \ diff --git a/packages/polypaudio/.mtn2git_empty b/packages/polypaudio/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/polypaudio/.mtn2git_empty diff --git a/packages/nonworking/polypaudio/polypaudio_0.7.bb b/packages/polypaudio/polypaudio_0.8.bb index f0c8737e9d..3e887533f5 100644 --- a/packages/nonworking/polypaudio/polypaudio_0.7.bb +++ b/packages/polypaudio/polypaudio_0.8.bb @@ -1,8 +1,10 @@ DESCRIPTION = "Polypaudio is a sound server for Linux and other Unix like operating systems" +HOMEPAGE = "http://0pointer.de/lennart/projects/polypaudio" +AUTHOR = "Lennart Poettering" SECTION = "libs" LICENSE = "LGPL" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" -DEPENDS = "libtool libsamplerate0 libsndfile1" +DEPENDS = "liboil libsamplerate0 libsndfile1 libtool" SRC_URI = "http://0pointer.de/lennart/projects/polypaudio/polypaudio-${PV}.tar.gz" @@ -10,3 +12,4 @@ inherit autotools EXTRA_OECONF = "--disable-lynx --without-x --without-glib --without-alsa --with-oss" +PARALLEL_MAKE = "" diff --git a/packages/poptop/.mtn2git_empty b/packages/poptop/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/poptop/.mtn2git_empty diff --git a/packages/poptop/poptop_1.3.0.bb b/packages/poptop/poptop_1.3.0.bb new file mode 100644 index 0000000000..2d8c59a2f1 --- /dev/null +++ b/packages/poptop/poptop_1.3.0.bb @@ -0,0 +1,36 @@ +DESCRIPTION = "Poptop is the PPTP server solution for Linux \ +Using Poptop, Linux servers can now function seamlessly in a PPTP VPN environment. \ +This enables administrators to leverage the considerable benefits of both Microsoft and Linux operating systems \ +The current release version supports Windows 95/98/Me/NT/2000/XP PPTP clients and Linux PPTP clients \ +For more info visit http://www.poptop.org/" + +MAINTAINER = "Stelios Koroneos <skoroneos@digital-opsis.com> " +HOMEPAGE = "http://www.poptop.org/" +LICENSE = "GPL" +SECTION = "network" +PRIORITY = "optional" +DEPENDS = "ppp" +RDEPENDS = "ppp" + +PR = "r0" + +inherit autotools + +SRC_URI = "${SOURCEFORGE_MIRROR}/poptop/pptpd-${PV}.tar.gz" +S = "${WORKDIR}/pptpd-${PV}" + + + +do_install() { + install -d ${D}${sbindir} + install -d ${D}/${sysconfdir} + install -d ${D}/${sysconfdir}/ppp/ + + install -m 0755 pptpd ${D}${sbindir}/ + install -m 0755 pptpctrl ${D}${sbindir}/ + install -m 0644 samples/options.pptpd ${D}/${sysconfdir}/ppp/ + install -m 0644 samples/pptpd.conf ${D}/${sysconfdir}/ + + +} + diff --git a/packages/python/python-sip4_4.4.1.bb b/packages/python/python-sip4_4.4.1.bb new file mode 100644 index 0000000000..97f7375056 --- /dev/null +++ b/packages/python/python-sip4_4.4.1.bb @@ -0,0 +1,43 @@ +DESCRIPTION = "Runtime helper for sip-generated python wrapper libraries" +SECTION = "devel/python" +HOMEPAGE = "http://www.riverbankcomputing.co.uk/sip" +AUTHOR = "Phil Thompson" +MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" +LICENSE = "GPL" +DEPENDS = "python" +RDEPENDS = "python-core" +PR = "ml0" + +SRC_URI = "http://www.vanille.de/mirror/sip-${PV}.tar.gz" +S = "${WORKDIR}/sip-${PV}/siplib" + +inherit qmake distutils-base + +EXTRA_QMAKEVARS_POST = " TEMPLATE=lib \ + CONFIG=console \ + DESTDIR= \ + VERSION=1.0.0 \ + TARGET=sip \ + DEFINES=SIP_QT_SUPPORT \ + INCLUDEPATH+=. \ + INCLUDEPATH+=${STAGING_INCDIR}/${PYTHON_DIR} \ + INCLUDEPATH+=${STAGING_INCDIR}" + + +do_configure_prepend() { + cat siplib.sbf | sed s,target,TARGET, | sed s,sources,SOURCES, | sed s,headers,HEADERS, > siplib.pro +} + +do_stage() { + install -d ${STAGING_DIR}/${BUILD_SYS}/lib/${PYTHON_DIR}/site-packages/ + # sipconfig.py sipdistutils.py + install -m 0644 sip.h ${STAGING_INCDIR}/sip.h +} + +do_install() { + install -d ${D}${libdir}/${PYTHON_DIR}/site-packages/ + install -m 0755 libsip.so.1.0.0 ${D}${libdir}/${PYTHON_DIR}/site-packages/sip.so +} + +FILES_${PN} = "${libdir}/${PYTHON_DIR}/site-packages/sip.so" + diff --git a/packages/python/python_2.3.4.bb b/packages/python/python_2.3.4.bb index de9c15c350..e6da09e48f 100644 --- a/packages/python/python_2.3.4.bb +++ b/packages/python/python_2.3.4.bb @@ -5,7 +5,7 @@ SECTION = "devel/python" PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" DEPENDS = "python-native zlib gdbm" -PR = "ml4" +PR = "ml5" SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.bz2 \ file://bindir-libdir.patch;patch=1 \ @@ -55,3 +55,4 @@ do_install() { } include python-${PV}-manifest.inc +RPROVIDES_python-core = "python" diff --git a/packages/python/python_2.4.3.bb b/packages/python/python_2.4.3.bb index 7d3856d719..600bee2df6 100644 --- a/packages/python/python_2.4.3.bb +++ b/packages/python/python_2.4.3.bb @@ -5,7 +5,7 @@ SECTION = "devel/python" PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" DEPENDS = "python-native readline zlib gdbm openssl tcl tk" -PR = "ml0" +PR = "ml1" PYTHON_MAJMIN = "2.4" @@ -62,6 +62,6 @@ do_install() { include python-${PV}-manifest.inc +RPROVIDES_python-core = "python" PACKAGES =+ "libpython2" FILES_libpython2 = "${libdir}/libpython*" - diff --git a/packages/qpdf2/qpdf2_2.2.1.bb b/packages/qpdf2/qpdf2_2.2.1.bb index 6e31f40bd6..c1da64f3f9 100644 --- a/packages/qpdf2/qpdf2_2.2.1.bb +++ b/packages/qpdf2/qpdf2_2.2.1.bb @@ -19,7 +19,7 @@ S = "${WORKDIR}/qpdf2_${PV}" inherit opie QMAKE_PROFILES = "qpdf_render-freetype.pro" -EXTRA_QMAKEVARS_POST = "TARGET=qpdf" +EXTRA_QMAKEVARS_POST += "TARGET=qpdf" export OE_QMAKE_LINK="${CXX}" do_configure_prepend() { diff --git a/packages/qpegps/qpegps_0.9.2.3.2.bb b/packages/qpegps/qpegps_0.9.2.3.2.bb index 1885f97855..073b95a96a 100644 --- a/packages/qpegps/qpegps_0.9.2.3.2.bb +++ b/packages/qpegps/qpegps_0.9.2.3.2.bb @@ -15,7 +15,7 @@ S = "${WORKDIR}/qpegps_my" inherit palmtop QMAKE_PROFILES = "qpegps.pro" -EXTRA_QMAKEVARS_POST = "LIBS=-lqpe" +EXTRA_QMAKEVARS_POST += "LIBS=-lqpe" do_install() { install -d ${D}${palmtopdir}/bin \ diff --git a/packages/qpegps/qpegps_0.9.2.3.bb b/packages/qpegps/qpegps_0.9.2.3.bb index baa174246f..0b4e5e3ccd 100644 --- a/packages/qpegps/qpegps_0.9.2.3.bb +++ b/packages/qpegps/qpegps_0.9.2.3.bb @@ -15,7 +15,7 @@ S = "${WORKDIR}/root/qpegps_src_my/qpegps_my" inherit palmtop QMAKE_PROFILES = "qpegps.pro" -EXTRA_QMAKEVARS_POST = "LIBS=-lqpe" +EXTRA_QMAKEVARS_POST += "LIBS=-lqpe" do_install() { install -d ${D}${palmtopdir}/bin \ diff --git a/packages/qte/qte-2.3.12/.mtn2git_empty b/packages/qte/qte-2.3.12/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/qte/qte-2.3.12/.mtn2git_empty diff --git a/packages/qte/qte-2.3.12/bidimetrics.patch b/packages/qte/qte-2.3.12/bidimetrics.patch new file mode 100644 index 0000000000..ea4765c601 --- /dev/null +++ b/packages/qte/qte-2.3.12/bidimetrics.patch @@ -0,0 +1,2389 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfxraster_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qgfxraster_qws.cpp 2006-01-20 20:50:26.577740040 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfxraster_qws.cpp 2006-01-20 21:09:56.399900040 +0100 +@@ -51,6 +51,11 @@ + #include <fcntl.h> + #include <errno.h> + ++//HAQ bidi patch ++#ifdef USE_BIDI ++#include "qbidi.h" ++#endif ++// end HAQ patch + + extern bool qws_sw_cursor; + +@@ -1408,6 +1413,53 @@ + setAlphaType(BigEndianMask); + } + ++#ifdef USE_BIDI ++ // HAQ do bidi ++ QString n; ++ qApplyBidi(s, n); ++ ++ for( loopc=0; loopc < int(n.length()); loopc++ ) { ++ QGlyph glyph = memorymanager->lockGlyph(myfont, n[loopc]); ++ int myw=glyph.metrics->width; ++ srcwidth = myw; ++ srcheight = glyph.metrics->height; ++ setAlphaSource(glyph.data,glyph.metrics->linestep); ++ int myx=x; ++ int myy=y; ++ myx+=glyph.metrics->bearingx; ++ myy-=glyph.metrics->bearingy; ++ ++ // HAQ hack to show arabic tashkeel (diacriticals) above ++ // the previous character (which in reversed arabic, as it is here, is the next character) ++ ++ QChar c = n[loopc]; ++ if (ISTASHKEEL(c.unicode())) { ++ //printf("glyph %d bearingx %d width %d advance %d\n", ++ // c.unicode(),glyph.metrics->bearingx, glyph.metrics->width, glyph.metrics->advance); ++ ++ if (loopc < int(n.length()-1)) // if there is a following character then place this glyph over it ++ { ++ QGlyph nextGlyph = memorymanager->lockGlyph(myfont, n[loopc+1]); ++ int nextCharWidth = nextGlyph.metrics->width; ++ myx += nextCharWidth/2 - glyph.metrics->width; ++ // pre-undo the advance in x so that the next glyph is placed over this one ++ x -= glyph.metrics->advance; ++ } ++ } ++ ++ if(glyph.metrics->width<1 || glyph.metrics->height<1 ++ || glyph.metrics->linestep==0) ++ { ++ // non-printing characters ++ } else { ++ blt(myx,myy,myw,glyph.metrics->height,0,0); ++ } ++ x+=glyph.metrics->advance; ++ // ... unlock glyph ++ } ++ ++#else ++ + for( loopc=0; loopc < int(s.length()); loopc++ ) { + QGlyph glyph = memorymanager->lockGlyph(myfont, s[loopc]); + int myw=glyph.metrics->width; +@@ -1428,6 +1480,9 @@ + x+=glyph.metrics->advance; + // ... unlock glyph + } ++ ++#endif ++ + #ifdef DEBUG_LOCKS + qDebug("unaccelerated drawText unlock"); + #endif +Index: qt-2.3.10-snapshot-20060120/src/kernel/qfont_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qfont_qws.cpp 2006-01-20 20:57:33.115896384 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qfont_qws.cpp 2006-01-20 21:09:56.400899888 +0100 +@@ -49,6 +49,12 @@ + #include "qfontmanager_qws.h" + #include "qmemorymanager_qws.h" + ++//HAQ ++#ifdef USE_BIDI ++#include "qbidi.h" ++#endif ++// end HAQ ++ + // QFont_Private accesses QFont protected functions + + class QFont_Private : public QFont +@@ -388,17 +394,46 @@ + + int QFontMetrics::width( QChar ch ) const + { ++#ifdef USE_BIDI ++ ++ int advance; ++ if (ISTASHKEEL(ch.unicode())) { ++ advance = 0; ++ } ++ else ++ advance = memorymanager->lockGlyphMetrics(((QFontMetrics*)this)->internal()->handle(),ch)->advance; ++ return advance; ++ ++#else ++ + return memorymanager->lockGlyphMetrics(((QFontMetrics*)this)->internal()->handle(),ch)->advance; ++ ++#endif + } + + int QFontMetrics::width( const QString &str, int len ) const + { ++#ifdef USE_BIDI ++ ++ QString n; ++ qApplyBidi(str, n); ++ if (len < 0) len = n.length(); ++ int ret=0; ++ for (int i=0; i<len; i++) ++ ret += width(n[i]); ++ return ret; ++ ++#else ++ + if ( len < 0 ) + len = str.length(); + int ret=0; + for (int i=0; i<len; i++) + ret += width(str[i]); + return ret; ++ ++#endif ++ + } + + QRect QFontMetrics::boundingRect( const QString &str, int len ) const +Index: qt-2.3.10-snapshot-20060120/src/kernel/qbidi.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qbidi.h 2006-01-20 21:09:56.400899888 +0100 +@@ -0,0 +1,6 @@ ++#include "stdio.h" ++#include <qstring.h> ++ ++#define ISTASHKEEL(x) ((x >= 0x64B && x<=0x658) || (x>=0x6d6 && x <= 0x6dc) || (x>=0x6df && x <= 0x6e4) || x==0x6e7 || x == 0x6e8 || (x>=0x6ea && x <= 0x6ed) || (x>=0xfe70 && x <= 0xfe7f)) ++ ++void qApplyBidi(const QString& s, QString& news); +Index: qt-2.3.10-snapshot-20060120/src/kernel/qbidi.cpp +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qbidi.cpp 2006-01-20 21:09:56.401899736 +0100 +@@ -0,0 +1,45 @@ ++#include <malloc.h> ++#include "qbidi.h" ++ ++ ++#define BLOCKTYPE unsigned short* ++#define CHARTYPE unsigned short ++ ++extern "C" { ++ ++int doShape(BLOCKTYPE line, CHARTYPE* to, int from, int count); ++int doBidi(BLOCKTYPE line, int count, int applyShape, int reorderCombining, int removeMarks); ++ ++} ++ ++void qApplyBidi(const QString& s, QString& news) { ++ //convert to utf16 zero-terminated ++ //printf(": qs length is %d\n",s.length()); ++ int loopc; ++ int slength = sizeof(unsigned short) * (s.length()); ++ //printf(": slength is %d\n",slength); ++ unsigned short* sutf16 = (unsigned short*)malloc(slength); ++ for( loopc=0; loopc < int(s.length()); loopc++ ) { ++ sutf16[loopc] = s[loopc].unicode(); ++ //printf(": char %d is %x\n",loopc,sutf16[loopc]); ++ } ++ //printf(": mark 0\n"); ++ ///sutf16[s.length()] = 0; ++ ++ unsigned short* sutf16s = (unsigned short*)malloc(slength); ++ doShape(sutf16,sutf16s,0,s.length()); ++ //printf(": do bidi\n"); ++ doBidi(sutf16s, s.length(),0,0,0); ++ //sutf16s[s.length()] = 0; ++ ++ //printf(": back to QString\n"); ++ news = ""; ++ for( loopc=0; loopc < s.length(); loopc++ ) { ++ QChar newChar((short) sutf16s[loopc]); ++ news = news + newChar; ++ //printf(": add char %x\n",newChar.unicode()); ++ } ++ ++ free(sutf16); ++ free(sutf16s); ++} +Index: qt-2.3.10-snapshot-20060120/src/kernel/minibidi.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qt-2.3.10-snapshot-20060120/src/kernel/minibidi.c 2006-01-20 21:09:56.403899432 +0100 +@@ -0,0 +1,2127 @@ ++/************************************************************************ ++ * $Id: minibidi.c,v 1.2 2005/04/08 18:01:45 lynch Exp $ ++ * ++ * ------------ ++ * Description: ++ * ------------ ++ * This is an implemention of Unicode's Bidirectional Algorithm ++ * (known as UAX #9). ++ * ++ * http://www.unicode.org/reports/tr9/ ++ * ++ * Author: Ahmad Khalifa ++ * ++ * ----------------- ++ * Revision Details: (Updated by Revision Control System) ++ * ----------------- ++ * $Date: 2005/04/08 18:01:45 $ ++ * $Author: lynch $ ++ * $Revision: 1.2 $ ++ * $Source: /home/arabeyes/cvs/projects/external/qt_e/minibidi.c,v $ ++ * ++ * (www.arabeyes.org - under MIT license) ++ * ++ ************************************************************************/ ++ ++#include <malloc.h> /* malloc() and free() definition */ ++ ++/* ++ * Datatype Extension Macros ++ */ ++#define BLOCKTYPE unsigned short* ++#define CHARTYPE unsigned short ++#define GETCHAR(from,i) from[i] ++ ++#define GetType(x) getType(x) ++/*=====TESTING mode===========*/ ++//#define GetType(x) getCAPRtl(x) ++ ++#define lenof(x) sizeof(x) / sizeof(x[0]) ++ ++/* character types */ ++enum ++{ ++ /* Strong Char Types */ ++ L, /* Left-to-Right char */ ++ LRE, /* Left-to-Right Embedding */ ++ LRO, /* Left-to-Right Override */ ++ R, /* Right-to-Left char */ ++ AL, /* Right-to-Left Arabic char */ ++ RLE, /* Right-to-Left Embedding */ ++ RLO, /* Right-to-Left Override */ ++ /* Weak Char Types */ ++ PDF, /* Pop Directional Format */ ++ EN, /* European Number */ ++ ES, /* European Number Separator */ ++ ET, /* European Number Terminator */ ++ AN, /* Arabic Number */ ++ CS, /* Common Number Separator */ ++ NSM, /* Non Spacing Mark */ ++ BN, /* Boundary Neutral */ ++ /* Neutral Char Types */ ++ B, /* Paragraph Separator */ ++ S, /* Segment Separator */ ++ WS, /* Whitespace */ ++ ON, /* Other Neutrals */ ++}; ++ ++/* Shaping Types */ ++enum ++{ ++ SL, /* Left-Joining, doesnt exist in U+0600 - U+06FF */ ++ SR, /* Right-Joining, ie has Isolated, Final */ ++ SD, /* Dual-Joining, ie has Isolated, Final, Initial, Medial */ ++ SU, /* Non-Joining */ ++ SC /* Join-Causing, like U+0640 (TATWEEL) */ ++}; ++ ++#define odd(x) (x%2) ++/* Returns the first odd/even value greater than x */ ++#define leastGreaterOdd(x) odd(x) ? (x+2) : (x+1) ++#define leastGreaterEven(x) odd(x) ? (x+1) : (x+2) ++ ++/* Shaping Helpers */ ++#define STYPE(xh) ((xh >= SHAPE_FIRST) && (xh <= SHAPE_LAST)) ? \ ++ shapetypes[xh-SHAPE_FIRST].type : SU ++#define SISOLATED(xh) shapetypes[xh-SHAPE_FIRST].form_b ++#define SFINAL(xh) xh+1 ++#define SINITIAL(xh) xh+2 ++#define SMEDIAL(xh) xh+3 ++ ++ ++/* function declarations */ ++int findIndexOfRun(unsigned char* level , int start, int count, int tlevel); ++unsigned char getType(CHARTYPE ch); ++unsigned char getCAPRtl(CHARTYPE ch); ++void doMirror(BLOCKTYPE ch); ++ ++typedef struct{ ++ unsigned char type; ++ unsigned short form_b; ++} shape_node; ++ ++/* Kept near the actual table, for verification. */ ++#define SHAPE_FIRST 0x621 ++#define SHAPE_LAST 0x668 ++/* very bad Memory alignment for 32-bit machines ++ * could split it to 2 arrays or promote type to 2 bytes type ++ */ ++shape_node shapetypes[] = { ++/* index, Typ, Iso */ ++/* 621 */ {SU, 0xFE80}, ++/* 622 */ {SR, 0xFE81}, ++/* 623 */ {SR, 0xFE83}, ++/* 624 */ {SR, 0xFE85}, ++/* 625 */ {SR, 0xFE87}, ++/* 626 */ {SD, 0xFE89}, ++/* 627 */ {SR, 0xFE8D}, ++/* 628 */ {SD, 0xFE8F}, ++/* 629 */ {SR, 0xFE93}, ++/* 62A */ {SD, 0xFE95}, ++/* 62B */ {SD, 0xFE99}, ++/* 62C */ {SD, 0xFE9D}, ++/* 62D */ {SD, 0xFEA1}, ++/* 62E */ {SD, 0xFEA5}, ++/* 62F */ {SR, 0xFEA9}, ++/* 630 */ {SR, 0xFEAB}, ++/* 631 */ {SR, 0xFEAD}, ++/* 632 */ {SR, 0xFEAF}, ++/* 633 */ {SD, 0xFEB1}, ++/* 634 */ {SD, 0xFEB5}, ++/* 635 */ {SD, 0xFEB9}, ++/* 636 */ {SD, 0xFEBD}, ++/* 637 */ {SD, 0xFEC1}, ++/* 638 */ {SD, 0xFEC5}, ++/* 639 */ {SD, 0xFEC9}, ++/* 63A */ {SD, 0xFECD}, ++/* 63B */ {SU, 0x0}, ++/* 63C */ {SU, 0x0}, ++/* 63D */ {SU, 0x0}, ++/* 63E */ {SU, 0x0}, ++/* 63F */ {SU, 0x0}, ++/* 640 */ {SC, 0x0}, ++/* 641 */ {SD, 0xFED1}, ++/* 642 */ {SD, 0xFED5}, ++/* 643 */ {SD, 0xFED9}, ++/* 644 */ {SD, 0xFEDD}, ++/* 645 */ {SD, 0xFEE1}, ++/* 646 */ {SD, 0xFEE5}, ++/* 647 */ {SD, 0xFEE9}, ++/* 648 */ {SR, 0xFEED}, ++/* 649 */ {SR, 0xFEEF}, /* SD */ ++/* 64A */ {SD, 0xFEF1}, ++/* 64B */ {SU, 0xFEF1}, ++/* 64C */ {SU, 0xFEF1}, ++/* 64D */ {SU, 0xFEF1}, ++/* 64E */ {SU, 0xFEF1}, ++/* 64F */ {SU, 0xFEF1}, ++/* 650 */ {SU,0xFEF1}, ++/* 651 */ {SU,0xFEF1}, ++/* 652 */ {SU,0xFEF1}, ++/* 653 */ {SU, 0xFEF1}, ++/* 654 */ {SU, 0xFEF1}, ++/* 655 */ {SU, 0xFEF1}, ++/* 656 */ {SU, 0xFEF1}, ++/* 657 */ {SU, 0xFEF1}, ++/* 658 */ {SU, 0xFEF1}, ++/* 659 */ {SU, 0xFEF1}, ++/* 65a */ {SU, 0xFEF1}, ++/* 65b */ {SU, 0xFEF1}, ++/* 65c */ {SU, 0xFEF1}, ++/* 65d */ {SU, 0xFEF1}, ++/* 65e */ {SU, 0xFEF1}, ++/* 65f */ {SU, 0xFEF1}, ++/* 660 */ {SU, 0xFEF1}, ++/* 661 */ {SU, 0xFEF1}, ++/* 662 */ {SU, 0xFEF1}, ++/* 663 */ {SU, 0xFEF1}, ++/* 664 */ {SU, 0xFEF1}, ++/* 665 */ {SU, 0xFEF1}, ++/* 666 */ {SU, 0xFEF1}, ++/* 667 */ {SU, 0xFEF1}, ++/* 668 */ {SU, 0xFEF1} ++}; ++ ++/* ++ * Flips the text buffer, according to max level, and ++ * all higher levels ++ * ++ * Input: ++ * from: text buffer, on which to apply flipping ++ * level: resolved levels buffer ++ * max: the maximum level found in this line (should be unsigned char) ++ * count: line size in wchar_t ++ */ ++void flipThisRun(BLOCKTYPE from, unsigned char* level, int max, int count) ++{ ++ int i, j, rcount, tlevel; ++ CHARTYPE temp; ++ ++ ++ j = i = 0; ++ while(i<count && j<count) ++ { ++ ++ /* find the start of the run of level=max */ ++ tlevel = max; ++ i = j = findIndexOfRun(level, i, count, max); ++ /* find the end of the run */ ++ while((tlevel <= level[i]) && (i < count)) ++ { ++ i++; ++ } ++ rcount = i-j; ++ for(; rcount>((i-j)/2); rcount--) ++ { ++ temp = GETCHAR(from, j+rcount-1); ++ GETCHAR(from, j+rcount-1) = GETCHAR(from, i-rcount); ++ GETCHAR(from, i-rcount) = temp; ++ } ++ } ++} ++ ++/* ++ * Finds the index of a run with level equals tlevel ++ */ ++int findIndexOfRun(unsigned char* level , int start, int count, int tlevel) ++{ ++ int i; ++ for(i=start; i<count; i++) ++ { ++ if(tlevel <= level[i]) ++ { ++ return i; ++ } ++ } ++ return count; ++} ++ ++unsigned char GetParagraphLevel(BLOCKTYPE line, int count) ++{ ++ int i; ++ for( i=0; i<count ; i++) ++ { ++ if(GetType(GETCHAR(line, i)) == R || GetType(/*line[i]*/ GETCHAR(line, i)) == AL) ++ return 1; ++ else if(GetType(GETCHAR(line, i)) == L) ++ return 0; ++ } ++ return 0; /* Compiler Nag-Stopper */ ++} ++ ++/* ++ * Returns character type of ch, by calling RLE table lookup ++ * function ++ */ ++unsigned char getCAPRtl(CHARTYPE ch) ++{ ++/* CAPRtl Charset */ ++int TypesFromChar[] = ++{ ++//0 1 2 3 4 5 6 7 8 9 a b c d e f ++ ON, ON, ON, ON, L, R, ON, ON, ON, ON, ON, ON, ON, B, RLO,RLE, /*00-0f*/ ++ LRO,LRE,PDF,WS, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, /*10-1f*/ ++ ++ WS, ON, ON, ON, ET, ON, ON, ON, ON, ON, ON, ET, CS, ON, ES, ES, /*20-2f*/ ++ EN, EN, EN, EN, EN, EN, AN, AN, AN, AN, LRE, RLE, RLO, PDF, LRO, ON, /*30-3f*/ ++ R, AL, AL, AL, AL, AL, AL, R, R, R, R, R, R, R, R, R, /*40-4f*/ ++ R, R, R, R, R, R, R, R, R, R, R, ON, B, ON, ON, ON, /*50-5f*/ ++ NSM, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, /*60-6f*/ ++ L, L, L, L, L, L, L, L, L, L, L, ON, S, ON, ON, ON, /*70-7f*/ ++}; ++ ++//0 1 2 3 4 5 6 7 8 9 a b c d e f ++// ON, ON, ON, ON, L, R, ON, ON, ON, ON, ON, ON, ON, B, RLO,RLE, /*00-0f*/ ++//LRO,LRE,PDF,WS, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, /*10-1f*/ ++ ++// WS, ON, ON, ON, ET, ON, ON, ON, ON, ON, ON, ET, CS, ON, ES, ES, /*20-2f*/ ++// EN, EN, EN, EN, EN, EN, AN, AN, AN, AN, CS, ON, ON, ON, ON, ON, /*30-3f*/ ++// R, AL, AL, AL, AL, AL, AL, R, R, R, R, R, R, R, R, R, /*40-4f*/ ++// R, R, R, R, R, R, R, R, R, R, R, ON, B, ON, ON, ON, /*50-5f*/ ++// NSM, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, /*60-6f*/ ++// L, L, L, L, L, L, L, L, L, L, L, ON, S, ON, ON, ON, /*70-7f*/ ++//}; ++ if(ch <0x7f) ++ return TypesFromChar[ch]; ++ else ++ return R; ++} ++ ++unsigned char getType(CHARTYPE ch) ++{ ++ static const struct { ++ CHARTYPE first, last, type; ++ } lookup[] = { ++ {0x0000, 0x0008, BN}, ++ {0x0009, 0x0009, S}, ++ {0x000a, 0x000a, B}, ++ {0x000b, 0x000b, S}, ++ {0x000c, 0x000c, WS}, ++ {0x000d, 0x000d, B}, ++ {0x000e, 0x001b, BN}, ++ {0x001c, 0x001e, B}, ++ {0x001f, 0x001f, S}, ++ {0x0020, 0x0020, WS}, ++ {0x0023, 0x0025, ET}, ++ {0x002b, 0x002b, ES}, ++ {0x002c, 0x002c, CS}, ++ {0x002d, 0x002d, ES}, ++ {0x002e, 0x002f, CS}, ++ {0x0030, 0x0039, EN}, ++ {0x003a, 0x003a, CS}, ++ {0x0041, 0x005a, L}, ++ {0x0061, 0x007a, L}, ++ {0x007f, 0x0084, BN}, ++ {0x0085, 0x0085, B}, ++ {0x0086, 0x009f, BN}, ++ {0x00a0, 0x00a0, CS}, ++ {0x00a2, 0x00a5, ET}, ++ {0x00aa, 0x00aa, L}, ++ {0x00ad, 0x00ad, BN}, ++ {0x00b0, 0x00b1, ET}, ++ {0x00b2, 0x00b3, EN}, ++ {0x00b5, 0x00b5, L}, ++ {0x00b9, 0x00b9, EN}, ++ {0x00ba, 0x00ba, L}, ++ {0x00c0, 0x00d6, L}, ++ {0x00d8, 0x00f6, L}, ++ {0x00f8, 0x0236, L}, ++ {0x0250, 0x02b8, L}, ++ {0x02bb, 0x02c1, L}, ++ {0x02d0, 0x02d1, L}, ++ {0x02e0, 0x02e4, L}, ++ {0x02ee, 0x02ee, L}, ++ {0x0300, 0x0357, NSM}, ++ {0x035d, 0x036f, NSM}, ++ {0x037a, 0x037a, L}, ++ {0x0386, 0x0386, L}, ++ {0x0388, 0x038a, L}, ++ {0x038c, 0x038c, L}, ++ {0x038e, 0x03a1, L}, ++ {0x03a3, 0x03ce, L}, ++ {0x03d0, 0x03f5, L}, ++ {0x03f7, 0x03fb, L}, ++ {0x0400, 0x0482, L}, ++ {0x0483, 0x0486, NSM}, ++ {0x0488, 0x0489, NSM}, ++ {0x048a, 0x04ce, L}, ++ {0x04d0, 0x04f5, L}, ++ {0x04f8, 0x04f9, L}, ++ {0x0500, 0x050f, L}, ++ {0x0531, 0x0556, L}, ++ {0x0559, 0x055f, L}, ++ {0x0561, 0x0587, L}, ++ {0x0589, 0x0589, L}, ++ {0x0591, 0x05a1, NSM}, ++ {0x05a3, 0x05b9, NSM}, ++ {0x05bb, 0x05bd, NSM}, ++ {0x05be, 0x05be, R}, ++ {0x05bf, 0x05bf, NSM}, ++ {0x05c0, 0x05c0, R}, ++ {0x05c1, 0x05c2, NSM}, ++ {0x05c3, 0x05c3, R}, ++ {0x05c4, 0x05c4, NSM}, ++ {0x05d0, 0x05ea, R}, ++ {0x05f0, 0x05f4, R}, ++ {0x0600, 0x0603, AL}, ++ {0x060c, 0x060c, CS}, ++ {0x060d, 0x060d, AL}, ++ {0x0610, 0x0615, NSM}, ++ {0x061b, 0x061b, AL}, ++ {0x061f, 0x061f, AL}, ++ {0x0621, 0x063a, AL}, ++ {0x0640, 0x064a, AL}, ++ {0x064b, 0x0658, NSM}, ++ {0x0660, 0x0669, AN}, ++ {0x066a, 0x066a, ET}, ++ {0x066b, 0x066c, AN}, ++ {0x066d, 0x066f, AL}, ++ {0x0670, 0x0670, NSM}, ++ {0x0671, 0x06d5, AL}, ++ {0x06d6, 0x06dc, NSM}, ++ {0x06dd, 0x06dd, AL}, ++ {0x06de, 0x06e4, NSM}, ++ {0x06e5, 0x06e6, AL}, ++ {0x06e7, 0x06e8, NSM}, ++ {0x06ea, 0x06ed, NSM}, ++ {0x06ee, 0x06ef, AL}, ++ {0x06f0, 0x06f9, EN}, ++ {0x06fa, 0x070d, AL}, ++ {0x070f, 0x070f, BN}, ++ {0x0710, 0x0710, AL}, ++ {0x0711, 0x0711, NSM}, ++ {0x0712, 0x072f, AL}, ++ {0x0730, 0x074a, NSM}, ++ {0x074d, 0x074f, AL}, ++ {0x0780, 0x07a5, AL}, ++ {0x07a6, 0x07b0, NSM}, ++ {0x07b1, 0x07b1, AL}, ++ {0x0901, 0x0902, NSM}, ++ {0x0903, 0x0939, L}, ++ {0x093c, 0x093c, NSM}, ++ {0x093d, 0x0940, L}, ++ {0x0941, 0x0948, NSM}, ++ {0x0949, 0x094c, L}, ++ {0x094d, 0x094d, NSM}, ++ {0x0950, 0x0950, L}, ++ {0x0951, 0x0954, NSM}, ++ {0x0958, 0x0961, L}, ++ {0x0962, 0x0963, NSM}, ++ {0x0964, 0x0970, L}, ++ {0x0981, 0x0981, NSM}, ++ {0x0982, 0x0983, L}, ++ {0x0985, 0x098c, L}, ++ {0x098f, 0x0990, L}, ++ {0x0993, 0x09a8, L}, ++ {0x09aa, 0x09b0, L}, ++ {0x09b2, 0x09b2, L}, ++ {0x09b6, 0x09b9, L}, ++ {0x09bc, 0x09bc, NSM}, ++ {0x09bd, 0x09c0, L}, ++ {0x09c1, 0x09c4, NSM}, ++ {0x09c7, 0x09c8, L}, ++ {0x09cb, 0x09cc, L}, ++ {0x09cd, 0x09cd, NSM}, ++ {0x09d7, 0x09d7, L}, ++ {0x09dc, 0x09dd, L}, ++ {0x09df, 0x09e1, L}, ++ {0x09e2, 0x09e3, NSM}, ++ {0x09e6, 0x09f1, L}, ++ {0x09f2, 0x09f3, ET}, ++ {0x09f4, 0x09fa, L}, ++ {0x0a01, 0x0a02, NSM}, ++ {0x0a03, 0x0a03, L}, ++ {0x0a05, 0x0a0a, L}, ++ {0x0a0f, 0x0a10, L}, ++ {0x0a13, 0x0a28, L}, ++ {0x0a2a, 0x0a30, L}, ++ {0x0a32, 0x0a33, L}, ++ {0x0a35, 0x0a36, L}, ++ {0x0a38, 0x0a39, L}, ++ {0x0a3c, 0x0a3c, NSM}, ++ {0x0a3e, 0x0a40, L}, ++ {0x0a41, 0x0a42, NSM}, ++ {0x0a47, 0x0a48, NSM}, ++ {0x0a4b, 0x0a4d, NSM}, ++ {0x0a59, 0x0a5c, L}, ++ {0x0a5e, 0x0a5e, L}, ++ {0x0a66, 0x0a6f, L}, ++ {0x0a70, 0x0a71, NSM}, ++ {0x0a72, 0x0a74, L}, ++ {0x0a81, 0x0a82, NSM}, ++ {0x0a83, 0x0a83, L}, ++ {0x0a85, 0x0a8d, L}, ++ {0x0a8f, 0x0a91, L}, ++ {0x0a93, 0x0aa8, L}, ++ {0x0aaa, 0x0ab0, L}, ++ {0x0ab2, 0x0ab3, L}, ++ {0x0ab5, 0x0ab9, L}, ++ {0x0abc, 0x0abc, NSM}, ++ {0x0abd, 0x0ac0, L}, ++ {0x0ac1, 0x0ac5, NSM}, ++ {0x0ac7, 0x0ac8, NSM}, ++ {0x0ac9, 0x0ac9, L}, ++ {0x0acb, 0x0acc, L}, ++ {0x0acd, 0x0acd, NSM}, ++ {0x0ad0, 0x0ad0, L}, ++ {0x0ae0, 0x0ae1, L}, ++ {0x0ae2, 0x0ae3, NSM}, ++ {0x0ae6, 0x0aef, L}, ++ {0x0af1, 0x0af1, ET}, ++ {0x0b01, 0x0b01, NSM}, ++ {0x0b02, 0x0b03, L}, ++ {0x0b05, 0x0b0c, L}, ++ {0x0b0f, 0x0b10, L}, ++ {0x0b13, 0x0b28, L}, ++ {0x0b2a, 0x0b30, L}, ++ {0x0b32, 0x0b33, L}, ++ {0x0b35, 0x0b39, L}, ++ {0x0b3c, 0x0b3c, NSM}, ++ {0x0b3d, 0x0b3e, L}, ++ {0x0b3f, 0x0b3f, NSM}, ++ {0x0b40, 0x0b40, L}, ++ {0x0b41, 0x0b43, NSM}, ++ {0x0b47, 0x0b48, L}, ++ {0x0b4b, 0x0b4c, L}, ++ {0x0b4d, 0x0b4d, NSM}, ++ {0x0b56, 0x0b56, NSM}, ++ {0x0b57, 0x0b57, L}, ++ {0x0b5c, 0x0b5d, L}, ++ {0x0b5f, 0x0b61, L}, ++ {0x0b66, 0x0b71, L}, ++ {0x0b82, 0x0b82, NSM}, ++ {0x0b83, 0x0b83, L}, ++ {0x0b85, 0x0b8a, L}, ++ {0x0b8e, 0x0b90, L}, ++ {0x0b92, 0x0b95, L}, ++ {0x0b99, 0x0b9a, L}, ++ {0x0b9c, 0x0b9c, L}, ++ {0x0b9e, 0x0b9f, L}, ++ {0x0ba3, 0x0ba4, L}, ++ {0x0ba8, 0x0baa, L}, ++ {0x0bae, 0x0bb5, L}, ++ {0x0bb7, 0x0bb9, L}, ++ {0x0bbe, 0x0bbf, L}, ++ {0x0bc0, 0x0bc0, NSM}, ++ {0x0bc1, 0x0bc2, L}, ++ {0x0bc6, 0x0bc8, L}, ++ {0x0bca, 0x0bcc, L}, ++ {0x0bcd, 0x0bcd, NSM}, ++ {0x0bd7, 0x0bd7, L}, ++ {0x0be7, 0x0bf2, L}, ++ {0x0bf9, 0x0bf9, ET}, ++ {0x0c01, 0x0c03, L}, ++ {0x0c05, 0x0c0c, L}, ++ {0x0c0e, 0x0c10, L}, ++ {0x0c12, 0x0c28, L}, ++ {0x0c2a, 0x0c33, L}, ++ {0x0c35, 0x0c39, L}, ++ {0x0c3e, 0x0c40, NSM}, ++ {0x0c41, 0x0c44, L}, ++ {0x0c46, 0x0c48, NSM}, ++ {0x0c4a, 0x0c4d, NSM}, ++ {0x0c55, 0x0c56, NSM}, ++ {0x0c60, 0x0c61, L}, ++ {0x0c66, 0x0c6f, L}, ++ {0x0c82, 0x0c83, L}, ++ {0x0c85, 0x0c8c, L}, ++ {0x0c8e, 0x0c90, L}, ++ {0x0c92, 0x0ca8, L}, ++ {0x0caa, 0x0cb3, L}, ++ {0x0cb5, 0x0cb9, L}, ++ {0x0cbc, 0x0cbc, NSM}, ++ {0x0cbd, 0x0cc4, L}, ++ {0x0cc6, 0x0cc8, L}, ++ {0x0cca, 0x0ccb, L}, ++ {0x0ccc, 0x0ccd, NSM}, ++ {0x0cd5, 0x0cd6, L}, ++ {0x0cde, 0x0cde, L}, ++ {0x0ce0, 0x0ce1, L}, ++ {0x0ce6, 0x0cef, L}, ++ {0x0d02, 0x0d03, L}, ++ {0x0d05, 0x0d0c, L}, ++ {0x0d0e, 0x0d10, L}, ++ {0x0d12, 0x0d28, L}, ++ {0x0d2a, 0x0d39, L}, ++ {0x0d3e, 0x0d40, L}, ++ {0x0d41, 0x0d43, NSM}, ++ {0x0d46, 0x0d48, L}, ++ {0x0d4a, 0x0d4c, L}, ++ {0x0d4d, 0x0d4d, NSM}, ++ {0x0d57, 0x0d57, L}, ++ {0x0d60, 0x0d61, L}, ++ {0x0d66, 0x0d6f, L}, ++ {0x0d82, 0x0d83, L}, ++ {0x0d85, 0x0d96, L}, ++ {0x0d9a, 0x0db1, L}, ++ {0x0db3, 0x0dbb, L}, ++ {0x0dbd, 0x0dbd, L}, ++ {0x0dc0, 0x0dc6, L}, ++ {0x0dca, 0x0dca, NSM}, ++ {0x0dcf, 0x0dd1, L}, ++ {0x0dd2, 0x0dd4, NSM}, ++ {0x0dd6, 0x0dd6, NSM}, ++ {0x0dd8, 0x0ddf, L}, ++ {0x0df2, 0x0df4, L}, ++ {0x0e01, 0x0e30, L}, ++ {0x0e31, 0x0e31, NSM}, ++ {0x0e32, 0x0e33, L}, ++ {0x0e34, 0x0e3a, NSM}, ++ {0x0e3f, 0x0e3f, ET}, ++ {0x0e40, 0x0e46, L}, ++ {0x0e47, 0x0e4e, NSM}, ++ {0x0e4f, 0x0e5b, L}, ++ {0x0e81, 0x0e82, L}, ++ {0x0e84, 0x0e84, L}, ++ {0x0e87, 0x0e88, L}, ++ {0x0e8a, 0x0e8a, L}, ++ {0x0e8d, 0x0e8d, L}, ++ {0x0e94, 0x0e97, L}, ++ {0x0e99, 0x0e9f, L}, ++ {0x0ea1, 0x0ea3, L}, ++ {0x0ea5, 0x0ea5, L}, ++ {0x0ea7, 0x0ea7, L}, ++ {0x0eaa, 0x0eab, L}, ++ {0x0ead, 0x0eb0, L}, ++ {0x0eb1, 0x0eb1, NSM}, ++ {0x0eb2, 0x0eb3, L}, ++ {0x0eb4, 0x0eb9, NSM}, ++ {0x0ebb, 0x0ebc, NSM}, ++ {0x0ebd, 0x0ebd, L}, ++ {0x0ec0, 0x0ec4, L}, ++ {0x0ec6, 0x0ec6, L}, ++ {0x0ec8, 0x0ecd, NSM}, ++ {0x0ed0, 0x0ed9, L}, ++ {0x0edc, 0x0edd, L}, ++ {0x0f00, 0x0f17, L}, ++ {0x0f18, 0x0f19, NSM}, ++ {0x0f1a, 0x0f34, L}, ++ {0x0f35, 0x0f35, NSM}, ++ {0x0f36, 0x0f36, L}, ++ {0x0f37, 0x0f37, NSM}, ++ {0x0f38, 0x0f38, L}, ++ {0x0f39, 0x0f39, NSM}, ++ {0x0f3e, 0x0f47, L}, ++ {0x0f49, 0x0f6a, L}, ++ {0x0f71, 0x0f7e, NSM}, ++ {0x0f7f, 0x0f7f, L}, ++ {0x0f80, 0x0f84, NSM}, ++ {0x0f85, 0x0f85, L}, ++ {0x0f86, 0x0f87, NSM}, ++ {0x0f88, 0x0f8b, L}, ++ {0x0f90, 0x0f97, NSM}, ++ {0x0f99, 0x0fbc, NSM}, ++ {0x0fbe, 0x0fc5, L}, ++ {0x0fc6, 0x0fc6, NSM}, ++ {0x0fc7, 0x0fcc, L}, ++ {0x0fcf, 0x0fcf, L}, ++ {0x1000, 0x1021, L}, ++ {0x1023, 0x1027, L}, ++ {0x1029, 0x102a, L}, ++ {0x102c, 0x102c, L}, ++ {0x102d, 0x1030, NSM}, ++ {0x1031, 0x1031, L}, ++ {0x1032, 0x1032, NSM}, ++ {0x1036, 0x1037, NSM}, ++ {0x1038, 0x1038, L}, ++ {0x1039, 0x1039, NSM}, ++ {0x1040, 0x1057, L}, ++ {0x1058, 0x1059, NSM}, ++ {0x10a0, 0x10c5, L}, ++ {0x10d0, 0x10f8, L}, ++ {0x10fb, 0x10fb, L}, ++ {0x1100, 0x1159, L}, ++ {0x115f, 0x11a2, L}, ++ {0x11a8, 0x11f9, L}, ++ {0x1200, 0x1206, L}, ++ {0x1208, 0x1246, L}, ++ {0x1248, 0x1248, L}, ++ {0x124a, 0x124d, L}, ++ {0x1250, 0x1256, L}, ++ {0x1258, 0x1258, L}, ++ {0x125a, 0x125d, L}, ++ {0x1260, 0x1286, L}, ++ {0x1288, 0x1288, L}, ++ {0x128a, 0x128d, L}, ++ {0x1290, 0x12ae, L}, ++ {0x12b0, 0x12b0, L}, ++ {0x12b2, 0x12b5, L}, ++ {0x12b8, 0x12be, L}, ++ {0x12c0, 0x12c0, L}, ++ {0x12c2, 0x12c5, L}, ++ {0x12c8, 0x12ce, L}, ++ {0x12d0, 0x12d6, L}, ++ {0x12d8, 0x12ee, L}, ++ {0x12f0, 0x130e, L}, ++ {0x1310, 0x1310, L}, ++ {0x1312, 0x1315, L}, ++ {0x1318, 0x131e, L}, ++ {0x1320, 0x1346, L}, ++ {0x1348, 0x135a, L}, ++ {0x1361, 0x137c, L}, ++ {0x13a0, 0x13f4, L}, ++ {0x1401, 0x1676, L}, ++ {0x1680, 0x1680, WS}, ++ {0x1681, 0x169a, L}, ++ {0x16a0, 0x16f0, L}, ++ {0x1700, 0x170c, L}, ++ {0x170e, 0x1711, L}, ++ {0x1712, 0x1714, NSM}, ++ {0x1720, 0x1731, L}, ++ {0x1732, 0x1734, NSM}, ++ {0x1735, 0x1736, L}, ++ {0x1740, 0x1751, L}, ++ {0x1752, 0x1753, NSM}, ++ {0x1760, 0x176c, L}, ++ {0x176e, 0x1770, L}, ++ {0x1772, 0x1773, NSM}, ++ {0x1780, 0x17b6, L}, ++ {0x17b7, 0x17bd, NSM}, ++ {0x17be, 0x17c5, L}, ++ {0x17c6, 0x17c6, NSM}, ++ {0x17c7, 0x17c8, L}, ++ {0x17c9, 0x17d3, NSM}, ++ {0x17d4, 0x17da, L}, ++ {0x17db, 0x17db, ET}, ++ {0x17dc, 0x17dc, L}, ++ {0x17dd, 0x17dd, NSM}, ++ {0x17e0, 0x17e9, L}, ++ {0x180b, 0x180d, NSM}, ++ {0x180e, 0x180e, WS}, ++ {0x1810, 0x1819, L}, ++ {0x1820, 0x1877, L}, ++ {0x1880, 0x18a8, L}, ++ {0x18a9, 0x18a9, NSM}, ++ {0x1900, 0x191c, L}, ++ {0x1920, 0x1922, NSM}, ++ {0x1923, 0x1926, L}, ++ {0x1927, 0x192b, NSM}, ++ {0x1930, 0x1931, L}, ++ {0x1932, 0x1932, NSM}, ++ {0x1933, 0x1938, L}, ++ {0x1939, 0x193b, NSM}, ++ {0x1946, 0x196d, L}, ++ {0x1970, 0x1974, L}, ++ {0x1d00, 0x1d6b, L}, ++ {0x1e00, 0x1e9b, L}, ++ {0x1ea0, 0x1ef9, L}, ++ {0x1f00, 0x1f15, L}, ++ {0x1f18, 0x1f1d, L}, ++ {0x1f20, 0x1f45, L}, ++ {0x1f48, 0x1f4d, L}, ++ {0x1f50, 0x1f57, L}, ++ {0x1f59, 0x1f59, L}, ++ {0x1f5b, 0x1f5b, L}, ++ {0x1f5d, 0x1f5d, L}, ++ {0x1f5f, 0x1f7d, L}, ++ {0x1f80, 0x1fb4, L}, ++ {0x1fb6, 0x1fbc, L}, ++ {0x1fbe, 0x1fbe, L}, ++ {0x1fc2, 0x1fc4, L}, ++ {0x1fc6, 0x1fcc, L}, ++ {0x1fd0, 0x1fd3, L}, ++ {0x1fd6, 0x1fdb, L}, ++ {0x1fe0, 0x1fec, L}, ++ {0x1ff2, 0x1ff4, L}, ++ {0x1ff6, 0x1ffc, L}, ++ {0x2000, 0x200a, WS}, ++ {0x200b, 0x200d, BN}, ++ {0x200e, 0x200e, L}, ++ {0x200f, 0x200f, R}, ++ {0x2028, 0x2028, WS}, ++ {0x2029, 0x2029, B}, ++ {0x202a, 0x202a, LRE}, ++ {0x202b, 0x202b, RLE}, ++ {0x202c, 0x202c, PDF}, ++ {0x202d, 0x202d, LRO}, ++ {0x202e, 0x202e, RLO}, ++ {0x202f, 0x202f, WS}, ++ {0x2030, 0x2034, ET}, ++ {0x2044, 0x2044, CS}, ++ {0x205f, 0x205f, WS}, ++ {0x2060, 0x2063, BN}, ++ {0x206a, 0x206f, BN}, ++ {0x2070, 0x2070, EN}, ++ {0x2071, 0x2071, L}, ++ {0x2074, 0x2079, EN}, ++ {0x207a, 0x207b, ET}, ++ {0x207f, 0x207f, L}, ++ {0x2080, 0x2089, EN}, ++ {0x208a, 0x208b, ET}, ++ {0x20a0, 0x20b1, ET}, ++ {0x20d0, 0x20ea, NSM}, ++ {0x2102, 0x2102, L}, ++ {0x2107, 0x2107, L}, ++ {0x210a, 0x2113, L}, ++ {0x2115, 0x2115, L}, ++ {0x2119, 0x211d, L}, ++ {0x2124, 0x2124, L}, ++ {0x2126, 0x2126, L}, ++ {0x2128, 0x2128, L}, ++ {0x212a, 0x212d, L}, ++ {0x212e, 0x212e, ET}, ++ {0x212f, 0x2131, L}, ++ {0x2133, 0x2139, L}, ++ {0x213d, 0x213f, L}, ++ {0x2145, 0x2149, L}, ++ {0x2160, 0x2183, L}, ++ {0x2212, 0x2213, ET}, ++ {0x2336, 0x237a, L}, ++ {0x2395, 0x2395, L}, ++ {0x2488, 0x249b, EN}, ++ {0x249c, 0x24e9, L}, ++ {0x2800, 0x28ff, L}, ++ {0x3000, 0x3000, WS}, ++ {0x3005, 0x3007, L}, ++ {0x3021, 0x3029, L}, ++ {0x302a, 0x302f, NSM}, ++ {0x3031, 0x3035, L}, ++ {0x3038, 0x303c, L}, ++ {0x3041, 0x3096, L}, ++ {0x3099, 0x309a, NSM}, ++ {0x309d, 0x309f, L}, ++ {0x30a1, 0x30fa, L}, ++ {0x30fc, 0x30ff, L}, ++ {0x3105, 0x312c, L}, ++ {0x3131, 0x318e, L}, ++ {0x3190, 0x31b7, L}, ++ {0x31f0, 0x321c, L}, ++ {0x3220, 0x3243, L}, ++ {0x3260, 0x327b, L}, ++ {0x327f, 0x32b0, L}, ++ {0x32c0, 0x32cb, L}, ++ {0x32d0, 0x32fe, L}, ++ {0x3300, 0x3376, L}, ++ {0x337b, 0x33dd, L}, ++ {0x33e0, 0x33fe, L}, ++ {0x3400, 0x4db5, L}, ++ {0x4e00, 0x9fa5, L}, ++ {0xa000, 0xa48c, L}, ++ {0xac00, 0xd7a3, L}, ++ {0xd800, 0xfa2d, L}, ++ {0xfa30, 0xfa6a, L}, ++ {0xfb00, 0xfb06, L}, ++ {0xfb13, 0xfb17, L}, ++ {0xfb1d, 0xfb1d, R}, ++ {0xfb1e, 0xfb1e, NSM}, ++ {0xfb1f, 0xfb28, R}, ++ {0xfb29, 0xfb29, ET}, ++ {0xfb2a, 0xfb36, R}, ++ {0xfb38, 0xfb3c, R}, ++ {0xfb3e, 0xfb3e, R}, ++ {0xfb40, 0xfb41, R}, ++ {0xfb43, 0xfb44, R}, ++ {0xfb46, 0xfb4f, R}, ++ {0xfb50, 0xfbb1, AL}, ++ {0xfbd3, 0xfd3d, AL}, ++ {0xfd50, 0xfd8f, AL}, ++ {0xfd92, 0xfdc7, AL}, ++ {0xfdf0, 0xfdfc, AL}, ++ {0xfe00, 0xfe0f, NSM}, ++ {0xfe20, 0xfe23, NSM}, ++ {0xfe50, 0xfe50, CS}, ++ {0xfe52, 0xfe52, CS}, ++ {0xfe55, 0xfe55, CS}, ++ {0xfe5f, 0xfe5f, ET}, ++ {0xfe62, 0xfe63, ET}, ++ {0xfe69, 0xfe6a, ET}, ++ {0xfe70, 0xfe74, AL}, ++ {0xfe76, 0xfefc, AL}, ++ {0xfeff, 0xfeff, BN}, ++ {0xff03, 0xff05, ET}, ++ {0xff0b, 0xff0b, ET}, ++ {0xff0c, 0xff0c, CS}, ++ {0xff0d, 0xff0d, ET}, ++ {0xff0e, 0xff0e, CS}, ++ {0xff0f, 0xff0f, ES}, ++ {0xff10, 0xff19, EN}, ++ {0xff1a, 0xff1a, CS}, ++ {0xff21, 0xff3a, L}, ++ {0xff41, 0xff5a, L}, ++ {0xff66, 0xffbe, L}, ++ {0xffc2, 0xffc7, L}, ++ {0xffca, 0xffcf, L}, ++ {0xffd2, 0xffd7, L}, ++ {0xffda, 0xffdc, L}, ++ {0xffe0, 0xffe1, ET}, ++ {0xffe5, 0xffe6, ET}, ++ }; ++ ++ int i, j, k; ++ ++ i = -1; ++ j = lenof(lookup); ++ ++ while (j - i > 1) { ++ k = (i + j) / 2; ++ if (ch < lookup[k].first) ++ j = k; ++ else if (ch > lookup[k].last) ++ i = k; ++ else ++ return (unsigned char)lookup[k].type; ++ } ++ ++ /* ++ * If we reach here, the character was not in any of the ++ * intervals listed in the lookup table. This means we return ++ * ON (`Other Neutrals'). This is the appropriate code for any ++ * character genuinely not listed in the Unicode table, and ++ * also the table above has deliberately left out any ++ * characters _explicitly_ listed as ON (to save space!). ++ */ ++ return ON; ++} ++ ++unsigned char getPreviousLevel(unsigned char* types, unsigned char* level, int from) ++{ ++ int skip = 0; ++ ++ while(--from > 0) ++ { ++ ++ switch(types[from]) ++ { ++ case LRE: ++ case LRO: ++ case RLE: ++ case RLO: ++ if(skip>0) ++ { ++ skip--; ++ break; ++ }else ++ return level[from-1]; ++ case PDF: ++ skip++; ++ break; ++ } ++ } ++ return 0; /* Compiler Nag-Stopper */ ++} ++ ++unsigned char getPreviousOverride(unsigned char* types, unsigned char* level, int from) ++{ ++ int skip = 1; ++ ++ from--; ++ while(from-- > 0) ++ { ++ switch(types[from]) ++ { ++ case LRE: ++ case RLE: ++ skip++; ++ break; ++ ++ case LRO: ++ if(skip>0) ++ { ++ skip--; ++ break; ++ }else ++ return L; ++ case RLO: ++ if(skip>0) ++ { ++ skip--; ++ break; ++ }else ++ return R; ++ case PDF: ++ skip++; ++ break; ++ } ++ } ++ return ON; ++} ++ ++ ++ ++/* The Main shaping function, and the only one to be used ++ * by the outside world. ++ * ++ * line: buffer to apply shaping to. this must be passed by doBidi() first ++ * to: output buffer for the shaped data ++ * from: start bidi at this index ++ * count: number of characters in line ++ */ ++int doShape(BLOCKTYPE line, CHARTYPE* to, int from, int count) ++{ ++ int i, j, ligFlag; ++ unsigned char prevTemp, nextTemp; ++ CHARTYPE tempChar; ++ ++ ligFlag = 0; ++ prevTemp = SU; ++ nextTemp = SU; ++ for(i=from; i<count; i++) ++ { ++ /* Get Previous and next Characters type */ ++ j=i; ++ while(--j >= 0) ++ { ++ //assert(j<count); ++ //assert(i<count); ++ if(GetType(GETCHAR(line, j)) != NSM) ++ { ++ prevTemp = STYPE(GETCHAR(line, j)); ++ break; ++ } ++ } ++ j=i; ++ while(++j < count) ++ { ++ //assert(j<count); ++ //assert(i<count); ++ if(GetType(GETCHAR(line, j)) != NSM) ++ { ++ nextTemp = STYPE(GETCHAR(line, j)); ++ break; ++ //HAQ ++ } else if(j == count-1) { ++ nextTemp = SU; ++ break; ++ } ++ } ++ ++ switch(STYPE(GETCHAR(line, i))) ++ { ++ case SC: ++ case SU: ++ to[i] = GETCHAR(line, i); ++ break; ++ ++ case SR: ++ if(prevTemp == SD || prevTemp == SC) ++ to[i] = SFINAL(SISOLATED(GETCHAR(line, i))); ++ else ++ to[i] = SISOLATED(GETCHAR(line, i)); ++ break; ++ ++ case SD: ++ /* Make Ligatures */ ++ if(GETCHAR(line, i) == 0x644) ++ { ++ j=i; ++ while(j++<count) ++ { ++ if(GetType(GETCHAR(line, j)) != NSM) ++ { ++ tempChar = GETCHAR(line, j); ++ break; ++ } ++ } ++ switch(tempChar) ++ { ++ case 0x622: ++ ligFlag = 1; ++ if(prevTemp == SD || prevTemp == SC) ++ to[i] = 0xFEF6; ++ else ++ to[i] = 0xFEF5; ++ break; ++ case 0x623: ++ ligFlag = 1; ++ if(prevTemp == SD || prevTemp == SC) ++ to[i] = 0xFEF8; ++ else ++ to[i] = 0xFEF7; ++ break; ++ case 0x625: ++ ligFlag = 1; ++ if(prevTemp == SD || prevTemp == SC) ++ to[i] = 0xFEFA; ++ else ++ to[i] = 0xFEF9; ++ break; ++ case 0x627: ++ ligFlag = 1; ++ if(prevTemp == SD || prevTemp == SC) ++ to[i] = 0xFEFC; ++ else ++ to[i] = 0xFEFB; ++ break; ++ } ++ if(ligFlag) ++ { ++ to[j] = 0x20; ++ i = j; ++ ligFlag = 0; ++ break; ++ } ++ } ++ //assert(j<count); ++ //assert(i<count); ++ if((prevTemp == SD) || (prevTemp == SC)) ++ { ++ if(nextTemp == SR || nextTemp == SD || nextTemp == SC) ++ to[i] = SMEDIAL(SISOLATED(GETCHAR(line, i))); ++ else ++ to[i] = SFINAL(SISOLATED(GETCHAR(line, i))); ++ break; ++ }else ++ { ++ if(nextTemp == SR || nextTemp == SD || nextTemp == SC) ++ to[i] = SINITIAL(SISOLATED(GETCHAR(line, i))); ++ else ++ to[i] = SISOLATED(GETCHAR(line, i)); ++ break; ++ } ++ ++ } ++ nextTemp = SU; ++ } ++ return 1; ++} ++ ++/* Rule (X1), (X2), (X3), (X4), (X5), (X6), (X7), (X8), (X9) */ ++void doTypes(BLOCKTYPE line, unsigned char paragraphLevel, unsigned char* types, ++ unsigned char* levels, int count, int fX) ++{ ++ ++ unsigned char tempType; ++ unsigned char currentEmbedding = paragraphLevel; ++ unsigned char currentOverride = ON; ++ int i; ++ ++ if(fX) ++ { ++ for( i=0; i<count; i++) ++ { ++ tempType = GetType(GETCHAR(line, i)); ++ switch(tempType) ++ { ++ case RLE: ++ currentEmbedding = levels[i] = leastGreaterOdd(currentEmbedding); ++ currentOverride = ON; ++ types[i] = BN; ++ break; ++ ++ case LRE: ++ currentEmbedding = levels[i] = leastGreaterEven(currentEmbedding); ++ currentOverride = ON; ++ types[i] = BN; ++ break; ++ ++ case RLO: ++ currentEmbedding = levels[i] = leastGreaterOdd(currentEmbedding); ++ currentOverride = R; ++ types[i] = BN; ++ break; ++ ++ case LRO: ++ currentEmbedding = levels[i] = leastGreaterEven(currentEmbedding); ++ currentOverride = L; ++ types[i] = BN; ++ break; ++ ++ case PDF: ++ levels[i] = currentEmbedding; ++ currentEmbedding = getPreviousLevel(types, levels, i); ++ currentOverride = getPreviousOverride(types, levels, i); ++ types[i] = BN; ++ break; ++ ++ /* Whitespace is treated as neutral for now */ ++ case WS: ++ case B: ++ case S: ++ levels[i] = currentEmbedding; ++ tempType = ON; ++ if(currentOverride != ON) ++ tempType = currentOverride; ++ break; ++ ++ default: ++ levels[i] = currentEmbedding; ++ if(currentOverride != ON) ++ tempType = currentOverride; ++ break; ++ ++ } ++ types[i] = tempType; ++ } ++ }else ++ { ++ for( i=0; i<count; i++) ++ { ++ tempType = GetType(GETCHAR(line, i)); ++ switch(tempType) ++ { ++ case WS: ++ case B: ++ case S: ++ levels[i] = currentEmbedding; ++ tempType = ON; ++ if(currentOverride != ON) ++ tempType = currentOverride; ++ break; ++ ++ default: ++ levels[i] = currentEmbedding; ++ if(currentOverride != ON) ++ tempType = currentOverride; ++ break; ++ ++ } ++ types[i] = tempType; ++ } ++ ++ } ++ ++} ++ ++/* Rule (W3) */ ++void doALtoR(unsigned char* types, int count) ++{ ++ int i=0; ++ for(; i<count; i++) ++ { ++ if(types[i] == AL) ++ types[i] = R; ++ } ++ ++} ++/* ++ * The Main Bidi Function, and the only function that should ++ * be used by the outside world. ++ * ++ * line: a buffer of size count containing text to apply ++ * the Bidirectional algorithm to. ++ */ ++int doBidi(BLOCKTYPE line, int count, int applyShape, int reorderCombining, int removeMarks) ++{ ++ unsigned char* types; ++ unsigned char* levels; ++ unsigned char paragraphLevel; ++ unsigned char tempType, tempTypeSec; ++ int i, j, imax, fX, fAL, fET, fNSM; ++ CHARTYPE* shapeTo; ++ ++ ++ fX = fAL = fET = fNSM = 0; ++ for(i=0; i<count; i++) ++ { ++ switch(GetType(line[i])) ++ { ++ case AL: ++ case R: ++ fAL = 1; ++ break; ++ case LRE: ++ case LRO: ++ case RLE: ++ case RLO: ++ case PDF: ++ case BN: ++ fX = 1; ++ break; ++ case ET: ++ fET = 1; ++ break; ++ case NSM: ++ fNSM = 1; ++ break; ++ } ++ } ++ ++ if(!fAL && !fX) ++ return 0; ++ ++ /* Initialize types, levels */ ++ types = (unsigned char*)malloc(sizeof(unsigned char) * count); ++ levels = (unsigned char*)malloc(sizeof(unsigned char) * count); ++ if(applyShape) ++ shapeTo = (CHARTYPE*)malloc(sizeof(CHARTYPE) * count); ++ ++ /* Rule (P1) NOT IMPLEMENTED ++ * P1. Split the text into separate paragraphs. A paragraph separator is ++ * kept with the previous paragraph. Within each paragraph, apply all the ++ * other rules of this algorithm. ++ */ ++ ++ /* Rule (P2), (P3) ++ * P2. In each paragraph, find the first character of type L, AL, or R. ++ * P3. If a character is found in P2 and it is of type AL or R, then set ++ * the paragraph embedding level to one; otherwise, set it to zero. ++ */ ++ paragraphLevel = GetParagraphLevel(line, count); ++ ++ /* Rule (X1), (X2), (X3), (X4), (X5), (X6), (X7), (X8), (X9) ++ * X1. Begin by setting the current embedding level to the paragraph ++ * embedding level. Set the directional override status to neutral. ++ * X2. With each RLE, compute the least greater odd embedding level. ++ * X3. With each LRE, compute the least greater even embedding level. ++ * X4. With each RLO, compute the least greater odd embedding level. ++ * X5. With each LRO, compute the least greater even embedding level. ++ * X6. For all types besides RLE, LRE, RLO, LRO, and PDF: ++ * a. Set the level of the current character to the current ++ * embedding level. ++ * b. Whenever the directional override status is not neutral, ++ * reset the current character type to the directional ++ * override status. ++ * X7. With each PDF, determine the matching embedding or override code. ++ * If there was a valid matching code, restore (pop) the last ++ * remembered (pushed) embedding level and directional override. ++ * X8. All explicit directional embeddings and overrides are completely ++ * terminated at the end of each paragraph. Paragraph separators are not ++ * included in the embedding. (Useless here) NOT IMPLEMENTED ++ * X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. ++ * Here, they're converted to BN. ++ */ ++ ++ doTypes(line, paragraphLevel, types, levels, count, fX); ++ ++ ++ /* Rule (W1) ++ * W1. Examine each non-spacing mark (NSM) in the level run, and change ++ * the type of the NSM to the type of the previous character. If the NSM ++ * is at the start of the level run, it will get the type of sor. ++ */ ++ ++ /* ++ * Clear BNs first ++ */ ++ if(fX) ++ { ++ for(i=0; i<count; i++) ++ { ++ if(types[i] == BN) ++ { ++ j=i; ++ while(types[--j] == ON); ++ levels[i] = levels[j]; ++ ++ j=i; ++ while(types[++j] == BN); ++ ++ if(levels[j] > levels[i]) ++ levels[i] = levels[j]; ++ ++ ++ ++ if((levels[i] % 2) == 0) ++ { ++ types[i] = L; ++ } ++ else ++ { ++ types[i] = R; ++ } ++ ++ } ++ } ++ } ++ ++ ++ if(fNSM) ++ { ++ if(types[0] == NSM) ++ types[0] = paragraphLevel; ++ ++ for(i=1; i<count; i++) ++ { ++ if(types[i] == NSM) ++ types[i] = types[i-1]; ++ /* Is this a safe assumption? ++ * I assumed the previous, IS a character. ++ */ ++ } ++ } ++ ++ /* BN TYPES !!!! */ ++ ++ if(fX) ++ { ++ for(i=0; i<count; i++) ++ { ++ if(types[i] == BN) ++ { ++ j=i; ++ while(--j>=0 && types[j] == ON); ++ tempType = types[j]; ++ j=i; ++ while(++j<count && types[j] == BN || types[j] == ON); ++ if(tempType != types[j]) ++ types[i] = tempType; ++ ++ } ++ } ++ } ++ ++ ++ /* Rule (W2) ++ * W2. Search backwards from each instance of a European number until the ++ * first strong type (R, L, AL, or sor) is found. If an AL is found, ++ * change the type of the European number to Arabic number. ++ */ ++ for(i=0; i<count; i++) ++ { ++ if(types[i] == EN) ++ { ++ j=i; ++ while(--j >= 0) ++ { ++ if(types[j] == AL) ++ { ++ types[i] = AN; ++ break; ++ } ++ else if(types[j] == R || types[j] == L) ++ { ++ break; ++ } ++ } ++ } ++ } ++ ++ /* Rule (W3) ++ * W3. Change all ALs to R. ++ * ++ * Optimization: on Rule Xn, we might set a flag on AL type ++ * to prevent this loop in L R lines only... ++ */ ++ doALtoR(types, count); ++ ++ /* Rule (W4) ++ * W4. A single European separator between two European numbers changes ++ * to a European number. A single common separator between two numbers ++ * of the same type changes to that type. ++ */ ++ for( i=0; i<(count-1); i++) ++ { ++ if(types[i] == ES) ++ { ++ if(types[i-1] == EN && types[i+1] == EN) ++ types[i] = EN; ++ }else if(types[i] == CS) ++ { ++ if(types[i-1] == EN && types[i+1] == EN) ++ types[i] = EN; ++ else if(types[i-1] == AN && types[i+1] == AN) ++ types[i] = AN; ++ } ++ } ++ ++ /* Rule (W5) ++ * W5. A sequence of European terminators adjacent to European numbers ++ * changes to all European numbers. ++ * ++ * Optimization: lots here... else ifs need rearrangement ++ */ ++ if(fET) ++ { ++ for(i=0; i<count; i++) ++ { ++ if(types[i] == ET) ++ { ++ if(types[i-1] == EN) ++ { ++ types[i] = EN; ++ continue; ++ }else if(types[i+1] == EN) ++ { ++ types[i] = EN; ++ continue; ++ }else if(types[i+1] == ET) ++ { ++ j=i; ++ while(j <count && types[j] == ET) ++ { ++ j++; ++ } ++ if(types[j] == EN) ++ types[i] = EN; ++ } ++ } ++ } ++ } ++ ++ /* Rule (W6) ++ * W6. Otherwise, separators and terminators change to Other Neutral: ++ */ ++ for(i=0; i<count; i++) ++ { ++ switch(types[i]) ++ { ++ case ES: ++ case ET: ++ case CS: ++ types[i] = ON; ++ break; ++ } ++ } ++ ++ /* Rule (W7) ++ * W7. Search backwards from each instance of a European number until ++ * the first strong type (R, L, or sor) is found. If an L is found, ++ * then change the type of the European number to L. ++ */ ++ ++ for(i=0; i<count; i++) ++ { ++ if(types[i] == EN) ++ { ++ j=i; ++ while(--j >= 0) ++ { ++ if(types[j] == L) ++ { ++ types[i] = L; ++ break; ++ } ++ else if(types[j] == R || types[j] == AL) ++ { ++ break; ++ } ++ ++ } ++ } ++ } ++ ++ ++ /* Rule (N1) ++ * N1. A sequence of neutrals takes the direction of the surrounding ++ * strong text if the text on both sides has the same direction. European ++ * and Arabic numbers are treated as though they were R. ++ */ ++ tempType = paragraphLevel; ++ for(i=0; i<count; i++) ++ { ++ if(types[i] == ON) ++ { ++ if(types[i-1] == R || types[i-1] == EN || types[i-1] == AN) ++ tempType = R; ++ else ++ tempType = L; ++ j=i; ++ ++ while(j < count) ++ { ++ tempTypeSec = types[j]; ++ if(tempTypeSec == ON || tempTypeSec == BN) ++ j++; ++ else ++ break; ++ } ++ ++ if(((types[j] == L || types[j] == LRE) && (tempType == L)) || ++ (((types[j] == R) || (types[j] == EN) || (types[j] == AN)) && (tempType == R))) ++ { ++ while(i<j) ++ { ++ types[i++] = tempType; ++ } ++ } ++ } ++ } ++ ++ ++ /* Rule (N2) ++ * N2. Any remaining neutrals take the embedding direction. ++ */ ++ for(i=0; i<count; i++) ++ { ++ if(types[i] == ON || types[i] == BN) ++ { ++ if((levels[i] % 2) == 0) ++ types[i] = L; ++ else ++ types[i] = R; ++ } ++ } ++ ++ /* Rule (I1) ++ * I1. For all characters with an even (left-to-right) embedding ++ * direction, those of type R go up one level and those of type AN or ++ * EN go up two levels. ++ */ ++ for(i=0; i<count; i++) ++ { ++ if((levels[i] % 2) == 0) ++ { ++ if(types[i] == R) ++ levels[i] += 1; ++ else if((types[i] == AN) || (types[i] == EN)) ++ levels[i] += 2; ++ }else ++ { ++ if((types[i] == L) || ++ (types[i] == EN) || ++ (types[i] == AN)) ++ levels[i] += 1; ++ } ++ } ++ ++ /* Rule (I2) ++ * I2. For all characters with an odd (right-to-left) embedding direction, ++ * those of type L, EN or AN go up one level. ++ */ ++/* ++ for(i=0; i<count; i++) ++ { ++ if((levels[i] % 2) == 1) ++ { ++ if(types[i] == L || types[i] == EN || types[i] == AN) ++ levels[i] += 1; ++ } ++ } ++*/ ++ /* Rule (L1) ++ * L1. On each line, reset the embedding level of the following characters ++ * to the paragraph embedding level: ++ * (1)segment separators, (2)paragraph separators, ++ * (3)any sequence of whitespace characters preceding ++ * a segment separator or paragraph separator, ++ * (4)and any sequence of white space characters ++ * at the end of the line. ++ * The types of characters used here are the original types, not those ++ * modified by the previous phase. ++ */ ++ ++ ++ ++ j=count-1; ++ while(j>0 && (GetType(GETCHAR(line, j)) == WS)) ++ { ++ j--; ++ } ++ if(j < (count-1)) ++ { ++ for(j++; j<count; j++) ++ levels[j] = paragraphLevel; ++ } ++ ++ for(i=0; i<count; i++) ++ { ++ tempType = GetType(GETCHAR(line, i)); ++ if(tempType == WS) ++ { ++ j=i; ++ while((++j < count) && ((tempType == WS) || (tempType == RLE)) ) ++ { ++ tempType = GetType(line[j]); ++ } ++ ++ if(GetType(GETCHAR(line, j)) == B || GetType(GETCHAR(line, j)) == S) ++ { ++ for(j--; j>=i ; j--) ++ { ++ levels[j] = paragraphLevel; ++ } ++ } ++ }else if(tempType == B || tempType == S) ++ levels[i] = paragraphLevel; ++ } ++ ++ /* Rule (L4) ++ * L4. A character that possesses the mirrored property as specified by ++ * Section 4.7, Mirrored, must be depicted by a mirrored glyph if the ++ * resolved directionality of that character is R. ++ */ ++ /* Note: this is implemented before L2 for efficiency */ ++ for(i=0; i<count; i++) ++ { ++ if((levels[i] % 2) == 1) ++ doMirror(&line[i]); ++ } ++ ++ ++ ++ /* Rule (L3) ++ * L3. Combining marks applied to a right-to-left base character will at ++ * this point precede their base character. If the rendering engine ++ * expects them to follow the base characters in the final display ++ * process, then the ordering of the marks and the base character must ++ * be reversed. ++ * Combining marks are reordered to the right of each character on an ++ * odd level. ++ */ ++ ++ if(fNSM && reorderCombining) ++ { ++ CHARTYPE temp; ++ int it; ++ for(i=0; i<count; i++) ++ { ++ if(GetType(GETCHAR(line, i)) == NSM && odd(levels[i])) ++ { ++ j=i; ++ while((++j < count) && (GetType(GETCHAR(line, j)) == NSM)); ++ j--; i--; ++ for(it=j; j>i; i++, j--) ++ { ++ temp = GETCHAR(line, i); ++ GETCHAR(line, i) = GETCHAR(line, j); ++ GETCHAR(line, j) = temp; ++ } ++ i=it+1; ++ } ++ } ++ } ++ ++ /* Shaping ++ * Shaping is Applied to each run of levels separately.... ++ */ ++ ++ if(applyShape) ++ { ++ ++ for(i=0; i<count; i++) ++ { ++ shapeTo[i] = GETCHAR(line, i); ++ } ++ ++ j=i=0; ++ while(j < count) ++ { ++ if(GetType(GETCHAR(line, j)) == AL) ++ { ++ if(j<count && j >= i ) ++ { ++ tempType = levels[j]; ++ i=j; ++ while((i++ < count) && (levels[i] == tempType)); ++ doShape(line, shapeTo, j, i); ++ j=i; ++ tempType = levels[j]; ++ ++ } ++ } ++ j++; ++ } ++ for(i=0; i<count; i++) ++ { ++ GETCHAR(line, i) = shapeTo[i]; ++ } ++ free(shapeTo); ++ } ++ ++ ++ ++ /* Rule (L2) ++ * L2. From the highest level found in the text to the lowest odd level on ++ * each line, including intermediate levels not actually present in the ++ * text, reverse any contiguous sequence of characters that are at that ++ * level or higher ++ */ ++ /* we flip the character string and leave the level array */ ++ imax = 0; ++ i=0; ++ tempType = levels[0]; ++ while(i < count) ++ { ++ if(levels[i] > tempType) ++ { ++ tempType = levels[i]; ++ imax=i; ++ } ++ i++; ++ } ++ /* maximum level in tempType, its index in imax. */ ++ while(tempType > 0) /* loop from highest level to the least odd, */ ++ { /* which i assume is 1 */ ++ flipThisRun(line, levels, tempType, count); ++ tempType--; ++ } ++ ++ /* The line should be reordered correctly, check for Explicits marks ++ * and remove them if removeMarks ++ */ ++ if(fX && removeMarks) ++ { ++ if(!GetParagraphLevel(line, count)) ++ { ++ for(i=0, j=0; i<count; i++) ++ { ++ tempType = GetType(GETCHAR(line, i)); ++ if(tempType != RLE && ++ tempType != LRE && ++ tempType != RLO && ++ tempType != LRO && ++ tempType != PDF) ++ GETCHAR(line, j++) = GETCHAR(line, i); ++ } ++ for(i=j; j<count; j++) ++ GETCHAR(line, j) = 0x20; ++ }else ++ { ++ for(j=i=count-1; i>=0; i--) ++ { ++ tempType = GetType(GETCHAR(line, i)); ++ if(tempType != RLE && ++ tempType != LRE && ++ tempType != RLO && ++ tempType != LRO && ++ tempType != PDF) ++ GETCHAR(line, j--) = GETCHAR(line, i); ++ } ++ for(i=j; j>=0; j--) ++ GETCHAR(line, j) = 0x20; ++ } ++ } ++ ++ ++ free(types); ++ free(levels); ++ /* if removeMarks is 1 and there were actual marks then return the new size */ ++ if(fX && removeMarks) return i; ++ return count; ++} ++ ++ ++/* ++ * Bad, Horrible function ++ * takes a pointer to a character that is checked for ++ * having a mirror glyph. ++ */ ++void doMirror(CHARTYPE* ch) ++{ ++ if ((*ch & 0xFF00) == 0) { ++ switch (*ch) { ++ case 0x0028: *ch = 0x0029; break; ++ case 0x0029: *ch = 0x0028; break; ++ case 0x003C: *ch = 0x003E; break; ++ case 0x003E: *ch = 0x003C; break; ++ case 0x005B: *ch = 0x005D; break; ++ case 0x005D: *ch = 0x005B; break; ++ case 0x007B: *ch = 0x007D; break; ++ case 0x007D: *ch = 0x007B; break; ++ case 0x00AB: *ch = 0x00BB; break; ++ case 0x00BB: *ch = 0x00AB; break; ++ } ++ } else if ((*ch & 0xFF00) == 0x2000) { ++ switch (*ch) { ++ case 0x2039: *ch = 0x203A; break; ++ case 0x203A: *ch = 0x2039; break; ++ case 0x2045: *ch = 0x2046; break; ++ case 0x2046: *ch = 0x2045; break; ++ case 0x207D: *ch = 0x207E; break; ++ case 0x207E: *ch = 0x207D; break; ++ case 0x208D: *ch = 0x208E; break; ++ case 0x208E: *ch = 0x208D; break; ++ } ++ } else if ((*ch & 0xFF00) == 0x2200) { ++ switch (*ch) { ++ case 0x2208: *ch = 0x220B; break; ++ case 0x2209: *ch = 0x220C; break; ++ case 0x220A: *ch = 0x220D; break; ++ case 0x220B: *ch = 0x2208; break; ++ case 0x220C: *ch = 0x2209; break; ++ case 0x220D: *ch = 0x220A; break; ++ case 0x2215: *ch = 0x29F5; break; ++ case 0x223C: *ch = 0x223D; break; ++ case 0x223D: *ch = 0x223C; break; ++ case 0x2243: *ch = 0x22CD; break; ++ case 0x2252: *ch = 0x2253; break; ++ case 0x2253: *ch = 0x2252; break; ++ case 0x2254: *ch = 0x2255; break; ++ case 0x2255: *ch = 0x2254; break; ++ case 0x2264: *ch = 0x2265; break; ++ case 0x2265: *ch = 0x2264; break; ++ case 0x2266: *ch = 0x2267; break; ++ case 0x2267: *ch = 0x2266; break; ++ case 0x2268: *ch = 0x2269; break; ++ case 0x2269: *ch = 0x2268; break; ++ case 0x226A: *ch = 0x226B; break; ++ case 0x226B: *ch = 0x226A; break; ++ case 0x226E: *ch = 0x226F; break; ++ case 0x226F: *ch = 0x226E; break; ++ case 0x2270: *ch = 0x2271; break; ++ case 0x2271: *ch = 0x2270; break; ++ case 0x2272: *ch = 0x2273; break; ++ case 0x2273: *ch = 0x2272; break; ++ case 0x2274: *ch = 0x2275; break; ++ case 0x2275: *ch = 0x2274; break; ++ case 0x2276: *ch = 0x2277; break; ++ case 0x2277: *ch = 0x2276; break; ++ case 0x2278: *ch = 0x2279; break; ++ case 0x2279: *ch = 0x2278; break; ++ case 0x227A: *ch = 0x227B; break; ++ case 0x227B: *ch = 0x227A; break; ++ case 0x227C: *ch = 0x227D; break; ++ case 0x227D: *ch = 0x227C; break; ++ case 0x227E: *ch = 0x227F; break; ++ case 0x227F: *ch = 0x227E; break; ++ case 0x2280: *ch = 0x2281; break; ++ case 0x2281: *ch = 0x2280; break; ++ case 0x2282: *ch = 0x2283; break; ++ case 0x2283: *ch = 0x2282; break; ++ case 0x2284: *ch = 0x2285; break; ++ case 0x2285: *ch = 0x2284; break; ++ case 0x2286: *ch = 0x2287; break; ++ case 0x2287: *ch = 0x2286; break; ++ case 0x2288: *ch = 0x2289; break; ++ case 0x2289: *ch = 0x2288; break; ++ case 0x228A: *ch = 0x228B; break; ++ case 0x228B: *ch = 0x228A; break; ++ case 0x228F: *ch = 0x2290; break; ++ case 0x2290: *ch = 0x228F; break; ++ case 0x2291: *ch = 0x2292; break; ++ case 0x2292: *ch = 0x2291; break; ++ case 0x2298: *ch = 0x29B8; break; ++ case 0x22A2: *ch = 0x22A3; break; ++ case 0x22A3: *ch = 0x22A2; break; ++ case 0x22A6: *ch = 0x2ADE; break; ++ case 0x22A8: *ch = 0x2AE4; break; ++ case 0x22A9: *ch = 0x2AE3; break; ++ case 0x22AB: *ch = 0x2AE5; break; ++ case 0x22B0: *ch = 0x22B1; break; ++ case 0x22B1: *ch = 0x22B0; break; ++ case 0x22B2: *ch = 0x22B3; break; ++ case 0x22B3: *ch = 0x22B2; break; ++ case 0x22B4: *ch = 0x22B5; break; ++ case 0x22B5: *ch = 0x22B4; break; ++ case 0x22B6: *ch = 0x22B7; break; ++ case 0x22B7: *ch = 0x22B6; break; ++ case 0x22C9: *ch = 0x22CA; break; ++ case 0x22CA: *ch = 0x22C9; break; ++ case 0x22CB: *ch = 0x22CC; break; ++ case 0x22CC: *ch = 0x22CB; break; ++ case 0x22CD: *ch = 0x2243; break; ++ case 0x22D0: *ch = 0x22D1; break; ++ case 0x22D1: *ch = 0x22D0; break; ++ case 0x22D6: *ch = 0x22D7; break; ++ case 0x22D7: *ch = 0x22D6; break; ++ case 0x22D8: *ch = 0x22D9; break; ++ case 0x22D9: *ch = 0x22D8; break; ++ case 0x22DA: *ch = 0x22DB; break; ++ case 0x22DB: *ch = 0x22DA; break; ++ case 0x22DC: *ch = 0x22DD; break; ++ case 0x22DD: *ch = 0x22DC; break; ++ case 0x22DE: *ch = 0x22DF; break; ++ case 0x22DF: *ch = 0x22DE; break; ++ case 0x22E0: *ch = 0x22E1; break; ++ case 0x22E1: *ch = 0x22E0; break; ++ case 0x22E2: *ch = 0x22E3; break; ++ case 0x22E3: *ch = 0x22E2; break; ++ case 0x22E4: *ch = 0x22E5; break; ++ case 0x22E5: *ch = 0x22E4; break; ++ case 0x22E6: *ch = 0x22E7; break; ++ case 0x22E7: *ch = 0x22E6; break; ++ case 0x22E8: *ch = 0x22E9; break; ++ case 0x22E9: *ch = 0x22E8; break; ++ case 0x22EA: *ch = 0x22EB; break; ++ case 0x22EB: *ch = 0x22EA; break; ++ case 0x22EC: *ch = 0x22ED; break; ++ case 0x22ED: *ch = 0x22EC; break; ++ case 0x22F0: *ch = 0x22F1; break; ++ case 0x22F1: *ch = 0x22F0; break; ++ case 0x22F2: *ch = 0x22FA; break; ++ case 0x22F3: *ch = 0x22FB; break; ++ case 0x22F4: *ch = 0x22FC; break; ++ case 0x22F6: *ch = 0x22FD; break; ++ case 0x22F7: *ch = 0x22FE; break; ++ case 0x22FA: *ch = 0x22F2; break; ++ case 0x22FB: *ch = 0x22F3; break; ++ case 0x22FC: *ch = 0x22F4; break; ++ case 0x22FD: *ch = 0x22F6; break; ++ case 0x22FE: *ch = 0x22F7; break; ++ } ++ } else if ((*ch & 0xFF00) == 0x2300) { ++ switch (*ch) { ++ case 0x2308: *ch = 0x2309; break; ++ case 0x2309: *ch = 0x2308; break; ++ case 0x230A: *ch = 0x230B; break; ++ case 0x230B: *ch = 0x230A; break; ++ case 0x2329: *ch = 0x232A; break; ++ case 0x232A: *ch = 0x2329; break; ++ } ++ } else if ((*ch & 0xFF00) == 0x2700) { ++ switch (*ch) { ++ case 0x2768: *ch = 0x2769; break; ++ case 0x2769: *ch = 0x2768; break; ++ case 0x276A: *ch = 0x276B; break; ++ case 0x276B: *ch = 0x276A; break; ++ case 0x276C: *ch = 0x276D; break; ++ case 0x276D: *ch = 0x276C; break; ++ case 0x276E: *ch = 0x276F; break; ++ case 0x276F: *ch = 0x276E; break; ++ case 0x2770: *ch = 0x2771; break; ++ case 0x2771: *ch = 0x2770; break; ++ case 0x2772: *ch = 0x2773; break; ++ case 0x2773: *ch = 0x2772; break; ++ case 0x2774: *ch = 0x2775; break; ++ case 0x2775: *ch = 0x2774; break; ++ case 0x27D5: *ch = 0x27D6; break; ++ case 0x27D6: *ch = 0x27D5; break; ++ case 0x27DD: *ch = 0x27DE; break; ++ case 0x27DE: *ch = 0x27DD; break; ++ case 0x27E2: *ch = 0x27E3; break; ++ case 0x27E3: *ch = 0x27E2; break; ++ case 0x27E4: *ch = 0x27E5; break; ++ case 0x27E5: *ch = 0x27E4; break; ++ case 0x27E6: *ch = 0x27E7; break; ++ case 0x27E7: *ch = 0x27E6; break; ++ case 0x27E8: *ch = 0x27E9; break; ++ case 0x27E9: *ch = 0x27E8; break; ++ case 0x27EA: *ch = 0x27EB; break; ++ case 0x27EB: *ch = 0x27EA; break; ++ } ++ } else if ((*ch & 0xFF00) == 0x2900) { ++ switch (*ch) { ++ case 0x2983: *ch = 0x2984; break; ++ case 0x2984: *ch = 0x2983; break; ++ case 0x2985: *ch = 0x2986; break; ++ case 0x2986: *ch = 0x2985; break; ++ case 0x2987: *ch = 0x2988; break; ++ case 0x2988: *ch = 0x2987; break; ++ case 0x2989: *ch = 0x298A; break; ++ case 0x298A: *ch = 0x2989; break; ++ case 0x298B: *ch = 0x298C; break; ++ case 0x298C: *ch = 0x298B; break; ++ case 0x298D: *ch = 0x2990; break; ++ case 0x298E: *ch = 0x298F; break; ++ case 0x298F: *ch = 0x298E; break; ++ case 0x2990: *ch = 0x298D; break; ++ case 0x2991: *ch = 0x2992; break; ++ case 0x2992: *ch = 0x2991; break; ++ case 0x2993: *ch = 0x2994; break; ++ case 0x2994: *ch = 0x2993; break; ++ case 0x2995: *ch = 0x2996; break; ++ case 0x2996: *ch = 0x2995; break; ++ case 0x2997: *ch = 0x2998; break; ++ case 0x2998: *ch = 0x2997; break; ++ case 0x29B8: *ch = 0x2298; break; ++ case 0x29C0: *ch = 0x29C1; break; ++ case 0x29C1: *ch = 0x29C0; break; ++ case 0x29C4: *ch = 0x29C5; break; ++ case 0x29C5: *ch = 0x29C4; break; ++ case 0x29CF: *ch = 0x29D0; break; ++ case 0x29D0: *ch = 0x29CF; break; ++ case 0x29D1: *ch = 0x29D2; break; ++ case 0x29D2: *ch = 0x29D1; break; ++ case 0x29D4: *ch = 0x29D5; break; ++ case 0x29D5: *ch = 0x29D4; break; ++ case 0x29D8: *ch = 0x29D9; break; ++ case 0x29D9: *ch = 0x29D8; break; ++ case 0x29DA: *ch = 0x29DB; break; ++ case 0x29DB: *ch = 0x29DA; break; ++ case 0x29F5: *ch = 0x2215; break; ++ case 0x29F8: *ch = 0x29F9; break; ++ case 0x29F9: *ch = 0x29F8; break; ++ case 0x29FC: *ch = 0x29FD; break; ++ case 0x29FD: *ch = 0x29FC; break; ++ } ++ } else if ((*ch & 0xFF00) == 0x2A00) { ++ switch (*ch) { ++ case 0x2A2B: *ch = 0x2A2C; break; ++ case 0x2A2C: *ch = 0x2A2B; break; ++ case 0x2A2D: *ch = 0x2A2C; break; ++ case 0x2A2E: *ch = 0x2A2D; break; ++ case 0x2A34: *ch = 0x2A35; break; ++ case 0x2A35: *ch = 0x2A34; break; ++ case 0x2A3C: *ch = 0x2A3D; break; ++ case 0x2A3D: *ch = 0x2A3C; break; ++ case 0x2A64: *ch = 0x2A65; break; ++ case 0x2A65: *ch = 0x2A64; break; ++ case 0x2A79: *ch = 0x2A7A; break; ++ case 0x2A7A: *ch = 0x2A79; break; ++ case 0x2A7D: *ch = 0x2A7E; break; ++ case 0x2A7E: *ch = 0x2A7D; break; ++ case 0x2A7F: *ch = 0x2A80; break; ++ case 0x2A80: *ch = 0x2A7F; break; ++ case 0x2A81: *ch = 0x2A82; break; ++ case 0x2A82: *ch = 0x2A81; break; ++ case 0x2A83: *ch = 0x2A84; break; ++ case 0x2A84: *ch = 0x2A83; break; ++ case 0x2A8B: *ch = 0x2A8C; break; ++ case 0x2A8C: *ch = 0x2A8B; break; ++ case 0x2A91: *ch = 0x2A92; break; ++ case 0x2A92: *ch = 0x2A91; break; ++ case 0x2A93: *ch = 0x2A94; break; ++ case 0x2A94: *ch = 0x2A93; break; ++ case 0x2A95: *ch = 0x2A96; break; ++ case 0x2A96: *ch = 0x2A95; break; ++ case 0x2A97: *ch = 0x2A98; break; ++ case 0x2A98: *ch = 0x2A97; break; ++ case 0x2A99: *ch = 0x2A9A; break; ++ case 0x2A9A: *ch = 0x2A99; break; ++ case 0x2A9B: *ch = 0x2A9C; break; ++ case 0x2A9C: *ch = 0x2A9B; break; ++ case 0x2AA1: *ch = 0x2AA2; break; ++ case 0x2AA2: *ch = 0x2AA1; break; ++ case 0x2AA6: *ch = 0x2AA7; break; ++ case 0x2AA7: *ch = 0x2AA6; break; ++ case 0x2AA8: *ch = 0x2AA9; break; ++ case 0x2AA9: *ch = 0x2AA8; break; ++ case 0x2AAA: *ch = 0x2AAB; break; ++ case 0x2AAB: *ch = 0x2AAA; break; ++ case 0x2AAC: *ch = 0x2AAD; break; ++ case 0x2AAD: *ch = 0x2AAC; break; ++ case 0x2AAF: *ch = 0x2AB0; break; ++ case 0x2AB0: *ch = 0x2AAF; break; ++ case 0x2AB3: *ch = 0x2AB4; break; ++ case 0x2AB4: *ch = 0x2AB3; break; ++ case 0x2ABB: *ch = 0x2ABC; break; ++ case 0x2ABC: *ch = 0x2ABB; break; ++ case 0x2ABD: *ch = 0x2ABE; break; ++ case 0x2ABE: *ch = 0x2ABD; break; ++ case 0x2ABF: *ch = 0x2AC0; break; ++ case 0x2AC0: *ch = 0x2ABF; break; ++ case 0x2AC1: *ch = 0x2AC2; break; ++ case 0x2AC2: *ch = 0x2AC1; break; ++ case 0x2AC3: *ch = 0x2AC4; break; ++ case 0x2AC4: *ch = 0x2AC3; break; ++ case 0x2AC5: *ch = 0x2AC6; break; ++ case 0x2AC6: *ch = 0x2AC5; break; ++ case 0x2ACD: *ch = 0x2ACE; break; ++ case 0x2ACE: *ch = 0x2ACD; break; ++ case 0x2ACF: *ch = 0x2AD0; break; ++ case 0x2AD0: *ch = 0x2ACF; break; ++ case 0x2AD1: *ch = 0x2AD2; break; ++ case 0x2AD2: *ch = 0x2AD1; break; ++ case 0x2AD3: *ch = 0x2AD4; break; ++ case 0x2AD4: *ch = 0x2AD3; break; ++ case 0x2AD5: *ch = 0x2AD6; break; ++ case 0x2AD6: *ch = 0x2AD5; break; ++ case 0x2ADE: *ch = 0x22A6; break; ++ case 0x2AE3: *ch = 0x22A9; break; ++ case 0x2AE4: *ch = 0x22A8; break; ++ case 0x2AE5: *ch = 0x22AB; break; ++ case 0x2AEC: *ch = 0x2AED; break; ++ case 0x2AED: *ch = 0x2AEC; break; ++ case 0x2AF7: *ch = 0x2AF8; break; ++ case 0x2AF8: *ch = 0x2AF7; break; ++ case 0x2AF9: *ch = 0x2AFA; break; ++ case 0x2AFA: *ch = 0x2AF9; break; ++ } ++ } else if ((*ch & 0xFF00) == 0x3000) { ++ switch (*ch) { ++ case 0x3008: *ch = 0x3009; break; ++ case 0x3009: *ch = 0x3008; break; ++ case 0x300A: *ch = 0x300B; break; ++ case 0x300B: *ch = 0x300A; break; ++ case 0x300C: *ch = 0x300D; break; ++ case 0x300D: *ch = 0x300C; break; ++ case 0x300E: *ch = 0x300F; break; ++ case 0x300F: *ch = 0x300E; break; ++ case 0x3010: *ch = 0x3011; break; ++ case 0x3011: *ch = 0x3010; break; ++ case 0x3014: *ch = 0x3015; break; ++ case 0x3015: *ch = 0x3014; break; ++ case 0x3016: *ch = 0x3017; break; ++ case 0x3017: *ch = 0x3016; break; ++ case 0x3018: *ch = 0x3019; break; ++ case 0x3019: *ch = 0x3018; break; ++ case 0x301A: *ch = 0x301B; break; ++ case 0x301B: *ch = 0x301A; break; ++ } ++ } else if ((*ch & 0xFF00) == 0xFF00) { ++ switch (*ch) { ++ case 0xFF08: *ch = 0xFF09; break; ++ case 0xFF09: *ch = 0xFF08; break; ++ case 0xFF1C: *ch = 0xFF1E; break; ++ case 0xFF1E: *ch = 0xFF1C; break; ++ case 0xFF3B: *ch = 0xFF3D; break; ++ case 0xFF3D: *ch = 0xFF3B; break; ++ case 0xFF5B: *ch = 0xFF5D; break; ++ case 0xFF5D: *ch = 0xFF5B; break; ++ case 0xFF5F: *ch = 0xFF60; break; ++ case 0xFF60: *ch = 0xFF5F; break; ++ case 0xFF62: *ch = 0xFF63; break; ++ case 0xFF63: *ch = 0xFF62; break; ++ } ++ } ++} +Index: qt-2.3.10-snapshot-20060120/src/qt.pro +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/qt.pro 2005-12-15 00:03:32.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/qt.pro 2006-01-20 21:09:56.404899280 +0100 +@@ -178,6 +178,7 @@ + $$KERNEL_H/qasyncimageio.h \ + $$KERNEL_H/qasyncio.h \ + $$KERNEL_H/qbitmap.h \ ++ $$KERNEL_H/qbidi.h \ + $$KERNEL_H/qbrush.h \ + $$KERNEL_H/qclipboard.h \ + $$KERNEL_H/qcolor.h \ +@@ -524,6 +525,8 @@ + kernel/qapplication.cpp \ + kernel/qasyncimageio.cpp \ + kernel/qasyncio.cpp \ ++ kernel/qbidi.cpp \ ++ kernel/minibidi.cpp \ + kernel/qbitmap.cpp \ + kernel/qclipboard.cpp \ + kernel/qcolor.cpp \ +Index: qt-2.3.10-snapshot-20060120/src/Makefile.in +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/Makefile.in 2006-01-20 20:57:33.109897296 +0100 ++++ qt-2.3.10-snapshot-20060120/src/Makefile.in 2006-01-20 21:09:56.409898520 +0100 +@@ -176,6 +176,8 @@ + kernel/qabstractlayout.o \ + kernel/qaccel.o \ + kernel/qapplication.o \ ++ kernel/qbidi.o \ ++ kernel/minibidi.o \ + kernel/qasyncimageio.o \ + kernel/qasyncio.o \ + kernel/qbitmap.o \ +@@ -4235,6 +4237,12 @@ + kernel/qthread.h \ + tools/qvaluestack.h + ++kernel/qbidi.o: kernel/qbidi.cpp \ ++ kernel/qbidi.h \ ++ tools/qstring.h ++ ++kernel/minibidi.o: kernel/minibidi.c ++ + kernel/qasyncimageio.o: kernel/qasyncimageio.cpp \ + kernel/qasyncimageio.h \ + kernel/qimage.h \ diff --git a/packages/qte/qte-2.3.12/c700-hardware.patch b/packages/qte/qte-2.3.12/c700-hardware.patch new file mode 100644 index 0000000000..a4ba2654dc --- /dev/null +++ b/packages/qte/qte-2.3.12/c700-hardware.patch @@ -0,0 +1,114 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwindowsystem_qws.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp 2006-01-20 21:27:28.283989352 +0100 +@@ -178,7 +178,7 @@ + static QRect maxwindow_rect; + extern Q_EXPORT QRect qt_maxWindowRect; + static const char *defaultMouse = +-#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_YOPY) || defined(QWS_CUSTOMTOUCHPANEL) ++#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_SLC700) || defined(QT_QWS_YOPY) || defined(QWS_CUSTOMTOUCHPANEL) + "TPanel" + #elif defined(QT_KEYPAD_MODE) + "None" +@@ -3324,7 +3324,7 @@ + void QWSServer::screenSaverSleep() + { + qt_screen->blank(TRUE); +-#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_SL5XXX) ++#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_SL5XXX) && !defined(QT_QWS_SLC700) + d->screensavertimer->stop(); + #else + if ( screensaverinterval ) { +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsmouse_qws.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.cpp 2006-01-20 21:28:39.035233528 +0100 +@@ -87,6 +87,19 @@ + #define QT_QWS_TP_PRESSURE_THRESHOLD 500 + #define QT_QWS_TP_MOVE_LIMIT 50 + #define QT_QWS_TP_JITTER_LIMIT 2 ++#elif defined(QT_QWS_SLC700) ++#define QT_QWS_SLC700_RAW ++typedef struct { ++ unsigned short pressure; ++ unsigned short x; ++ unsigned short y; ++ unsigned short millisecs; ++} TS_EVENT; ++#define QT_QWS_TP_SAMPLE_SIZE 10 ++#define QT_QWS_TP_MINIMUM_SAMPLES 4 ++#define QT_QWS_TP_PRESSURE_THRESHOLD 500 ++#define QT_QWS_TP_MOVE_LIMIT 50 ++#define QT_QWS_TP_JITTER_LIMIT 2 + #endif + + #ifndef QT_QWS_TP_SAMPLE_SIZE +@@ -592,7 +605,7 @@ + sub[nsub++] = new QAutoMouseSubHandler_intellimouse(fd); + notify(fd); + } +-#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_SL5XXX) && !defined(QT_QWS_K2) ++#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_SL5XXX) && !defined(QT_QWS_K2) && !defined(QT_QWS_SLC700) + char fn[] = "/dev/ttyS?"; + for (int ch='0'; ch<='3'; ch++) { + fn[9] = ch; +@@ -1274,7 +1287,7 @@ + numSamples(0), skipCount(0) + { + mouseFD = -1; +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) + if ( dev.isEmpty() ) + #if defined(QT_QWS_IPAQ) + #ifdef QT_QWS_IPAQ_RAW +@@ -1283,7 +1296,7 @@ + dev = "/dev/h3600_ts"; + #endif + +-#elif defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) ++#elif defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) + //# ifdef QT_QWS_SL5XXX_TSRAW + # if 0 + dev = "/dev/tsraw"; +@@ -1309,7 +1322,7 @@ + + QTPanelHandlerPrivate::~QTPanelHandlerPrivate() + { +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) + if (mouseFD >= 0) + close(mouseFD); + #endif +@@ -1317,7 +1330,7 @@ + + void QTPanelHandlerPrivate::readMouseData() + { +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) + if(!qt_screen) + return; + +@@ -1336,7 +1349,7 @@ + uchar *mb = mouseBuf+idx; + data = (TS_EVENT *) mb; + if(data->pressure >= QT_QWS_TP_PRESSURE_THRESHOLD) { +-#ifdef QT_QWS_SL5XXX ++#if defined(QT_QWS_SL5XXX) || defined(QT_QWS_SLC700) + samples[currSample] = QPoint( 1000 - data->x, data->y ); + #else + samples[currSample] = QPoint( data->x, data->y ); +@@ -2017,7 +2030,7 @@ + handler = new QTSLibHandlerPrivate(mouseProtocol,mouseDev); + #elif defined(QT_QWS_YOPY) + handler = new QYopyTPanelHandlerPrivate(mouseProtocol,mouseDev); +-#elif defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) ++#elif defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) + handler = new QTPanelHandlerPrivate(mouseProtocol,mouseDev); + #elif defined(QT_QWS_CASSIOPEIA) + handler = new QVrTPanelHandlerPrivate( mouseProtocol, mouseDev ); diff --git a/packages/qte/qte-2.3.12/c7x0-w100-accel.patch b/packages/qte/qte-2.3.12/c7x0-w100-accel.patch new file mode 100644 index 0000000000..06a723447c --- /dev/null +++ b/packages/qte/qte-2.3.12/c7x0-w100-accel.patch @@ -0,0 +1,3414 @@ +ATI IMAGEON (W100) Accelerated support +Manuel Teira <manuel.teira@telefonica.net> + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/configure +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/configure 2006-01-20 21:15:58.395868288 +0100 ++++ qt-2.3.10-snapshot-20060120/configure 2006-01-20 21:17:39.451505496 +0100 +@@ -366,6 +366,9 @@ + -accel-matrox) + QWS_ACCEL_MATROX=y + ;; ++ -accel-w100) ++ QWS_ACCEL_W100=y ++ ;; + -qvfb) + QWS_QVFB=y + ;; +@@ -767,6 +770,10 @@ + then + QT_CXX="$QT_CXX -DQT_NO_QWS_MATROX" + fi ++if [ -z "$QWS_ACCEL_W100" -a -n "$EMB" ] ++then ++ QT_CXX="$QT_CXX -DQT_NO_QWS_W100" ++fi + if [ -z "$QWS_VNC" -a -n "$EMB" ] + then + QT_CXX="$QT_CXX -DQT_NO_QWS_VNC" +@@ -1398,6 +1405,7 @@ + -accel-voodoo3 ..... Enable Voodoo3 acceleration. + -accel-mach64 ...... Enable Mach64 acceleration. + -accel-matrox ...... Enable Matrox MGA acceleration. ++ -accel-w100 ........ Enable ATI Imageon w100 acceleration (experimental). + -qvfb .............. Enable X11-based Qt Virtual Frame Buffer. + -vnc ............... Enable VNC server (requires network module). + +@@ -1522,6 +1530,7 @@ + [ "x$JPEG" = "xyes" ] && QT_LIBS="${QT_LIBS} -ljpeg" + [ "x$MNG" = "xyes" ] && QT_LIBS="${QT_LIBS} -lmng -ljpeg" # assume JNG support + [ "x$NAS_SOUND" = "xyes" ] && QT_LIBS="${QT_LIBS} -laudio -lXt" # Xt junk in audio library ++[ "x$QWS_ACCEL_W100" = "xy" ] && QT_LIBS="${QT_LIBS} -laticore" # Aticore W100 support + QT_LIBS="$L_FLAGS $R_FLAGS $QT_LIBS $l_FLAGS" + + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfxraster_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qgfxraster_qws.cpp 2006-01-20 21:09:56.399900040 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfxraster_qws.cpp 2006-01-20 21:17:39.454505040 +0100 +@@ -2699,7 +2699,6 @@ + } + #endif + // Bresenham algorithm from Graphics Gems +- + int ax=QABS(dx)*2; + int ay=QABS(dy)*2; + int sy=dy>0 ? 1 : -1; +@@ -5984,6 +5983,10 @@ + # include "qgfxmatrox_qws.cpp" + #endif + ++#if !defined(QT_NO_QWS_W100) ++# include "qgfxw100_qws.cpp" ++#endif ++ + #if !defined(QT_NO_QWS_VFB) + # include "qgfxvfb_qws.cpp" + #endif +@@ -6038,6 +6041,9 @@ + #if !defined(QT_NO_QWS_MATROX) + { "Matrox", qt_get_screen_matrox, 1 }, + #endif ++#if !defined(QT_NO_QWS_W100) ++ { "W100", qt_get_screen_w100, 1 }, ++#endif + #if !defined(QT_NO_QWS_TRANSFORMED) + { "Transformed", qt_get_screen_transformed, 0 }, + #endif +@@ -6078,6 +6084,8 @@ + qt_screen = driverTable[i].qt_get_screen( display_id ); + if ( qt_screen ) { + if ( qt_screen->connect( spec ) ) { ++ printf( "[%d]:Connected to screen '%s'\n", ++ getpid(), driverTable[i].name ); + return qt_screen; + } else { + delete qt_screen; +Index: qt-2.3.10-snapshot-20060120/src/3rdparty/kernel/aticore/aticore.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qt-2.3.10-snapshot-20060120/src/3rdparty/kernel/aticore/aticore.h 2006-01-20 21:17:39.455504888 +0100 +@@ -0,0 +1,574 @@ ++/* ++ * AtiCore 2D acceleration API ++ * ++ */ ++ ++#include <inttypes.h> ++#include <sys/types.h> ++ ++#ifndef __W100API_H__ ++#define __W100API_H__ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define SolidRop_GXclear 0x00 /* 0 */ ++#define SolidRop_GXand 0xa0 /* src AND dst */ ++#define SolidRop_GXandReverse 0x50 /* src AND NOT dst */ ++#define SolidRop_GXcopy 0xf0 /* src */ ++#define SolidRop_GXandInverted 0x0a /* NOT src AND dst */ ++#define SolidRop_GXnoop 0xaa /* dst */ ++#define SolidRop_GXxor 0x5a /* src XOR dst */ ++#define SolidRop_GXor 0xfa /* src OR dst */ ++#define SolidRop_GXnor 0x05 /* NOT src AND NOT dst */ ++#define SolidRop_GXequiv 0xa5 /* NOT src XOR dst */ ++#define SolidRop_GXinvert 0x55 /* NOT dst */ ++#define SolidRop_GXorReverse 0xf5 /* src OR NOT dst */ ++#define SolidRop_GXcopyInverted 0x0f /* NOT src */ ++#define SolidRop_GXorInverted 0xaf /* NOT src OR dst */ ++#define SolidRop_GXnand 0x5f /* NOT src OR NOT dst */ ++#define SolidRop_GXset 0xff /* 1 */ ++ ++#define BltRop_GXclear 0x00 /* 0 */ ++#define BltRop_GXand 0x88 /* src AND dst */ ++#define BltRop_GXandReverse 0x44 /* src AND NOT dst */ ++#define BltRop_GXcopy 0xcc /* src */ ++#define BltRop_GXandInverted 0x22 /* NOT src AND dst */ ++#define BltRop_GXnoop 0xaa /* dst */ ++#define BltRop_GXxor 0x66 /* src XOR dst */ ++#define BltRop_GXor 0xee /* src OR dst */ ++#define BltRop_GXnor 0x11 /* NOT src AND NOT dst */ ++#define BltRop_GXequiv 0x99 /* NOT src XOR dst */ ++#define BltRop_GXinvert 0x55 /* NOT dst */ ++#define BltRop_GXorReverse 0xdd /* src OR NOT dst */ ++#define BltRop_GXcopyInverted 0x33 /* NOT src */ ++#define BltRop_GXorInverted 0xbb /* NOT src OR dst */ ++#define BltRop_GXnand 0x77 /* NOT src OR NOT dst */ ++#define BltRop_GXset 0xff /* 1 */ ++ ++#define DSTTYPE_8BPP 2 //8bpp ++#define DSTTYPE_16BPP_1555 3 //16 bpp aRGB 1555 ++#define DSTTYPE_16BPP_444 5 //16 bpp aRGB 4444 ++ ++#define SRCTYPE_1BPP_OPA 0 //mono (expanded to frgd, bkgd) ++#define SRCTYPE_1BPP_TRA 1 //mono (expanded to frgd, leave_alone) ++#define SRCTYPE_EQU_DST 3 //color (same as DST) ++#define SRCTYPE_SOLID_COLOR_BLT 4 //solid color for Blt (use frgd) ++#define SRCTYPE_4BPP 5 //4 bpp ++#define SRCTYPE_12BPP_PACKED 6 //12 bpp packed ++ ++#define ROP3_SRCCOPY 0xcc ++#define ROP3_PATCOPY 0xf0 ++ ++#define OVLTYPE_YUV420 7 ++#define OVLTYPE_RGB565 8 ++ ++#define DP_BRUSH_8x8MONOOPA 0 //8x8 mono pattern (expanded to frgd, bkgd ) ++#define DP_BRUSH_8x8MONOTRA 1 //8x8 mono pattern (expanded to frgd, leave alone ) ++#define DP_PEN_32x1MONOOPA 6 //32x1 mono pattern (expanded to frgd, bkgd) ++#define DP_PEN_32x1MONOTRA 7 //32x1 mono pattern (expanded to frgd, leave alone) ++#define DP_BRUSH_8x8COLOR 10 //8x8 color pattern ++#define DP_BRUSH_SOLIDCOLOR 13 //solid color pattern (frgd) ++#define DB_BRUSH_NONE 15 //No brush used ++ ++ typedef struct { ++ int16_t XCoord; ++ int16_t YCoord; ++ } ATI_POINT; ++ ++ typedef struct { ++ int16_t XCoord; ++ int16_t YCoord; ++ int16_t Width; ++ int16_t Height; ++ } ATI_RECT; ++ ++ typedef struct { ++ int16_t X_Top_Left; // x coordinate of top left corner ++ int16_t Y_Top_Left; // y coordinate of top left corner ++ int16_t X_Bottom_Right; // x coordinate of bottom right corner ++ int16_t Y_Bottom_Right; // y coordinate of bottom right corner ++ } ATI_CLIPRECT; ++ ++ typedef struct { ++ uint32_t Count; ++ uint8_t ScaleXFactor; ++ uint8_t ScaleYFactor; ++ uint8_t BlendOn; ++ uint8_t dummy1; ++ } ATI_STRETCH; ++ ++ typedef struct { ++ uint32_t *lpSrcBitmap; /* ¥µ¡¼¥Õ¥§¥¹¤Î¥ª¥Õ¥»¥Ã¥È */ ++ uint16_t XCoord; /* +4 ³ÎÄê:¥µ¡¼¥Õ¥§¥¹Æâ¤ÎxºÂɸ */ ++ uint16_t YCoord; /* +6 ³ÎÄê:¥µ¡¼¥Õ¥§¥¹Æâ¤ÎyºÂɸ */ ++ uint16_t SrcPitch; /* +8 ³ÎÄê: */ ++ uint16_t SrcHeight; /* +10 ³ÎÄê: */ ++ uint16_t OverlayWidth; /* ¥ª¡¼¥Ð¥ì¥¤¤ÎÉý(Src¤È°ã¤¦Ãͤˤ·¤Æ¤â¡¢Æ°Åª¤Ë³ÈÂç½Ì¾®¤µ¤ì¤¿¤ê¤Ï¤·¤Ê¤¤¡¢°ÕÌ£¤¢¤ó¤Î¡©) */ ++ uint16_t OverlayHeight; ++ uint32_t lpOverlayKey; /* +16 ³ÎÄê:Ææ(¥«¥é¡¼¥¡¼¡©) */ ++ uint8_t OverlayFormat; /* +20 ³ÎÄê */ ++ uint8_t dummy1; ++ uint16_t dummy2; ++ } ATI_OVERLAYPROP; /* 24bytes? */ ++ ++ typedef struct { ++ int HInvert; ++ int VInvert; ++ } ATI_EXTVIDEOPROP; ++ ++ typedef struct { ++ ATI_EXTVIDEOPROP ExtVideoProp; ++ } ATI_UNKNOWN1; ++ ++ typedef struct { ++ unsigned long clr_cmp_fcn_src :3; ++ unsigned long :5; ++ unsigned long clr_cmp_fcn_dst :3; ++ unsigned long :13; ++ unsigned long clr_cmp_src :2; ++ unsigned long :6; ++ } clr_cmp_cntl_t; ++ ++ typedef struct { ++ uint16_t x; ++ uint16_t y; ++ uint16_t w; ++ uint16_t h; ++ clr_cmp_cntl_t cmp_cntl; ++ unsigned long tcolour; ++ } transbitblt_t; ++ ++ typedef struct { ++ uint32_t dummy1; ++ uint32_t dummy2; ++ uint8_t HExpansion; /* +8 ³ÎÄê */ ++ uint8_t VExpansion; /* +9 ³ÎÄê */ ++ uint8_t dummy3; ++ uint8_t dummy4; ++ uint8_t RConversion; /* +12 ³ÎÄê */ ++ uint8_t dummy5; ++ uint8_t dummy6; ++ uint8_t dummy7; ++ ATI_UNKNOWN1 x; ++ } ATI_EXTENDEDOVERLAYPROP; /* 16byte? */ ++ ++ /** ++ * AtiCore initialization. ++ * Sets up the shared memory area ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_ProcessAttach( void ); ++ ++ /** ++ * AtiCore finish. ++ * ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_ProcessDetach( void ); ++ ++ ++ /** ++ * Allocates a surface on the internal RAM. ++ * Perhaps there's a way to indicate to allocate on the ++ * internal RAM? ++ * @arg handle Reference to the returned surface handle ++ * @arg offset Returned offset of this surface on the video memory ++ * @arg size Size (bytes) to be reserved (16 multiple) ++ * @arg direction ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_AllocateSurface( uint16_t *handle, uint32_t *offset, ++ uint32_t size, uint32_t direction ); ++ ++ /** ++ * Deallocates a given surface. ++ * @arg handle Handle to the allocated surface ++ * (As returned by AllocateSurface) ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_DestroySurface( uint16_t handle ); ++ ++ /** ++ * Sets the kind of Raster Operation. ++ * @param rop Raster operation to be performed ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetRopOperation( uint32_t rop ); ++ ++ /** ++ * Sets the destination type for raster operation. ++ * @param dsttype ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetDstType( uint32_t dsttype ); ++ ++ /** ++ * Sets the source type for raster operation. ++ * @param srctype ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetSrcType( uint32_t srctype ); ++ ++ /** ++ * Sets Source clipping rectangle. ++ * @param cliprect Rectangle to perform clipping. ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetSrcClippingRect( ATI_CLIPRECT *cliprect ); ++ ++ /** ++ * Sets Destination clipping rectangle. ++ * @param cliprect Rectangle to perform clipping. ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetDstClippingRect(ATI_CLIPRECT *cliprect); ++ ++ /** ++ * Sets pitch and offset for source in a raster operation. ++ * @param pitch Pitch (line width) of source ++ * @param offset Offset of source ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetSrcPitchOffset( int pitch, int offset ); ++ ++ /** ++ * Sets pitch and offset destination source in a raster operation. ++ * @param pitch Pitch (line width) of destination ++ * @param offset Offset of destination (memory offset) ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetDstPitchOffset( int pitch, int offset ); ++ ++ /** ++ * Performs a BitBlt with source rotation. ++ * @param flags Rotation degree ++ * @param dstRect Rectangle for destination Bitblitting ++ * @param srcRect Rectangle for origin bitblitting ++ * @test Tested with specified flags parameter ++ */ ++ int AtiCore_BitBltFilpRotate( int flags, ++ ATI_RECT *dstRect, ++ ATI_RECT *srcRect); ++ ++ /** ++ * Performs a BitBlt with source stretching. ++ * @param option Unknown ++ * @param point Unknown ++ * @param srcRect Source blitting surface ++ * @test Untested ++ */ ++ int AtiCore_StretchBlt( ATI_STRETCH *option, ++ ATI_POINT *point, ++ ATI_RECT *srcRect); ++ ++ /** ++ * Waits for the FIFO to be idle at least msecs. ++ * @param msecs Maximum time to wait for FIFO to idle ++ * @return 1:success, 0:fail ++ * @test Untested ++ */ ++ int AtiCore_WaitComplete( int msec ); ++ ++ /** ++ * Allocates a new overlay handle. ++ * @param handle overlay ++ * @return 1:success, 0:fail ++ * @test Yes ++ */ ++ int AtiCore_AllocOverlay( uint16_t *handle ); ++ ++ /** ++ * Deallocates a overlay handle. ++ * @param handle overlay ++ * @return 1:success, 0:fail ++ * @test Yes ++ */ ++ int AtiCore_ReleaseOverlay( uint16_t handle ); ++ ++ /** ++ * Sets up an overlay given a handle an a set of properties. ++ * @param handle Allocated handle to setup the overlay. ++ * @param props Overlay properties struct ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetupOverlay( uint16_t handle, ATI_OVERLAYPROP *props ); ++ ++ /** ++ * Sets up extended overlay features. ++ * @param handle Allocated handle to an overlay ++ * @param props Extended overlay properties ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetupOverlayExtended( uint16_t handle, ++ ATI_EXTENDEDOVERLAYPROP *props ); ++ ++ /** ++ * Enable/Disable an overlayed surface. ++ * @param handle Overlay to be enabled/disabled ++ * @param enable 1: Enable, 0: Disable ++ * @return 1:success, 0:fail ++ * @test Tested ++ */ ++ int AtiCore_SetOverlayOnOff( uint16_t handle, int enable ); ++ ++ /** ++ * Sets up the overlay position for a given handle. ++ * @param handle Overlay Handle ++ * @param x X Coordinate (Seems to be a bug with x < 4 ) ++ * @param y Y Coordinate ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetOverlayPos( uint16_t handle, ++ uint16_t x, ++ uint16_t y ); ++ ++ /** ++ * Translates between physical/virtual addresses. ++ * @param offset VRAM offset to be translated ++ * @param viraddr Virtual address for VRAM ++ * @return 1:success,0:fail ++ */ ++ int AtiCore_SetupMemoryTransfer( uint32_t offset, ++ uint32_t *viraddr ); ++ ++ /** ++ * Related with the previous one. It seems to be necesary to be called ++ * but I'm not sure of its function. ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_TerminateMemoryTransfer( void ); ++ ++ /** ++ * Returns the frontbuffer pitch and offset. ++ * @param pitch Return value for the frontbuffer pitch (width) ++ * @param offset Return value for the frontbuffer offset ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_GetFrontBufferPitchOffset( uint32_t *pitch, ++ uint32_t *offset ); ++ ++ /** ++ * Changes display brighness ? ++ * @param brightness -64...63 ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetDisplayBrightness( int brightness ); ++ ++ /** ++ * Returns the amount of available internal/external memory. ++ * @param internal Pointer to return internal memory size ++ * @param external Pointer to return external memory size ++ * @return 1:success, 0:fail ++ */ ++ int GetAvailableVideoMem( uint32_t *internal, ++ uint32_t *external ); ++ ++/** ++ * ++ * ++ * ++ ++ { ++ (uint32_t) 0 ++ (uint32_t) 0 ++ (uint16_t) 480 ++ (uint16_t) 640 ++ (uint16_t) 480 ++ (uint16_t) 640 ++ (uint32_t) 5 ++ */ ++ ++ typedef struct { ++ uint32_t dummy1; ++ ATI_RECT Size; ++ uint16_t Width; ++ uint16_t Height; ++ uint32_t Flag; ++ } ATI_GRAPHICWINDOW; ++ ++ int AtiCore_SetupGraphicWindow(void* ); ++ ++ /** ++ * It seems to be necessary after AtiCore_ProcessAttach ++ * @param mode: 0xaaab for portrait, 0xaaaa for landscape ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_ProcessAttachSpecialMode( int mode ); ++ ++ /** ++ * Detach from the special mode. Whatever it means. ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_ProcessDetachSpecialMode( void ); ++ ++ /** ++ * Sets up the position of the Graphic viewport ? ++ * @param x X coordinate ++ * @param y Y coordinate ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetGraphicWindowPos( int x, int y ); ++ ++ /** ++ * Get the graphic viewport position. ++ * @param x Pointer to xcoord placeholder ++ * @param y Pointer to ycoord placeholder ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_GetGraphicWindowPos( int *x, int *y ); ++ ++ /** ++ * Sets up the frontbuffer position. ++ * @param offset VRAM offset to be used. ++ * @param x X Coordinate? ++ * @param y Y Coordinate? ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetFrontBuffer( int offset, int x, int y ); ++ ++ /** ++ * Enable/Disable the frontbuffer? ++ * @param enable 1 enables/ 0 disables ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetGraphicWindowOnOff( int enable ); ++ ++ /* ++ * Sets the foreground color. ++ * @param colour Color in 565 format (perhaps depends on the source format) ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetFrgColour( int colour ); ++ ++ /* ++ * Sets the background colour. ++ * @param colour Colour in 565 format (perhaps depends on the source format) ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_SetBkgColour( int colour ); ++ ++ /** ++ * Changes the painting brush ++ * @param btype Type of brush to use ++ * 4: Uses the pattern ++ * 6: SolidLine ++ * @param pattern Pointer to a 32 bit pattern ++ * @return 1:success, 0:fail ++ * @test Some values for btype produces a kind of antialiasing line ++ */ ++ int AtiCore_BrushType( int btype, unsigned int *pattern ); ++ ++ /** ++ * Performs a rectangle paint. ++ * @param nrects Number of rectangles to be painted ++ * @param rects Array of rectangles to be painted ++ * @return 1:success, 0:fail ++ * @test Tested with nrects==1 ++ */ ++ int AtiCore_PaintRect( int nrects , ++ ATI_RECT rects[] ); ++ ++ /** ++ * Draws a set of lines. ++ * @param npoints Number of points in the polyline set ++ * @param points Pointer to an array of ATI_POINT ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_Polyline( int npoints, ATI_POINT points[] ); ++ ++ int AtiCore_GetPitchOffsetProperty( void *, void *); ++ ++ int AtiCore_CursorOnOff( int, int ); ++ ++ /** ++ * Performs a BitBlt ROP operation. ++ * @param unk Unknown (Always set to 1) ++ * @param dstrect Bounding destination rect ++ * @param srcrect Bounding source rect ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_BitBlt( int unk, ++ ATI_RECT *dstrect, ++ ATI_RECT *srcrect ); ++ ++ /** ++ * Performs a Transparent BitBlt ROP operation. ++ * @param dstrect Transparent DstRect bitblt argument ++ * @param srcrect Transparent SrcRect bitblt argument ++ * @return 1:success, 0:fail ++ * @test Doesn't work. It sets to zero CLR_CMP_CNTL and CLR_CMP_MSK ++ */ ++ int AtiCore_TransBitBlt( transbitblt_t *dstrect, ++ transbitblt_t *srcrect ); ++ ++ int AtiCore_WakeUpCall( void ); ++ ++ /** ++ * Draws a set of pixels ++ * @param npoints Number of points to draw ++ * @param points Pointer to an array of ATI_POINT ++ * @return 1:success, 0:fail ++ */ ++ int AtiCore_DrawPixel( int npoints, ATI_POINT *points ); ++ ++ int AtiCore_SetSysClk( unsigned short in0 ); ++ int AtiCore_SetFastSysClk( unsigned short in0 ); ++ int AtiCore_SetSlowSysClk( unsigned short in0 ); ++ ++ int AtiCore_GetCursorPos( unsigned long in0, ++ unsigned short *x, ++ unsigned short *y ); ++ ++ ++ ++/* ================================================================ */ ++/* from libqte.so.2.3.2 */ ++/* ++AtiCore_AlphaBlend ++ ++AtiCore_Flush ++AtiCore_GammaCorrection ++AtiCore_GetCRC ++AtiCore_GetCursorPos ++AtiCore_GetDeviceInfo ++AtiCore_GetGPIO_Data ++AtiCore_GetGraphicExtended ++AtiCore_GetGraphicWindowPos ++AtiCore_GetLargestVideoMemBlock ++AtiCore_GetLastError ++AtiCore_GetMultiCRC ++AtiCore_GetOverlayPos ++AtiCore_Host ++AtiCore_LoadCursorBitMap ++AtiCore_PolyScanline ++AtiCore_ProcessAttachMinimal(void)? ++AtiCore_ProcessDetachMinimal(void)? ++AtiCore_ProcessDetachSpecialMode ++AtiCore_ReadCfgReg ++AtiCore_ReadMem(int, int)? ++AtiCore_ReadReg(int, int)? ++AtiCore_ScanlineShading ++AtiCore_SetApertures ++AtiCore_SetBytePixelOrder ++AtiCore_SetCursorPos ++AtiCore_SetDisplayParameters ++AtiCore_SetDriverBehaviour ++AtiCore_SetGPIO_Data ++AtiCore_SetOverlayPosUsingGraphicWindowXY ++AtiCore_SetPartialCursor ++AtiCore_SetupGraphicExtended ++AtiCore_SetupPM4 ++AtiCore_SmallText ++AtiCore_SubmitPM4Packet ++AtiCore_WriteCfgReg ++AtiCore_WriteMem ++AtiCore_WriteReg ++ */ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfxw100_qws.cpp +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfxw100_qws.cpp 2006-01-20 21:17:39.459504280 +0100 +@@ -0,0 +1,2709 @@ ++ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil -*- */ ++/*************************************************************************** ++ ++** Imageon driver for qte using libAticore ++** Manuel Teira( 2005 ) ++** BUGS ++* - Enable again internal memory surfaces. ++****************************************************************************/ ++#include <unistd.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <errno.h> ++#include <string.h> ++#include <dirent.h> ++#include <fcntl.h> ++#include <sys/types.h> ++#include <sys/mman.h> ++#include <sys/time.h> ++#include <time.h> ++ ++#include <sys/ipc.h> ++#include <sys/shm.h> ++ ++#include <qapplication.h> ++ ++#ifndef __sparc__ ++#include <sys/io.h> ++#endif ++ ++#include "qgfxraster_qws.h" ++#include "qgfxlinuxfb_qws.h" ++#include <aticore/aticore.h> ++ ++#include <stdarg.h> ++ ++class W100Driver { ++public: ++ ++ typedef enum Loglevel { ++ ERROR = 0, ++ WARNING, ++ INFO ++ }; ++ ++ typedef enum Opcodes { ++ DRAWLINE = 0, ++ DRAWPOINT, ++ DRAWPOINTS, ++ FILLRECT, ++ SCROLL, ++ BITBLT, ++ POLYLINE, ++ EOO ++ }; ++ ++ typedef enum Retcodes { ++ codOK, ++ codError ++ }; ++ ++ ++ typedef struct Opcode { ++ QString str; ++ int index; ++ bool accelerated; ++ int hits; ++ int misses; ++ }; ++ ++ static Opcode lOpcodes[]; ++ ++ static QString level2str( int level ) ++ { ++ switch( level ) { ++ case ERROR: ++ return QString( "ERROR" ); ++ break; ++ case WARNING: ++ return QString( "WARNING" ); ++ break; ++ case INFO: ++ return QString( "INFO" ); ++ break; ++ default: ++ return QString( "UNKNOWN" ); ++ break; ++ } ++ } ++ ++ W100Driver(): ++ m_loglevel( 0 ), ++ m_logenabled( 0 ), ++ m_logcount( 0 ), ++ m_attached( false ) ++ { ++ m_pid = getpid(); ++ m_loglevel = 0; ++ char *var; ++ if ( var = getenv( "W100_DEBUG" ) ) { ++ if ( strtol( var, 0, 0 ) == 1 ) { ++ m_logenabled = 1; ++ } ++ } ++ ++ if ( m_logenabled ) { ++ if ( var = getenv( "W100_DEBUGLEVEL" ) ) { ++ if ( ( m_loglevel = strtol( var, 0, 0 ) ) < 0 ) { ++ m_loglevel = 0; ++ } ++ } ++ ++ QString path( "/mnt/card/w100/w100debug.log" ); ++ if ( var = getenv( "W100_DEBUGPATH" ) ) { ++ path = QString( var ) + "/w100debug.log"; ++ } ++ m_logfile = fopen( path.latin1(), "a" ); ++ if ( m_logfile == NULL ) m_logenabled = 0; ++ } ++ ++ Opcode *opcodePtr = lOpcodes; ++ while ( opcodePtr->index != EOO ) { ++ QString varName = "W100_ACCEL_" + opcodePtr->str; ++ char *varPtr; ++ if ( ( varPtr = getenv( varName.latin1() ) ) ) { ++ if ( ( strtol( varPtr, NULL, 0 ) == 0 ) || ++ ( strcmp( varPtr, "false" ) == 0 ) ) { ++ opcodePtr->accelerated = false; ++ } ++ } ++ opcodePtr++; ++ } ++ } ++ ++ ~W100Driver() ++ { ++ //Dump statistics about any opcode ++ Opcode *opcodePtr = lOpcodes; ++ while ( opcodePtr->index != EOO ) { ++ log( WARNING, "Opcode %s. Accelerated=%s. Hits=%d. Misses=%d", ++ opcodePtr->str.latin1(), ++ opcodePtr->accelerated ? "true" : "false", ++ opcodePtr->hits, ++ opcodePtr->misses ); ++ opcodePtr++; ++ } ++ if ( m_logenabled && m_logfile ) { ++ fclose( m_logfile ); ++ } ++ } ++ ++ bool accelerated( int opcode ) ++ { ++ if ( !m_attached ) { ++ log( WARNING, "Asking for accelerated '%s' when not attached", ++ lOpcodes[opcode].str.latin1() ); ++ return false; ++ } ++ if ( opcode < EOO ) { ++ if ( lOpcodes[opcode].accelerated ) { ++ return true; ++ } else { ++ log( WARNING, "Not accelerated '%s'", ++ lOpcodes[opcode].str.latin1() ); ++ return false; ++ } ++ } ++ return false; ++ } ++ ++ void addHit( int opcode ) ++ { ++ lOpcodes[opcode].hits++; ++ } ++ ++ void addMiss( int opcode ) ++ { ++ lOpcodes[opcode].misses++; ++ } ++ ++ void log( int level, const char *fmt, ... ) ++ { ++ if ( m_logenabled && ( level <= m_loglevel ) ) { ++ timeval tv; ++ char buffer[1024]; ++ va_list ap; ++ va_start( ap, fmt ); ++ vsnprintf( buffer, 1023, fmt, ap ); ++ va_end( ap ); ++ gettimeofday( &tv, NULL ); ++ fprintf( m_logfile, "(%010u.%06u)%d:%d:%s:%s\n", ++ tv.tv_sec, tv.tv_usec, ++ m_logcount++, ++ m_pid, ++ level2str( level ).latin1(), ++ buffer ); ++ fflush( m_logfile ); ++ } ++ } ++ ++ bool attached( void ) const ++ { ++ return m_attached; ++ } ++ ++ int processAttach( void ) ++ { ++ if ( !m_attached ) { ++ if ( AtiCore_ProcessAttach() ) { ++ log( WARNING, "Process attached succesfully" ); ++ m_attached = true; ++ return codOK; ++ } else { ++ log( WARNING, "Error attaching process" ); ++ } ++ } else { ++ log( WARNING, "Process already attached" ); ++ } ++ return codError; ++ } ++ ++ int processDetach( void ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_ProcessDetach() ) { ++ log( WARNING, "Process detached succesfully" ); ++ m_attached = false; ++ return codOK; ++ } else { ++ log( WARNING, "Error detaching process" ); ++ } ++ } else { ++ log( WARNING, "Trying to detach while not attached" ); ++ } ++ return codError; ++ } ++ ++ int allocateSurface( uint16_t *handle, uint32_t *offset, ++ uint32_t size, uint32_t direction ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_AllocateSurface( handle, offset, ++ size, direction ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in allocateSurface" ); ++ } ++ } else { ++ log( WARNING, "Trying to allocateSurface while not attached" ); ++ } ++ return codError; ++ } ++ ++ int destroySurface( uint16_t handle ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_DestroySurface( handle ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in destroySurface" ); ++ } ++ } else { ++ log( WARNING, "Trying to destroySurface while not attached" ); ++ } ++ return codError; ++ } ++ ++ int drawPixel( int npoints, ATI_POINT *points ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_DrawPixel( npoints, points ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in drawPixel" ); ++ } ++ } else { ++ log( WARNING, "Trying to drawPixel while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setRopOperation( uint32_t rop ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetRopOperation( rop ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setRopOperation" ); ++ } ++ } else { ++ log( WARNING, "Trying to setRopOperation while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setDstType( uint32_t dtype ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetDstType( dtype ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setDstType" ); ++ } ++ } else { ++ log( WARNING, "Trying to setDstType while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setSrcType( uint32_t stype ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetSrcType( stype ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setSrcType" ); ++ } ++ } else { ++ log( WARNING, "Trying to setSrcType while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setSrcClippingRect( ATI_CLIPRECT *cliprect ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetSrcClippingRect( cliprect ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setSrcClippingRect" ); ++ } ++ } else { ++ log( WARNING, "Trying to setSrcClippingRect while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setDstClippingRect( ATI_CLIPRECT *cliprect ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetDstClippingRect( cliprect ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setDstClippingRect" ); ++ } ++ } else { ++ log( WARNING, "Trying to setDstClippingRect while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setSrcPitchOffset( int pitch, int offset ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetSrcPitchOffset( pitch, offset ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setSrcPitchOffset" ); ++ } ++ } else { ++ log( WARNING, "Trying to setSrcPitchOffset while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setDstPitchOffset( int pitch, int offset ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetDstPitchOffset( pitch, offset ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setDstPitchOffset" ); ++ } ++ } else { ++ log( WARNING, "Trying to setDstPitchOffset while not attached" ); ++ } ++ return codError; ++ } ++ ++ int bitBltFlipRotate( int rot, ++ ATI_RECT *dstRect, ++ ATI_RECT *srcRect ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_BitBltFilpRotate( rot, dstRect, srcRect ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in bitBltFlipRotate" ); ++ } ++ } else { ++ log( WARNING, "Trying to bitBltFlipRotate while not attached" ); ++ } ++ return codError; ++ } ++ ++ int stretchBlt( ATI_STRETCH *option, ++ ATI_POINT *point, ++ ATI_RECT *srcRect ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_StretchBlt( option, point, srcRect ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in stretchBlt" ); ++ } ++ } else { ++ log( WARNING, "Trying to stretchBlt while not attached" ); ++ } ++ return codError; ++ } ++ ++ int waitComplete( int msec ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_WaitComplete( msec ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in waitComplete" ); ++ } ++ } else { ++ log( WARNING, "Trying to waitComplete while not attached" ); ++ } ++ return codError; ++ } ++ ++ int allocOverlay( uint16_t *handle ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_AllocOverlay( handle ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in allocOverlay" ); ++ } ++ } else { ++ log( WARNING, "Trying to allocOverlay while not attached" ); ++ } ++ return codError; ++ } ++ ++ int releaseOverlay( uint16_t handle ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_ReleaseOverlay( handle ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in releaseOverlay" ); ++ } ++ } else { ++ log( WARNING, "Trying to releaseOverlay while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setupOverlay( uint16_t handle, ATI_OVERLAYPROP *prop ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetupOverlay( handle, prop ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setupOverlay" ); ++ } ++ } else { ++ log( WARNING, "Trying to setupOverlay while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setupOverlayExtended( uint16_t handle, ++ ATI_EXTENDEDOVERLAYPROP *prop ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetupOverlayExtended( handle, prop ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setupOverlayExtended" ); ++ } ++ } else { ++ log( WARNING, "Trying to setupOverlayExtended while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setOverlayOnOff( uint16_t handle, int isShow ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetOverlayOnOff( handle, isShow ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setOverlayOnOff" ); ++ } ++ } else { ++ log( WARNING, "Trying to setOverlayOnOff while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setOverlayPos( uint16_t handle, uint16_t x, uint16_t y ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetOverlayPos( handle, x, y ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setOverlayPos" ); ++ } ++ } else { ++ log( WARNING, "Trying to setOverlayPos while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setupMemoryTransfer( uint32_t offset, uint32_t *regdata ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetupMemoryTransfer( offset, regdata ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setupMemoryTransfer" ); ++ } ++ } else { ++ log( WARNING, "Trying to setupMemoryTransfer while not attached" ); ++ } ++ return codError; ++ } ++ ++ int terminateMemoryTransfer( void ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_TerminateMemoryTransfer() ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in terminateMemoryTransfer" ); ++ } ++ } else { ++ log( WARNING, "Trying to terminateMemoryTransfer while not attached" ); ++ } ++ return codError; ++ } ++ ++ int getFrontBufferPitchOffset( uint32_t *pitch, uint32_t *offset ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_GetFrontBufferPitchOffset( pitch, offset ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in getFrontBufferPitchOffset" ); ++ } ++ } else { ++ log( WARNING, "Trying to getFrontBufferPitchOffset while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setDisplayBrightness( int bri ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetDisplayBrightness( bri ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setDisplayBrightness" ); ++ } ++ } else { ++ log( WARNING, "Trying to setDisplayBrighness while not attached" ); ++ } ++ return codError; ++ } ++ ++ int getAvailableVideoMem( uint32_t *internal, uint32_t *external ) ++ { ++ if ( m_attached ) { ++ if ( GetAvailableVideoMem( internal, external ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in getAvailableVideoMem" ); ++ } ++ } else { ++ log( WARNING, "Trying to getAvailableVideoMem while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setupGraphicWindow( ATI_GRAPHICWINDOW *win ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetupGraphicWindow( ( void * ) win ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setupGraphicWindow" ); ++ } ++ } else { ++ log( WARNING, "Trying to setupGraphicWindow while not attached" ); ++ } ++ return codError; ++ } ++ ++ int processAttachSpecialMode( int mode ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_ProcessAttachSpecialMode( mode ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in processAttachSpecialMode" ); ++ } ++ } else { ++ log( WARNING, "Trying to processAttachSpecialMode while not attached" ); ++ } ++ return codError; ++ } ++ ++ int processDetachSpecialMode( void ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_ProcessDetachSpecialMode() ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in processDetachSpecialMode" ); ++ } ++ } else { ++ log( WARNING, "Trying to processDetachSpecialMode while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setGraphicWindowPos( int x, int y ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetGraphicWindowPos( x, y ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setGraphicWindowPos" ); ++ } ++ } else { ++ log( WARNING, "Trying to setGraphicWindow while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setFrontBuffer( int offset, int a, int b ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetFrontBuffer( offset, a, b ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setFrontBuffer" ); ++ } ++ } else { ++ log( WARNING, "Trying to setFrontBuffer while not attached" ); ++ } ++ return codError; ++ } ++ ++ int setGraphicWindowOnOff( int val ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetGraphicWindowOnOff( val ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setGraphicWindowOnOff" ); ++ } ++ } else { ++ log( WARNING, "Trying to setGraphicWindowOnOff while not attached" ); ++ } ++ } ++ ++ static unsigned long ccolor( unsigned int rgb ) ++ { ++ unsigned char r = ( rgb & 0xff0000 ) >> 19; ++ unsigned char g = ( rgb & 0xff00 ) >> 10; ++ unsigned char b = ( rgb & 0xff ) >> 3; ++ return ( ( ( ( unsigned short )0x1f & r ) << 11 ) | ++ ( ( ( unsigned short )0x3f & g ) << 5 ) | ++ ( ( ( unsigned short )0x1f & b ) ) ); ++ } ++ ++ int setFrgColour( int val ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_SetFrgColour( ccolor( val ) ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in setFrgColour" ); ++ } ++ } else { ++ log( WARNING, "Trying to setFrgColour while not attached" ); ++ } ++ return codError; ++ } ++ ++ int brushType( int type, unsigned int pattern ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_BrushType( type, &pattern ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in brushType" ); ++ } ++ } else { ++ log( WARNING, "Trying to brushType while not attached" ); ++ } ++ return codError; ++ } ++ ++ int paintRect( int flags, ATI_RECT *rect ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_PaintRect( flags, rect ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in paintRect" ); ++ } ++ } else { ++ log( WARNING, "Trying to paintRect while not attached" ); ++ } ++ return codError; ++ } ++ ++ int polyline( int npoints, ATI_POINT *points ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_Polyline( npoints, points ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in polyline" ); ++ } ++ } else { ++ log( WARNING, "Trying to polyline while not attached" ); ++ } ++ return codError; ++ } ++ ++ int getPitchOffsetProperty( void *pitch, void *offset ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_GetPitchOffsetProperty( pitch, offset ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in getPitchOffsetProperty" ); ++ } ++ } else { ++ log( WARNING, "Trying to getPitchOffsetProperty while not attached" ); ++ } ++ return codError; ++ } ++ ++ int cursorOnOff( int a, int b ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_CursorOnOff( a, b ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in cursorOnOff" ); ++ } ++ } else { ++ log( WARNING, "Trying to cursorOnOff while not attached" ); ++ } ++ return codError; ++ } ++ ++ int bitBlt( int flags, ATI_RECT *dst, ATI_RECT *src ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_BitBlt( flags, dst, src ) ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in bitBlt" ); ++ } ++ } else { ++ log( WARNING, "Trying to bitBlt while not attached" ); ++ } ++ return codError; ++ } ++ ++ int wakeUpCall( void ) ++ { ++ if ( m_attached ) { ++ if ( AtiCore_WakeUpCall() ) { ++ return codOK; ++ } else { ++ log( ERROR, "Error in wakeUpCall" ); ++ } ++ } else { ++ log( WARNING, "Trying to wakeupCall while not attached" ); ++ } ++ return codError; ++ } ++ ++private: ++ FILE *m_logfile; ++ int m_loglevel; ++ bool m_logenabled; ++ bool m_attached; ++ int m_pid; ++ int m_logcount; ++}; ++ ++W100Driver::Opcode W100Driver::lOpcodes[] = { ++ { "DRAWLINE", W100Driver::DRAWLINE, true, 0, 0 }, ++ { "DRAWPOINT", W100Driver::DRAWPOINT, true, 0, 0 }, ++ { "DRAWPOINTS", W100Driver::DRAWPOINTS, true, 0, 0 }, ++ { "FILLRECT", W100Driver::FILLRECT, true, 0, 0 }, ++ { "SCROLL", W100Driver::SCROLL, true, 0, 0 }, ++ { "BITBLT", W100Driver::BITBLT, true, 0, 0 }, ++ { "POLYLINE", W100Driver::POLYLINE, true, 0, 0 }, ++ { "" , W100Driver::EOO, false, 0, 0 } ++}; ++ ++W100Driver driver; ++ ++class QW100Screen; ++static QW100Screen *qt_w100_screen = 0; ++ ++class QW100Screen : public QLinuxFbScreen { ++public: ++ class HWSurface { ++ public: ++ HWSurface( void ): ++ m_handle( 0 ), ++ m_offset( 0 ), ++ m_addr( 0 ), ++ m_size( 0 ), ++ m_internal( false ), ++ m_clientid( -1 ) {}; ++ HWSurface( unsigned short handle, ++ uint32_t sOffset, ++ unsigned char *localAddr, ++ int amount, ++ bool internal, ++ int clientid ): ++ m_handle( handle ), ++ m_offset( sOffset ), ++ m_addr( localAddr ), ++ m_size( amount ), ++ m_internal( internal ), ++ m_clientid( clientid ) {}; ++ HWSurface( uint32_t sOffset, ++ unsigned char *localAddr, ++ bool internal, ++ int amount ): ++ m_handle( 0 ), ++ m_offset( sOffset ), ++ m_addr( localAddr ), ++ m_size( amount ), ++ m_internal( internal ), ++ m_clientid( -1 ) {}; ++ bool operator!=( HWSurface &other ) { ++ return( m_offset == other.getSOffset() ); ++ }; ++ HWSurface &operator=( const HWSurface &c ) { ++ m_handle = c.getHandle(); ++ m_offset = c.getSOffset(); ++ m_addr = c.getAddr(); ++ m_size = c.getSize(); ++ m_clientid= c.getCId(); ++ m_internal = c.internal(); ++ return( *this ); ++ }; ++ unsigned short getHandle( void ) const { return m_handle; }; ++ uint32_t getSOffset( void ) const { return m_offset; }; ++ unsigned char *getAddr( void ) const { return m_addr; }; ++ unsigned int getSize( void ) const { return m_size; }; ++ int getCId( void ) const { return m_clientid; }; ++ bool internal( void ) const { return m_internal; }; ++ ++ private: ++ unsigned short m_handle; ++ uint32_t m_offset; ++ unsigned char *m_addr; ++ int m_size; ++ bool m_internal; ++ int m_clientid; ++ }; ++ ++ QW100Screen( int display_id ); ++ virtual ~QW100Screen(); ++ virtual bool connect( const QString &spec ); ++ virtual void disconnect( void ); ++ virtual bool initDevice(); ++ virtual void shutdownDevice(); ++ virtual void restore(); ++ virtual bool useOffscreen() { return true; } ++ virtual QGfx * createGfx( unsigned char *, int, int, int, int); ++ virtual uchar *cache( int amount, int optim ); ++ virtual void uncache( uchar *c ); ++ virtual bool onCard( unsigned char *p ) const; ++ virtual bool onCard( unsigned char *p, ulong& offset ) const; ++ QMap< uchar*, HWSurface > *getPSurfaceMap( void ) const; ++ void clearCache( int clientId ); ++ ++ // Suspend/resume hooks ++ virtual void prepareToSuspend(); ++ virtual void prepareToResume(); ++ // Rotation stuff ++ enum Transformation { None, Rot90, Rot180, Rot270 }; ++ void setTransformation( Transformation t ); ++ Transformation transformation() const; ++ virtual bool isTransformed() const { return trans != None; }; ++ virtual QSize mapToDevice( const QSize & ) const; ++ virtual QSize mapFromDevice( const QSize & ) const; ++ virtual QPoint mapToDevice( const QPoint &, const QSize & ) const; ++ virtual QPoint mapFromDevice( const QPoint &, const QSize & ) const; ++ virtual QRect mapToDevice( const QRect &, const QSize & ) const; ++ virtual QRect mapFromDevice( const QRect &, const QSize & ) const; ++ virtual QImage mapToDevice( const QImage & ) const; ++ virtual QImage mapFromDevice( const QImage & ) const; ++ virtual QRegion mapToDevice( const QRegion &, const QSize & ) const; ++ virtual QRegion mapFromDevice( const QRegion &, const QSize & ) const; ++ virtual int transformOrientation() const; ++ ++protected: ++ bool w100init(); ++ void w100shutdown(); ++ Transformation trans; ++ static Transformation getTransSpec( const QString &dspec ); ++ static void clearCache( QScreen *instance, int clientId ); ++ QMap< uchar*, HWSurface > surfaceMap; ++ int vramoffset; ++ bool m_isServer; ++ virtual int pixmapLinestepAlignment() { return 128; } ++}; ++ ++template <const int depth, const int type> ++class QGfxW100 : public QGfxRaster<depth,type> { ++ ++public: ++ QGfxW100( unsigned char *b, int w, int h ); ++ virtual void drawLine( int, int, int, int); ++ virtual void fillRect( int, int, int, int); ++ virtual void blt( int, int, int, int, int, int ); ++ virtual void sync(); ++ virtual void setOffset( int x, int y ); ++ virtual void setPen( const QPen & p ); ++ ++ virtual void drawPolyline( const QPointArray &, int, int ); ++ virtual void drawPolygon( const QPointArray &, bool, int, int ); ++ virtual void drawPoint( int, int ); ++ virtual void drawPoints( const QPointArray &, int, int ); ++ virtual void scroll( int, int, int, int, int, int ); ++ virtual void tiledBlt( int rx, int ry, int w, int h ); ++ ++ inline int tx( int x, int y ) { ++ switch ( qt_w100_screen->transformation() ) { ++ case QW100Screen::Rot90: ++ return y - this->xoffs + this->yoffs; ++ case QW100Screen::Rot180: ++ return ( this->width - x - 1) - this->xoffs - this->xoffs; ++ case QW100Screen::Rot270: ++ return ( this->height - y - 1) - this->xoffs - this->yoffs; ++ default: ++ return x; ++ } ++ } ++ inline int ty( int x, int y ) { ++ switch ( qt_w100_screen->transformation() ) { ++ case QW100Screen::Rot90: ++ return (this->width - x - 1) - this->yoffs - this->xoffs; ++ case QW100Screen::Rot180: ++ return (this->height - y - 1) - this->yoffs - this->yoffs; ++ case QW100Screen::Rot270: ++ return x - this->yoffs + this->xoffs; ++ default: ++ return y; ++ } ++ } ++ ++protected: ++ bool checkDest( bool setsrc = false ); ++ bool checkSourceDest(); ++ virtual void setSourceWidgetOffset( int x, int y ); ++ void processSpans( int n, QPoint* point, int* width ); ++ bool inDraw; ++ ++ virtual void dDrawLine( int, int, int, int); ++ virtual void dFillRect( int, int, int, int); ++ virtual void dBlt( int, int, int, int, int, int ); ++ void dDrawPolyline( const QPointArray &, int, int ); ++ void dDrawPolygon( const QPointArray &, bool, int, int ); ++ void dDrawPoint( int, int ); ++ void dDrawPoints( const QPointArray &, int, int ); ++ void dScroll( int, int, int, int, int, int ); ++ void dTiledBlt( int rx, int ry, int w, int h ); ++}; ++ ++template<const int depth,const int type> ++QGfxW100<depth,type>::QGfxW100( unsigned char * b, int w, int h ) ++ : QGfxRaster<depth,type>(b, w, h), ++ inDraw( false ) ++{ ++} ++ ++template<const int depth,const int type> ++inline void QGfxW100<depth,type>::setOffset( int x, int y ) ++{ ++ QGfxRaster<depth,type>::setOffset( x, y ); ++} ++ ++namespace { ++ QString penStyleStr( const QPen &pen ) ++ { ++ QString res; ++ switch( pen.style() ) { ++ case Qt::NoPen: ++ res = "NoPen"; ++ break; ++ case Qt::SolidLine: ++ res = "SolidLine"; ++ break; ++ case Qt::DashLine: ++ res = "DashLine"; ++ break; ++ case Qt::DotLine: ++ res = "DotLine"; ++ break; ++ case Qt::DashDotLine: ++ res = "DashDotLine"; ++ break; ++ case Qt::DashDotDotLine: ++ res = "DashDotDotLine"; ++ break; ++ default: ++ res = "Unknown"; ++ } ++ return res; ++ } ++} ++ ++template<const int depth, const int type> ++inline void QGfxW100<depth,type>::setPen( const QPen &p ) ++{ ++ QGfxRaster<depth,type>::setPen( p ); ++} ++ ++template<const int depth,const int type> ++inline bool QGfxW100<depth,type>::checkSourceDest() ++{ ++ if ( !checkDest() ) { ++ return FALSE; ++ } ++ ++ int sourcepixelpitch; ++ ulong src_buffer_offset; ++ if ( this->srctype == this->SourcePen ) { ++ src_buffer_offset = -1; ++ return FALSE; ++ } else { ++ if ( !qt_screen->onCard( this->srcbits, src_buffer_offset ) ) { ++ return FALSE; ++ } ++ sourcepixelpitch = ( this->srclinestep * 8 ) / this->srcdepth; ++ driver.setSrcPitchOffset( sourcepixelpitch, ++ src_buffer_offset ); ++ } ++ return TRUE; ++} ++ ++template< const int depth, const int type> ++inline bool QGfxW100<depth, type>::checkDest( bool setsrc ) ++{ ++ //Main framebuffer should be registered as a hardware surface ++ ulong buffer_offset; ++ if ( !qt_screen->onCard( this->buffer, buffer_offset ) ) { ++ return FALSE; ++ } ++ int pixelstep = ( this->linestep() * 8 ) / depth; ++ driver.setDstPitchOffset( pixelstep, buffer_offset ); ++ if ( setsrc ) { ++ driver.setSrcPitchOffset( pixelstep, buffer_offset ); ++ } ++ return TRUE; ++} ++ ++template<const int depth,const int type> ++void QGfxW100<depth,type>::drawLine( int x1, int y1, int x2, int y2 ) ++{ ++ if ( inDraw ) { ++ dDrawLine( x1, y1, x2, y2 ); ++ } else { ++ inDraw = true; ++ dDrawLine( tx(x1,y1), ty(x1,y1), ++ tx(x2,y2), ty(x2,y2) ); ++ inDraw = false; ++ } ++} ++ ++template<const int depth,const int type> ++void QGfxW100<depth,type>::dDrawLine( int x1, int y1, int x2, int y2 ) ++{ ++ if ( ( this->ncliprect < 1) || ++ ( this->cpen.style() == this->NoPen ) ) { ++ return; ++ } ++ ++ if ( depth != 16 || ++ !driver.accelerated( W100Driver::DRAWLINE ) ) { ++ driver.addMiss( W100Driver::DRAWLINE ); ++ QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2 ); ++ return; ++ } ++ ++ // Only handle 'normal' lines ++ if ( ( this->cpen.style() != this->SolidLine ) || ++ ( this->myrop != this->CopyROP ) || ++ ( this->cpen.width() > 1 ) || ++ ( this->dashedLines ) ) { ++ driver.addMiss( W100Driver::DRAWLINE ); ++ QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2); ++ return; ++ } ++ ++ // Stop anyone else trying to access optype/lastop/the graphics engine ++ // to avoid synchronization problems with other processes ++ QWSDisplay::grab( true ); ++ if ( !checkDest() ) { ++ QWSDisplay::ungrab(); ++ driver.addMiss( W100Driver::DRAWLINE ); ++ QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2 ); ++ return; ++ } ++ ++ ++ // Note that the last operation used the 2d engine ++ ( *optype ) = 1; ++ ++ // Add the offset of the gfx - used to make the origin the right ++ // place for windows ++ x1 += this->xoffs; ++ y1 += this->yoffs; ++ x2 += this->xoffs; ++ y2 += this->yoffs; ++ ++ QRect boundRect( x1 < x2 ? x1: x2, ++ y1 < y2 ? y1 : y2, ++ QABS( x2 - x1 ) + 1, ++ QABS( y2 - y1 ) + 1 ); ++ ++ GFX_START( boundRect ); ++ ++ // The clip region is defined as a series of rectangles ++ // We repeatedly set up the hardware clip rectangle to one of ++ // these rectangles and re-draw the line - an alternative approach ++ // would be to clip to the rectangle in software ++ ++ driver.setDstType( DSTTYPE_16BPP_1555 ); ++ driver.setSrcType( SRCTYPE_EQU_DST ); ++ driver.setRopOperation( ROP3_PATCOPY ); ++ driver.brushType( 6, 0 ); ++ driver.setFrgColour( this->cpen.color().rgb() ); ++ driver.addHit( W100Driver::DRAWLINE ); ++ ++ //The imageon seems not to write on the edge of the clip ++ //for the polyline op. ++ //We are using a three points array repeating the last point ++ //to get the last single point painted. ++ ATI_POINT points[3]; ++ points[0].XCoord = x1; ++ points[0].YCoord = y1; ++ points[1].XCoord = x2; ++ points[1].YCoord = y2; ++ points[2].XCoord = x2; ++ points[2].YCoord = y2; ++ for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) { ++ if ( boundRect.intersects( this->cliprect[loopc] ) ) { ++ ATI_CLIPRECT clip; ++ clip.X_Top_Left = this->cliprect[loopc].x(); ++ clip.Y_Top_Left = this->cliprect[loopc].y(); ++ clip.X_Bottom_Right = this->cliprect[loopc].right() + 1; ++ clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1; ++ driver.setDstClippingRect( &clip ); ++ driver.polyline( 3, points ); ++ } ++ } ++ ++ // Software mouse cursor stuff ++ GFX_END; ++ ++ // Release display again - not doing so will cause Qt/Embedded applications ++ // to deadlock ++ QWSDisplay::ungrab(); ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::drawPolyline( const QPointArray &a, ++ int index, ++ int npoints ) ++{ ++ if ( inDraw ) { ++ dDrawPolyline( a, index, npoints ); ++ } else { ++ inDraw = true; ++ QPointArray na( npoints ); ++ ++ for ( int i = 0; i < npoints; i++ ) { ++ int x, y; ++ a.point( i+index, &x, &y ); ++ na.setPoint( i, tx(x,y), ty(x,y) ); ++ } ++ ++ dDrawPolyline( na, 0, npoints ); ++ inDraw = false; ++ } ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::dDrawPolyline( const QPointArray &a, ++ int index, ++ int npoints ) ++{ ++ if ( ( this->ncliprect < 1 ) || ++ ( npoints < 1 ) || ++ ( this->cpen.style() == this->NoPen ) ) { ++ return; ++ } ++ ++ if ( depth != 16 || ++ !driver.accelerated( W100Driver::POLYLINE ) ) { ++ driver.addMiss( W100Driver::POLYLINE ); ++ QGfxRaster<depth,type>::drawPolyline( a, index, npoints ); ++ return; ++ } ++ ++ if ( this->cpen.style() != this->SolidLine || ++ this->myrop != this->CopyROP ) { ++ driver.addMiss( W100Driver::POLYLINE ); ++ QGfxRaster<depth,type>::drawPolyline( a, index, npoints ); ++ return; ++ } ++ ++ QWSDisplay::grab( TRUE ); ++ if ( !checkDest() ) { ++ QWSDisplay::ungrab(); ++ driver.addMiss( W100Driver::POLYLINE ); ++ QGfxRaster<depth,type>::drawPolyline( a, index, npoints ); ++ return; ++ } ++ ++ ( *optype ) = 1; ++ ++ driver.setDstType( DSTTYPE_16BPP_1555 ); ++ driver.setSrcType( SRCTYPE_EQU_DST ); ++ driver.setRopOperation( ROP3_PATCOPY ); ++ driver.brushType( 6, 0 ); ++ driver.setFrgColour( this->cpen.color().rgb() ); ++ ++ driver.addHit( W100Driver::POLYLINE ); ++ ++ ATI_POINT *points = new ATI_POINT[ npoints + 1 ]; ++ ++ for ( int i = 0; i < npoints; i++ ) { ++ points[i].XCoord = a[i+index].x() + this->xoffs; ++ points[i].YCoord = a[i+index].y() + this->yoffs; ++ } ++ //Hack to get the last point of the last line painted ++ points[ npoints ] = points[ npoints - 1 ]; ++ ++ ++ GFX_START( clipbounds ); ++ driver.setFrgColour( this->cpen.color().rgb() ); ++ driver.setRopOperation( ROP3_PATCOPY ); ++ for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) { ++ ATI_CLIPRECT clip; ++ clip.X_Top_Left = this->cliprect[loopc].x(); ++ clip.Y_Top_Left = this->cliprect[loopc].y(); ++ clip.X_Bottom_Right = this->cliprect[loopc].right() + 1; ++ clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1; ++ driver.setDstClippingRect( &clip ); ++ driver.polyline( npoints + 1, points ); ++ } ++ GFX_END; ++ ++ delete [] points; ++ ++ QWSDisplay::ungrab(); ++} ++ ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::drawPolygon( const QPointArray &a, ++ bool w, int index, ++ int npoints ) ++{ ++ if ( inDraw || this->cpen.style()==this->NoPen || this->patternedbrush ) { ++ //slowpath ++ dDrawPolygon( a, w, index, npoints ); ++ } else { ++ inDraw = TRUE; ++ QPointArray na( npoints ); ++ ++ for ( int i = 0; i < npoints; i++ ) { ++ int x,y; ++ a.point( i+index, &x, &y ); ++ na.setPoint( i, tx(x,y), ty(x,y) ); ++ } ++ dDrawPolygon( na, w, 0, npoints ); ++ inDraw = FALSE; ++ } ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::dDrawPolygon( const QPointArray &a, bool w, int index, int npoints ) ++{ ++ QGfxRaster<depth,type>::drawPolygon( a, w, index, npoints ); ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::drawPoint( int x, int y ) ++{ ++ dDrawPoint( tx( x, y ), ty( x, y ) ); ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::dDrawPoint( int x, int y ) ++{ ++ ++ if ( this->ncliprect < 1 ) { ++ return; ++ } ++ ++ if ( depth != 16 || ++ !driver.accelerated( W100Driver::DRAWPOINT) ) { ++ driver.addMiss( W100Driver::DRAWPOINT ); ++ QGfxRaster<depth,type>::drawPoint( x, y ); ++ return; ++ } ++ ++ if ( this->cpen.style() != this->SolidLine || ++ this->myrop != this->CopyROP ) { ++ driver.addMiss( W100Driver::DRAWPOINT ); ++ QGfxRaster<depth,type>::drawPoint( x, y ); ++ return; ++ } ++ ++ QWSDisplay::grab( TRUE ); ++ if ( !checkDest() ) { ++ QWSDisplay::ungrab(); ++ driver.addMiss( W100Driver::DRAWPOINT ); ++ QGfxRaster<depth,type>::drawPoint( x, y ); ++ return; ++ } ++ ++ driver.addHit( W100Driver::DRAWPOINT ); ++ ( *optype ) = 1; ++ ++ ATI_POINT point; ++ point.XCoord = x + this->xoffs; ++ point.YCoord = y + this->yoffs; ++ ++ GFX_START( clipbounds ); ++ driver.setFrgColour( this->cpen.color().rgb() ); ++ driver.setRopOperation( ROP3_PATCOPY ); ++ for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) { ++ ATI_CLIPRECT clip; ++ clip.X_Top_Left = this->cliprect[loopc].x(); ++ clip.Y_Top_Left = this->cliprect[loopc].y(); ++ clip.X_Bottom_Right = this->cliprect[loopc].right() + 1; ++ clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1; ++ driver.setDstClippingRect( &clip ); ++ driver.drawPixel( 1, &point ); ++ } ++ GFX_END; ++ QWSDisplay::ungrab(); ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::drawPoints( const QPointArray &a, ++ int index, ++ int npoints ) ++{ ++ QPointArray na( npoints ); ++ ++ for ( int i = 0; i < npoints; i++ ) { ++ int x, y; ++ a.point( i+index, &x, &y ); ++ na.setPoint( i, tx( x, y ), ty( x, y ) ); ++ } ++ ++ dDrawPoints( na, 0, npoints ); ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::dDrawPoints( const QPointArray &a, ++ int index, ++ int npoints ) ++{ ++ if ( ( this->ncliprect < 1 ) || ( npoints < 1 ) ) { ++ return; ++ } ++ ++ if ( depth != 16 || ++ !driver.accelerated( W100Driver::DRAWPOINTS ) ) { ++ driver.addMiss( W100Driver::DRAWPOINTS ); ++ QGfxRaster<depth,type>::drawPoints( a, index, npoints ); ++ return; ++ } ++ ++ if ( this->cpen.style() != this->SolidLine || ++ this->myrop != this->CopyROP ) { ++ driver.addMiss( W100Driver::DRAWPOINTS ); ++ QGfxRaster<depth,type>::drawPoints( a, index, npoints ); ++ return; ++ } ++ ++ QWSDisplay::grab( TRUE ); ++ if ( !checkDest() ) { ++ QWSDisplay::ungrab(); ++ driver.addMiss( W100Driver::DRAWPOINTS ); ++ QGfxRaster<depth,type>::drawPoints( a, index, npoints ); ++ return; ++ } ++ ++ driver.addHit( W100Driver::DRAWPOINTS ); ++ ( *optype ) = 1; ++ ++ ATI_POINT *points = new ATI_POINT[ npoints ]; ++ for ( int i = 0; i < npoints; i++ ) { ++ points[i].XCoord = a[i+index].x() + this->xoffs; ++ points[i].YCoord = a[i+index].y() + this->yoffs; ++ } ++ ++ GFX_START( clipbounds ); ++ driver.setFrgColour( this->cpen.color().rgb() ); ++ driver.setRopOperation( ROP3_PATCOPY ); ++ for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) { ++ ATI_CLIPRECT clip; ++ clip.X_Top_Left = this->cliprect[loopc].x(); ++ clip.Y_Top_Left = this->cliprect[loopc].y(); ++ clip.X_Bottom_Right = this->cliprect[loopc].right() + 1; ++ clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1; ++ driver.setDstClippingRect( &clip ); ++ driver.drawPixel( npoints, points ); ++ } ++ GFX_END; ++ ++ delete [] points; ++ QWSDisplay::ungrab(); ++} ++ ++template <const int depth, const int type> ++void QGfxW100<depth,type>::scroll( int x, int y, int w, int h, int sx, int sy ) ++{ ++ if ( w == 0 || h == 0 ) ++ return; ++ QRect r; ++ QRect s; ++ if ( inDraw ) { ++ r = QRect( x, y, w, h ); ++ s = QRect( sx, sy, w, h ); ++ } else { ++ r.setCoords( tx(x,y), ty(x,y), tx(x+w-1,y+h-1), ty(x+w-1,y+h-1) ); ++ s.setCoords( tx(sx,sy), ty(sx,sy), tx(sx+w-1,sy+h-1), ty(sx+w-1,sy+h-1) ); ++ r = r.normalize(); ++ s = s.normalize(); ++ } ++ dScroll( r.x(), r.y(), r.width(), r.height(), s.x(), s.y() ); ++} ++ ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::dScroll( int rx, int ry, ++ int w, int h, ++ int sx, int sy ) ++{ ++ if ( depth != 16 || ++ !driver.accelerated( W100Driver::SCROLL ) ) { ++ driver.addMiss( W100Driver::SCROLL ); ++ QGfxRaster<depth,type>::scroll( rx, ry, w, h, sx, sy ); ++ return; ++ } ++ ++ if ( this->ncliprect < 1 ) return; ++ ++ if ( ( w < 1 ) || ( h < 1 ) ) return; ++ ++ int dy = sy - ry; ++ int dx = sx - rx; ++ ++ if ( dx == 0 && dy == 0 ) return; ++ ++ ++ QWSDisplay::grab( TRUE ); ++ ++ if ( checkDest( true ) ) { ++ ++ rx += this->xoffs; ++ sx += this->xoffs; ++ ry += this->yoffs; ++ sy += this->yoffs; ++ ++ QRect boundRect( QMIN( rx , sx ), ++ QMIN( ry , sy ), ++ w + QABS( dx ) + 1, ++ h + QABS( dy ) + 1 ); ++ GFX_START( boundRect ); ++ ( *optype ) = 1; ++ ++ ++ //if ( driver.lastOp() != W100Driver::SCROLL ) { ++ driver.setRopOperation( ROP3_SRCCOPY ); ++ driver.setDstType( DSTTYPE_16BPP_1555 ); ++ driver.setSrcType( SRCTYPE_EQU_DST ); ++ //} ++ ++ driver.addHit( W100Driver::SCROLL ); ++ ++ ATI_RECT srcrect, dstrect; ++ ++ srcrect.XCoord = sx; ++ srcrect.YCoord = sy; ++ srcrect.Width = w; ++ srcrect.Height = h; ++ dstrect.XCoord = rx; ++ dstrect.YCoord = ry; ++ dstrect.Width = w; ++ dstrect.Height = h; ++ for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) { ++ if ( boundRect.intersects( this->cliprect[loopc] ) ) { ++ ATI_CLIPRECT clip; ++ clip.X_Top_Left = this->cliprect[ loopc ].x(); ++ clip.Y_Top_Left = this->cliprect[ loopc ].y(); ++ clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1; ++ clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1; ++ driver.setDstClippingRect( &clip ); ++ driver.bitBlt( 1, &dstrect, &srcrect ); ++ } ++ } ++ GFX_END; ++ QWSDisplay::ungrab(); ++ ++ } else { ++ QWSDisplay::ungrab(); ++ // software fallback ++ driver.addMiss( W100Driver::SCROLL ); ++ QGfxRaster<depth,type>::scroll( rx, ry, w, h, sx, sy ); ++ } ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::fillRect( int x, int y, int w, int h ) ++{ ++ if ( w == 0 || h == 0 ) ++ return; ++ QRect r( x, y, w, h ); ++ r.setCoords( tx( x, y ), ty( x, y ), ++ tx( x + w - 1, y + h - 1 ), ty( x + w - 1, y + h - 1 ) ); ++ r = r.normalize(); ++ inDraw = TRUE; ++ dFillRect( r.x(), r.y(), r.width(), r.height() ); ++ inDraw = FALSE; ++} ++ ++template< const int depth, const int type > ++void QGfxW100< depth, type>::dFillRect( int rx, int ry, int w, int h ) ++{ ++ if ( w <= 0 || h <= 0 || this->ncliprect < 1 ) return; ++ ++ if ( depth != 16 || ++ !driver.accelerated( W100Driver::FILLRECT ) ) { ++ driver.addMiss( W100Driver::FILLRECT ); ++ QGfxRaster<depth,type>::fillRect( rx, ry, w, h ); ++ return; ++ } ++ ++ if ( ( this->cbrush.style() != this->NoBrush ) && ++ ( this->cbrush.style() != this->SolidPattern ) ) { ++ driver.addMiss( W100Driver::FILLRECT ); ++ QGfxRaster<depth,type>::fillRect( rx, ry, w, h ); ++ return; ++ } ++ ++ if ( !checkDest() || ( this->myrop != this->CopyROP ) ) { ++ driver.addMiss( W100Driver::FILLRECT ); ++ QGfxRaster<depth,type>::fillRect( rx, ry, w, h ); ++ return; ++ } ++ ++ QWSDisplay::grab( TRUE ); ++ rx += this->xoffs; ++ ry += this->yoffs; ++ ++ QRect boundRect( rx, ry, w + 1, h + 1 ); ++ GFX_START( boundRect ); ++ ++ ( *optype ) = 1; ++ ++ driver.setDstType( DSTTYPE_16BPP_1555 ); ++ driver.setSrcType( SRCTYPE_EQU_DST ); ++ driver.setRopOperation( ROP3_PATCOPY ); ++ driver.brushType( 6, 0 ); ++ driver.setFrgColour( this->cbrush.color().rgb() ); ++ ++ driver.addHit( W100Driver::FILLRECT ); ++ ++ if ( this->cbrush.style() != this->NoBrush ) { ++ //Using all the cliprects ++ for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) { ++ if ( boundRect.intersects( this->cliprect[loopc] ) ) { ++ ATI_CLIPRECT clip; ++ ATI_RECT rect; ++ ++ clip.X_Top_Left = this->cliprect[ loopc ].x(); ++ clip.Y_Top_Left = this->cliprect[ loopc ].y(); ++ clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1; ++ clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1; ++ ++ driver.setDstClippingRect( &clip ); ++ rect.XCoord = rx; ++ rect.YCoord = ry; ++ rect.Width = w; ++ rect.Height = h; ++ driver.paintRect( 1, &rect ); ++ } ++ } ++ } ++ GFX_END; ++ ++ QWSDisplay::ungrab(); ++} ++ ++template <const int depth, const int type> ++void QGfxW100<depth,type>::blt( int x, int y, int w, int h, int sx, int sy ) ++{ ++ if ( w == 0 || h == 0 ) ++ return; ++ QRect r; ++ int rsx; ++ int rsy; ++ if ( inDraw ) { ++ r = QRect( x, y, w, h ); ++ rsx = sx; ++ rsy = sy; ++ } else { ++ r.setCoords( tx(x,y), ty(x,y), tx(x+w-1,y+h-1), ty(x+w-1,y+h-1) ); ++ r = r.normalize(); ++ switch ( qt_w100_screen->transformation() ) { ++ case QW100Screen::Rot90: ++ rsx = sy; ++ rsy = this->srcwidth - sx - w; ++ break; ++ case QW100Screen::Rot180: ++ rsx = this->srcwidth - sx - w; ++ rsy = this->srcheight - sy - h; ++ break; ++ case QW100Screen::Rot270: ++ rsx = this->srcheight - sy - h; ++ rsy = sx; ++ break; ++ default: ++ rsx = sx; ++ rsy = sy; ++ break; ++ } ++ } ++ dBlt( r.x(), r.y(), r.width(), r.height(), rsx, rsy ); ++} ++ ++template< const int depth, const int type > ++inline void QGfxW100< depth, type>::dBlt( int rx, int ry, ++ int w, int h, ++ int sx, int sy ) ++{ ++ if ( !w || !h || this->ncliprect < 1 ) { ++ return; ++ } ++ ++ if ( depth != 16 || ++ !driver.accelerated( W100Driver::BITBLT ) ) { ++ driver.addMiss( W100Driver::BITBLT ); ++ QGfxRaster<depth,type>::blt( rx, ry, w, h, sx, sy ); ++ return; ++ } ++ ++ if ( this->alphatype == this->BigEndianMask || ++ this->alphatype == this->LittleEndianMask || ++ this->alphatype == this->SeparateAlpha || ++ this->srctype == this->SourcePen || ++ ( this->myrop != this->CopyROP ) ) { ++ driver.addMiss( W100Driver::BITBLT ); ++ QGfxRaster<depth,type>::blt( rx, ry, w, h, sx, sy ); ++ return; ++ } ++ ++ if ( ( this->srcdepth != 16 ) || this->alphatype != this->IgnoreAlpha ) { ++ driver.addMiss( W100Driver::BITBLT ); ++ QGfxRaster<depth,type>::blt( rx, ry, w, h, sx, sy ); ++ return; ++ } ++ ++ QWSDisplay::grab( TRUE ); ++ ++ if ( checkSourceDest() ) { ++ QRect boundRect( rx + this->xoffs, ry + this->yoffs, ++ w + 1, h + 1 ); ++ GFX_START( boundRect ); ++ ( *optype ) = 1; ++ ++ driver.setRopOperation( ROP3_SRCCOPY ); ++ driver.setDstType( DSTTYPE_16BPP_1555 ); ++ driver.setSrcType( SRCTYPE_EQU_DST ); ++ ++ driver.addHit( W100Driver::BITBLT ); ++ ++ ATI_RECT rect1; ++ ATI_RECT rect2; ++ ++ rx += this->xoffs; ++ ry += this->yoffs; ++ ++ rect1.XCoord = this->srcwidgetoffs.x() + sx; ++ rect1.YCoord = this->srcwidgetoffs.y() + sy; ++ rect1.Width = w; ++ rect1.Height = h; ++ rect2.XCoord = rx; ++ rect2.YCoord = ry; ++ rect2.Width = w; ++ rect2.Height = h; ++ for(int loopc = 0; loopc < this->ncliprect; loopc++ ) { ++ if ( boundRect.intersects( this->cliprect[loopc] ) ) { ++ ATI_CLIPRECT clip; ++ clip.X_Top_Left = this->cliprect[ loopc ].x(); ++ clip.Y_Top_Left = this->cliprect[ loopc ].y(); ++ clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1; ++ clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1; ++ driver.setDstClippingRect( &clip ); ++ driver.bitBlt( 1, &rect2, &rect1 ); ++ } ++ } ++ GFX_END; ++ ++ QWSDisplay::ungrab(); ++ return; ++ } else { ++ QWSDisplay::ungrab(); ++ driver.addMiss( W100Driver::BITBLT ); ++ QGfxRaster<depth,type>::blt( rx, ry, ++ w, h, sx, sy ); ++ } ++} ++ ++ ++template <const int depth, const int type> ++void QGfxW100<depth,type>::tiledBlt( int rx,int ry,int w,int h ) ++{ ++ if ( w <= 0 || h <= 0 ) ++ return; ++ QRect r; ++ if ( inDraw ) { ++ r = QRect(rx,ry,w,h); ++ } else { ++ r.setCoords( tx(rx,ry), ty(rx,ry), tx(rx+w-1,ry+h-1), ty(rx+w-1,ry+h-1) ); ++ r = r.normalize(); ++ } ++ ++ inDraw = TRUE; ++ ++ QPoint oldBrushOffs = this->brushoffs; ++ int brx, bry; ++ switch ( qt_w100_screen->transformation() ) { ++ case QW100Screen::Rot90: ++ brx = this->brushoffs.y(); ++ bry = this->srcwidth - this->brushoffs.x() - w; ++ break; ++ case QW100Screen::Rot180: ++ brx = this->srcwidth - this->brushoffs.x() - w; ++ bry = this->srcheight - this->brushoffs.y() - h; ++ break; ++ case QW100Screen::Rot270: ++ brx = this->srcheight - this->brushoffs.y() - h; ++ bry = this->brushoffs.x(); ++ break; ++ default: ++ brx = this->brushoffs.x(); ++ bry = this->brushoffs.y(); ++ break; ++ } ++ this->brushoffs = QPoint( brx, bry ); ++ ++ int oldsw = this->srcwidth; ++ int oldsh = this->srcheight; ++ QSize s = qt_screen->mapToDevice( QSize(this->srcwidth,this->srcheight) ); ++ this->srcwidth = s.width(); ++ this->srcheight = s.height(); ++ ++ dTiledBlt( r.x(), r.y(), r.width(), r.height() ); ++ ++ this->srcwidth = oldsw; ++ this->srcheight = oldsh; ++ this->brushoffs = oldBrushOffs; ++ inDraw = FALSE; ++} ++ ++ ++template <const int depth, const int type> ++void QGfxW100<depth,type>::dTiledBlt( int rx,int ry, int w,int h ) ++{ ++ if ( this->srcwidth == 0 || this->srcheight == 0 ) ++ return; ++ QGfxRaster<depth,type>::tiledBlt( rx, ry, w, h ); ++} ++ ++template<const int depth,const int type> ++void QGfxW100<depth,type>::sync() ++{ ++ driver.waitComplete( -1 ); ++} ++ ++template <const int depth, const int type> ++void QGfxW100<depth,type>::setSourceWidgetOffset(int x, int y) ++{ ++ if ( this->srcbits == this->buffer ) { ++ switch ( qt_w100_screen->transformation() ) { ++ case QW100Screen::Rot90: ++ this->srcwidgetoffs = QPoint( y, this->width - x - this->srcwidth ); ++ break; ++ case QW100Screen::Rot180: ++ this->srcwidgetoffs = QPoint( this->width - x - this->srcwidth, this->height - y - this->srcheight ); ++ break; ++ case QW100Screen::Rot270: ++ this->srcwidgetoffs = QPoint( this->height - y - this->srcheight, x ); ++ break; ++ default: ++ this->srcwidgetoffs = QPoint( x, y ); ++ break; ++ } ++ } else { ++ this->srcwidgetoffs = QPoint( x, y ); ++ } ++} ++ ++template <const int depth, const int type> ++void QGfxW100<depth,type>::processSpans( int n, QPoint* point, int* width ) ++{ ++ if ( inDraw || ++ this->patternedbrush && ++ this->srcwidth != 0 && ++ this->srcheight != 0 ) { ++ //in the patternedbrush case, we let blt do the transformation ++ // so we leave inDraw false. ++ QGfxRaster<depth,type>::processSpans( n, point, width ); ++ } else { ++ inDraw = true; ++ while (n--) { ++ if ( *width > 0 ) { ++ int x=tx(point->x(),point->y())+this->xoffs; ++ int y=ty(point->x(),point->y())+this->yoffs; ++ ++ switch( qt_w100_screen->transformation() ) { ++ case QW100Screen::Rot90: ++ this->vline( x, y-(*width-1), y ); ++ break; ++ case QW100Screen::Rot180: ++ this->hline( x - (*width-1), x, y ); ++ break; ++ case QW100Screen::Rot270: ++ this->vline( x, y, y+*width-1 ); ++ break; ++ default: ++ this->hline( x, x+*width-1, y ); ++ break; ++ } ++ } ++ point++; ++ width++; ++ } ++ inDraw = false; ++ } ++} ++ ++QW100Screen::QW100Screen( int display_id ) ++ :QLinuxFbScreen( display_id ), ++ vramoffset( 0 ), ++ m_isServer( false ) ++{ ++ qt_w100_screen = this; ++ vramoffset = 0; ++ clearCacheFunc = &clearCache; ++ trans = None; ++} ++ ++static const char *trans2str( QW100Screen::Transformation t ) ++{ ++ switch( t ) { ++ case QW100Screen::None: ++ return "None"; ++ break; ++ case QW100Screen::Rot90: ++ return "Rot90"; ++ break; ++ case QW100Screen::Rot180: ++ return "Rot180"; ++ break; ++ case QW100Screen::Rot270: ++ return "Rot270"; ++ break; ++ default: ++ return "Unknown"; ++ break; ++ } ++} ++ ++QW100Screen::Transformation QW100Screen::getTransSpec( const QString &dspec ) ++{ ++ Transformation mytrans = None; ++ if ( dspec.find( ":Rot270" ) >= 0 ) { ++ mytrans = Rot270; ++ } else if ( dspec.find( ":Rot180" ) >= 0 ) { ++ mytrans = Rot180; ++ } else if ( dspec.find( ":Rot90" ) >= 0 ) { ++ mytrans = Rot90; ++ } ++ return mytrans; ++} ++ ++bool QW100Screen::connect( const QString &displaySpec ) ++{ ++ driver.log( W100Driver::WARNING, "QW100Screen::connect('%s')", ++ displaySpec.latin1() ); ++ trans = getTransSpec( displaySpec ); ++ ++ if ( QLinuxFbScreen::connect( displaySpec ) ) { ++ vramoffset = ( w == 320 ) ? 0 : 0x0f000000; ++ if ( driver.processAttach() == W100Driver::codOK ) { ++ driver.processAttachSpecialMode( ( w == 480 ) ? 0xaaab : 0xaaaa ); ++ surfaceMap.clear(); ++ surfaceMap.insert( 0, HWSurface( vramoffset, ++ data , false, ++ w*h*d/8 ) ); ++ canaccel = true; ++ QSize s = mapFromDevice( QSize( w, h ) ); ++ w = s.width(); ++ h = s.height(); ++ return true; ++ } ++ } ++ return false; ++} ++ ++void QW100Screen::disconnect( void ) ++{ ++ driver.log( W100Driver::WARNING, "QW100Screen::disconnect()" ); ++ driver.processDetachSpecialMode(); ++ driver.processDetach(); ++ QLinuxFbScreen::disconnect(); ++ printf( "[%d]QW100Screen disconnected with %d surfaces\n", ++ getpid(), surfaceMap.count() ); ++ surfaceMap.clear(); ++} ++ ++void QW100Screen::prepareToSuspend( void ) ++{ ++ ++ driver.log( W100Driver::WARNING, ++ "QW100Screen::prepareToSuspend. Server = %s", ++ m_isServer ? "true" : "false" ); ++ ++ QWSDisplay::grab( true ); ++ driver.waitComplete( -1 ); ++ ++ if ( !driver.attached() ) { ++ driver.log( W100Driver::ERROR, "Driver was not attached. " ); ++ } else { ++ driver.processDetachSpecialMode(); ++ driver.processDetach(); ++ } ++ QWSDisplay::ungrab(); ++ ++ driver.log( W100Driver::WARNING, "prepareToSuspend done" ); ++ ++} ++ ++void QW100Screen::prepareToResume( void ) ++{ ++ ++ driver.log( W100Driver::WARNING, ++ "QW100Screen::prepareToResume. Server = %s", ++ m_isServer ? "true": "false" ); ++ ++ driver.processAttach(); ++ driver.processAttachSpecialMode( ( w == 480 ) ? 0xaaab : 0xaaaa ); ++ if ( m_isServer ) { ++ QWSDisplay::grab( true ); ++ w100init(); ++ QWSDisplay::ungrab(); ++ driver.log( W100Driver::WARNING, "W100 restarted" ); ++ } ++ driver.log( W100Driver::WARNING, "prepareToResume done" ); ++ ++} ++ ++QW100Screen::~QW100Screen() ++{ ++} ++ ++bool QW100Screen::w100init() ++{ ++ driver.log( W100Driver::WARNING, ++ "QW100Screen::w100init(%dx%d)", dw, dh ); ++ ATI_GRAPHICWINDOW win; ++ ATI_CLIPRECT clip; ++ uint16_t overlay; ++ ++ win.dummy1 = 0; ++ win.Size.XCoord = 0; ++ win.Size.YCoord = 0; ++ win.Size.Width = dw; ++ win.Size.Height = dh; ++ win.Width = dw > dh ? dh : dw; ++ win.Height = dw > dh ? dw : dh; ++ win.Flag = DSTTYPE_16BPP_444; ++ ++ driver.waitComplete( -1 ); ++ driver.setGraphicWindowOnOff( 0 ); ++ ++ driver.setupGraphicWindow( &win ); ++ driver.setGraphicWindowPos( 0, 0 ); ++ ++ driver.setFrontBuffer( vramoffset, 0, 0 ); ++ driver.setDstPitchOffset( dw, vramoffset ); ++ driver.setDstType( DSTTYPE_16BPP_444 ); ++ driver.setSrcPitchOffset( dw, vramoffset ); ++ driver.setSrcType( SRCTYPE_SOLID_COLOR_BLT ); ++ clip.X_Top_Left = 0; ++ clip.Y_Top_Left = 0; ++ clip.X_Bottom_Right = dw; ++ clip.Y_Bottom_Right = dh; ++ driver.setDstClippingRect( &clip ); ++ ++ clip.X_Top_Left = 0xE000; ++ clip.Y_Top_Left = 0xE000; ++ clip.X_Bottom_Right = 0x1FFF; ++ clip.Y_Bottom_Right = 0x1FFF; ++ ++ driver.setSrcClippingRect( &clip ); ++ ++ driver.setRopOperation( ROP3_SRCCOPY ); ++ driver.setGraphicWindowOnOff( 1 ); ++ driver.allocOverlay( &overlay ); ++ driver.setOverlayOnOff( overlay, 0 ); ++ driver.releaseOverlay( overlay ); ++ driver.setDstPitchOffset( dw, vramoffset ); ++ driver.setDstClippingRect( NULL ); ++ for ( int i = 0; i < dw * dh ; i++ ) { ++ *( data + i ) = 0; ++ } ++ driver.waitComplete( -1 ); ++ return true; ++} ++ ++void QW100Screen::w100shutdown() ++{ ++} ++ ++bool QW100Screen::initDevice() ++{ ++ QWSDisplay::grab( true ); ++ driver.log( W100Driver::WARNING, "initDevice( dw=%d, dh=%d )", ++ dw, dh ); ++ m_isServer = true; ++ ++ if ( !w100init() ) { ++ QWSDisplay::ungrab(); ++ return false; ++ } ++ ++ if ( QLinuxFbScreen::initDevice() ) { ++ //HACK ++ //Some sprite corruption seems to be avoided ++ //reserving some upper memory on the offscreen framebuffer memory ++ QLinuxFbScreen::cache( 65535 * 2, 0 ); ++ QWSDisplay::ungrab(); ++ return true; ++ } ++ QWSDisplay::ungrab(); ++ return false; ++} ++ ++void QW100Screen::shutdownDevice() ++{ ++ driver.log( W100Driver::WARNING, "Shutting down device" ); ++ QLinuxFbScreen::shutdownDevice(); ++} ++ ++void QW100Screen::restore() ++{ ++ driver.log( W100Driver::WARNING, "Restoring W100..." ); ++ QLinuxFbScreen::restore(); ++ driver.log( W100Driver::WARNING, "Restoring done" ); ++} ++ ++ ++QGfx *QW100Screen::createGfx( unsigned char *b, ++ int w, int h, int d, int linestep ) ++{ ++ //We need ALL the gfx created to be QGfxW100 to allow software ++ //drawing syncing after hardware operations ++ QGfx * ret=0; ++ if ( false ) { ++#ifndef QT_NO_QWS_DEPTH_1 ++ } else if ( d == 1 ) { ++ ret = new QGfxW100<1,0>( b, w, h ); ++#endif ++#ifndef QT_NO_QWS_DEPTH_4 ++ } else if ( d == 4 ) { ++ ret = new QGfxW100<4,0>( b, w, h ); ++#endif ++#ifndef QT_NO_QWS_DEPTH_8 ++ } else if ( d == 8 ) { ++ ret = new QGfxW100<8,0>( b, w, h ); ++#endif ++#ifndef QT_NO_QWS_DEPTH_16 ++ } else if ( d == 16 ) { ++ ret = new QGfxW100<16,0>( b, w, h ); ++#endif ++#ifndef QT_NO_QWS_DEPTH_24 ++ } else if ( d == 24 ) { ++ ret = new QGfxW100<24,0>( b, w, h ); ++#endif ++#ifndef QT_NO_QWS_DEPTH_32 ++ } else if ( d == 32 ) { ++ ret = new QGfxW100<32,0>( b, w, h ); ++#endif ++ } else { ++ qFatal( "Unsupported depth %d\n", d ); ++ ret = 0; ++ } ++ ++ ret->setLineStep( linestep ); ++ return ret; ++} ++ ++ ++uchar *QW100Screen::cache( int amount, int optim ) ++{ ++ unsigned short hSurface = 0; ++ uint32_t surfaceOffset = 0; ++ uchar* localAddr = 0; ++ bool internal = false; ++ ++ /* The size must have 0xF bit zeroed (16 multiple)*/ ++ /* Perhaps this is not needed anymore, after setting ++ * QW100Screen::pixmapLinestepAlignment to 128 ++ */ ++ amount = ( amount & 0x0F ) ? ( amount | 0x10 ) & ~0x0F : amount; ++ ++ /* Experimenting memory corruption with the ++ * internal AtiCore memory allocation routines ++ * disabled for now ++ */ ++#if 1 ++ if ( !( localAddr = QLinuxFbScreen::cache( amount, optim ) ) ) { ++ return( 0 ); ++ } ++ surfaceOffset = vramoffset + ( uint32_t ) localAddr - ( uint32_t )data; ++ ++#else ++ int retcode = 0; ++ qt_fbdpy->grab( true ); ++ retcode = driver.allocateSurface( &hSurface, ++ &surfaceOffset, ++ amount, 1 ); ++ qt_fbdpy->ungrab(); ++ if ( retcode ) { ++ internal = true; ++ driver.setupMemoryTransfer( surfaceOffset, ++ (uint32_t*) &localAddr ); ++ driver.terminateMemoryTransfer(); ++ } else { ++ // Try to use the offscreen framebuffer memory ++ // to allocate the surface. Use the qgfxlinuxfb routines ++ if ( !( localAddr = QLinuxFbScreen::cache( amount, optim ) ) ) { ++ return( 0 ); ++ } ++ //Distance between physical vram start and surface should be ++ //the same than distance between logical addresses ++ surfaceOffset = vramoffset + ( uint32_t ) localAddr - ( uint32_t ) data; ++ } ++#endif ++ ++ HWSurface surface( hSurface, surfaceOffset, ++ localAddr, amount, ++ internal, ++ qws_client_id ); ++ surfaceMap.insert( surface.getAddr(), surface ); ++ return( ( uchar* ) localAddr ); ++} ++ ++void QW100Screen::uncache( uchar *c ) ++{ ++ QMap< uchar*, HWSurface >::Iterator itr; ++ if ( ( itr = surfaceMap.find( c ) ) != surfaceMap.end() ) { ++ driver.waitComplete( -1 ); ++ if ( itr.data().internal() ) { ++ qt_fbdpy->grab( true ); ++ driver.destroySurface( itr.data().getHandle() ); ++ qt_fbdpy->ungrab(); ++ } else { ++ QLinuxFbScreen::uncache( c ); ++ } ++ surfaceMap.remove( itr ); ++ } ++} ++ ++bool QW100Screen::onCard( uchar *p ) const ++{ ++ QMap< uchar*, HWSurface >::ConstIterator itr = surfaceMap.begin(); ++ for ( ; itr != surfaceMap.end(); itr++ ) { ++ uchar *begin; ++ if ( ( begin = itr.data().getAddr() ) <= p ) { ++ if ( ( itr.data().getSize() + begin ) >= p ) { ++ return TRUE; ++ } ++ } ++ } ++ return FALSE; ++} ++ ++bool QW100Screen::onCard( unsigned char *p, ulong& offset ) const ++{ ++ QMap< uchar*, HWSurface >::ConstIterator itr; ++ for ( itr = surfaceMap.begin(); itr != surfaceMap.end(); itr++ ) { ++ uchar *begin; ++ if ( ( begin = itr.data().getAddr() ) <= p ) { ++ if ( ( itr.data().getSize() + begin ) >= p ) { ++ offset = itr.data().getSOffset() + ( p - begin ); ++ return TRUE; ++ } ++ } ++ } ++ return FALSE; ++} ++ ++QMap< uchar*, QW100Screen::HWSurface > ++*QW100Screen::getPSurfaceMap( void ) const ++{ ++ return ( QMap<uchar*,HWSurface> *) &surfaceMap; ++} ++ ++void QW100Screen::clearCache( int clientId ) ++{ ++ printf( "[%d] CLEARING CACHE FOR %d\n", getpid(), clientId ); ++ driver.log( W100Driver::WARNING, "Cleaning cache for '%d'", clientId ); ++ QMap< uchar*, HWSurface >::Iterator itr = surfaceMap.begin(); ++ while ( itr != surfaceMap.end() ) { ++ if ( itr.data().getCId() == clientId ) { ++ if ( itr.data().internal() ) { ++ qt_fbdpy->grab(); ++ driver.destroySurface( itr.data().getHandle() ); ++ qt_fbdpy->ungrab(); ++ } ++ surfaceMap.remove( itr ); ++ } ++ itr++; ++ } ++ QLinuxFbScreen::clearCache( this, clientId ); ++} ++ ++void QW100Screen::clearCache( QScreen *instance, int clientId ) ++{ ++ QW100Screen *screen = reinterpret_cast<QW100Screen *> ( instance ); ++ screen->clearCache( clientId ); ++} ++ ++void QW100Screen::setTransformation( Transformation t ) ++{ ++ qt_fbdpy->grab( true ); ++ trans = t; ++ ++ QSize s = mapFromDevice( QSize( dw,dh ) ); ++ w = s.width(); ++ h = s.height(); ++ qt_fbdpy->ungrab(); ++} ++ ++QW100Screen::Transformation QW100Screen::transformation( void ) const ++{ ++ return trans; ++} ++ ++QSize QW100Screen::mapToDevice( const QSize &s ) const ++{ ++ if ( trans == Rot90 || trans == Rot270 ) { ++ return QSize( s.height(), s.width() ); ++ } ++ ++ return s; ++} ++ ++QSize QW100Screen::mapFromDevice( const QSize &s ) const ++{ ++ if ( trans == Rot90 || trans == Rot270 ) { ++ return QSize( s.height(), s.width() ); ++ } ++ ++ return s; ++} ++ ++QPoint QW100Screen::mapToDevice( const QPoint &p, const QSize &s ) const ++{ ++ QPoint rp( p ); ++ ++ switch ( trans ) { ++ case Rot90: ++ rp.setX( p.y() ); ++ rp.setY( s.width() - p.x() - 1 ); ++ break; ++ case Rot180: ++ rp.setX( s.width() - p.x() - 1 ); ++ rp.setY( s.height() - p.y() - 1 ); ++ break; ++ case Rot270: ++ rp.setX( s.height() - p.y() - 1 ); ++ rp.setY( p.x() ); ++ break; ++ default: ++ break; ++ } ++ ++ return rp; ++} ++ ++QPoint QW100Screen::mapFromDevice( const QPoint &p, const QSize &s ) const ++{ ++ QPoint rp( p ); ++ ++ switch ( trans ) { ++ case Rot90: ++ rp.setX( s.height() - p.y() - 1 ); ++ rp.setY( p.x() ); ++ break; ++ case Rot180: ++ rp.setX( s.width() - p.x() - 1 ); ++ rp.setY( s.height() - p.y() - 1 ); ++ break; ++ case Rot270: ++ rp.setX( p.y() ); ++ rp.setY( s.width() - p.x() - 1 ); ++ break; ++ default: ++ break; ++ } ++ ++ return rp; ++} ++ ++QRect QW100Screen::mapToDevice( const QRect &r, const QSize &s ) const ++{ ++ QRect tr; ++ switch ( trans ) { ++ case Rot90: ++ tr.setCoords( r.y(), s.width() - r.x() - 1, ++ r.bottom(), s.width() - r.right() - 1 ); ++ break; ++ case Rot180: ++ tr.setCoords( s.width() - r.x() - 1, s.height() - r.y() - 1, ++ s.width() - r.right() - 1, s.height() - r.bottom() - 1 ); ++ break; ++ case Rot270: ++ tr.setCoords( s.height() - r.y() - 1, r.x(), ++ s.height() - r.bottom() - 1, r.right() ); ++ break; ++ default: ++ tr = r; ++ break; ++ } ++ ++ return tr.normalize(); ++} ++ ++QRect QW100Screen::mapFromDevice( const QRect &r, const QSize &s ) const ++{ ++ QRect tr; ++ switch ( trans ) { ++ case Rot90: ++ tr.setCoords( s.height() - r.y() - 1, r.x(), ++ s.height() - r.bottom() - 1, r.right() ); ++ break; ++ case Rot180: ++ tr.setCoords( s.width() - r.x() - 1, s.height() - r.y() - 1, ++ s.width() - r.right() - 1, s.height() - r.bottom() - 1 ); ++ break; ++ case Rot270: ++ tr.setCoords( r.y(), s.width() - r.x() - 1, ++ r.bottom(), s.width() - r.right() - 1 ); ++ break; ++ default: ++ tr = r; ++ break; ++ } ++ ++ return tr.normalize(); ++} ++ ++template<class T> ++static inline void rotateLoopTemplate( uchar *src, int srcBytesPerLine, ++ uchar *dst, int dstBytesPerLine, ++ int width, int height, ++ QW100Screen::Transformation trans, ++ bool mapToDevice ) ++{ ++ int dstXAdd = 0; ++ int dstYAdd = 0; ++ int dstXOfs = 0; ++ int dstYOfs = 0; ++ int srcYAdd = srcBytesPerLine - width * sizeof(T); ++ ++ if ( !mapToDevice ) { ++ if ( trans == QW100Screen::Rot90 ) ++ trans = QW100Screen::Rot270; ++ else if ( trans == QW100Screen::Rot270 ) ++ trans = QW100Screen::Rot90; ++ } ++ ++ switch ( trans ) { ++ case QW100Screen::Rot90: ++ dstXOfs = 0; ++ dstYOfs = width - 1; ++ dstXAdd = -dstBytesPerLine; ++ dstYAdd = 1 * sizeof(T) + width * dstBytesPerLine; ++ break; ++ case QW100Screen::Rot270: ++ dstXOfs = height - 1; ++ dstYOfs = 0; ++ dstXAdd = dstBytesPerLine; ++ dstYAdd = -1 * sizeof(T) - width * dstBytesPerLine; ++ break; ++ default: ++ dstXOfs = width - 1; ++ dstYOfs = height - 1; ++ dstXAdd = -1 * sizeof(T); ++ dstYAdd = -dstBytesPerLine + width * sizeof(T); ++ break; ++ }; ++ ++ T *dstPtr = (T *)(dst + dstYOfs * dstBytesPerLine) + dstXOfs; ++ T *srcPtr = (T *)src; ++ for ( int y = 0; y < height; y++ ) { ++ for ( int x = 0; x < width; x++ ) { ++ *dstPtr = *srcPtr++; ++ dstPtr = (T *)((uchar*)dstPtr + dstXAdd); // add dstXAdd number of bytes ++ } ++ srcPtr = (T *)((uchar*)srcPtr + srcYAdd); // add srcYAdd number of bytes ++ dstPtr = (T *)((uchar*)dstPtr + dstYAdd); // add dstYAdd number of bytes ++ } ++} ++ ++QImage QW100Screen::mapToDevice( const QImage &img ) const ++{ ++ if ( img.isNull() || trans == None ) ++ return img; ++ ++ int iw = img.width(); ++ int ih = img.height(); ++ int w = iw; ++ int h = ih; ++ if ( trans == Rot90 || trans == Rot270 ) { ++ w = ih; ++ h = iw; ++ } ++ ++ QImage rimg( w, h, img.depth(), img.numColors(), img.bitOrder() ); ++ ++ for ( int i = 0; i < img.numColors(); i++ ) { ++ rimg.colorTable()[i] = img.colorTable()[i]; ++ } ++ ++ // Optimized image rotation code for nice bit depths ++ int d = img.depth(); ++ if ( d == 8 || d == 16 || d == 32 ) { ++ int srcBytesPerLine = img.bytesPerLine(); ++ int dstBytesPerLine = rimg.bytesPerLine(); ++ uchar *srcBits = img.bits(); ++ uchar *dstBits = rimg.bits(); ++ switch ( d ) { ++ case 8: ++ rotateLoopTemplate<uchar>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, TRUE ); ++ break; ++ case 16: ++ rotateLoopTemplate<ushort>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, TRUE ); ++ break; ++ case 32: ++ rotateLoopTemplate<uint>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, TRUE ); ++ break; ++ } ++ rimg.setAlphaBuffer( img.hasAlphaBuffer() ); ++ rimg.setOffset( img.offset() ); ++ return rimg; ++ } ++ ++ // Slower fall back code for image rotation for 1-bit and other depths ++#define ROTATE_LOOP( X, Y, VAL ) \ ++ for ( int y = 0; y < ih; y++ ) { \ ++ for ( int x = 0; x < iw; x++ ) { \ ++ rimg.setPixel( X, Y, VAL ); \ ++ } \ ++ } \ ++ break; ++ ++ if ( img.depth() > 8 ) { ++ switch ( trans ) { ++ case Rot90: ++ ROTATE_LOOP( y, iw - x - 1, img.pixel(x, y) ) ++ case Rot270: ++ ROTATE_LOOP( ih - y - 1, x, img.pixel(x, y) ); ++ default: ++ ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixel(x, y) ); ++ } ++ } else { ++ switch ( trans ) { ++ case Rot90: ++ ROTATE_LOOP( y, iw - x - 1, img.pixelIndex(x, y) ); ++ case Rot270: ++ ROTATE_LOOP( ih - y - 1, x, img.pixelIndex(x, y) ); ++ default: ++ ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixelIndex(x, y) ); ++ } ++ } ++ ++#undef ROTATE_LOOP ++ ++ rimg.setAlphaBuffer( img.hasAlphaBuffer() ); ++ rimg.setOffset( img.offset() ); ++ ++ return rimg; ++} ++ ++QImage QW100Screen::mapFromDevice( const QImage &img ) const ++{ ++ if ( img.isNull() || trans == None ) ++ return img; ++ ++ int iw = img.width(); ++ int ih = img.height(); ++ int w = iw; ++ int h = ih; ++ if ( trans == Rot90 || trans == Rot270 ) { ++ w = ih; ++ h = iw; ++ } ++ ++ QImage rimg( w, h, img.depth(), img.numColors(), img.bitOrder() ); ++ ++ for ( int i = 0; i < img.numColors(); i++ ) { ++ rimg.colorTable()[i] = img.colorTable()[i]; ++ } ++ ++ // Optimized image rotation code for nice bit depths ++ int d = img.depth(); ++ if ( d == 8 || d == 16 || d == 32 ) { ++ int srcBytesPerLine = img.bytesPerLine(); ++ int dstBytesPerLine = rimg.bytesPerLine(); ++ uchar *srcBits = img.bits(); ++ uchar *dstBits = rimg.bits(); ++ switch ( d ) { ++ case 8: ++ rotateLoopTemplate<uchar>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, FALSE ); ++ break; ++ case 16: ++ rotateLoopTemplate<ushort>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, FALSE ); ++ break; ++ case 32: ++ rotateLoopTemplate<uint>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, FALSE ); ++ break; ++ } ++ rimg.setAlphaBuffer( img.hasAlphaBuffer() ); ++ rimg.setOffset( img.offset() ); ++ return rimg; ++ } ++ ++ // Slower fall back code for image rotation for 1-bit and other depths ++#define ROTATE_LOOP( X, Y, VAL ) \ ++ for ( int y = 0; y < ih; y++ ) { \ ++ for ( int x = 0; x < iw; x++ ) { \ ++ rimg.setPixel( X, Y, VAL ); \ ++ } \ ++ } \ ++ break; ++ ++ if ( img.depth() > 8 ) { ++ switch ( trans ) { ++ case Rot90: ++ ROTATE_LOOP( ih - y - 1, x, img.pixel(x, y) ); ++ case Rot270: ++ ROTATE_LOOP( y, iw - x - 1, img.pixel(x, y) ) ++ default: ++ ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixel(x, y) ); ++ } ++ } else { ++ switch ( trans ) { ++ case Rot90: ++ ROTATE_LOOP( ih - y - 1, x, img.pixelIndex(x, y) ); ++ case Rot270: ++ ROTATE_LOOP( y, iw - x - 1, img.pixelIndex(x, y) ); ++ default: ++ ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixelIndex(x, y) ); ++ } ++ } ++ ++#undef ROTATE_LOOP ++ ++ rimg.setAlphaBuffer( img.hasAlphaBuffer() ); ++ rimg.setOffset( img.offset() ); ++ ++ return rimg; ++} ++ ++QRegion QW100Screen::mapToDevice( const QRegion &rgn, const QSize &s ) const ++{ ++ if ( trans == None ) ++ return rgn; ++ ++ QRegion trgn; ++ QArray<QRect> a = rgn.rects(); ++ QRect tr; ++ const QRect *r = a.data(); ++ ++ int w = s.width(); ++ int h = s.height(); ++ int size = a.size(); ++ ++ switch ( trans ) { ++ case Rot270: ++ for ( int i = 0; i < size; i++, r++ ) { ++ tr.setCoords( h - r->y() - 1, r->x(), ++ h - r->bottom() - 1, r->right() ); ++ trgn |= tr.normalize(); ++ } ++ break; ++ case Rot90: ++ for ( int i = 0; i < size; i++, r++ ) { ++ tr.setCoords( r->y(), w - r->x() - 1, ++ r->bottom(), w - r->right() - 1 ); ++ trgn |= tr.normalize(); ++ } ++ break; ++ case Rot180: ++ for ( int i = 0; i < size; i++, r++ ) { ++ tr.setCoords( w - r->x() - 1, h - r->y() - 1, ++ w - r->right() - 1, h - r->bottom() - 1 ); ++ trgn |= tr.normalize(); ++ } ++ break; ++ default: ++ break; ++ } ++ return trgn; ++} ++ ++QRegion QW100Screen::mapFromDevice( const QRegion &rgn, const QSize &s ) const ++{ ++ if ( trans == None ) ++ return rgn; ++ ++ QRegion trgn; ++ QArray<QRect> a = rgn.rects(); ++ const QRect *r = a.data(); ++ QRect tr; ++ ++ int w = s.width(); ++ int h = s.height(); ++ int size = a.size(); ++ ++ switch ( trans ) { ++ case Rot270: ++ for ( int i = 0; i < size; i++, r++ ) { ++ tr.setCoords( r->y(), w - r->x() - 1, ++ r->bottom(), w - r->right() - 1 ); ++ trgn |= tr.normalize(); ++ } ++ break; ++ case Rot90: ++ for ( int i = 0; i < size; i++, r++ ) { ++ tr.setCoords( h - r->y() - 1, r->x(), ++ h - r->bottom() - 1, r->right() ); ++ trgn |= tr.normalize(); ++ } ++ break; ++ case Rot180: ++ for ( int i = 0; i < size; i++, r++ ) { ++ tr.setCoords( w - r->x() - 1, h - r->y() - 1, ++ w - r->right() - 1, h - r->bottom() - 1 ); ++ trgn |= tr.normalize(); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return trgn; ++} ++ ++/*! ++ 0 = none ++ 1..3 = rotates 90..270 ++ 4..7 = mirrored 0..3 ++*/ ++int QW100Screen::transformOrientation() const ++{ ++ return (int)trans; ++} ++ ++ ++void qws_w100Transformation( int t ) ++{ ++ if ( qt_w100_screen ) { ++ qt_w100_screen->setTransformation( static_cast<QW100Screen::Transformation>( t ) ); ++ } ++} ++ ++extern bool qws_accel; ++ ++extern "C" QScreen * qt_get_screen_w100( int display_id ) ++{ ++ return( new QW100Screen( display_id ) ); ++} +Index: qt-2.3.10-snapshot-20060120/src/kernel/qapplication_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qapplication_qws.cpp 2006-01-20 20:48:07.131939024 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qapplication_qws.cpp 2006-01-20 21:17:39.461503976 +0100 +@@ -1450,16 +1450,25 @@ + extern void qws_clearLoadedFonts(); + #endif + ++#ifndef QT_NO_QWS_W100 ++extern void qws_w100Transformation( int t ); ++#endif ++ + void QWSDisplay::setTransformation( int t ) + { +-#ifndef QT_NO_QWS_TRANSFORMED ++#if !defined(QT_NO_QWS_TRANSFORMED) || !defined(QT_NO_QWS_W100) + QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect, + QSize(qt_screen->width(), qt_screen->height()) ); + + QPixmapCache::clear(); + qws_clearLoadedFonts(); + qws_mapPixmaps( TRUE ); ++#ifndef QT_NO_QWS_TRANSFORMED + qws_setScreenTransformation( t ); ++#endif ++#ifndef QT_NO_QWS_W100 ++ qws_w100Transformation( t ); ++#endif + qws_mapPixmaps( FALSE ); + + if ( qt_fbdpy->d->directServerConnection() ) { diff --git a/packages/qte/qte-2.3.12/daemonize.patch b/packages/qte/qte-2.3.12/daemonize.patch new file mode 100644 index 0000000000..49124b5dbc --- /dev/null +++ b/packages/qte/qte-2.3.12/daemonize.patch @@ -0,0 +1,115 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qapplication_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qapplication_qws.cpp 2006-01-20 20:46:52.639263632 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qapplication_qws.cpp 2006-01-20 20:48:07.131939024 +0100 +@@ -105,6 +105,7 @@ + + #include <sys/time.h> + #include <sys/times.h> ++#include <syslog.h> + + #if defined(_OS_AIX_) && defined(_CC_GNU_) + #include <sys/select.h> +@@ -164,6 +165,7 @@ + //these used to be environment variables, they are initialized from + //environment variables in + ++bool qws_daemon = TRUE; + bool qws_savefonts = FALSE; + bool qws_screen_is_interlaced=FALSE; //### should be detected + bool qws_shared_memory = FALSE; +@@ -1688,6 +1690,10 @@ + mwGeometry = argv[i]; + } else if ( arg == "-shared" ) { + qws_shared_memory = TRUE; ++ } else if ( arg == "-daemon" ) { ++ qws_daemon = TRUE; ++ } else if ( arg == "-nodaemon" ) { ++ qws_daemon = FALSE; + } else if ( arg == "-noshared" ) { + qws_shared_memory = FALSE; + } else if ( arg == "-savefonts" ) { +@@ -1745,6 +1751,78 @@ + qt_appType = type; + qws_single_process = TRUE; + ++ /* Daemonize the server process -- (C) Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> ++ * Added a new command line option which only is relevant if the application is created as a GuiServer. ++ * The option is -daemon respectively -nodaemon. If in daemon mode (which is the default now), the ++ * server will detach from the controlling terminal and continue as a daemon. This is done via the standard ++ * UNIX double fork magic. ++ */ ++ if ( qws_daemon ) ++ { ++ qWarning( "qt_init() - starting in daemon mode..." ); ++ ++ int pid1 = fork(); ++ if ( pid1 == -1 ) ++ { ++ qWarning( "qt_init() - can't perform initial fork: %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ if ( pid1 ) _exit( 0 ); // ok, first fork performed ++ ++ chdir( "/" ); ++ setsid(); ++ umask(0); ++ close(0); ++ close(1); ++ close(2); ++ ++ int fdnull = ::open( "/dev/null", O_RDWR ); ++ if ( fdnull == -1 ) ++ { ++ syslog( 3, "qt_init() - can't open /dev/null to redirect std{in|out|err}: %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ dup2( fdnull, 0 ); // stdin ++ dup2( fdnull, 1 ); // stdout ++ dup2( fdnull, 2 ); // stderr ++ ++ int pid2 = fork(); ++ if ( pid2 == -1 ) ++ { ++ syslog( 3, "qt_init() - can't perform initial fork: %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ if ( pid2 ) ++ { ++ syslog( 4, "qt_init() [%d] - successfully entered daemon mode", pid2 ); ++ _exit( 0 ); // ok, second fork performed ++ } ++ } ++ ++ /* ++ * , , ++ * /( )` ++ * \ \___ / | B E W A R E ! ++ * /- _ `-/ ' We are a DAEMON now! ++ * (/\/ \ \ /\ ++ * / / | ` \ ++ * O O ) / | ++ * `-^--'`< ' ++ * (_.) _ ) / ++ * `.___/` / ++ * `-----' / ++ * <----. __ / __ \ ++ * <----|====O)))==) \) /==== ++ * <----' `--' `.__,' \ ++ * | | ++ * \ / ++ * ______( (_ / \______ ++ * (FL) ,' ,-----' | \ ++ * `--{__________) \/ ++ * ++ */ ++ ++ + /* Allocate a dedicated virtual terminal -- (C) Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> + * Added a new command line option which only is relevant if the application is created as a GuiServer. + * The option is -terminal <num>, where <num> specifies the virtual terminal to be occupied by the server. diff --git a/packages/qte/qte-2.3.12/devfs.patch b/packages/qte/qte-2.3.12/devfs.patch new file mode 100644 index 0000000000..dd46d516ff --- /dev/null +++ b/packages/qte/qte-2.3.12/devfs.patch @@ -0,0 +1,161 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10/configure +=================================================================== +--- qt-2.3.10.orig/configure 2005-07-03 12:26:10.000000000 +0200 ++++ qt-2.3.10/configure 2005-07-03 12:30:36.000000000 +0200 +@@ -412,6 +412,9 @@ + -visibility-hidden) + VISIBILITY=YES + ;; ++ -devfs) ++ DEVFS=yes ++ ;; + -no-g++-exceptions) + GPLUSPLUS_EXCEPTIONS=no + ;; +@@ -1302,6 +1305,8 @@ + -visibility-hidden . Use -fvisibility=hidden as default. This requires GCC 4.0 + or a special patched GCC to support the visibility attribute + ++ -devfs ............. Use devfs /dev paths. ++ + -no-g++-exceptions . Disable exceptions on platforms using the GNU C++ + compiler by using the -fno-exceptions flag. + +@@ -1374,6 +1379,10 @@ + then + QT_CXX="${QT_CXX} -DGCC_SUPPORTS_VISIBILITY -fvisibility=hidden" + fi ++if [ "x$DEVFS" = "xyes" ] ++then ++ QT_CXX="${QT_CXX} -DQT_QWS_DEVFS" ++fi + if [ "x$THREAD" = "xyes" ] + then + cat >src-mt.mk <<EOF +Index: qt-2.3.10/src/kernel/qgfxlinuxfb_qws.cpp +=================================================================== +--- qt-2.3.10.orig/src/kernel/qgfxlinuxfb_qws.cpp 2005-07-03 12:26:13.000000000 +0200 ++++ qt-2.3.10/src/kernel/qgfxlinuxfb_qws.cpp 2005-07-03 12:30:36.000000000 +0200 +@@ -101,11 +101,19 @@ + bool QLinuxFbScreen::connect( const QString &displaySpec ) + { + // Check for explicitly specified device ++#ifdef QT_QWS_DEVFS ++ QRegExp r( "/dev/fb/[0-9]+" ); ++#else + QRegExp r( "/dev/fb[0-9]+" ); ++#endif + int len; + int m = r.match( displaySpec, 0, &len ); + ++#ifdef QT_QWS_DEVFS ++ QString dev = (m>=0) ? displaySpec.mid( m, len ) : QString("/dev/fb/0"); ++#else + QString dev = (m>=0) ? displaySpec.mid( m, len ) : QString("/dev/fb0"); ++#endif + + fd=open( dev.latin1(), O_RDWR ); + if (fd<0) { +@@ -121,14 +129,22 @@ + + /* Get fixed screen information */ + if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) { ++#ifdef QT_QWS_DEVFS ++ perror("reading /dev/fb/0"); ++#else + perror("reading /dev/fb0"); ++#endif + qWarning("Error reading fixed information"); + return FALSE; + } + + /* Get variable screen information */ + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) { ++#ifdef QT_QWS_DEVFS ++ perror("reading /dev/fb/0"); ++#else + perror("reading /dev/fb0"); ++#endif + qWarning("Error reading variable information"); + return FALSE; + } +@@ -165,7 +181,11 @@ + data += dataoffset; + + if ((int)data == -1) { +- perror("mapping /dev/fb0"); ++#ifdef QT_QWS_DEVFS ++ perror("reading /dev/fb/0"); ++#else ++ perror("reading /dev/fb0"); ++#endif + qWarning("Error: failed to map framebuffer device to memory."); + return FALSE; + } +@@ -229,7 +249,11 @@ + + static void writeTerm(const char* termctl, int sizeof_termctl) + { ++#ifdef QT_QWS_DEVFS ++ const char* tt[]={"/dev/vc/1","/dev/console","/dev/tty",0}; ++#else + const char* tt[]={"/dev/console","/dev/tty","/dev/tty0",0}; ++#endif + const char** dev=tt; + while (*dev) { + int tty=::open(*dev,O_WRONLY); +Index: qt-2.3.10/src/kernel/qkeyboard_qws.cpp +=================================================================== +--- qt-2.3.10.orig/src/kernel/qkeyboard_qws.cpp 2005-07-03 12:26:13.000000000 +0200 ++++ qt-2.3.10/src/kernel/qkeyboard_qws.cpp 2005-07-03 12:30:36.000000000 +0200 +@@ -1253,7 +1253,11 @@ + + QWSTtyKeyboardHandler::QWSTtyKeyboardHandler(const QString& device) + { ++#ifdef QT_QWS_DEVFS ++ kbdFD=open(device.isEmpty() ? "/dev/vc/1" : device.latin1(), O_RDWR | O_NDELAY, 0); ++#else + kbdFD=open(device.isEmpty() ? "/dev/tty0" : device.latin1(), O_RDWR | O_NDELAY, 0); ++#endif + + if ( kbdFD >= 0 ) { + QSocketNotifier *notifier; +Index: qt-2.3.10/src/kernel/qwindowsystem_qws.cpp +=================================================================== +--- qt-2.3.10.orig/src/kernel/qwindowsystem_qws.cpp 2005-07-03 12:26:11.000000000 +0200 ++++ qt-2.3.10/src/kernel/qwindowsystem_qws.cpp 2005-07-03 12:30:36.000000000 +0200 +@@ -836,7 +836,11 @@ + void openDevice() + { + if ( !sn ) { ++#ifdef QT_QWS_DEVFS ++ int fd = ::open("/dev/sound/dsp",O_RDWR); ++#else + int fd = ::open("/dev/dsp",O_RDWR); ++#endif + if ( fd < 0 ) { + // For debugging purposes - defined QT_NO_SOUND if you + // don't have sound hardware! +Index: qt-2.3.10/src/kernel/qsoundqss_qws.cpp +=================================================================== +--- qt-2.3.10.orig/src/kernel/qsoundqss_qws.cpp 2005-01-23 15:00:46.000000000 +0100 ++++ qt-2.3.10/src/kernel/qsoundqss_qws.cpp 2005-07-03 12:30:36.000000000 +0200 +@@ -1088,7 +1088,12 @@ + // Don't block open right away. + // + bool openOkay = false; +- if ((fd = ::open("/dev/dsp", O_WRONLY|O_NONBLOCK)) != -1) { ++#ifdef QT_QWS_DEVFS ++ if ((fd = ::open("/dev/sound/dsp", O_WRONLY|O_NONBLOCK)) != -1) ++#else ++ if ((fd = ::open("/dev/dsp", O_WRONLY|O_NONBLOCK)) != -1) ++#endif ++ { + int flags = fcntl(fd, F_GETFL); + flags &= ~O_NONBLOCK; + openOkay = (fcntl(fd, F_SETFL, flags) == 0); diff --git a/packages/qte/qte-2.3.12/encoding.patch b/packages/qte/qte-2.3.12/encoding.patch new file mode 100644 index 0000000000..77626c48bf --- /dev/null +++ b/packages/qte/qte-2.3.12/encoding.patch @@ -0,0 +1,36 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/tools/qstring.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/tools/qstring.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/tools/qstring.cpp 2006-01-20 20:49:57.610143784 +0100 +@@ -14468,7 +14468,11 @@ + return qt_winQString2MB( *this ); + #endif + #ifdef _WS_QWS_ +- return utf8(); // ##### if there is ANY 8 bit format supported? ++ QTextCodec* codec = QTextCodec::codecForLocale(); ++ return codec ++ ? codec->fromUnicode(*this) ++ : utf8(); ++ //return latin1(); // ##### if there is ANY 8 bit format supported? + #endif + #endif + } +@@ -14514,7 +14518,12 @@ + return qt_winMB2QString( local8Bit ); + #endif + #ifdef _WS_QWS_ +- return fromUtf8(local8Bit,len); ++ QTextCodec* codec = QTextCodec::codecForLocale(); ++ if( len < 0) len = qstrlen(local8Bit); ++ return codec ++ ? codec->toUnicode(local8Bit, len) ++ : QString::fromUtf8(local8Bit,len); ++// return fromLatin1(local8Bit,len); + #endif + #endif // QT_NO_TEXTCODEC + } diff --git a/packages/qte/qte-2.3.12/fix-errno-exception-spec.patch b/packages/qte/qte-2.3.12/fix-errno-exception-spec.patch new file mode 100644 index 0000000000..19a5c134c8 --- /dev/null +++ b/packages/qte/qte-2.3.12/fix-errno-exception-spec.patch @@ -0,0 +1,16 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.10/src/kernel/qsoundqss_qws.cpp~fix-errno-exception-spec.patch ++++ qt-2.3.10/src/kernel/qsoundqss_qws.cpp +@@ -51,8 +51,6 @@ + #include <sys/ioctl.h> + #include <sys/soundcard.h> + +-extern int errno; +- + #define QT_QWS_SOUND_16BIT 1 // or 0, or undefined for always 0 + #define QT_QWS_SOUND_STEREO 1 // or 0, or undefined for always 0 + diff --git a/packages/qte/qte-2.3.12/fix-linuxfb-offscreenoverflow.patch b/packages/qte/qte-2.3.12/fix-linuxfb-offscreenoverflow.patch new file mode 100644 index 0000000000..a0bb12940c --- /dev/null +++ b/packages/qte/qte-2.3.12/fix-linuxfb-offscreenoverflow.patch @@ -0,0 +1,24 @@ +Fix an overflow when the amount of requested cache memory +is greater than the *lowest value +Manuel Teira <manuel.teira@telefonica.net> + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfxlinuxfb_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qgfxlinuxfb_qws.cpp 2006-01-20 21:07:51.803841520 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfxlinuxfb_qws.cpp 2006-01-20 21:08:13.655519560 +0100 +@@ -616,6 +616,11 @@ + + // No free blocks in already-taken memory; get some more + // if we can ++ if ( amount >= (*lowest ) ) { ++ //Avoid this overflow ++ qt_fbdpy->ungrab(); ++ return 0; ++ } + unsigned int newlowest = (*lowest)-amount; + if (newlowest % align) { + newlowest -= align; diff --git a/packages/qte/qte-2.3.12/fix-linuxfb-setmode.patch b/packages/qte/qte-2.3.12/fix-linuxfb-setmode.patch new file mode 100644 index 0000000000..e6cb25c385 --- /dev/null +++ b/packages/qte/qte-2.3.12/fix-linuxfb-setmode.patch @@ -0,0 +1,36 @@ +Set lstep properly on a mode change +Manuel Teira <manuel.teira@telefonica.net> + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfxlinuxfb_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qgfxlinuxfb_qws.cpp 2006-01-20 20:46:52.641263328 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfxlinuxfb_qws.cpp 2006-01-20 21:07:51.803841520 +0100 +@@ -119,13 +119,6 @@ + memset( &finfo, 0, sizeof(fb_fix_screeninfo) ); // keep valgrind happy + memset( &vinfo, 0, sizeof(fb_var_screeninfo) ); // keep valgrind happy + +- /* Get fixed screen information */ +- if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) { +- perror("reading /dev/fb0"); +- qWarning("Error reading fixed information"); +- return FALSE; +- } +- + /* Get variable screen information */ + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) { + perror("reading /dev/fb0"); +@@ -826,6 +819,10 @@ + qFatal("Error reading fixed information"); + } + ++ if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) { ++ qFatal("Error reading changed fixed information in mode change"); ++ } ++ + w=vinfo.xres; + h=vinfo.yres; + d=vinfo.bits_per_pixel; diff --git a/packages/qte/qte-2.3.12/fix-qgfxraster.patch b/packages/qte/qte-2.3.12/fix-qgfxraster.patch new file mode 100644 index 0000000000..26bbe1e957 --- /dev/null +++ b/packages/qte/qte-2.3.12/fix-qgfxraster.patch @@ -0,0 +1,30 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfxraster_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qgfxraster_qws.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfxraster_qws.cpp 2006-01-20 20:50:26.577740040 +0100 +@@ -4076,13 +4076,14 @@ + for( loopc2=0;loopc2<frontadd;loopc2++ ) + *(alphaptr++)=get_value_32(16,(unsigned char **)&temppos); + +- PackType temp2; +- unsigned char * cp; ++ volatile PackType temp2; ++ volatile unsigned short int * cp; + for( loopc2=0;loopc2<count;loopc2++ ) { +- temp2=*((PackType *)temppos); +- cp=(unsigned char *)&temp2; +- *(alphaptr++)=get_value_32(16,&cp); +- *(alphaptr++)=get_value_32(16,&cp); ++ temp2=*reinterpret_cast<PackType *>(temppos); ++ cp=reinterpret_cast<volatile unsigned short int *>(&temp2); ++ *(alphaptr++)=qt_conv16ToRgb(*cp); ++ cp++; ++ *(alphaptr++)=qt_conv16ToRgb(*cp); + temppos += 2; + } + diff --git a/packages/qte/qte-2.3.12/fix-qscreen-sync.patch b/packages/qte/qte-2.3.12/fix-qscreen-sync.patch new file mode 100644 index 0000000000..47929ee1f2 --- /dev/null +++ b/packages/qte/qte-2.3.12/fix-qscreen-sync.patch @@ -0,0 +1,17 @@ +Add a sync member to QScreen class +Manuel Teira <manuel.teira@telefonica.net> + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.10/src/kernel/qgfx_qws.h~fix-qscreen-sync ++++ qt-2.3.10/src/kernel/qgfx_qws.h +@@ -191,6 +191,7 @@ + virtual int pixmapOffsetAlignment() { return 64; } + virtual int pixmapLinestepAlignment() { return 64; } + ++ virtual void sync() {} + virtual bool onCard(unsigned char *) const; + virtual bool onCard(unsigned char *, ulong& out_offset) const; + diff --git a/packages/qte/qte-2.3.12/gcc3.patch b/packages/qte/qte-2.3.12/gcc3.patch new file mode 100644 index 0000000000..fc1656aa24 --- /dev/null +++ b/packages/qte/qte-2.3.12/gcc3.patch @@ -0,0 +1,27 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.9-snapshot-20041211/src/tools/qcstring.h~gcc3 ++++ qt-2.3.9-snapshot-20041211/src/tools/qcstring.h +@@ -119,7 +119,7 @@ + // We want to keep source compatibility for 2.x + // ### TODO for 4.0: completely remove these and the cstr* functions + +-#if !defined(QT_GENUINE_STR) ++#if 0 + + #undef strlen + #define strlen qstrlen +--- qt-2.3.9-snapshot-20041211/src/kernel/qwsdecoration_qws.h~gcc3 ++++ qt-2.3.9-snapshot-20041211/src/kernel/qwsdecoration_qws.h +@@ -50,7 +50,7 @@ + enum Region { None=0, All=1, Title=2, Top=3, Bottom=4, Left=5, Right=6, + TopLeft=7, TopRight=8, BottomLeft=9, BottomRight=10, + Close=11, Minimize=12, Maximize=13, Normalize=14, +- Menu=15, LastRegion=Menu }; ++ Menu=15, LastRegion=Menu, UserDefined = 100 }; + + virtual QRegion region(const QWidget *, const QRect &rect, Region r=All) = 0; + virtual void close( QWidget * ); diff --git a/packages/qte/qte-2.3.12/gcc4.patch b/packages/qte/qte-2.3.12/gcc4.patch new file mode 100644 index 0000000000..550effd7ba --- /dev/null +++ b/packages/qte/qte-2.3.12/gcc4.patch @@ -0,0 +1,16 @@ + +# +# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher +# + +--- qt-2.3.10/src/tools/qvaluestack.h~gcc4 2005-01-23 15:00:47.000000000 +0100 ++++ qt-2.3.10/src/tools/qvaluestack.h 2006-03-19 02:32:56.000000000 +0100 +@@ -54,7 +54,7 @@ + { + T elem( this->last() ); + if ( !this->isEmpty() ) +- remove( this->fromLast() ); ++ this->remove( this->fromLast() ); + return elem; + } + T& top() { return this->last(); } diff --git a/packages/qte/qte-2.3.12/handhelds.patch b/packages/qte/qte-2.3.12/handhelds.patch new file mode 100644 index 0000000000..c4e3c8ce59 --- /dev/null +++ b/packages/qte/qte-2.3.12/handhelds.patch @@ -0,0 +1,66 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/widgets/qcommonstyle.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/widgets/qcommonstyle.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/widgets/qcommonstyle.cpp 2006-01-20 21:03:08.477913608 +0100 +@@ -572,7 +572,7 @@ + bool enabled, bool active ) + { + #ifndef QT_NO_MENUBAR +-#ifndef QT_NO_STYLE_SGI ++#if 1 // #ifndef QT_NO_STYLE_SGI + if (draw_menu_bar_impl != 0) { + QDrawMenuBarItemImpl impl = draw_menu_bar_impl; + (this->*impl)(p, x, y, w, h, mi, g, enabled, active); +Index: qt-2.3.10-snapshot-20060120/src/widgets/qlistview.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/widgets/qlistview.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/widgets/qlistview.cpp 2006-01-20 21:03:08.480913152 +0100 +@@ -5053,9 +5053,9 @@ + l = l->childItem ? l->childItem : l->siblingItem; + + if ( l && l->height() ) +- s.setHeight( s.height() + 10 * l->height() ); +- else +- s.setHeight( s.height() + 140 ); ++ s.setHeight( s.height() + 4 /*10*/ * l->height() ); ++ else // ^v much too big for handhelds ++ s.setHeight( s.height() + 30 /*140*/ ); + + if ( s.width() > s.height() * 3 ) + s.setHeight( s.width() / 3 ); +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwindowsystem_qws.cpp 2006-01-20 20:57:33.113896688 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp 2006-01-20 21:03:08.482912848 +0100 +@@ -918,6 +918,18 @@ + { + } + ++static void catchSegvSignal( int ) ++{ ++#ifndef QT_NO_QWS_KEYBOARD ++ if ( qwsServer ) ++ qwsServer->closeKeyboard(); ++#endif ++ QWSServer::closedown(); ++ fprintf(stderr, "Segmentation fault.\n"); ++ exit(1); ++} ++ ++ + /*! + \class QWSServer qwindowsystem_qws.h + \brief Server-specific functionality in Qt/Embedded +@@ -1043,6 +1055,7 @@ + } + + signal(SIGPIPE, ignoreSignal); //we get it when we read ++ signal(SIGSEGV, catchSegvSignal); //recover the keyboard on crash + #endif + focusw = 0; + mouseGrabber = 0; diff --git a/packages/qte/qte-2.3.12/improve-calibration-r0.patch b/packages/qte/qte-2.3.12/improve-calibration-r0.patch new file mode 100644 index 0000000000..9b11f52d83 --- /dev/null +++ b/packages/qte/qte-2.3.12/improve-calibration-r0.patch @@ -0,0 +1,159 @@ +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsmouse_qws.cpp 2006-01-20 21:02:45.087469496 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.cpp 2006-01-20 21:08:58.697672112 +0100 +@@ -14,10 +14,6 @@ + ** Foundation and appearing in the file LICENSE.GPL included in the + ** packaging of this file. + ** +-** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +-** licenses for Qt/Embedded may use this file in accordance with the +-** Qt Embedded Commercial License Agreement provided with the Software. +-** + ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + ** +@@ -30,6 +26,12 @@ + ** + **********************************************************************/ + ++/* ++ * The 5 point algorithim in QTSLibHandlerPrivate::calibrate() is ++ * GPL only code and Copyright (C) 2001 Russel King. ++ * ++ * Taken from ts_calibrate.c from tslib ++ */ + #include "qwindowsystem_qws.h" + #include "qsocketnotifier.h" + #include "qwsevent_qws.h" +@@ -1810,6 +1812,7 @@ + + void QTSLibHandlerPrivate::calibrate( QWSPointerCalibrationData * cd) + { ++#ifdef ORIG_CALIBRATE + QPoint dev_tl = cd->devPoints[ QWSPointerCalibrationData::TopLeft ]; + QPoint dev_br = cd->devPoints[ QWSPointerCalibrationData::BottomRight ]; + QPoint screen_tl = cd->screenPoints[ QWSPointerCalibrationData::TopLeft ]; +@@ -1840,6 +1843,122 @@ + { + qDebug( "Could not save calibration: %s", calFile.latin1() ); + } ++ ++#else ++ int j; ++ float n, x, y, x2, y2, xy, z, zx, zy; ++ float det, cal_a, cal_b, cal_c, cal_d, cal_e, cal_f, cal_i; ++ float scaling = 65536.0; ++ int cal_x[5], cal_xfb[5], cal_y[5], cal_yfb[5], cal_o[7]; ++ ++ cal_x[0]=cd->devPoints[ QWSPointerCalibrationData::TopLeft ].x(); ++ cal_y[0]=cd->devPoints[ QWSPointerCalibrationData::TopLeft ].y(); ++ cal_x[1]=cd->devPoints[ QWSPointerCalibrationData::TopRight ].x(); ++ cal_y[1]=cd->devPoints[ QWSPointerCalibrationData::TopRight ].y(); ++ cal_x[2]=cd->devPoints[ QWSPointerCalibrationData::BottomLeft ].x(); ++ cal_y[2]=cd->devPoints[ QWSPointerCalibrationData::BottomLeft ].y(); ++ cal_x[3]=cd->devPoints[ QWSPointerCalibrationData::BottomRight ].x(); ++ cal_y[3]=cd->devPoints[ QWSPointerCalibrationData::BottomRight ].y(); ++ cal_x[4]=cd->devPoints[ QWSPointerCalibrationData::Center ].x(); ++ cal_y[4]=cd->devPoints[ QWSPointerCalibrationData::Center ].y(); ++ ++ cal_xfb[0]=cd->screenPoints[ QWSPointerCalibrationData::TopLeft ].x(); ++ cal_yfb[0]=cd->screenPoints[ QWSPointerCalibrationData::TopLeft ].y(); ++ cal_xfb[1]=cd->screenPoints[ QWSPointerCalibrationData::TopRight ].x(); ++ cal_yfb[1]=cd->screenPoints[ QWSPointerCalibrationData::TopRight ].y(); ++ cal_xfb[2]=cd->screenPoints[ QWSPointerCalibrationData::BottomLeft ].x(); ++ cal_yfb[2]=cd->screenPoints[ QWSPointerCalibrationData::BottomLeft ].y(); ++ cal_xfb[3]=cd->screenPoints[ QWSPointerCalibrationData::BottomRight ].x(); ++ cal_yfb[3]=cd->screenPoints[ QWSPointerCalibrationData::BottomRight ].y(); ++ cal_xfb[4]=cd->screenPoints[ QWSPointerCalibrationData::Center ].x(); ++ cal_yfb[4]=cd->screenPoints[ QWSPointerCalibrationData::Center ].y(); ++ ++ //qDebug("Top left : X = %4d Y = %4d", cal_x[0], cal_y[0]); ++ //qDebug("Top right: X = %4d Y = %4d", cal_x[1], cal_y[1]); ++ //qDebug("Bot left : X = %4d Y = %4d", cal_x[2], cal_y[2]); ++ //qDebug("Bot right: X = %4d Y = %4d", cal_x[3], cal_y[3]); ++ //qDebug("Middle: X = %4d Y = %4d", cal_x[4], cal_y[4]); ++ ++ // Get sums for matrix ++ n = x = y = x2 = y2 = xy = 0; ++ for(j=0;j<5;j++) { ++ n += 1.0; ++ x += (float)cal_x[j]; ++ y += (float)cal_y[j]; ++ x2 += (float)(cal_x[j]*cal_x[j]); ++ y2 += (float)(cal_y[j]*cal_y[j]); ++ xy += (float)(cal_x[j]*cal_y[j]); ++ } ++ ++ // Get determinant of matrix -- check if determinant is too small ++ det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2); ++ if(det < 0.1 && det > -0.1) { ++ qDebug("determinant is too small -- %f",det); ++ return;// false; ++ } ++ ++ // Get elements of inverse matrix ++ cal_a = (x2*y2 - xy*xy)/det; ++ cal_b = (xy*y - x*y2)/det; ++ cal_c = (x*xy - y*x2)/det; ++ cal_e = (n*y2 - y*y)/det; ++ cal_f = (x*y - n*xy)/det; ++ cal_i = (n*x2 - x*x)/det; ++ ++ // Get sums for x calibration ++ z = zx = zy = 0; ++ for(j=0;j<5;j++) { ++ z += (float)cal_xfb[j]; ++ zx += (float)(cal_xfb[j]*cal_x[j]); ++ zy += (float)(cal_xfb[j]*cal_y[j]); ++ } ++ ++ // Now multiply out to get the calibration for framebuffer x coord ++ cal_o[0] = (int)((cal_a*z + cal_b*zx + cal_c*zy)*(scaling)); ++ cal_o[1] = (int)((cal_b*z + cal_e*zx + cal_f*zy)*(scaling)); ++ cal_o[2] = (int)((cal_c*z + cal_f*zx + cal_i*zy)*(scaling)); ++ ++ qDebug("%f %f %f",(cal_a*z + cal_b*zx + cal_c*zy), (cal_b*z + cal_e*zx + cal_f*zy), (cal_c*z + cal_f*zx + cal_i*zy)); ++ ++ // Get sums for y calibration ++ z = zx = zy = 0; ++ for (j=0;j<5;j++) { ++ z += (float)cal_yfb[j]; ++ zx += (float)(cal_yfb[j]*cal_x[j]); ++ zy += (float)(cal_yfb[j]*cal_y[j]); ++ } ++ ++ // Now multiply out to get the calibration for framebuffer y coord ++ cal_o[3] = (int)((cal_a*z + cal_b*zx + cal_c*zy)*(scaling)); ++ cal_o[4] = (int)((cal_b*z + cal_e*zx + cal_f*zy)*(scaling)); ++ cal_o[5] = (int)((cal_c*z + cal_f*zx + cal_i*zy)*(scaling)); ++ ++ qDebug("%f %f %f",(cal_a*z + cal_b*zx + cal_c*zy), (cal_b*z + cal_e*zx + cal_f*zy), (cal_c*z + cal_f*zx + cal_i*zy)); ++ ++ ++ // If we got here, we're OK, so assign scaling to a[6] and return ++ cal_o[6] = (int) scaling; ++ ++ qDebug("Calibration constants: %d %d %d %d %d %d %d", ++ cal_o[0], cal_o[1], cal_o[2], ++ cal_o[3], cal_o[4], cal_o[5], ++ cal_o[6]); ++ ++ QString calFile = "/etc/pointercal"; ++#ifndef QT_NO_TEXTSTREAM ++ QFile file( calFile ); ++ if ( file.open( IO_WriteOnly ) ) { ++ QTextStream t( &file ); ++ t << cal_o[1] << " " << cal_o[2] << " " << cal_o[0] << " "; ++ t << cal_o[4] << " " << cal_o[5] << " " << cal_o[3] << " " << cal_o[6]; ++ file.flush(); closeTs(); ++ openTs(); ++ } else ++#endif ++ { ++ qDebug( "Could not save calibration: %s", calFile.latin1() ); ++ } ++#endif + } + + void QTSLibHandlerPrivate::readMouseData() diff --git a/packages/qte/qte-2.3.12/increase-qxml-robustness.patch b/packages/qte/qte-2.3.12/increase-qxml-robustness.patch new file mode 100644 index 0000000000..3a29b4ab03 --- /dev/null +++ b/packages/qte/qte-2.3.12/increase-qxml-robustness.patch @@ -0,0 +1,17 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.10/src/xml/qxml.cpp~xml ++++ qt-2.3.10/src/xml/qxml.cpp +@@ -809,6 +809,9 @@ + // ### The input source should not do the encoding detection! + void QXmlInputSource::readInput( QByteArray& rawData ) + { ++ // avoid crash if the array has less than 5 characters (skyhusker@handhelds.org) ++ if ( rawData.size() < 6 ) ++ return; + QBuffer buf( rawData ); + buf.open( IO_ReadOnly ); + QTextStream *stream = new QTextStream( &buf ); diff --git a/packages/qte/qte-2.3.12/ipaq-keyboard.patch b/packages/qte/qte-2.3.12/ipaq-keyboard.patch new file mode 100644 index 0000000000..6aa33242f5 --- /dev/null +++ b/packages/qte/qte-2.3.12/ipaq-keyboard.patch @@ -0,0 +1,27 @@ +Index: qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:22:10.391316384 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:25:41.190270072 +0100 +@@ -571,17 +571,17 @@ + { Qt::Key_Plus, '+' , '-' , 0xffff }, + { Qt::Key_Pause, 0xffff , 0xffff , 0xffff }, // 120 + { Qt::Key_F31, 0xffff , 0xffff , 0xffff }, // IM toggle +- { Qt::Key_F32, 0xffff , 0xffff , 0xffff }, // Sync +- { Qt::Key_F34, 0xffff , 0xffff , 0xffff }, // Power +- { Qt::Key_F35, 0xffff , 0xffff , 0xffff }, // Backlight ++ { Qt::Key_SysReq, 0xffff , 0xffff , 0xffff }, // iPAQ ++ { Qt::Key_F9, 0xffff , 0xffff , 0xffff }, // iPAQ ++ { Qt::Key_F10, 0xffff , 0xffff , 0xffff }, // iPAQ + #if defined(QT_KEYPAD_MODE) + { Qt::Key_Context1, 0xffff , 0xffff , 0xffff }, + { Qt::Key_Context2, 0xffff , 0xffff , 0xffff }, + { Qt::Key_Context3, 0xffff , 0xffff , 0xffff }, + { Qt::Key_Context4, 0xffff , 0xffff , 0xffff }, + #else +- { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, +- { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, ++ { Qt::Key_F13, 0xffff , 0xffff , 0xffff }, // iPAQ ++ { Qt::Key_F12, 0xffff , 0xffff , 0xffff }, // iPAQ + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, + #endif diff --git a/packages/qte/qte-2.3.12/ipaq_sound_fix.patch b/packages/qte/qte-2.3.12/ipaq_sound_fix.patch new file mode 100644 index 0000000000..a5874b4d6c --- /dev/null +++ b/packages/qte/qte-2.3.12/ipaq_sound_fix.patch @@ -0,0 +1,60 @@ +Attention HACK ahead: + The OpenSoundSystem is just scary this is a special hack + for supporting iPAQ(s) at least h3870. + + Features: + -It does not crash when playing a 'null' file + -Change sound fragment size to 12 + -Force stereo on!!! (hardcoded at least uda1341 needs it) + + + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qsoundqss_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qsoundqss_qws.cpp 2006-01-20 21:15:58.396868136 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qsoundqss_qws.cpp 2006-01-20 21:22:27.674688912 +0100 +@@ -73,7 +73,7 @@ + }; + + #if defined(QT_QWS_IPAQ) +-static const int sound_fragment_size = 12; ++static const int sound_fragment_size = 14; + #else + static const int sound_fragment_size = 12; + #endif +@@ -520,8 +520,14 @@ + + int devSamples() + { +- int possible = (((max1+max2-out) / ((chunkdata.wBitsPerSample>>3)*chunkdata.channels)) +- *sound_speed)/chunkdata.samplesPerSec; ++ if ( !(chunkdata.wBitsPerSample>>3) || ++ !chunkdata.channels || ++ !sound_speed || ++ !chunkdata.samplesPerSec ) ++ return 0; ++ ++ int possible = (((max1+max2-out) / ((chunkdata.wBitsPerSample>>3 )*chunkdata.channels)) ++ *sound_speed)/chunkdata.samplesPerSec; + + return possible; + } +@@ -1510,12 +1516,14 @@ + if ( AFMT_U8 != v ) + qDebug("Want format %d got %d", AFMT_U8, v); + #endif +- v=sound_stereo; if ( ioctl(fd, SNDCTL_DSP_STEREO, &v) ) ++ v=1; if ( ioctl(fd, SNDCTL_DSP_STEREO, &v) ) + qWarning("Could not set stereo %d",v); + if ( sound_stereo != v ) +- qDebug("Want stereo %d got %d", sound_stereo, v); +-#ifdef QT_QWS_SOUND_STEREO +- sound_stereo=v; ++ qDebug("Want stereo %d got %d", sound_stereo, v); ++#if defined(QT_QWS_IPAQ) ++ sound_stereo=1; ++#elif QT_QWS_SOUND_STEREO ++ sound_stereo=v; + #endif + v=sound_speed; if ( ioctl(fd, SNDCTL_DSP_SPEED, &sound_speed) ) + qWarning("Could not set speed %d",v); diff --git a/packages/qte/qte-2.3.12/kernel-keymap-CXK.patch b/packages/qte/qte-2.3.12/kernel-keymap-CXK.patch new file mode 100644 index 0000000000..6aca81e97d --- /dev/null +++ b/packages/qte/qte-2.3.12/kernel-keymap-CXK.patch @@ -0,0 +1,19 @@ + +# +# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher +# + +--- qt-2.3.10/src/kernel/qkeyboard_qws.cpp~kernel-keymap-CXK.patch 2005-05-05 19:34:05.000000000 +0200 ++++ qt-2.3.10/src/kernel/qkeyboard_qws.cpp 2005-05-05 19:35:47.000000000 +0200 +@@ -1809,7 +1809,11 @@ + case Qt::Key_Up: + case Qt::Key_Down: + mod_key = false; ++#if QT_QWS_SLCXK ++ if (qt_screen->transformOrientation() != 3) ++#else + if (qt_screen->isTransformed()) ++#endif + qtKeyCode = static_cast<Qt::Key>( xform_dirkey(static_cast<int>( qtKeyCode ) ) ); + break; + /* diff --git a/packages/qte/qte-2.3.12/kernel-keymap-corgi.patch b/packages/qte/qte-2.3.12/kernel-keymap-corgi.patch new file mode 100644 index 0000000000..7611590322 --- /dev/null +++ b/packages/qte/qte-2.3.12/kernel-keymap-corgi.patch @@ -0,0 +1,25 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:16:25.412761096 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:16:49.508098048 +0100 +@@ -420,6 +420,15 @@ + { 0x20ac, 0xffff , 0x20ac , 0x20ac }, // 73 Euro sign + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 74 + { Qt::Key_F32, 0xffff , 0xffff , 0xffff }, // 75 Sync ++ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 76 ++ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 77 ++ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 78 ++ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 79 ++ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 7a ++ { Qt::Key_Return, 0xffff , 0xffff , 0xffff }, // 7b ++ { Qt::Key_Escape, 0xffff , 0xffff , 0xffff }, // 7c ++ { Qt::Key_Up, 0xffff , 0xffff , 0xffff }, // 7d ++ { Qt::Key_Down, 0xffff , 0xffff , 0xffff }, // 7e + { 0, 0xffff , 0xffff , 0xffff } + }; + #else diff --git a/packages/qte/qte-2.3.12/kernel-keymap-tosa.patch b/packages/qte/qte-2.3.12/kernel-keymap-tosa.patch new file mode 100644 index 0000000000..ca445f4d1d --- /dev/null +++ b/packages/qte/qte-2.3.12/kernel-keymap-tosa.patch @@ -0,0 +1,81 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.9-snapshot-20050114/src/kernel/qkeyboard_qws.cpp~kernel-keymap-tosa ++++ qt-2.3.9-snapshot-20050114/src/kernel/qkeyboard_qws.cpp +@@ -355,14 +355,24 @@ + { Qt::Key_CapsLock, 0xffff , 0xffff , 0xffff }, // 3c 60 + { Qt::Key_At, '@' , 's' , 'S'-64 }, // 3d + { Qt::Key_Question, '?' , '?' , 0xffff }, // 3e ++#ifdef QT_QWS_SL6000 ++ { Qt::Key_Comma, ',' , ';' , 0xffff }, // 3f ++ { Qt::Key_Period, '.' , ':' , 0xffff }, // 40 ++#else + { Qt::Key_Comma, ',' , ',' , 0xffff }, // 3f + { Qt::Key_Period, '.' , '.' , 0xffff }, // 40 ++#endif + { Qt::Key_Tab, 9 , '\\' , 0xffff }, // 41 + { Qt::Key_X, 0xffff , 'x' , 'X'-64 }, // 42 + { Qt::Key_C, 0xffff , 'c' , 'C'-64 }, // 43 + { Qt::Key_V, 0xffff , 'v' , 'V'-64 }, // 44 ++#ifdef QT_QWS_SL6000 ++ { Qt::Key_Slash, '/' , '?' , 0xffff }, // 45 ++ { Qt::Key_Apostrophe, '\'' , '"' , 0xffff }, // 46 70 ++#else + { Qt::Key_Slash, '/' , '/' , 0xffff }, // 45 + { Qt::Key_Apostrophe, '\'' , '\'' , 0xffff }, // 46 70 ++#endif + { Qt::Key_Semicolon, ';' , ';' , 0xffff }, // 47 + { Qt::Key_QuoteDbl, '\"' , '\"' , 0xffff }, // 48 + { Qt::Key_Colon, ':' , ':' , 0xffff }, // 49 +@@ -572,6 +582,32 @@ + static const int keyMSize = sizeof(keyM)/sizeof(QWSServer::KeyMap)-1; + static QIntDict<QWSServer::KeyMap> *overrideMap = 0; + ++#if defined(QT_QWS_SL6000) ++/* Translation table to obtain a 'legacy' keycode corresponding to ++ Fn+key on tosa ++ Other devices obviously send different keycodes while Fn is down, tosa sends ++ the same keys as usual bracketed by Fn-down/Fn-up. ++ This table is used while Fn is down to obtain the key-code the SL-5xxx would ++ send, so the rest of keyboard processing does not need to be adjusted. */ ++static const uchar sl6kFnTrans[] = { 0x00, ++ 0x5e, 0x3a, 0x43, 0x4a, 0x2b, 0x4b, 0x4c, 0x4d, 0x30, 0x4e, 0x4f, 0x50, ++ // !, -, cpy, #, 3, $, %, _, 8, &, *, (, ++ 0x53, 0x3b, 0x31, 0x32, 0x29, 0x2c, 0x3d, 0x2d, 0x2f, 0x44, 0x2a, 0x42, ++ // =, +, 9, 0, 1, 4, @, 5, 7, pste, 2, cut, ++ // padding for keycodes which don't ever get directly sent on tosa ++ // except for y->6, ret->'>', BS->DEL ++ 0x2e, 0x00, 0x00, 0x57, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, ++ // 6, _Z, shft, ret, F11, fn, BS?, F31, lght, cncl, lft, up, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ // dn, rght, OK, home, 1, 2, 3, 4, 5, 6, 7, 8, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ // 9, 0, UNK, UNK, UNK, UNK, UNK, UNK, UNK, -, +, caps, ++ // here are a few translatable codes again... ++ 0x00, 0x00, 0x54, 0x56, 0x3c, 0x00, 0x00, 0x00, 0x70, 0x55 }; ++ // @, ?, ,, ., tab, cut, cpy, pste, /, ' ++static const int sl6kFnSize = sizeof(sl6kFnTrans); ++#endif ++ + /*! + Changes the mapping of the keyboard; adding the scancode to Unicode + mappings from \a map. The server takes over ownership of \a map +@@ -882,6 +918,15 @@ + int keypad = 0; + + #ifndef QT_QWS_USE_KEYCODES ++#if defined(QT_QWS_SL6000) ++ qDebug("Key pressed: %x", code); ++ if (fn) ++ if (code < sl6kFnSize) { ++ code = sl6kFnTrans[code]; ++ qDebug("Translated Fn: %x", code); ++ } else ++ qDebug("Untranslatable Fn: %x", code); ++#endif + #if defined(QT_QWS_IPAQ) + // map ipaq 'action' key (0x60, 0xe0) + if ((code & 0x7f) == 0x60) { diff --git a/packages/qte/qte-2.3.12/kernel-keymap.patch b/packages/qte/qte-2.3.12/kernel-keymap.patch new file mode 100644 index 0000000000..52771b0398 --- /dev/null +++ b/packages/qte/qte-2.3.12/kernel-keymap.patch @@ -0,0 +1,1042 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:15:58.396868136 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:16:25.412761096 +0100 +@@ -30,6 +30,42 @@ + ** + **********************************************************************/ + ++/**************************************************************************** ++** ++** Keyboard Handling Redesign ++** Copyright 2003, Chris Larson <kergoth@handhelds.org> ++** Copyright 2004,2005 Holger Hans Peter Frether <freyther@handhelds.org> ++** ++** TODO: (key: . = in progress, x = completed) ++** ++** [.] Tty driver should load its initial keymap from the kernel, ++** thereby ensuring keymap consistency between X, console, and qt/e ++** [x] Read kernel keymappings. ++** [x] Read kernel keycode -> unicode map. ++** [x] Use them, along with the existing keyM, to push events up. ++** [x] Create a new table, from transformed keycode -> qt keycode, rather ++** than the existing raw keycode -> qt keycode. ++** [ ] Adapt handleKey to deal with keys that have no unicode value, such as ++** keypresses that are mapped to strings in the string table. (e.g. F keys) ++** [x] Cursor orientation change based on display rotation should not ++** be bound to Ipaq or 5xxx, but instead as a runtime choice based ++** on whether or not we're using a Transformed display driver. ++** [.] Double check that VT handling, particularly with regard to switching, ++** is handled properly. ++** [ ] Add a generic means of dealing with additional (outside the realm of ++** ctrl, alt, shift, altgr) modifiers. Also ensure a means of binding ++** a keypress/combination to a 'lock' of said additional modifiers. ++** ++** Holgers Todo ++** ++** [ ] Fix NumLock handling ++** [ ] Fix Keypad handling ++** [ ] Fix LED handling (LED_NUM and LED_CAP) don't seem to work ++** [ ] Fix CTRL+ALT+H (somehow takes the function of CTRL+ALT+BACKSPACE) ++** ++**********************************************************************/ ++ ++ + #include "qwindowsystem_qws.h" + #include "qwsutils_qws.h" + #include "qgfx_qws.h" +@@ -45,15 +81,18 @@ + #include <ctype.h> + + #include <unistd.h> +-#ifdef _OS_LINUX_ +-#include <linux/kd.h> +-#endif ++#include <sys/wait.h> + #include <sys/ioctl.h> + #include <sys/types.h> + #include <sys/stat.h> + #include <fcntl.h> + #include <errno.h> + #include <signal.h> ++#include <termios.h> ++#ifdef _OS_LINUX_ ++#include <linux/kd.h> ++#include <linux/keyboard.h> ++#endif + + #ifdef QT_QWS_TIP2 + #include <qcopchannel_qws.h> +@@ -135,17 +174,6 @@ + }; + + +-#ifdef QT_QWS_SL5XXX +-#include <asm/sharp_char.h> +-#endif +- +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) +-#define QT_QWS_AUTOREPEAT_MANUALLY +-#endif +- +- +- +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) + static int dir_keyrot = -1; + + static int xform_dirkey(int key) +@@ -169,7 +197,6 @@ + int xf = qt_screen->transformOrientation() + dir_keyrot; + return (key-Qt::Key_Left+xf)%4+Qt::Key_Left; + } +-#endif + + #define VTSWITCHSIG SIGUSR2 + +@@ -300,11 +327,19 @@ + { Qt::Key_F35, 0xffff , 0xffff , 0xffff }, // 21 light + { Qt::Key_Escape, 0xffff , 0xffff , 0xffff }, // 22 + ++#ifdef QT_QWS_SL6000 ++ // Direction key code are for *UNROTATED* display. ++ { Qt::Key_Left, 0xffff , 0xffff , 0xffff }, // 23 ++ { Qt::Key_Up, 0xffff , 0xffff , 0xffff }, // 24 ++ { Qt::Key_Down, 0xffff , 0xffff , 0xffff }, // 25 ++ { Qt::Key_Right, 0xffff , 0xffff , 0xffff }, // 26 ++#else + // Direction key code are for *UNROTATED* display. +- { Qt::Key_Up, 0xffff , 0xffff , 0xffff }, // 23 +- { Qt::Key_Right, 0xffff , 0xffff , 0xffff }, // 24 +- { Qt::Key_Left, 0xffff , 0xffff , 0xffff }, // 25 +- { Qt::Key_Down, 0xffff , 0xffff , 0xffff }, // 26 ++ { Qt::Key_Up, 0xffff , 0xffff , 0xffff }, // 23 ++ { Qt::Key_Right, 0xffff , 0xffff , 0xffff }, // 24 ++ { Qt::Key_Left, 0xffff , 0xffff , 0xffff }, // 25 ++ { Qt::Key_Down, 0xffff , 0xffff , 0xffff }, // 26 ++#endif + + { Qt::Key_F33, 0xffff , 0xffff , 0xffff }, // 27 OK + { Qt::Key_F12, 0xffff , 0xffff , 0xffff }, // 28 40 home +@@ -369,7 +404,7 @@ + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 63 + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 64 + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 65 +- { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 66 ++ { Qt::Key_F14, 0xffff , 0xffff , 0xffff }, // 66 + { Qt::Key_Meta, 0xffff , 0xffff , 0xffff }, // 67 + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 68 + { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 69 +@@ -649,12 +684,61 @@ + public: + QWSTtyKeyboardHandler(const QString&); + virtual ~QWSTtyKeyboardHandler(); ++ void readKeyboardMap(); ++ void readUnicodeMap(); ++ void handleKey(unsigned char code); + + private slots: + void readKeyboardData(); + + private: ++ void modifyModifier( int map, int modify, bool release ); ++ void modifyLock( unsigned int lock, bool release ); ++ void handleExtra( unsigned int key, bool release ); ++ static void restoreLeds(); ++ static void toggleLed(unsigned int); ++ int map_to_modif (); ++ ++private: + struct termios origTermData; ++ unsigned short acm[E_TABSZ]; ++ struct KeyMap { ++ enum ExtraKey{ ++ Key_AltGr = 0x01ffff, ++ Key_Console1 = 0x02ffff, ++ Key_Console2 = 0x03ffff, ++ Key_Console3 = 0x04ffff, ++ Key_Console4 = 0x05ffff, ++ Key_Console5 = 0x06ffff, ++ Key_Console6 = 0x07ffff, ++ Key_Console7 = 0x08ffff, ++ Key_Console8 = 0x09ffff, ++ Key_Console9 = 0x0affff, ++ Key_Console10 = 0x0bffff, ++ Key_Console11 = 0x0cffff, ++ Key_Console12 = 0x0dffff, ++ Key_NumLock = 0x0effff, ++ Key_ShiftLock = 0x0fffff, ++ Key_CtrlLock = 0x10ffff, ++ Key_AltLock = 0x11ffff, ++ Key_AltGrLock = 0x12ffff ++ }; ++ ++ KeyMap( Qt::Key _key = Qt::Key_unknown, unsigned short _code = 0 ) ++ : key( _key ), code( _code ) ++ {} ++ KeyMap( ExtraKey _key, unsigned short _code ) ++ : key( _key ), code( _code ) ++ {} ++ unsigned int key; // 16 Bit ++ unsigned short code; ++ }; ++ ++ KeyMap kernel_map[(1<<KG_CAPSSHIFT)][NR_KEYS]; ++ int current_map; ++ int modifier; ++ bool numlock : 1; ++ bool capslock : 1; + }; + + +@@ -814,6 +898,7 @@ + fn = FALSE; + + numLock = FALSE; ++#if 0 + sharp_kbdctl_modifstat st; + int dev = ::open("/dev/sharp_kbdctl", O_RDWR); + if( dev >= 0 ) { +@@ -825,6 +910,7 @@ + ::close(dev); + } + #endif ++#endif + #if defined(QT_QWS_IPAQ) + // iPAQ Action Key has ScanCode 0x60: 0x60|0x80 = 0xe0 == extended mode 1 ! + ipaq_return_pressed = FALSE; +@@ -957,7 +1043,7 @@ + } + } else if ( extended == 2 ) { + switch (code) { +- case 0x1d: ++ case 0x1d: + return; + case 0x45: + keyCode = Qt::Key_Pause; +@@ -1197,7 +1283,7 @@ + unicode = '`'; + } else + #endif +- ++ + if (bCtrl) + unicode = currentKey->ctrl_unicode; + else if (bCaps) +@@ -1250,9 +1336,12 @@ + // + // Tty keyboard + // ++#include "keyboard_linux_to_qt.h" + + QWSTtyKeyboardHandler::QWSTtyKeyboardHandler(const QString& device) ++ : current_map(0), modifier( 0 ), numlock( false ), capslock( false ) + { ++ restoreLeds(); + kbdFD=open(device.isEmpty() ? "/dev/tty0" : device.latin1(), O_RDWR | O_NDELAY, 0); + + if ( kbdFD >= 0 ) { +@@ -1268,11 +1357,7 @@ + tcgetattr( kbdFD, &termdata ); + + #if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_) +-# ifdef QT_QWS_USE_KEYCODES +- ioctl(kbdFD, KDSKBMODE, K_MEDIUMRAW); +-# else +- ioctl(kbdFD, KDSKBMODE, K_RAW); +-# endif ++ ioctl(kbdFD, KDSKBMODE, K_MEDIUMRAW); + #endif + + termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP); +@@ -1285,6 +1370,9 @@ + cfsetospeed(&termdata, 9600); + tcsetattr(kbdFD, TCSANOW, &termdata); + ++ readUnicodeMap(); ++ readKeyboardMap(); ++ + signal(VTSWITCHSIG, vtSwitchHandler); + + #if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_) +@@ -1306,6 +1394,7 @@ + + QWSTtyKeyboardHandler::~QWSTtyKeyboardHandler() + { ++ restoreLeds(); + if (kbdFD >= 0) + { + +@@ -1334,13 +1423,451 @@ + kbdFD = -1; + } + } ++void QWSTtyKeyboardHandler::readUnicodeMap() ++{ ++ if (kbdFD < 0) ++ return; ++ if (ioctl(kbdFD,GIO_UNISCRNMAP,acm) != 0) ++ return; ++} ++ ++ ++void QWSTtyKeyboardHandler::readKeyboardMap() ++{ ++ struct kbentry kbe; ++ if (kbdFD < 0) ++ return; ++ ++ for (int map = 0; map < (1<<KG_CAPSSHIFT); ++map) { ++ unsigned short kval; ++ kbe.kb_table = map; ++ ++ for (int key = 0; key < NR_KEYS; ++key) { ++ kbe.kb_index = key; ++ ++ if (ioctl(kbdFD, KDGKBENT, &kbe) != 0) ++ continue; ++ ++ if ((kbe.kb_value == K_HOLE) || (kbe.kb_value == K_NOSUCHMAP)) ++ continue; ++ ++ kval = KVAL(kbe.kb_value); ++ switch (KTYP(kbe.kb_value)) { ++ /* ++ * Map asciis and letters to Qt KeyCodes ++ * via the map (0-255) ++ */ ++ case KT_LETTER: ++ case KT_LATIN: ++ kernel_map[map][key] = KeyMap( linux_to_qt[kval], kval ); ++ break; ++ ++ /* ++ * Handle the F Keys and map them ++ * to Qt ++ */ ++ case KT_FN: ++ if ( kval <= 19 ) ++ kernel_map[map][key] = KeyMap( static_cast<Qt::Key>( Qt::Key_F1 + kval ), kval ); ++ else if ( kval >= 31 && kval <= 33) ++ kernel_map[map][key] = KeyMap( static_cast<Qt::Key>( Qt::Key_F21 + kval ), kval ); ++ else if ( kval >= 34 && kval <= 45 ) { ++ int off = kval-34; ++ kernel_map[map][key] = KeyMap(static_cast<KeyMap::ExtraKey>( KeyMap::Key_Console1+off ), kval ); ++ }else ++ switch(kbe.kb_value ) { ++ case K_INSERT: ++ kernel_map[map][key] = KeyMap( Qt::Key_Insert, kval ); ++ break; ++ case K_REMOVE: ++ kernel_map[map][key] = KeyMap( Qt::Key_Delete, kval ); // right? ++ break; ++ case K_SELECT: ++ kernel_map[map][key] = KeyMap( Qt::Key_End , kval ); ++ break; ++ case K_PGUP: ++ kernel_map[map][key] = KeyMap( Qt::Key_Prior, kval ); ++ break; ++ case K_PGDN: ++ kernel_map[map][key] = KeyMap( Qt::Key_Next, kval ); ++ break; ++ case K_MACRO: ++ kernel_map[map][key] = KeyMap( Qt::Key_Menu, kval ); ++ break; ++ case K_HELP: ++ kernel_map[map][key] = KeyMap( Qt::Key_Help, kval ); ++ break; ++ case K_PAUSE: ++ kernel_map[map][key] = KeyMap( Qt::Key_Pause, kval ); ++ break; ++ case K_FIND: ++ case K_DO: ++ default: ++ kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval ); ++ break; ++ } ++ break; ++ ++ case KT_SPEC: ++ switch ( kbe.kb_value ) { ++ case K_ENTER: ++ kernel_map[map][key] = KeyMap( Qt::Key_Enter, kval ); ++ break; ++ case K_CAPS: ++ kernel_map[map][key] = KeyMap( Qt::Key_CapsLock, kval ); ++ break; ++ case K_NUM: ++ kernel_map[map][key] = KeyMap( Qt::Key_NumLock, kval ); ++ break; ++ case K_HOLD: ++ kernel_map[map][key] = KeyMap( Qt::Key_ScrollLock, kval ); ++ break; ++ case K_HOLE: ++ case K_SH_REGS: ++ case K_SH_MEM: ++ case K_SH_STAT: ++ case K_BREAK: ++ case K_CONS: ++ case K_SCROLLFORW: ++ case K_SCROLLBACK: ++ case K_BOOT: ++ case K_CAPSON: ++ case K_COMPOSE: ++ case K_SAK: ++ case K_DECRCONSOLE: ++ case K_INCRCONSOLE: ++ case K_SPAWNCONSOLE: ++ case K_BARENUMLOCK: ++ default: ++ kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval ); ++ break; ++ } ++ break; ++ case KT_PAD: ++ /* ++ * Number Values might be wrong ++ */ ++ switch(kbe.kb_value ) { ++ case K_P0: ++ kernel_map[map][key] = KeyMap( Qt::Key_0, kval ); ++ break; ++ case K_P1: ++ kernel_map[map][key] = KeyMap( Qt::Key_1, kval ); ++ break; ++ case K_P2: ++ kernel_map[map][key] = KeyMap( Qt::Key_2, kval ); ++ break; ++ case K_P3: ++ kernel_map[map][key] = KeyMap( Qt::Key_3, kval ); ++ break; ++ case K_P4: ++ kernel_map[map][key] = KeyMap( Qt::Key_4, kval ); ++ break; ++ case K_P5: ++ kernel_map[map][key] = KeyMap( Qt::Key_5, kval ); ++ break; ++ case K_P6: ++ kernel_map[map][key] = KeyMap( Qt::Key_6, kval ); ++ break; ++ case K_P7: ++ kernel_map[map][key] = KeyMap( Qt::Key_7, kval ); ++ break; ++ case K_P8: ++ kernel_map[map][key] = KeyMap( Qt::Key_8, kval ); ++ break; ++ case K_P9: ++ kernel_map[map][key] = KeyMap( Qt::Key_9, kval ); ++ break; ++ case K_PPLUS: ++ kernel_map[map][key] = KeyMap( Qt::Key_Plus, kval ); ++ break; ++ case K_PMINUS: ++ kernel_map[map][key] = KeyMap( Qt::Key_Minus, kval ); ++ break; ++ case K_PSTAR: ++ kernel_map[map][key] = KeyMap( Qt::Key_multiply, kval ); ++ break; ++ case K_PSLASH: ++ kernel_map[map][key] = KeyMap( Qt::Key_division, kval ); ++ break; ++ case K_PENTER: ++ kernel_map[map][key] = KeyMap( Qt::Key_Enter, kval ); ++ break; ++ case K_PCOMMA: ++ kernel_map[map][key] = KeyMap( Qt::Key_Comma, kval ) ; ++ break; ++ case K_PPLUSMINUS: ++ kernel_map[map][key] = KeyMap( Qt::Key_plusminus, kval ); ++ case K_PDOT: ++ break; ++ case K_PPARENL: ++ kernel_map[map][key] = KeyMap( Qt::Key_ParenLeft, kval ); ++ break; ++ case K_PPARENR: ++ kernel_map[map][key] = KeyMap( Qt::Key_ParenRight, kval ); ++ break; ++ default: ++ kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval ); ++ break; ++ } ++ break; ++ case KT_DEAD: ++ switch(kbe.kb_value ) { ++ case K_DGRAVE: ++ case K_DACUTE: ++ case K_DCIRCM: ++ case K_DTILDE: ++ case K_DDIERE: ++ case K_DCEDIL: ++ default: ++ kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval ); ++ break; ++ } ++ break; ++ ++ case KT_CONS: ++ kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval ); ++ break; ++ ++ case KT_CUR: ++ switch(kbe.kb_value ) { ++ case K_DOWN: ++ kernel_map[map][key] = KeyMap( Qt::Key_Down, kval ); ++ break; ++ case K_LEFT: ++ kernel_map[map][key] = KeyMap( Qt::Key_Left, kval ); ++ break; ++ case K_RIGHT: ++ kernel_map[map][key] = KeyMap( Qt::Key_Right, kval ); ++ break; ++ case K_UP: ++ kernel_map[map][key] = KeyMap( Qt::Key_Up, kval ); ++ break; ++ } ++ break; ++ ++ case KT_SHIFT: ++ switch( kbe.kb_value ) { ++ case K_SHIFT: ++ kernel_map[map][key] = KeyMap( Qt::Key_Shift, kval ); ++ break; ++ case K_ALT: ++ kernel_map[map][key] = KeyMap( Qt::Key_Alt, kval ); ++ break; ++ case K_CTRL: ++ kernel_map[map][key] = KeyMap( Qt::Key_Control, kval ); ++ break; ++ case K_ALTGR: ++ kernel_map[map][key] = KeyMap( KeyMap::Key_AltGr, kval ); ++ break; ++ case K_SHIFTL: ++ case K_SHIFTR: ++ case K_CTRLL: ++ case K_CTRLR: ++ case K_CAPSSHIFT: ++ default: ++ kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval ); ++ break; ++ } ++ break; ++ /* ++ * What is this for? ++ */ ++ case KT_ASCII: ++ case KT_LOCK: ++ case KT_SLOCK: ++ default: ++ kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval ); ++ //qWarning("keycode %d, map %d, type %d, val %d, acm %c\n", key, map, KTYP(kbe.kb_value), kval, acm[kval]); ++ break; ++ } ++ } ++ } ++} ++int QWSTtyKeyboardHandler::map_to_modif() ++{ ++ int modifiers = 0; ++ ++ if (current_map & (1<<KG_ALT)) ++ modifiers |= Qt::AltButton; ++ else if (current_map & (1<<KG_CTRL)) ++ modifiers |= Qt::ControlButton; ++ else if (current_map & (1<<KG_SHIFT)) ++ modifiers |= Qt::ShiftButton; ++ ++ return modifiers; ++} ++ ++/* ++ * Handle Extra Keys for VT switching and Quitting ++ */ ++void QWSTtyKeyboardHandler::handleExtra( unsigned int key, bool release ) { ++ if ( !release ) { ++ int term = 0; ++ if ( (modifier & (1<<KG_ALT)) && (modifier & (1<<KG_CTRL)) ) { ++ if ( key == Qt::Key_Left ) ++ term = QMAX(vtQws -1, 1 ); ++ else if ( key == Qt::Key_Right ) ++ term = QMIN(vtQws +1, 12 ); ++ } ++ ++ if ( key >= KeyMap::Key_Console1 && key <= KeyMap::Key_Console12 ) ++ term = key - KeyMap::Key_Console1 + 1; ++ ++ if ( term != 0 ) { ++ current_map = modifier = 0; ++ numlock = capslock = false; ++ ioctl(kbdFD, VT_ACTIVATE, term ); ++ return; ++ } ++ } ++ ++ if ( (modifier & (1<<KG_ALT)) && (modifier & (1<<KG_CTRL) ) ) ++ if ( key == Qt::Key_Delete || key == Qt::Key_Backspace ) { ++ qWarning( "Instructed to quit on %d", key ); ++ qApp->quit(); ++ } ++} ++ ++/* ++ * apply modifier ++ */ ++void QWSTtyKeyboardHandler::modifyModifier( int map, int modify, bool release ) { ++ if (map != -1) { ++ if (release) ++ current_map &= ~map; ++ else ++ current_map |= map; ++ } ++ ++ if ( modify != -1 ) { ++ if (release) ++ modifier &= ~modify; ++ else ++ modifier |= modify; ++ } ++} ++ ++void QWSTtyKeyboardHandler::handleKey(unsigned char code) ++{ ++ int old_modifier = modifier; ++ bool release = false; ++ bool mod_key = true; ++ ++ if (code & 0x80) ++ { ++ release = true; ++ code &= 0x7f; ++ } ++ ++ KeyMap key_map = kernel_map[current_map][code]; ++ unsigned short unicode = acm[key_map.code]; ++ unsigned int qtKeyCode = key_map.key; ++ ++ if ( !release ) ++ qWarning( "KeyCode: %d KVAL: %d", qtKeyCode, key_map.code ); ++// qWarning( "Alt:%d Ctrl:%d Shift:%d Key = %d", modifier & (1<<KG_ALT), ++// modifier & (1<<KG_CTRL), ++// modifier & (1<<KG_SHIFT), key_map.key ); ++// qDebug("code %d, mCode %d, uni '%c', qtKeyCode %d", code, map.code, ++// QChar(unicode ).isPrint() ? ++// unicode : '?' , qtKeyCode); ++ ++ // Handle map changes based on press/release of modifiers ++ // hardcoded for now ++ int modif = -1; ++ int map = -1; ++ bool lock = false; ++ switch (qtKeyCode) ++ { ++ case Qt::Key_Alt: ++ case Qt::Key_F22: ++ modif = (1<<KG_ALT); ++ break; ++ case Qt::Key_Control: ++ modif = (1<<KG_CTRL); ++ map = modif; ++ break; ++ case Qt::Key_Shift: ++ modif = (1<<KG_SHIFT); ++ map = modif; ++ break; ++ case KeyMap::Key_AltGr: ++ map = (1<<KG_ALTGR ); ++ break; ++ case Qt::Key_Left: ++ case Qt::Key_Right: ++ case Qt::Key_Up: ++ case Qt::Key_Down: ++ mod_key = false; ++ if (qt_screen->isTransformed()) ++ qtKeyCode = static_cast<Qt::Key>( xform_dirkey(static_cast<int>( qtKeyCode ) ) ); ++ break; ++ /* ++ * handle lock, we don't handle scroll lock! ++ */ ++ case Qt::Key_CapsLock: ++ case Qt::Key_NumLock: ++ lock = true; ++ default: ++ mod_key = false; ++ break; ++ } ++ ++ ++ /* ++ * Change the Map. We handle locks a bit different ++ */ ++ if ( lock ) ++ modifyLock( qtKeyCode, release ); ++ else ++ modifyModifier( map, modif, release ); ++ ++ handleExtra( qtKeyCode, release ); ++ ++ /* ++ * do not repeat modifier keys ++ */ ++ if ( modifier == old_modifier && mod_key ) ++ return; ++ ++ processKeyEvent(unicode & 0xff, qtKeyCode, map_to_modif(), !release, 0); ++} + + void QWSTtyKeyboardHandler::readKeyboardData() + { + unsigned char buf[81]; + int n = ::read(kbdFD, buf, 80 ); + for ( int loop = 0; loop < n; loop++ ) +- doKey(buf[loop]); ++ handleKey(buf[loop]); ++} ++ ++void QWSTtyKeyboardHandler::modifyLock( unsigned int lock, bool release ) { ++ if ( !release ) ++ return; ++ ++ if ( lock == Qt::Key_CapsLock ) { ++ toggleLed( LED_CAP ); ++ capslock = !capslock; ++ }else if ( lock == Qt::Key_NumLock ) { ++ toggleLed( LED_NUM ); ++ numlock = !numlock; ++ } ++} ++ ++void QWSTtyKeyboardHandler::restoreLeds() { ++ unsigned int leds; ++ ioctl(kbdFD, KDGETLED, &leds ); ++ leds &= ~LED_CAP; ++ leds &= ~LED_NUM; ++ ioctl(kbdFD, KDSETLED, &leds ); ++} ++ ++void QWSTtyKeyboardHandler::toggleLed(unsigned int led) { ++ unsigned int leds; ++ int ret = ioctl(kbdFD, KDGETLED, &leds ); ++ leds = leds & led ? (leds & ~led) : (leds | led); ++ ret = ioctl(kbdFD, KDSETLED, &leds ); + } + + typedef struct { +@@ -1445,13 +1972,13 @@ + return; + #ifdef QT_QWS_TIP2 + // custom scan codes - translate them and create a key event immediately +- if( overrideMap && event.value == 0 || overrideMap->find( event.value ) ) ++ if( overrideMap && event.value == 0 || overrideMap->find( event.value ) ) + { + if( event.value ) + { + int modifiers = 0; + QWSServer::KeyMap *km = overrideMap->find( event.value ); +- switch( km->unicode ) ++ switch( km->unicode ) + { + case Key_Menu: + case Key_Back: +@@ -1479,14 +2006,14 @@ + TRUE, FALSE ); + } + lastPress = km; +- } +- else if( lastPress ) ++ } ++ else if( lastPress ) + { +- processKeyEvent( lastPress->unicode, lastPress->key_code, 0, ++ processKeyEvent( lastPress->unicode, lastPress->key_code, 0, + FALSE, FALSE ); + lastPress = 0; + } +- } ++ } + else + #endif + { +@@ -1854,10 +2381,10 @@ + handler = new QWSUsbKeyboardHandler(device); + } else if ( type == "TTY" ) { + handler = new QWSTtyKeyboardHandler(device); +- } ++ } + else if( type == "Samsung" ) { + handler = new QWSSamsungKeypadHandler(device); +- } ++ } + else { + qWarning( "Keyboard type %s:%s unsupported", spec.latin1(), device.latin1() ); + } +Index: qt-2.3.10-snapshot-20060120/src/kernel/keyboard_linux_to_qt.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qt-2.3.10-snapshot-20060120/src/kernel/keyboard_linux_to_qt.h 2006-01-20 21:16:25.413760944 +0100 +@@ -0,0 +1,263 @@ ++/* ++ * Generated with a small python utility found at ++ * http://handhelds.org/~zecke/downloads/python_keytable_creator.py ++ */ ++ ++static const Qt::Key linux_to_qt[] = { ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_Backspace, ++Qt::Key_Tab, ++Qt::Key_unknown, // LineFeed ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, // No Symbol ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, // No Symbol ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_Escape, ++Qt::Key_unknown, ++Qt::Key_unknown, // No symbol ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_Space, ++Qt::Key_Exclam, ++Qt::Key_QuoteDbl, ++Qt::Key_NumberSign, ++Qt::Key_Dollar, ++Qt::Key_Percent, ++Qt::Key_Ampersand, ++Qt::Key_Apostrophe, ++Qt::Key_ParenLeft, ++Qt::Key_ParenRight, ++Qt::Key_Asterisk, ++Qt::Key_Plus, ++Qt::Key_Comma, ++Qt::Key_Minus, ++Qt::Key_Period, ++Qt::Key_Slash, ++Qt::Key_0, ++Qt::Key_1, ++Qt::Key_2, ++Qt::Key_3, ++Qt::Key_4, ++Qt::Key_5, ++Qt::Key_6, ++Qt::Key_7, ++Qt::Key_8, ++Qt::Key_9, ++Qt::Key_Colon, ++Qt::Key_Semicolon, ++Qt::Key_Less, ++Qt::Key_Equal, ++Qt::Key_Greater, ++Qt::Key_Question, ++Qt::Key_At, ++Qt::Key_A, ++Qt::Key_B, ++Qt::Key_C, ++Qt::Key_D, ++Qt::Key_E, ++Qt::Key_F, ++Qt::Key_G, ++Qt::Key_H, ++Qt::Key_I, ++Qt::Key_J, ++Qt::Key_K, ++Qt::Key_L, ++Qt::Key_M, ++Qt::Key_N, ++Qt::Key_O, ++Qt::Key_P, ++Qt::Key_Q, ++Qt::Key_R, ++Qt::Key_S, ++Qt::Key_T, ++Qt::Key_U, ++Qt::Key_V, ++Qt::Key_W, ++Qt::Key_X, ++Qt::Key_Y, ++Qt::Key_Z, ++Qt::Key_BracketLeft, ++Qt::Key_Backslash, ++Qt::Key_BracketRight, ++Qt::Key_AsciiCircum, ++Qt::Key_Underscore, ++Qt::Key_QuoteLeft, // grave ++Qt::Key_A, ++Qt::Key_B, ++Qt::Key_C, ++Qt::Key_D, ++Qt::Key_E, ++Qt::Key_F, ++Qt::Key_G, ++Qt::Key_H, ++Qt::Key_I, ++Qt::Key_J, ++Qt::Key_K, ++Qt::Key_L, ++Qt::Key_M, ++Qt::Key_N, ++Qt::Key_O, ++Qt::Key_P, ++Qt::Key_Q, ++Qt::Key_R, ++Qt::Key_S, ++Qt::Key_T, ++Qt::Key_U, ++Qt::Key_V, ++Qt::Key_W, ++Qt::Key_X, ++Qt::Key_Y, ++Qt::Key_Z, ++Qt::Key_BraceLeft, ++Qt::Key_Bar, ++Qt::Key_BraceRight, ++Qt::Key_AsciiTilde, ++Qt::Key_BackSpace, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_unknown, ++Qt::Key_nobreakspace, ++Qt::Key_exclamdown, ++Qt::Key_cent, ++Qt::Key_sterling, ++Qt::Key_currency, ++Qt::Key_yen, ++Qt::Key_brokenbar, ++Qt::Key_section, ++Qt::Key_diaeresis, ++Qt::Key_copyright, ++Qt::Key_ordfeminine, ++Qt::Key_guillemotleft, ++Qt::Key_notsign, ++Qt::Key_hyphen, ++Qt::Key_registered, ++Qt::Key_macron, ++Qt::Key_degree, ++Qt::Key_plusminus, ++Qt::Key_twosuperior, ++Qt::Key_threesuperior, ++Qt::Key_acute, ++Qt::Key_mu, ++Qt::Key_paragraph, ++Qt::Key_periodcentered, ++Qt::Key_cedilla, ++Qt::Key_onesuperior, ++Qt::Key_masculine, ++Qt::Key_guillemotright, ++Qt::Key_onequarter, ++Qt::Key_onehalf, ++Qt::Key_threequarters, ++Qt::Key_questiondown, ++Qt::Key_Agrave, ++Qt::Key_Aacute, ++Qt::Key_Acircumflex, ++Qt::Key_Atilde, ++Qt::Key_Adiaeresis, ++Qt::Key_Aring, ++Qt::Key_AE, ++Qt::Key_Ccedilla, ++Qt::Key_Egrave, ++Qt::Key_Eacute, ++Qt::Key_Ecircumflex, ++Qt::Key_Ediaeresis, ++Qt::Key_Igrave, ++Qt::Key_Iacute, ++Qt::Key_Icircumflex, ++Qt::Key_Idiaeresis, ++Qt::Key_ETH, ++Qt::Key_Ntilde, ++Qt::Key_Ograve, ++Qt::Key_Oacute, ++Qt::Key_Ocircumflex, ++Qt::Key_Otilde, ++Qt::Key_Odiaeresis, ++Qt::Key_multiply, ++Qt::Key_Ooblique, ++Qt::Key_Ugrave, ++Qt::Key_Uacute, ++Qt::Key_Ucircumflex, ++Qt::Key_Udiaeresis, ++Qt::Key_Yacute, ++Qt::Key_THORN, ++Qt::Key_ssharp, ++Qt::Key_agrave, ++Qt::Key_aacute, ++Qt::Key_acircumflex, ++Qt::Key_atilde, ++Qt::Key_adiaeresis, ++Qt::Key_aring, ++Qt::Key_ae, ++Qt::Key_ccedilla, ++Qt::Key_egrave, ++Qt::Key_eacute, ++Qt::Key_ecircumflex, ++Qt::Key_ediaeresis, ++Qt::Key_igrave, ++Qt::Key_iacute, ++Qt::Key_icircumflex, ++Qt::Key_idiaeresis, ++Qt::Key_eth, ++Qt::Key_ntilde, ++Qt::Key_ograve, ++Qt::Key_oacute, ++Qt::Key_ocircumflex, ++Qt::Key_otilde, ++Qt::Key_odiaeresis, ++Qt::Key_division, ++Qt::Key_oslash, ++Qt::Key_ugrave, ++Qt::Key_uacute, ++Qt::Key_ucircumflex, ++Qt::Key_udiaeresis, ++Qt::Key_yacute, ++Qt::Key_thorn, ++Qt::Key_ydiaeresis ++}; diff --git a/packages/qte/qte-2.3.12/key.patch b/packages/qte/qte-2.3.12/key.patch new file mode 100644 index 0000000000..590ae9a7c6 --- /dev/null +++ b/packages/qte/qte-2.3.12/key.patch @@ -0,0 +1,90 @@ + +# +# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qkeyboard_qws.cpp 2006-01-20 20:57:47.547702416 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:09:23.001977296 +0100 +@@ -848,6 +848,9 @@ + bool release = false; + int keypad = 0; + ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) // need autorepeat implemented here? ++ bool repeatable = TRUE; ++ + #ifndef QT_QWS_USE_KEYCODES + #if defined(QT_QWS_IPAQ) + // map ipaq 'action' key (0x60, 0xe0) +@@ -984,9 +987,6 @@ + if ( currentKey ) + keyCode = currentKey->key_code; + +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) // need autorepeat implemented here? +- bool repeatable = TRUE; +- + #if defined(QT_QWS_IPAQ) + switch (code) { + #if defined(QT_QWS_SL5XXX) +@@ -1061,25 +1061,23 @@ + repeatable = FALSE; + #endif + ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) + if ( qt_screen->isTransformed() + && keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down ) + { + keyCode = xform_dirkey(keyCode); + } +- +-#ifdef QT_QWS_AUTOREPEAT_MANUALLY +- if ( repeatable && !release ) +- rep->start(prevuni,prevkey,modifiers); +- else +- rep->stop(); + #endif ++ + #endif + /* + Translate shift+Key_Tab to Key_Backtab + */ + if (( keyCode == Key_Tab ) && shift ) + keyCode = Key_Backtab; ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) + } ++#endif + + #ifndef QT_QWS_USE_KEYCODES + /* +@@ -1234,6 +1232,14 @@ + } else { + prevkey = prevuni = 0; + } ++ ++#ifdef QT_QWS_AUTOREPEAT_MANUALLY ++ if ( repeatable && !release ) ++ rep->start(prevuni,prevkey,modifiers); ++ else ++ rep->stop(); ++#endif ++ + } + #ifndef QT_QWS_USE_KEYCODES + extended = 0; +@@ -2059,6 +2065,7 @@ + press ? "press" : "release", + repeatable ? "true":"false" ); + ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) + if ( qt_screen->isTransformed() && k >= Qt::Key_Left && k <= Qt::Key_Down ) + { + qDebug( "SimpadButtonsHandler() - We are transformed! Correcting..." ); +@@ -2066,6 +2073,7 @@ + k = xform_dirkey( k ); + qDebug( "SimpadButtonsHandler() - Old Key: %d - New Key %d", oldK, k ); + } ++#endif + + if ( repeatable && press ) + repeater->start( repeatdelay, true ); diff --git a/packages/qte/qte-2.3.12/mnci-touchscreen.patch b/packages/qte/qte-2.3.12/mnci-touchscreen.patch new file mode 100644 index 0000000000..570c2ff290 --- /dev/null +++ b/packages/qte/qte-2.3.12/mnci-touchscreen.patch @@ -0,0 +1,1987 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.10/src/kernel/qwsmouse_qws.cpp~ramses-touchscreen ++++ qt-2.3.10/src/kernel/qwsmouse_qws.cpp +@@ -1,5 +1,5 @@ + /**************************************************************************** +-** $Id: qt/src/kernel/qwsmouse_qws.cpp 2.3.10 edited 2005-01-24 $ ++** $Id: qt/src/kernel/qwsmouse_qws.cpp 2.3.7 edited 2003-02-04 $ + ** + ** Implementation of Qt/Embedded mouse drivers + ** +@@ -47,85 +47,32 @@ + #include <stdlib.h> + #include <stdio.h> + #include <sys/ioctl.h> +-#include <sys/time.h> + #include <sys/types.h> + #include <sys/stat.h> + #include <fcntl.h> + #include <errno.h> + #include <termios.h> + ++ + #include <qgfx_qws.h> + #if !defined(_OS_QNX6_) + +-#ifdef QT_QWS_CASSIOPEIA +-#include <linux/tpanel.h> +-#endif +-#ifdef QT_QWS_TSLIB +-#include <tslib.h> +-#endif +- +- +-//#define QT_QWS_K2 +- +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_K2) +-#define QT_QWS_IPAQ_RAW +-typedef struct { +- unsigned short pressure; +- unsigned short x; +- unsigned short y; +- unsigned short pad; +- struct timeval stamp; +-} TS_EVENT; +-#elif defined(QT_QWS_SL5XXX) +-#define QT_QWS_SL5XXX_RAW +-typedef struct { +- long y; +- long x; +- long pressure; +- long long millisecs; +-} TS_EVENT; +-#define QT_QWS_TP_SAMPLE_SIZE 10 +-#define QT_QWS_TP_MINIMUM_SAMPLES 4 +-#define QT_QWS_TP_PRESSURE_THRESHOLD 500 +-#define QT_QWS_TP_MOVE_LIMIT 50 +-#define QT_QWS_TP_JITTER_LIMIT 2 +-#elif defined(QT_QWS_SLC700) +-#define QT_QWS_SLC700_RAW +-typedef struct { +- unsigned short pressure; +- unsigned short x; +- unsigned short y; +- unsigned short millisecs; +-} TS_EVENT; +-#define QT_QWS_TP_SAMPLE_SIZE 10 +-#define QT_QWS_TP_MINIMUM_SAMPLES 4 +-#define QT_QWS_TP_PRESSURE_THRESHOLD 500 +-#define QT_QWS_TP_MOVE_LIMIT 50 +-#define QT_QWS_TP_JITTER_LIMIT 2 +-#endif +- +-#ifndef QT_QWS_TP_SAMPLE_SIZE +-#define QT_QWS_TP_SAMPLE_SIZE 5 +-#endif +- +-#ifndef QT_QWS_TP_MINIMUM_SAMPLES +-#define QT_QWS_TP_MINIMUM_SAMPLES 5 ++#ifndef QT_QWS_TP_PRESSURE_DOWN_THRESHOLD ++#define QT_QWS_TP_PRESSURE_DOWN_THRESHOLD 500 + #endif + +-#ifndef QT_QWS_TP_PRESSURE_THRESHOLD +-#define QT_QWS_TP_PRESSURE_THRESHOLD 1 ++#ifndef QT_QWS_TP_PRESSURE_UP_THRESHOLD ++#define QT_QWS_TP_PRESSURE_UP_THRESHOLD 450 + #endif + +-#ifndef QT_QWS_TP_MOVE_LIMIT +-#define QT_QWS_TP_MOVE_LIMIT 100 ++#ifndef QT_QWS_TP_TABLE_SIZE ++#define QT_QWS_TP_TABLE_SIZE 2 + #endif + +-#ifndef QT_QWS_TP_JITTER_LIMIT +-#define QT_QWS_TP_JITTER_LIMIT 2 ++#ifndef QT_QWS_TP_MOVE_MAX ++#define QT_QWS_TP_MOVE_MAX 100 + #endif + +-//#define QWS_CUSTOMTOUCHPANEL +- + /*! + \class QWSMouseHandler qwsmouse_qws.h + \brief Mouse driver/handler for Qt/Embedded +@@ -168,8 +115,7 @@ + enum MouseProtocol { Unknown = -1, Auto = 0, + MouseMan, IntelliMouse, Microsoft, + QVFBMouse, TPanel, BusMouse, +- FirstAuto = MouseMan, +- LastAuto = Microsoft }; ++ }; + + static void limitToScreen( QPoint &pt ) + { +@@ -186,810 +132,14 @@ + } MouseConfig; + + static const MouseConfig mouseConfig[] = { +-#ifndef QT_NO_QWS_MOUSE_AUTO + { "Auto", Auto }, +-#endif +-#ifndef QT_NO_QWS_MOUSE_PC +- { "MouseMan", MouseMan }, +- { "IntelliMouse", IntelliMouse }, +- { "USB", IntelliMouse }, +- { "Microsoft", Microsoft }, +-#endif +-#ifndef QT_NO_QWS_VFB + { "QVFbMouse", QVFBMouse }, +-#endif + { "TPanel", TPanel }, +- { "BusMouse", BusMouse }, + { 0, Unknown } + }; + +-#ifndef QT_NO_QWS_MOUSE_AUTO +-/* +- * Automatic-detection mouse driver +- */ +- +-class QAutoMouseSubHandler { +-protected: +- enum { max_buf=32 }; +- +- int fd; +- +- uchar buffer[max_buf]; +- int nbuf; +- +- QPoint motion; +- int bstate; +- +- int goodness; +- int badness; +- +- virtual int tryData()=0; +- +-public: +- QAutoMouseSubHandler(int f) : fd(f) +- { +- nbuf = bstate = goodness = badness = 0; +- } +- +- int file() const { return fd; } +- +- void closeIfNot(int& f) +- { +- if ( fd != f ) { +- f = fd; +- close(fd); +- } +- } +- +- void worse(int by=1) { badness+=by; } +- bool reliable() const { return goodness >= 5 && badness < 50; } +- int buttonState() const { return bstate; } +- bool motionPending() const { return motion!=QPoint(0,0); } +- QPoint takeMotion() { QPoint r=motion; motion=QPoint(0,0); return r; } +- +- void appendData(uchar* data, int length) +- { +- memcpy(buffer+nbuf, data, length); +- nbuf += length; +- } +- +- enum UsageResult { Insufficient, Motion, Button }; +- +- UsageResult useData() +- { +- int pbstate = bstate; +- int n = tryData(); +- if ( n > 0 ) { +- if ( n<nbuf ) +- memmove( buffer, buffer+n, nbuf-n ); +- nbuf -= n; +- return pbstate == bstate ? Motion : Button; +- } +- return Insufficient; +- } +-}; +- +-class QAutoMouseSubHandler_intellimouse : public QAutoMouseSubHandler { +- int packetsize; +-public: +- QAutoMouseSubHandler_intellimouse(int f) : QAutoMouseSubHandler(f) +- { +- init(); +- } +- +- void init() +- { +- int n; +- uchar reply[20]; +- +- tcflush(fd,TCIOFLUSH); +- static const uchar initseq[] = { 243, 200, 243, 100, 243, 80 }; +- static const uchar query[] = { 0xf2 }; +- if (write(fd, initseq, sizeof(initseq))!=sizeof(initseq)) { +- badness = 100; +- return; +- } +- usleep(10000); +- tcflush(fd,TCIOFLUSH); +- if (write(fd, query, sizeof(query))!=sizeof(query)) { +- badness = 100; +- return; +- } +- usleep(10000); +- n = read(fd, reply, 20); +- if ( n > 0 ) { +- goodness = 10; +- switch ( reply[n-1] ) { +- case 3: +- case 4: +- packetsize = 4; +- break; +- default: +- packetsize = 3; +- } +- } else { +- badness = 100; +- } +- } +- +- int tryData() +- { +- if ( nbuf >= packetsize ) { +- //int overflow = (buffer[0]>>6 )& 0x03; +- +- if ( /*overflow ||*/ !(buffer[0] & 8) ) { +- badness++; +- return 1; +- } else { +- motion += +- QPoint((buffer[0] & 0x10) ? buffer[1]-256 : buffer[1], +- (buffer[0] & 0x20) ? 256-buffer[2] : -buffer[2]); +- int nbstate = buffer[0] & 0x7; +- if ( motion.x() || motion.y() || bstate != nbstate ) { +- bstate = nbstate; +- goodness++; +- } else { +- badness++; +- return 1; +- } +- } +- return packetsize; +- } +- return 0; +- } +-}; +- +-class QAutoMouseSubHandler_serial : public QAutoMouseSubHandler { +-public: +- QAutoMouseSubHandler_serial(int f) : QAutoMouseSubHandler(f) +- { +- initSerial(); +- } +- +-protected: +- void setflags(int f) +- { +- termios tty; +- tcgetattr(fd, &tty); +- tty.c_iflag = IGNBRK | IGNPAR; +- tty.c_oflag = 0; +- tty.c_lflag = 0; +- tty.c_cflag = f | CREAD | CLOCAL | HUPCL; +-#if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_) +- tty.c_line = 0; +-#endif +- tty.c_cc[VTIME] = 0; +- tty.c_cc[VMIN] = 1; +- tcsetattr(fd, TCSANOW, &tty); +- } +- +-private: +- void initSerial() +- { +- int speed[4] = { B9600, B4800, B2400, B1200 }; +- +- for (int n = 0; n < 4; n++) { +- setflags(CSTOPB | speed[n]); +- write(fd, "*q", 2); +- usleep(10000); +- } +- } +-}; +- +-class QAutoMouseSubHandler_mousesystems : public QAutoMouseSubHandler_serial { +-public: +- // ##### This driver has not been tested +- +- QAutoMouseSubHandler_mousesystems(int f) : QAutoMouseSubHandler_serial(f) +- { +- init(); +- } +- +- void init() +- { +- setflags(B1200|CS8|CSTOPB); +- // 60Hz +- if (write(fd, "R", 1)!=1) { +- badness = 100; +- return; +- } +- tcflush(fd,TCIOFLUSH); +- } +- +- int tryData() +- { +- if ( nbuf >= 5 ) { +- if ( (buffer[0] & 0xf8) != 0x80 ) { +- badness++; +- return 1; +- } +- motion += +- QPoint((signed char)buffer[1] + (signed char)buffer[3], +- -(signed char)buffer[2] + (signed char)buffer[4]); +- int t = ~buffer[0]; +- int nbstate = ((t&3) << 1) | ((t&4) >> 2); +- if ( motion.x() || motion.y() || bstate != nbstate ) { +- bstate = nbstate; +- goodness++; +- } else { +- badness++; +- return 1; +- } +- return 5; +- } +- return 0; +- } +-}; +- +-class QAutoMouseSubHandler_ms : public QAutoMouseSubHandler_serial { +- int mman; +-public: +- QAutoMouseSubHandler_ms(int f) : QAutoMouseSubHandler_serial(f) +- { +- mman=0; +- init(); +- } +- +- void init() +- { +- setflags(B1200|CS7); +- // 60Hz +- if (write(fd, "R", 1)!=1) { +- badness = 100; +- return; +- } +- tcflush(fd,TCIOFLUSH); +- } +- +- int tryData() +- { +- if ( !(buffer[0] & 0x40) ) { +- if ( buffer[0] == 0x20 && (bstate & Qt::MidButton) ) { +- mman=1; // mouseman extension +- } +- return 1; +- } +- int extra = mman&&(bstate & Qt::MidButton); +- if ( nbuf >= 3+extra ) { +- int nbstate = 0; +- if ( buffer[0] == 0x40 && !bstate && !buffer[1] && !buffer[2] ) { +- nbstate = Qt::MidButton; +- } else { +- nbstate = ((buffer[0] & 0x20) >> 5) +- | ((buffer[0] & 0x10) >> 3); +- if ( extra && buffer[3] == 0x20 ) +- nbstate = Qt::MidButton; +- } +- +- if ( buffer[1] & 0x40 ) { +- badness++; +- return 1; +- } else { +- motion += +- QPoint((signed char)((buffer[0]&0x3)<<6) +- |(signed char)(buffer[1]&0x3f), +- (signed char)((buffer[0]&0xc)<<4) +- |(signed char)(buffer[2]&0x3f)); +- if ( motion.x() || motion.y() || bstate != nbstate ) { +- bstate = nbstate; +- goodness++; +- } else { +- badness++; +- return 1; +- } +- return 3+extra; +- } +- } +- return 0; +- } +-}; +- +-/* +-QAutoMouseHandler::UsageResult QAutoMouseHandler::useDev(Dev& d) +-{ +- if ( d.nbuf >= mouseData[d.protocol].bytesPerPacket ) { +- uchar *mb = d.buf; +- int bstate = 0; +- int dx = 0; +- int dy = 0; +- +- switch (mouseProtocol) { +- case MouseMan: +- case IntelliMouse: +- { +- bstate = mb[0] & 0x7; // assuming Qt::*Button order +- +- int overflow = (mb[0]>>6 )& 0x03; +- if (mouseProtocol == MouseMan && overflow) { +- //### wheel events signalled with overflow bit, ignore for now +- } +- else { +- bool xs = mb[0] & 0x10; +- bool ys = mb[0] & 0x20; +- dx = xs ? mb[1]-256 : mb[1]; +- dy = ys ? mb[2]-256 : mb[2]; +- } +- break; +- } +- case Microsoft: +- if ( ((mb[0] & 0x20) >> 3) ) { +- bstate |= Qt::LeftButton; +- } +- if ( ((mb[0] & 0x10) >> 4) ) { +- bstate |= Qt::RightButton; +- } +- +- dx=(signed char)(((mb[0] & 0x03) << 6) | (mb[1] & 0x3f)); +- dy=-(signed char)(((mb[0] & 0x0c) << 4) | (mb[2] & 0x3f)); +- +- break; +- } +- } +- } +-*/ +- +-#endif +- +-class QAutoMouseHandler : public QWSMouseHandler { +- Q_OBJECT +- +-public: +- QAutoMouseHandler(); +- ~QAutoMouseHandler(); +- +-#ifndef QT_NO_QWS_MOUSE_AUTO +-private: +- enum { max_dev=32 }; +- QAutoMouseSubHandler *sub[max_dev]; +- QList<QSocketNotifier> notifiers; +- int nsub; +- int retries; +-#endif +- +-private slots: +- void readMouseData(int); +- +-private: +-#ifndef QT_NO_QWS_MOUSE_AUTO +- void openDevices(); +- void closeDevices(); +- void notify(int fd); +- bool sendEvent(QAutoMouseSubHandler& h) +- { +- if ( h.reliable() ) { +- mousePos += h.takeMotion(); +- limitToScreen( mousePos ); +-/* +-qDebug("%d,%d %c%c%c", +-mousePos.x(),mousePos.y(), +-(h.buttonState()&Qt::LeftButton)?'L':'.', +-(h.buttonState()&Qt::MidButton)?'M':'.', +-(h.buttonState()&Qt::RightButton)?'R':'.'); +-*/ +- emit mouseChanged(mousePos,h.buttonState()); +- return TRUE; +- } else { +- h.takeMotion(); +- if ( h.buttonState() & (Qt::RightButton|Qt::MidButton) ) { +- // Strange for the user to press right or middle without +- // a moving mouse! +- h.worse(); +- } +- return FALSE; +- } +- } +-#endif +-}; +- +-QAutoMouseHandler::QAutoMouseHandler() +-{ +-#ifndef QT_NO_QWS_MOUSE_AUTO +- notifiers.setAutoDelete( TRUE ); +- retries = 0; +- openDevices(); +-#endif +-} +- +-QAutoMouseHandler::~QAutoMouseHandler() +-{ +-#ifndef QT_NO_QWS_MOUSE_AUTO +- closeDevices(); +-#endif +-} +- +-#ifndef QT_NO_QWS_MOUSE_AUTO +-void QAutoMouseHandler::openDevices() +-{ +- nsub=0; +- int fd; +- fd = open( "/dev/psaux", O_RDWR | O_NDELAY ); +- if ( fd >= 0 ) { +- sub[nsub++] = new QAutoMouseSubHandler_intellimouse(fd); +- notify(fd); +- } +-#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_SL5XXX) && !defined(QT_QWS_K2) && !defined(QT_QWS_SLC700) +- char fn[] = "/dev/ttyS?"; +- for (int ch='0'; ch<='3'; ch++) { +- fn[9] = ch; +- fd = open( fn, O_RDWR | O_NDELAY ); +- if ( fd >= 0 ) { +- //sub[nsub++] = new QAutoMouseSubHandler_intellimouse(fd); +- sub[nsub++] = new QAutoMouseSubHandler_mousesystems(fd); +- sub[nsub++] = new QAutoMouseSubHandler_ms(fd); +- notify(fd); +- } +- } +-#endif +- // ... +-} +- +-void QAutoMouseHandler::closeDevices() +-{ +- int pfd=-1; +- for (int i=0; i<nsub; i++) { +- sub[i]->closeIfNot(pfd); +- delete sub[i]; +- } +- notifiers.clear(); +-} +- +-void QAutoMouseHandler::notify(int fd) +-{ +- QSocketNotifier *mouseNotifier +- = new QSocketNotifier( fd, QSocketNotifier::Read, this ); +- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData(int))); +- notifiers.append( mouseNotifier ); +-} +-#endif +- +-void QAutoMouseHandler::readMouseData(int fd) +-{ +-#ifndef QT_NO_QWS_MOUSE_AUTO +- for (;;) { +- uchar buf[8]; +- int n = read(fd, buf, 8); +- if ( n<=0 ) +- break; +- for (int i=0; i<nsub; i++) { +- QAutoMouseSubHandler& h = *sub[i]; +- if ( h.file() == fd ) { +- h.appendData(buf,n); +- for (;;) { +- switch ( h.useData() ) { +- case QAutoMouseSubHandler::Button: +- sendEvent(h); +- break; +- case QAutoMouseSubHandler::Insufficient: +- goto breakbreak; +- case QAutoMouseSubHandler::Motion: +- break; +- } +- } +- breakbreak: +- ; +- } +- } +- } +- bool any_reliable=FALSE; +- for (int i=0; i<nsub; i++) { +- QAutoMouseSubHandler& h = *sub[i]; +- if ( h.motionPending() ) +- sendEvent(h); +- any_reliable = any_reliable || h.reliable(); +- } +- if ( any_reliable ) { +- // ... get rid of all unreliable ones? All bad ones? +- } else if ( retries < 2 ) { +- // Try again - maybe the mouse was being moved when we tried to init. +- closeDevices(); +- openDevices(); +- retries++; +- } +-#else +- Q_UNUSED( fd ); +-#endif +-} +- +- +- +- +-/* +- * Standard mouse driver +- */ +- +-typedef struct { +- int bytesPerPacket; +-} MouseData; +- +-static const MouseData mouseData[] = { +- { 3 }, // dummy for auto protocal, correction made by add by YYD +- { 3 }, // MouseMan +- { 4 }, // intelliMouse +- { 3 }, // Microsoft +- { 0 }, // QVFBMouse, +- { 0 }, // TPanel, +- { 3 }, // BusMouse, +-}; +- +- +-class QWSMouseHandlerPrivate : public QWSMouseHandler { +- Q_OBJECT +-public: +- QWSMouseHandlerPrivate( MouseProtocol protocol, QString mouseDev ); +- ~QWSMouseHandlerPrivate(); +- +-#ifndef QT_NO_QWS_MOUSE_PC +-private: +- static const int mouseBufSize = 128; +- int mouseFD; +- int mouseIdx; +- uchar mouseBuf[mouseBufSize]; +- MouseProtocol mouseProtocol; +- void handleMouseData(); +-#endif +- +-private slots: +- void readMouseData(); +- +-private: +- int obstate; +-}; +- +- +-void QWSMouseHandlerPrivate::readMouseData() +-{ +-#ifndef QT_NO_QWS_MOUSE_PC +- int n; +- if ( BusMouse == mouseProtocol ) { +- // a workaround of linux busmouse driver interface. +- // It'll only read 3 bytes a time and return all other buffer zeroed, thus cause protocol errors +- for (;;) { +- if ( mouseBufSize - mouseIdx < 3 ) +- break; +- n = read( mouseFD, mouseBuf+mouseIdx, 3 ); +- if ( n != 3 ) +- break; +- mouseIdx += 3; +- } +- } else { +- do { +- n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx ); +- if ( n > 0 ) +- mouseIdx += n; +- } while ( n > 0 ); +- } +- handleMouseData(); +-#endif +-} +- +- +-#ifndef QT_NO_QWS_MOUSE_PC +-/* +-*/ +- +-void QWSMouseHandlerPrivate::handleMouseData() +-{ +- static const int accel_limit = 5; +- static const int accel = 2; +- +- int idx = 0; +- int bstate = 0; +- int dx = 0, dy = 0; +- bool sendEvent = false; +- int tdx = 0, tdy = 0; +- +- while ( mouseIdx-idx >= mouseData[mouseProtocol].bytesPerPacket ) { +- //qDebug( "Got mouse data" ); +- uchar *mb = mouseBuf+idx; +- bstate = 0; +- dx = 0; +- dy = 0; +- sendEvent = false; +- switch (mouseProtocol) { +- case MouseMan: +- case IntelliMouse: +- { +- if (mb[0] & 0x01) +- bstate |= Qt::LeftButton; +- if (mb[0] & 0x02) +- bstate |= Qt::RightButton; +- if (mb[0] & 0x04) +- bstate |= Qt::MidButton; +- +- int overflow = (mb[0]>>6 )& 0x03; +- if (mouseProtocol == MouseMan && overflow) { +- //### wheel events signalled with overflow bit, ignore for now +- } +- else { +- bool xs = mb[0] & 0x10; +- bool ys = mb[0] & 0x20; +- dx = xs ? mb[1]-256 : mb[1]; +- dy = ys ? mb[2]-256 : mb[2]; + +- sendEvent = true; +- } +-#if 0 //debug +- if (mouseProtocol == MouseMan) +- printf("(%2d) %02x %02x %02x ", idx, mb[0], mb[1], mb[2]); +- else +- printf("(%2d) %02x %02x %02x %02x ",idx,mb[0],mb[1],mb[2],mb[3]); +- const char *b1 = (mb[0] & 0x01) ? "b1":" ";//left +- const char *b2 = (mb[0] & 0x02) ? "b2":" ";//right +- const char *b3 = (mb[0] & 0x04) ? "b3":" ";//mid + +- if ( overflow ) +- printf( "Overflow%d %s %s %s (%4d,%4d)\n", overflow, +- b1, b2, b3, mousePos.x(), mousePos.y() ); +- else +- printf( "%s %s %s (%+3d,%+3d) (%4d,%4d)\n", +- b1, b2, b3, dx, dy, mousePos.x(), mousePos.y() ); +-#endif +- break; +- } +- case Microsoft: +- if ( (mb[0] & 0x20) ) +- bstate |= Qt::LeftButton; +- if ( (mb[0] & 0x10) ) +- bstate |= Qt::RightButton; +- +- dx=(signed char)(((mb[0] & 0x03) << 6) | (mb[1] & 0x3f)); +- dy=-(signed char)(((mb[0] & 0x0c) << 4) | (mb[2] & 0x3f)); +- sendEvent=true; +- +- break; +- case BusMouse: +- if ( !(mb[0] & 0x04) ) +- bstate |= Qt::LeftButton; +- if ( !(mb[0] & 0x01) ) +- bstate |= Qt::RightButton; +- +- dx=(signed char)mb[1]; +- dy=(signed char)mb[2]; +- sendEvent=true; +- break; +- +- default: +- qWarning( "Unknown mouse protocol in QWSMouseHandlerPrivate" ); +- break; +- } +- if (sendEvent) { +- if ( QABS(dx) > accel_limit || QABS(dy) > accel_limit ) { +- dx *= accel; +- dy *= accel; +- } +- tdx += dx; +- tdy += dy; +- if ( bstate != obstate ) { +- mousePos += QPoint(tdx,-tdy); +- limitToScreen( mousePos ); +- emit mouseChanged(mousePos,bstate); +- sendEvent = FALSE; +- tdx = 0; +- tdy = 0; +- obstate = bstate; +- } +- } +- idx += mouseData[mouseProtocol].bytesPerPacket; +- } +- if ( sendEvent ) { +- mousePos += QPoint(tdx,-tdy); +- limitToScreen( mousePos ); +- emit mouseChanged(mousePos,bstate); +- } +- +- int surplus = mouseIdx - idx; +- for ( int i = 0; i < surplus; i++ ) +- mouseBuf[i] = mouseBuf[idx+i]; +- mouseIdx = surplus; +-} +-#endif +- +- +-QWSMouseHandlerPrivate::QWSMouseHandlerPrivate( MouseProtocol protocol, +- QString mouseDev ) +-{ +-#ifndef QT_NO_QWS_MOUSE_PC +- mouseProtocol = protocol; +- +- if ( mouseDev.isEmpty() ) +- mouseDev = "/dev/mouse"; +- obstate = -1; +- mouseFD = -1; +- mouseFD = open( mouseDev.local8Bit().data(), O_RDWR | O_NDELAY); +- if ( mouseFD < 0 ) { +- mouseFD = open( mouseDev.local8Bit().data(), O_RDONLY | O_NDELAY); +- if ( mouseFD < 0 ) +- qDebug( "Cannot open %s (%s)", mouseDev.ascii(), +- strerror(errno)); +- } else { +- // Clear pending input +- tcflush(mouseFD,TCIFLUSH); +- +- bool ps2 = false; +- +- switch (mouseProtocol) { +- case MouseMan: +- ps2 = true; +- write(mouseFD,"",1); +- usleep(50000); +- write(mouseFD,"@EeI!",5); +- break; +- +- case IntelliMouse: { +-// ps2 = true; +- const unsigned char init1[] = { 243, 200, 243, 100, 243, 80 }; +- const unsigned char init2[] = { 246, 230, 244, 243, 100, 232, 3 }; +- write(mouseFD,init1,sizeof(init1)); +- usleep(50000); +- write(mouseFD,init2,sizeof(init2)); +- } +- break; +- +- case Microsoft: +- struct termios tty; +- +- tcgetattr(mouseFD, &tty); +- +- tty.c_iflag = IGNBRK | IGNPAR; +- tty.c_oflag = 0; +- tty.c_lflag = 0; +-#if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_) +- tty.c_line = 0; +-#endif // _OS_FREEBSD_ +- tty.c_cc[VTIME] = 0; +- tty.c_cc[VMIN] = 1; +- tty.c_cflag = B1200 | CS7 | CREAD | CLOCAL | HUPCL; +- tcsetattr(mouseFD, TCSAFLUSH, &tty); /* set parameters */ +- break; +- +- case BusMouse: +- usleep(50000); +- break; +- +- default: +- qDebug("Unknown mouse protocol"); +- exit(1); +- } +- +- if (ps2) { +- char buf[] = { 246, 244 }; +- write(mouseFD,buf,1); +- write(mouseFD,buf+1,1); +- } +- +- usleep(50000); +- tcflush(mouseFD,TCIFLUSH); // ### doesn't seem to work. +- usleep(50000); +- tcflush(mouseFD,TCIFLUSH); // ### doesn't seem to work. +- +- char buf[100]; // busmouse driver will not read if bufsize < 3, YYD +- while (read(mouseFD, buf, 100) > 0) { } // eat unwanted replies +- +- mouseIdx = 0; +- +- QSocketNotifier *mouseNotifier; +- mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, this ); +- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); +- } +-#else +- Q_UNUSED(protocol); +- Q_UNUSED(mouseDev); +-#endif +-} +- +-QWSMouseHandlerPrivate::~QWSMouseHandlerPrivate() +-{ +-#ifndef QT_NO_QWS_MOUSE_PC +- if (mouseFD >= 0) { +- tcflush(mouseFD,TCIFLUSH); // yyd. +- close(mouseFD); +- } +-#endif +-} +- +-/* +- * +- */ + + QCalibratedMouseHandler::QCalibratedMouseHandler() + : samples(5), currSample(0), numSamples(0) +@@ -1030,7 +180,8 @@ + if ( file.open( IO_WriteOnly ) ) { + QTextStream t( &file ); + t << a << " " << b << " " << c << " "; +- t << d << " " << e << " " << f << " " << s; ++ t << d << " " << e << " " << f << " " << s << endl; ++ file.close(); + } else + #endif + { +@@ -1046,6 +197,7 @@ + if ( file.open( IO_ReadOnly ) ) { + QTextStream t( &file ); + t >> a >> b >> c >> d >> e >> f >> s; ++ file.close(); + } else + #endif + { +@@ -1073,12 +225,24 @@ + writeCalibration(); + } + ++void QCalibratedMouseHandler::setCalibration(int aa, int bb, int cc, int dd, int ee, int ff, int ss) ++{ ++ a = aa; ++ b = bb; ++ c = cc; ++ d = dd; ++ e = ee; ++ f = ff; ++ s = ss; ++} ++ + QPoint QCalibratedMouseHandler::transform( const QPoint &p ) + { + QPoint tp; + + tp.setX( (a * p.x() + b * p.y() + c) / s ); + tp.setY( (d * p.x() + e * p.y() + f) / s ); ++//qDebug("QCalibratedMouseHandler::transform(%d,%d) -> %d,%d)", p.x(), p.y(), tp.x(), tp.y() ); + + return tp; + } +@@ -1143,814 +307,192 @@ + return sent; + } + +-/* +- * Handler for /dev/tpanel Linux kernel driver +- */ + +-class QVrTPanelHandlerPrivate : public QCalibratedMouseHandler { +- Q_OBJECT +-public: +- QVrTPanelHandlerPrivate(MouseProtocol, QString dev); +- ~QVrTPanelHandlerPrivate(); + +-private: +- int mouseFD; +- MouseProtocol mouseProtocol; +-private slots: +- void sendRelease(); +- void readMouseData(); +-private: +- static const int mouseBufSize = 1280; +- QTimer *rtimer; +- int mouseIdx; +- uchar mouseBuf[mouseBufSize]; +-}; + +-#ifndef QT_QWS_CASSIOPEIA +-QVrTPanelHandlerPrivate::QVrTPanelHandlerPrivate( MouseProtocol, QString ) : +- QCalibratedMouseHandler() +-{ +-} +-#else +-QVrTPanelHandlerPrivate::QVrTPanelHandlerPrivate( MouseProtocol, QString dev ) : +- QCalibratedMouseHandler() +-{ +- if ( dev.isEmpty() ) +- dev = "/dev/tpanel"; +- +- if ((mouseFD = open( dev, O_RDONLY)) < 0) { +- qFatal( "Cannot open %s (%s)", dev.latin1(), strerror(errno)); +- } else { +- sleep(1); +- } +- +- struct scanparam s; +- s.interval = 20000; +- s.settletime = 480; +- if ( ioctl(mouseFD, TPSETSCANPARM, &s) < 0 +- || fcntl(mouseFD, F_SETFL, O_NONBLOCK) < 0 ) +- qWarning("Error initializing touch panel."); +- +- QSocketNotifier *mouseNotifier; +- mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, +- this ); +- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); +- +- rtimer = new QTimer( this ); +- connect( rtimer, SIGNAL(timeout()), this, SLOT(sendRelease())); +- mouseIdx = 0; +- setFilterSize( 3 ); +- +- printf("\033[?25l"); fflush(stdout); // VT100 cursor off +-} +-#endif +- +-QVrTPanelHandlerPrivate::~QVrTPanelHandlerPrivate() +-{ +- if (mouseFD >= 0) +- close(mouseFD); +-} +- +-void QVrTPanelHandlerPrivate::sendRelease() +-{ +- sendFiltered( mousePos, 0 ); +-} + +-void QVrTPanelHandlerPrivate::readMouseData() +-{ +-#ifdef QT_QWS_CASSIOPEIA +- if(!qt_screen) +- return; +- static bool pressed = FALSE; +- +- int n; +- do { +- n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx ); +- if ( n > 0 ) +- mouseIdx += n; +- } while ( n > 0 && mouseIdx < mouseBufSize ); +- +- int idx = 0; +- while ( mouseIdx-idx >= (int)sizeof( short ) * 6 ) { +- uchar *mb = mouseBuf+idx; +- ushort *data = (ushort *) mb; +- if ( data[0] & 0x8000 ) { +- if ( data[5] > 750 ) { +- QPoint t(data[3]-data[4],data[2]-data[1]); +- if ( sendFiltered( t, Qt::LeftButton ) ) +- pressed = TRUE; +- if ( pressed ) +- rtimer->start( 200, TRUE ); // release unreliable +- } +- } else if ( pressed ) { +- rtimer->start( 50, TRUE ); +- pressed = FALSE; +- } +- idx += sizeof( ushort ) * 6; +- } ++struct input_event { ++ struct timeval time; ++ unsigned short type; ++ unsigned short code; ++ unsigned int value; ++}; + +- int surplus = mouseIdx - idx; +- for ( int i = 0; i < surplus; i++ ) +- mouseBuf[i] = mouseBuf[idx+i]; +- mouseIdx = surplus; + +-#endif +-} ++#define EV_ABS 0x03 ++#define ABS_X 0x00 ++#define ABS_Y 0x01 ++#define ABS_PRESSURE 0x18 + + +-class QTPanelHandlerPrivate : public QCalibratedMouseHandler ++class QInputEventHandler : public QCalibratedMouseHandler + { + Q_OBJECT + public: +- QTPanelHandlerPrivate(MouseProtocol, QString dev); +- ~QTPanelHandlerPrivate(); ++ QInputEventHandler(MouseProtocol, QString dev); ++ ~QInputEventHandler(); ++ ++ virtual void calibrate( QWSPointerCalibrationData * ); ++ virtual void setCalibration(int aa, int bb, int cc, int dd, int ee, int ff, int ss); + + private: +- static const int mouseBufSize = 2048; ++ void init(); ++ void fini(); ++ + int mouseFD; +- QPoint oldmouse; +- QPoint oldTotalMousePos; +- bool waspressed; +- QPointArray samples; +- unsigned int currSample; +- unsigned int lastSample; +- unsigned int numSamples; +- int skipCount; +- int mouseIdx; +- uchar mouseBuf[mouseBufSize]; ++ struct input_event sample; ++ int myX, myY, myP, oldX, oldY, oldP; ++ int xtable[QT_QWS_TP_TABLE_SIZE]; ++ int ytable[QT_QWS_TP_TABLE_SIZE]; ++ int ptr; + + private slots: + void readMouseData(); + }; + + +-QTPanelHandlerPrivate::QTPanelHandlerPrivate( MouseProtocol, QString dev ) +- : samples(QT_QWS_TP_SAMPLE_SIZE), currSample(0), lastSample(0), +- numSamples(0), skipCount(0) +-{ +- Q_UNUSED(dev); +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) +-#if defined(QT_QWS_IPAQ) +-# ifdef QT_QWS_IPAQ_RAW +- if ((mouseFD = open( "/dev/h3600_tsraw", O_RDONLY | O_NDELAY)) < 0) { +-# else +- if ((mouseFD = open( "/dev/h3600_ts", O_RDONLY | O_NDELAY)) < 0) { +-# endif +- qWarning( "Cannot open /dev/h3600_ts (%s)", strerror(errno)); +- return; +- } +-#elif defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) +-//# ifdef QT_QWS_SL5XXX_TSRAW +-# if 0 +- if ((mouseFD = open( "/dev/tsraw", O_RDONLY | O_NDELAY)) < 0) { +- qWarning( "Cannot open /dev/tsraw (%s)", strerror(errno)); +- return; +- } +-# else +- if ((mouseFD = open( "/dev/ts", O_RDONLY | O_NDELAY)) < 0) { +- qWarning( "Cannot open /dev/ts (%s)", strerror(errno)); +- return; +- } +-# endif +-#elif defined(QT_QWS_SIMPAD ) +- if ((mouseFD = open( "/dev/touchscreen/ucb1x00", O_RDONLY | O_NONBLOCK )) < 0) { +- qWarning( "Cannot open /dev/touchscreen/ucb1x00 (%s)", strerror(errno)); +- return; +- } +-#endif +- +- QSocketNotifier *mouseNotifier; +- mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, +- this ); +- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); +- waspressed=FALSE; +- mouseIdx = 0; +-#endif +-} +- +-QTPanelHandlerPrivate::~QTPanelHandlerPrivate() ++QInputEventHandler::QInputEventHandler( MouseProtocol, QString ) ++ : myP(-1) + { +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) || defined(QT_QWS_SIMPAD) +- if (mouseFD >= 0) +- close(mouseFD); +-#endif ++ init(); + } + +-void QTPanelHandlerPrivate::readMouseData() ++QInputEventHandler::~QInputEventHandler() + { +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) || defined(QT_QWS_SIMPAD) +- if(!qt_screen) +- return; +- +- int n; +- do { +- n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx ); +- if ( n > 0 ) +- mouseIdx += n; +- } while ( n > 0 && mouseIdx < mouseBufSize ); +- +- TS_EVENT *data; +- int idx = 0; +- +- // perhaps we shouldn't be reading EVERY SAMPLE. +- while ( mouseIdx-idx >= (int)sizeof( TS_EVENT ) ) { +- uchar *mb = mouseBuf+idx; +- data = (TS_EVENT *) mb; +- if(data->pressure >= QT_QWS_TP_PRESSURE_THRESHOLD) { +-#if defined(QT_QWS_SL5XXX) || defined(QT_QWS_SLC700) +- samples[currSample] = QPoint( 1000 - data->x, data->y ); +-#else +- samples[currSample] = QPoint( data->x, data->y ); +-#endif +- +- numSamples++; +- if ( numSamples >= QT_QWS_TP_MINIMUM_SAMPLES ) { +- int sampleCount = QMIN(numSamples + 1,samples.count()); +- +- // average the rest +- mousePos = QPoint( 0, 0 ); +- QPoint totalMousePos = oldTotalMousePos; +- totalMousePos += samples[currSample]; +- if(numSamples >= samples.count()) +- totalMousePos -= samples[lastSample]; +- +- mousePos = totalMousePos / (sampleCount - 1); +- +-# if defined(QT_QWS_IPAQ_RAW) || defined(QT_QWS_SL5XXX_RAW) +- mousePos = transform( mousePos ); +-# endif +- if(!waspressed) +- oldmouse = mousePos; +- QPoint dp = mousePos - oldmouse; +- int dxSqr = dp.x() * dp.x(); +- int dySqr = dp.y() * dp.y(); +- if ( dxSqr + dySqr < (QT_QWS_TP_MOVE_LIMIT * QT_QWS_TP_MOVE_LIMIT) ) { +- if ( waspressed ) { +- if ( (dxSqr + dySqr > (QT_QWS_TP_JITTER_LIMIT * QT_QWS_TP_JITTER_LIMIT) ) || skipCount > 2) { +- emit mouseChanged(mousePos,Qt::LeftButton); +- oldmouse = mousePos; +- skipCount = 0; +- } else { +- skipCount++; +- } +- } else { +- emit mouseChanged(mousePos,Qt::LeftButton); +- oldmouse=mousePos; +- waspressed=true; +- } +- +- // save recuring information +- currSample++; +- if (numSamples >= samples.count()) +- lastSample++; +- oldTotalMousePos = totalMousePos; +- } else { +- numSamples--; // don't use this sample, it was bad. +- } +- } else { +- // build up the average +- oldTotalMousePos += samples[currSample]; +- currSample++; +- } +- if ( currSample >= samples.count() ) +- currSample = 0; +- if ( lastSample >= samples.count() ) +- lastSample = 0; +- } else { +- currSample = 0; +- lastSample = 0; +- numSamples = 0; +- skipCount = 0; +- oldTotalMousePos = QPoint(0,0); +- if ( waspressed ) { +- emit mouseChanged(oldmouse,0); +- oldmouse = QPoint( -100, -100 ); +- waspressed=false; +- } +- } +- idx += sizeof( TS_EVENT ); +- } ++ fini(); + +- int surplus = mouseIdx - idx; +- for ( int i = 0; i < surplus; i++ ) +- mouseBuf[i] = mouseBuf[idx+i]; +- mouseIdx = surplus; +-#endif + } + +-// YOPY touch panel support based on changes contributed by Ron Victorelli +-// (victorrj at icubed.com) to Custom TP driver. +-// +-class QYopyTPanelHandlerPrivate : public QWSMouseHandler { +- Q_OBJECT +-public: +- QYopyTPanelHandlerPrivate(MouseProtocol, QString dev); +- ~QYopyTPanelHandlerPrivate(); +- +-private: +- int mouseFD; +- int prevstate; +-private slots: +- void readMouseData(); +- +-}; +- +-QYopyTPanelHandlerPrivate::QYopyTPanelHandlerPrivate( MouseProtocol, QString ) ++void QInputEventHandler::setCalibration(int aa, int bb, int cc, int dd, int ee, int ff, int ss) + { +-#ifdef QT_QWS_YOPY +- if ((mouseFD = open( "/dev/ts", O_RDONLY)) < 0) { +- qWarning( "Cannot open /dev/ts (%s)", strerror(errno)); +- return; +- } else { +- sleep(1); +- } +- prevstate=0; +- QSocketNotifier *mouseNotifier; +- mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, +- this ); +- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); +-#endif +-} ++ QCalibratedMouseHandler::setCalibration(aa, bb, cc, dd, ee, ff, ss); + +-QYopyTPanelHandlerPrivate::~QYopyTPanelHandlerPrivate() +-{ +- if (mouseFD >= 0) +- close(mouseFD); ++ writeCalibration(); ++ fini(); ++ init(); + } + +-#define YOPY_XPOS(d) (d[1]&0x3FF) +-#define YOPY_YPOS(d) (d[2]&0x3FF) +-#define YOPY_PRES(d) (d[0]&0xFF) +-#define YOPY_STAT(d) (d[3]&0x01 ) +- +-struct YopyTPdata { +- +- unsigned char status; +- unsigned short xpos; +- unsigned short ypos; +- +-}; +- +-void QYopyTPanelHandlerPrivate::readMouseData() ++void QInputEventHandler::calibrate( QWSPointerCalibrationData *cd ) + { +-#ifdef QT_QWS_YOPY +- if(!qt_screen) +- return; +- YopyTPdata data; +- +- unsigned int yopDat[4]; +- +- int ret; +- +- ret=read(mouseFD,&yopDat,sizeof(yopDat)); ++ QCalibratedMouseHandler::calibrate( cd ); + +- if(ret) { +- data.status= ( YOPY_PRES(yopDat) ) ? 1 : 0; +- data.xpos=YOPY_XPOS(yopDat); +- data.ypos=YOPY_YPOS(yopDat); +- QPoint q; +- q.setX(data.xpos); +- q.setY(data.ypos); +- mousePos=q; +- if(data.status && !prevstate) { +- emit mouseChanged(mousePos,Qt::LeftButton); +- } else if( !data.status && prevstate ) { +- emit mouseChanged(mousePos,0); +- } +- prevstate = data.status; +- } +- if(ret<0) { +- qDebug("Error %s",strerror(errno)); +- } +-#endif ++ // write calibration data, and close and reopen ++ // tslib, in order to ensure it uses the new values ++ writeCalibration(); ++ fini(); ++ init(); + } + +-class QCustomTPanelHandlerPrivate : public QWSMouseHandler { +- Q_OBJECT +-public: +- QCustomTPanelHandlerPrivate(MouseProtocol, QString dev); +- ~QCustomTPanelHandlerPrivate(); +- +-private: +- int mouseFD; +-private slots: +- void readMouseData(); +- +-}; +- +-QCustomTPanelHandlerPrivate::QCustomTPanelHandlerPrivate( MouseProtocol, QString ) ++void QInputEventHandler::init() + { +-#ifdef QWS_CUSTOMTOUCHPANEL +- if ((mouseFD = open( "/dev/ts", O_RDONLY)) < 0) { +- qWarning( "Cannot open /dev/ts (%s)", strerror(errno)); ++ if ((mouseFD = open( "/dev/input/event1", O_RDONLY)) < 0) { ++ qWarning( "Cannot open /dev/input/event1 (%s)", strerror(errno)); + return; +- } else { +- sleep(1); + } + + QSocketNotifier *mouseNotifier; +- mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, +- this ); ++ mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, this ); ++ setFilterSize(2); + connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); +-#endif + } + +-QCustomTPanelHandlerPrivate::~QCustomTPanelHandlerPrivate() ++void QInputEventHandler::fini() + { + if (mouseFD >= 0) + close(mouseFD); + } + +-struct CustomTPdata { +- +- unsigned char status; +- unsigned short xpos; +- unsigned short ypos; +- +-}; +- +-void QCustomTPanelHandlerPrivate::readMouseData() ++void QInputEventHandler::readMouseData() + { +-#ifdef QWS_CUSTOMTOUCHPANEL +- if(!qt_screen) +- return; +- CustomTPdata data; +- +- unsigned char data2[5]; +- +- int ret; +- +- ret=read(mouseFD,data2,5); ++ if (!qt_screen) ++ return; + +- if(ret==5) { +- data.status=data2[0]; +- data.xpos=(data2[1] << 8) | data2[2]; +- data.ypos=(data2[3] << 8) | data2[4]; +- QPoint q; +- q.setX(data.xpos); +- q.setY(data.ypos); +- mousePos=q; +- if(data.status & 0x40) { +- emit mouseChanged(mousePos,Qt::LeftButton); +- } else { +- emit mouseChanged(mousePos,0); ++ unsigned int size = read(mouseFD, &sample, sizeof(sample)); ++ if (size < sizeof(sample)) { ++ qDebug("no input"); ++ return; ++ } ++ //qDebug("type,code,val: %d,%d,%d", sample.type, sample.code, sample.value); ++ if (sample.type == EV_ABS) { ++ if (sample.code == ABS_Y) { ++ myY = sample.value; ++ return; ++ } else ++ if (sample.code == ABS_X) { ++ myX = sample.value; ++ return; ++ } else ++ if (sample.code == ABS_PRESSURE) { ++ myP = sample.value; ++ } + } +- } +- if(ret<0) { +- qDebug("Error %s",strerror(errno)); +- } +-#endif +-} +- +-/* +- * Virtual framebuffer mouse driver +- */ +- +-#ifndef QT_NO_QWS_VFB +-#include "qvfbhdr.h" +-extern int qws_display_id; +-#endif +- +-class QVFbMouseHandlerPrivate : public QWSMouseHandler { +- Q_OBJECT +-public: +- QVFbMouseHandlerPrivate(MouseProtocol, QString dev); +- ~QVFbMouseHandlerPrivate(); +- +-#ifndef QT_NO_QWS_VFB +- bool isOpen() const { return mouseFD > 0; } +- +-private: +- static const int mouseBufSize = 128; +- int mouseFD; +- int mouseIdx; +- uchar mouseBuf[mouseBufSize]; +-#endif +- +-private slots: +- void readMouseData(); +-}; +- +-QVFbMouseHandlerPrivate::QVFbMouseHandlerPrivate( MouseProtocol, QString mouseDev ) +-{ +-#ifndef QT_NO_QWS_VFB +- mouseFD = -1; +- if ( mouseDev.isEmpty() ) +- mouseDev = QString(QT_VFB_MOUSE_PIPE).arg(qws_display_id); +- +- if ((mouseFD = open( mouseDev.local8Bit().data(), O_RDWR | O_NDELAY)) < 0) { +- qDebug( "Cannot open %s (%s)", mouseDev.ascii(), +- strerror(errno)); +- } else { +- // Clear pending input +- char buf[2]; +- while (read(mouseFD, buf, 1) > 0) { } +- +- mouseIdx = 0; +- +- QSocketNotifier *mouseNotifier; +- mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, this ); +- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); +- } +-#endif +-} +- +-QVFbMouseHandlerPrivate::~QVFbMouseHandlerPrivate() +-{ +-#ifndef QT_NO_QWS_VFB +- if (mouseFD >= 0) +- close(mouseFD); +-#endif +-} +- +-void QVFbMouseHandlerPrivate::readMouseData() +-{ +-#ifndef QT_NO_QWS_VFB +- int n; +- do { +- n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx ); +- if ( n > 0 ) +- mouseIdx += n; +- } while ( n > 0 ); +- +- int idx = 0; +- while ( mouseIdx-idx >= int(sizeof( QPoint ) + sizeof( int )) ) { +- uchar *mb = mouseBuf+idx; +- QPoint *p = (QPoint *) mb; +- mb += sizeof( QPoint ); +- int *bstate = (int *)mb; +- mousePos = *p; +- limitToScreen( mousePos ); +- emit mouseChanged(mousePos, *bstate); +- idx += sizeof( QPoint ) + sizeof( int ); +- } +- +- int surplus = mouseIdx - idx; +- for ( int i = 0; i < surplus; i++ ) +- mouseBuf[i] = mouseBuf[idx+i]; +- mouseIdx = surplus; +-#endif +-} +- +-/* +- mouse handler for tslib +- see http://cvs.arm.linux.org.uk/ +- */ +-/* +- +- Copyright (C) 2003, 2004, 2005 Texas Instruments, Inc. +- Copyright (C) 2004, 2005 Holger Hans Peter Freyther +- 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 Texas Instruments, Inc 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. +- +-*/ +-class QTSLibHandlerPrivate : public QCalibratedMouseHandler +-{ +- Q_OBJECT +-public: +- QTSLibHandlerPrivate(); +- ~QTSLibHandlerPrivate(); +- +- virtual void clearCalibration(); +- virtual void calibrate( QWSPointerCalibrationData * ); +- static int sortByX( const void*, const void* ); +- static int sortByY( const void*, const void* ); +- +-private: +- bool m_raw : 1; +- QSocketNotifier *m_notify; +- +-#ifdef QT_QWS_TSLIB +- struct tsdev *m_ts; +-#endif +- void openTs(); +- void closeTs(); +- void interpolateSample(); +- +-private slots: +- void readMouseData(); +- +-}; +- +-QTSLibHandlerPrivate::QTSLibHandlerPrivate() +- : m_raw(false), m_notify(0 ) +-{ +- openTs(); +-} +- +-QTSLibHandlerPrivate::~QTSLibHandlerPrivate() +-{ +- closeTs(); +-} +- +-void QTSLibHandlerPrivate::openTs() +-{ +-#ifdef QT_QWS_TSLIB +- char *tsdevice; +- if((tsdevice = getenv("TSLIB_TSDEVICE")) != NULL) { +- m_ts = ts_open( tsdevice, 1 ); //1 = nonblocking, 0 = blocking mode +- } else { +- m_ts = ts_open( "/dev/ts", 1 ); +- } +- +- if (!m_ts) { +- qWarning( "Cannot open touchscreen (%s)", strerror( errno)); +- return; +- } +- +- if (ts_config( m_ts)) { +- qWarning( "Cannot configure touchscreen (%s)", strerror( errno)); +- return; +- } +- m_notify = new QSocketNotifier( ts_fd(m_ts), QSocketNotifier::Read, this ); +- connect( m_notify, SIGNAL(activated(int)),this, SLOT(readMouseData())); +-#endif +-} +- +-void QTSLibHandlerPrivate::closeTs() +-{ +-#ifdef QT_QWS_TSLIB +- if (m_ts) +- ts_close(m_ts); +- m_ts = 0; +-#endif +- +- delete m_notify; +- m_notify = 0; +- m_raw = false; +-} +- +-void QTSLibHandlerPrivate::clearCalibration() +-{ +- m_raw = true; +-} +- +-void QTSLibHandlerPrivate::calibrate( QWSPointerCalibrationData * cd) +-{ +- QPoint dev_tl = cd->devPoints[ QWSPointerCalibrationData::TopLeft ]; +- QPoint dev_br = cd->devPoints[ QWSPointerCalibrationData::BottomRight ]; +- QPoint screen_tl = cd->screenPoints[ QWSPointerCalibrationData::TopLeft ]; +- QPoint screen_br = cd->screenPoints[ QWSPointerCalibrationData::BottomRight ]; +- int a, b, c, d, e, f, s; +- +- s = 1 << 16; + +- a = s * (screen_tl.x() - screen_br.x() ) / (dev_tl.x() - dev_br.x()); +- b = 0; +- c = s * screen_tl.x() - a * dev_tl.x(); ++ // up->up ++ if (oldP==0 && myP==0) { ++ //qDebug("uu %d,%d,%d", myX,myY,myP); ++ return; ++ } + +- d = 0; +- e = s * (screen_tl.y() - screen_br.y() ) / (dev_tl.y() - dev_br.y()); +- f = s * screen_tl.y() - e * dev_tl.y(); ++ // up->down ++ if (oldP==0 && myP>QT_QWS_TP_PRESSURE_DOWN_THRESHOLD) { ++ //qDebug("ud %d,%d,%d", myX,myY,myP); + +- QString calFile = "/etc/pointercal"; +-#ifndef QT_NO_TEXTSTREAM +- QFile file( calFile ); +- if ( file.open( IO_WriteOnly ) ) { +- QTextStream t( &file ); +- t << a << " " << b << " " << c << " "; +- t << d << " " << e << " " << f << " " << s; +- file.flush(); closeTs(); +- openTs(); +- } else +-#endif +- { +- qDebug( "Could not save calibration: %s", calFile.latin1() ); +- } +-} ++ xtable[0] = myX; ++ ytable[0] = myY; ++ ptr = 1; ++ oldX = myX; ++ oldY = myY; ++ oldP = myP; ++ return; ++ } + +-void QTSLibHandlerPrivate::readMouseData() +-{ +-#ifdef QT_QWS_TSLIB +- if(!qt_screen) +- return; ++ // down->down ++ if (oldP>QT_QWS_TP_PRESSURE_DOWN_THRESHOLD && myP>QT_QWS_TP_PRESSURE_UP_THRESHOLD) { ++ //qDebug("dd %d,%d,%d (%d,%d)", myX,myY,myP, oldX,oldY); + +- /* +- * After clear Calibration +- * we're in raw mode and do some easy median +- * search. +- */ +- if ( m_raw ) +- return interpolateSample(); ++ int dxSqr = myX-oldX; dxSqr *= dxSqr; ++ int dySqr = myY-oldY; dySqr *= dySqr; ++ oldX = myX; ++ oldY = myY; ++ if (dxSqr+dySqr > QT_QWS_TP_MOVE_MAX*QT_QWS_TP_MOVE_MAX) { ++ //qWarning("distance too wide %d", dxSqr+dySqr); ++ return; ++ } + +- static struct ts_sample sample; +- static int ret; ++ if (ptr < QT_QWS_TP_TABLE_SIZE) { ++ xtable[ptr] = myX; ++ ytable[ptr++] = myY; ++ } + +- /* +- * Ok. We need to see if we can read more than one event +- * We do this not to lose an update. +- */ +- while ( true ) { +- if ((ret = ts_read(m_ts, &sample, 1)) != 1 ) +- return; ++ if (ptr == QT_QWS_TP_TABLE_SIZE) { ++ int i; ++ int mx = 0; ++ int my = 0; ++ for (i=0; i<QT_QWS_TP_TABLE_SIZE; i++) { ++ mx += xtable[i]; ++ my += ytable[i]; ++ if (i>0) { ++ xtable[i-1] = xtable[i]; ++ ytable[i-1] = ytable[i]; ++ } ++ } ++ ptr--; ++ mousePos = transform(QPoint(mx/QT_QWS_TP_TABLE_SIZE, my/QT_QWS_TP_TABLE_SIZE)); + ++ emit mouseChanged(mousePos, Qt::LeftButton); ++ } ++ return; ++ } + +- QPoint pos( sample.x, sample.y ); +- mouseChanged( pos, sample.pressure != 0 ? 1 : 0 ); +- } +-#endif ++ // down->up ++ //qDebug("du %d,%d,%d", myX,myY,myP); ++ emit mouseChanged(mousePos, 0); ++ oldP = 0; + } + +-/* +- * Lets take all down events and then sort them +- * and take the event in the middle. +- * +- * inspired by testutils.c +- */ +-void QTSLibHandlerPrivate::interpolateSample() { +-#ifdef QT_QWS_TSLIB +-#define TSLIB_MAX_SAMPLES 25 +- static struct ts_sample samples[TSLIB_MAX_SAMPLES]; +- int index = 0; +- int read_samples = 0; +- int ret; +- +- do { +- /* do not access negative arrays */ +- if ( index < 0 ) +- index = 0; +- +- /* we're opened non-blocking */ +- if((ret= ts_read_raw(m_ts, &samples[index], 1 ) ) != 1 ) +- /* no event yet, so try again */ +- if (ret==-1 ) +- continue; +- +- read_samples++; +- index = (index+1)%TSLIB_MAX_SAMPLES; +- }while (samples[index == 0 ? (TSLIB_MAX_SAMPLES-1) : index-1].pressure != 0); +- +- /* +- * If we've wrapped around each sample is used otherwise +- * we will use the index +- */ +- index = read_samples >= TSLIB_MAX_SAMPLES ? +- (TSLIB_MAX_SAMPLES-1 ) : index; +- int x, y; +- +- /* +- * now let us use the median value +- * even index does not have an item in the middle +- * so let us take the average of n/2 and (n/2)-1 as the middle +- */ +- int m = index/2; +- ::qsort(samples, index, sizeof(ts_sample), QTSLibHandlerPrivate::sortByX); +- x = (index % 2 ) ? samples[m].x : +- ( samples[m-1].x + samples[m].x )/2; +- +- ::qsort(samples, index, sizeof(ts_sample), QTSLibHandlerPrivate::sortByY); +- y = (index % 2 ) ? samples[m].y : +- ( samples[m-1].y + samples[m].y )/2; + +- emit mouseChanged( QPoint(x, y), 1 ); +- emit mouseChanged( QPoint(0, 0), 0 ); +-#endif +-} + +-int QTSLibHandlerPrivate::sortByX( const void* one, const void* two) { +-#ifdef QT_QWS_TSLIB +- return reinterpret_cast<const struct ts_sample*>(one)->x - +- reinterpret_cast<const struct ts_sample*>(two)->x; +-#else +- return 0; +-#endif +-} + +-int QTSLibHandlerPrivate::sortByY( const void* one, const void* two) { +-#ifdef QT_QWS_TSLIB +- return reinterpret_cast<const struct ts_sample*>(one)->y - +- reinterpret_cast<const struct ts_sample*>(two)->y; +-#else +- return 0; +-#endif +-} +-////// + + /* + * return a QWSMouseHandler that supports /a spec. +@@ -1977,7 +519,7 @@ + + if ( mouseProto == "USB" && mouseDev.isEmpty() ) + mouseDev = "/dev/input/mice"; +- ++ + MouseProtocol mouseProtocol = Unknown; + + int idx = 0; +@@ -1988,50 +530,7 @@ + idx++; + } + +- +- QWSMouseHandler *handler = 0; +- +- switch ( mouseProtocol ) { +-#ifndef QT_NO_QWS_MOUSE_AUTO +- case Auto: +- handler = new QAutoMouseHandler(); +- break; +-#endif +- +-#ifndef QT_NO_QWS_MOUSE_PC +- case MouseMan: +- case IntelliMouse: +- case Microsoft: +- case BusMouse: +- handler = new QWSMouseHandlerPrivate( mouseProtocol, mouseDev ); +- break; +-#endif +- +-#ifndef QT_NO_QWS_VFB +- case QVFBMouse: +- handler = new QVFbMouseHandlerPrivate( mouseProtocol, mouseDev ); +- break; +-#endif +- +- case TPanel: +-#if defined(QWS_CUSTOMTOUCHPANEL) +- handler = new QCustomTPanelHandlerPrivate(mouseProtocol,mouseDev); +-#elif defined(QT_QWS_TSLIB) +- handler = new QTSLibHandlerPrivate(); +-#elif defined(QT_QWS_YOPY) +- handler = new QYopyTPanelHandlerPrivate(mouseProtocol,mouseDev); +-#elif defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) || defined(QT_QWS_SIMPAD) +- handler = new QTPanelHandlerPrivate(mouseProtocol,mouseDev); +-#elif defined(QT_QWS_CASSIOPEIA) +- handler = new QVrTPanelHandlerPrivate( mouseProtocol, mouseDev ); +-#endif +- break; +- +- default: +- qDebug( "Mouse type %s unsupported", spec.latin1() ); +- } +- +- return handler; ++ return new QInputEventHandler( mouseProtocol, mouseDev ); + } + + #include "qwsmouse_qws.moc" +--- qt-2.3.10/src/kernel/qwsmouse_qws.h~ramses-touchscreen ++++ qt-2.3.10/src/kernel/qwsmouse_qws.h +@@ -1,5 +1,5 @@ + /**************************************************************************** +-** $Id: qt/src/kernel/qwsmouse_qws.h 2.3.10 edited 2005-01-24 $ ++** $Id: qt/src/kernel/qwsmouse_qws.h 2.3.7 edited 2001-10-03 $ + ** + ** Definition of Qt/FB central server classes + ** +@@ -70,6 +70,7 @@ + virtual void clearCalibration(); + virtual void calibrate( QWSPointerCalibrationData * ); + virtual void getCalibration( QWSPointerCalibrationData * ); ++ virtual void setCalibration(int aa, int bb, int cc, int dd, int ee, int ff, int ss); + + protected: + void readCalibration(); diff --git a/packages/qte/qte-2.3.12/mnci.patch b/packages/qte/qte-2.3.12/mnci.patch new file mode 100644 index 0000000000..c2e0e079d9 --- /dev/null +++ b/packages/qte/qte-2.3.12/mnci.patch @@ -0,0 +1,125 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.10/src/kernel/qgfxlinuxfb_qws.cpp~ramses.patch ++++ qt-2.3.10/src/kernel/qgfxlinuxfb_qws.cpp +@@ -249,20 +249,12 @@ + + static void writeTerm(const char* termctl, int sizeof_termctl) + { +-#ifdef QT_QWS_DEVFS +- const char* tt[]={"/dev/vc/1","/dev/console","/dev/tty",0}; +-#else +- const char* tt[]={"/dev/console","/dev/tty","/dev/tty0",0}; +-#endif +- const char** dev=tt; +- while (*dev) { +- int tty=::open(*dev,O_WRONLY); ++qWarning("writeTerm"); ++ int tty=::open("/dev/vc/2", O_WRONLY); + if ( tty>=0 ) { + ::write(tty,termctl,sizeof_termctl); + ::close(tty); + } +- dev++; +- } + } + + /*! +@@ -275,6 +267,7 @@ + + bool QLinuxFbScreen::initDevice() + { ++qWarning("QLinuxFbScreen::initDevice"); + /* Setting up the VT parameters is done in qapplication_qws.cpp + const char termctl[]="\033[9;0]\033[?33l\033[?25l"; + writeTerm(termctl,sizeof(termctl)); */ +@@ -765,9 +758,12 @@ + } + */ + ++qWarning("QLinuxFbScreen::shutdownDevice"); ++/* + // Blankin' screen, blinkin' cursor! + const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c"; + writeTerm(termctl,sizeof(termctl)); ++*/ + } + + /*! +--- qt-2.3.10/src/kernel/qapplication_qws.cpp~ramses.patch ++++ qt-2.3.10/src/kernel/qapplication_qws.cpp +@@ -1756,8 +1756,6 @@ + */ + if ( qws_daemon ) + { +- qWarning( "qt_init() - starting in daemon mode..." ); +- + int pid1 = fork(); + if ( pid1 == -1 ) + { +@@ -1791,7 +1789,6 @@ + } + if ( pid2 ) + { +- syslog( 4, "qt_init() [%d] - successfully entered daemon mode", pid2 ); + _exit( 0 ); // ok, second fork performed + } + } +@@ -1828,9 +1825,12 @@ + #if defined(_OS_LINUX_) + if ( qws_terminal_id ) + { +- qDebug( "qt_init() - terminal specification is '%d'.", qws_terminal_id ); + struct vt_stat console_stat; ++#ifdef QT_QWS_DEVFS ++ int console_fd = ::open( QString().sprintf( "/dev/vc/%d", qws_terminal_id ).latin1(), O_RDWR ); ++#else + int console_fd = ::open( QString().sprintf( "/dev/tty%d", qws_terminal_id ).latin1(), O_RDWR ); ++#endif + if ( console_fd == -1) + { + qWarning( "qt_init() - can't open tty: %s", strerror( errno ) ); +@@ -1927,7 +1927,11 @@ + { + qDebug( "qt_cleanup() - switching back to virtual terminal #%d", qws_terminal_old ); + ++#ifdef QT_QWS_DEVFS ++ int console_fd = ::open( "/dev/vc/0", O_RDWR ); ++#else + int console_fd = ::open( "/dev/tty0", O_RDWR ); ++#endif + if ( console_fd == -1) + { + qWarning( "qt_init() - can't open tty: %s", strerror( errno ) ); +--- qt-2.3.10/src/kernel/qwindowsystem_qws.cpp~ramses.patch ++++ qt-2.3.10/src/kernel/qwindowsystem_qws.cpp +@@ -1791,6 +1791,7 @@ + } + + #ifndef QT_NO_QWS_KEYBOARD ++#ifndef QT_QWS_RAMSES + static int keyUnicode(int keycode) + { + const QWSServer::KeyMap *km = QWSServer::keyMap(); +@@ -1803,6 +1804,7 @@ + return 0xffff; + } + #endif ++#endif + /*! + Send a key event. You can use this to send key events generated by + "virtual keyboards". +@@ -1845,8 +1847,10 @@ + + event.simpleData.unicode = + #ifndef QT_NO_QWS_KEYBOARD ++#ifndef QT_QWS_RAMSES + unicode < 0 ? keyUnicode(keycode) : + #endif ++#endif + unicode; + event.simpleData.keycode = keycode; + event.simpleData.modifiers = modifiers; diff --git a/packages/qte/qte-2.3.12/no-moc.patch b/packages/qte/qte-2.3.12/no-moc.patch new file mode 100644 index 0000000000..0b2cdea6df --- /dev/null +++ b/packages/qte/qte-2.3.12/no-moc.patch @@ -0,0 +1,39 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/Makefile +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/Makefile 2006-01-20 01:09:29.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/Makefile 2006-01-20 20:49:03.232410456 +0100 +@@ -8,7 +8,7 @@ + init: FORCE + @$(MAKE) QTDIR=`pwd` all + +-all: symlinks src-moc src-mt sub-src sub-tools sub-tutorial sub-examples ++all: symlinks src-mt sub-src sub-tools sub-tutorial sub-examples + @echo + @echo "The Qt library is now built in ./lib" + @echo "The Qt examples are built in the directories in ./examples" +@@ -31,10 +31,10 @@ + symlinks: .buildopts + @cd include; rm -f q*.h; for i in ../src/*/q*.h ../src/3rdparty/*/q*.h ../extensions/*/src/q*.h; do ln -s $$i .; done; rm -f q*_p.h + +-sub-src: src-moc src-mt .buildopts FORCE ++sub-src: src-mt .buildopts FORCE + cd src; $(MAKE) + +-src-mt: src-moc .buildopts FORCE ++src-mt: .buildopts FORCE + $(MAKE) -f src-mt.mk + + sub-tutorial: sub-src FORCE +@@ -44,7 +44,6 @@ + cd examples; $(MAKE) + + clean: +- cd src/moc; $(MAKE) clean + cd src; $(MAKE) clean + -rm src/tmp/*.o src/tmp/*.a src/allmoc.cpp + -find src/3rdparty -name '*.o' | xargs rm diff --git a/packages/qte/qte-2.3.12/qiconview-speed.patch b/packages/qte/qte-2.3.12/qiconview-speed.patch new file mode 100644 index 0000000000..bac9b9705f --- /dev/null +++ b/packages/qte/qte-2.3.12/qiconview-speed.patch @@ -0,0 +1,122 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.10-snapshot-20050131/src/iconview/qiconview.cpp~qiconview-speed ++++ qt-2.3.10-snapshot-20050131/src/iconview/qiconview.cpp +@@ -225,6 +225,7 @@ + QIconView::SelectionMode selectionMode; + QIconViewItem *currentItem, *tmpCurrentItem, *highlightedItem, *startDragItem, *pressedItem, *selectAnchor; + QRect *rubber; ++ QPixmap *backBuffer; + QTimer *scrollTimer, *adjustTimer, *updateTimer, *inputTimer, + *fullRedrawTimer; + int rastX, rastY, spacing; +@@ -2268,6 +2269,7 @@ + d->currentItem = 0; + d->highlightedItem = 0; + d->rubber = 0; ++ d->backBuffer = 0; + d->scrollTimer = 0; + d->startDragItem = 0; + d->tmpCurrentItem = 0; +@@ -2416,6 +2418,8 @@ + delete item; + item = tmp; + } ++ delete d->backBuffer; ++ d->backBuffer = 0; + delete d->fm; + d->fm = 0; + #ifndef QT_NO_TOOLTIP +@@ -2882,6 +2886,48 @@ + } + + /*! ++ This function grabs all paintevents that otherwise would have been ++ processed by the QScrollView::viewportPaintEvent(). Here we use a ++ doublebuffer to reduce 'on-paint' flickering on QIconView ++ (and of course its childs). ++ ++ \sa QScrollView::viewportPaintEvent(), QIconView::drawContents() ++*/ ++ ++void QIconView::bufferedPaintEvent( QPaintEvent* pe ) ++{ ++ QWidget* vp = viewport(); ++ QRect r = pe->rect() & vp->rect(); ++ int ex = r.x() + contentsX(); ++ int ey = r.y() + contentsY(); ++ int ew = r.width(); ++ int eh = r.height(); ++ ++ if ( !d->backBuffer ) ++ d->backBuffer = new QPixmap(vp->size()); ++ if ( d->backBuffer->size() != vp->size() ) { ++ //Resize function (with hysteesis). Uses a good compromise between memory ++ //consumption and speed (number) of resizes. ++ float newWidth = (float)vp->width(); ++ float newHeight = (float)vp->height(); ++ if ( newWidth > d->backBuffer->width() || newHeight > d->backBuffer->height() ) ++ { ++ newWidth *= 1.1892; ++ newHeight *= 1.1892; ++ d->backBuffer->resize( (int)newWidth, (int)newHeight ); ++ } else if ( 1.5*newWidth < d->backBuffer->width() || 1.5*newHeight < d->backBuffer->height() ) ++ d->backBuffer->resize( (int)newWidth, (int)newHeight ); ++ } ++ ++ QPainter p; ++ p.begin(d->backBuffer, vp); ++ drawContentsOffset(&p, contentsX(), contentsY(), ex, ey, ew, eh); ++ p.end(); ++ bitBlt(vp, r.x(), r.y(), d->backBuffer, r.x(), r.y(), ew, eh); ++} ++ ++/*! ++ + \reimp + */ + +@@ -4939,7 +4985,7 @@ + if ( !d->rubber ) + drawDragShapes( d->oldDragPos ); + } +- viewportPaintEvent( (QPaintEvent*)e ); ++ bufferedPaintEvent ((QPaintEvent*)e ); + if ( d->dragging ) { + if ( !d->rubber ) + drawDragShapes( d->oldDragPos ); +@@ -5377,11 +5423,19 @@ + return; + + if ( item->d->container1 && d->firstContainer ) { +- item->d->container1->items.removeRef( item ); ++ //Special-case checking of the last item, since this may be ++ //called a few times for the same item. ++ if (item->d->container1->items.last() == item) ++ item->d->container1->items.removeLast(); ++ else ++ item->d->container1->items.removeRef( item ); + } + item->d->container1 = 0; + if ( item->d->container2 && d->firstContainer ) { +- item->d->container2->items.removeRef( item ); ++ if (item->d->container2->items.last() == item) ++ item->d->container2->items.removeLast(); ++ else ++ item->d->container2->items.removeRef( item ); + } + item->d->container2 = 0; + +--- qt-2.3.10-snapshot-20050131/src/iconview/qiconview.h~qiconview-speed ++++ qt-2.3.10-snapshot-20050131/src/iconview/qiconview.h +@@ -444,6 +444,7 @@ + virtual void contentsDropEvent( QDropEvent *e ); + #endif + ++ void bufferedPaintEvent( QPaintEvent* ); + virtual void resizeEvent( QResizeEvent* e ); + virtual void keyPressEvent( QKeyEvent *e ); + virtual void focusInEvent( QFocusEvent *e ); diff --git a/packages/qte/qte-2.3.12/qpe.patch b/packages/qte/qte-2.3.12/qpe.patch new file mode 100644 index 0000000000..af2e31664a --- /dev/null +++ b/packages/qte/qte-2.3.12/qpe.patch @@ -0,0 +1,105 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- /dev/null ++++ qt-2.3.9-snapshot-20041211/src/tools/qconfig-qpe.h +@@ -0,0 +1,97 @@ ++/********************************************************************** ++** Copyright (C) 2000 Trolltech AS. All rights reserved. ++** ++** This file is part of Qtopia Environment. ++** ++** This file may be distributed and/or modified under the terms of the ++** GNU General Public License version 2 as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL included in the ++** packaging of this file. ++** ++** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ++** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++** ++** See http://www.trolltech.com/gpl/ for GPL licensing information. ++** ++** Contact info@trolltech.com if any conditions of this licensing are ++** not clear to you. ++** ++**********************************************************************/ ++#ifndef QT_H ++#endif // QT_H ++ ++// Empty leaves all features enabled. See doc/html/features.html for choices. ++ ++// Note that disabling some features will produce a libqt that is not ++// compatible with other libqt builds. Such modifications are only ++// supported on Qt/Embedded where reducing the library size is important ++// and where the application-suite is often a fixed set. ++ ++#ifndef QT_DLL ++#define QT_DLL // Internal ++#endif ++ ++#define QT_NO_QWS_CURSOR ++#define QT_NO_QWS_MOUSE_AUTO ++#ifndef QT_NO_CODECS ++#define QT_NO_CODECS ++#endif ++#define QT_NO_UNICODETABLES ++//#define QT_NO_IMAGEIO_BMP ++#define QT_NO_IMAGEIO_PPM ++//#define QT_NO_ASYNC_IO ++//#define QT_NO_ASYNC_IMAGE_IO ++#define QT_NO_FREETYPE ++#define QT_NO_BDF ++//#define QT_NO_FONTDATABASE ++#define QT_NO_DRAGANDDROP ++//#define QT_NO_CLIPBOARD ++#define QT_NO_PROPERTIES ++#define QT_NO_NETWORKPROTOCOL ++ ++#define QT_NO_IMAGE_TEXT ++ ++//#define QT_NO_TOOLTIP ++#define QT_NO_COLORNAMES ++#define QT_NO_TRANSFORMATIONS ++#define QT_NO_TRANSLATION_BUILDER ++#define QT_NO_COMPLEXTEXT ++#define QT_NO_PRINTER ++#define QT_NO_PICTURE ++//#define QT_NO_ICONVIEW ++#define QT_NO_DIAL ++#define QT_NO_SIZEGRIP ++#define QT_NO_WORKSPACE ++//#define QT_NO_TABLE ++//#define QT_NO_ACTION ++//#define QT_NO_SETTINGS ++#define QT_NO_STYLE_POCKETPC ++#ifndef QT_NO_STYLE_AQUA ++# define QT_NO_STYLE_AQUA ++#endif ++#define QT_NO_STYLE_MOTIF ++#define QT_NO_STYLE_PLATINUM ++#define QT_NO_FILEDIALOG ++#define QT_NO_FONTDIALOG ++#define QT_NO_PRINTDIALOG ++#define QT_NO_COLORDIALOG ++#define QT_NO_INPUTDIALOG ++//#define QT_NO_MESSAGEBOX ++#define QT_NO_PROGRESSDIALOG ++//#define QT_NO_TABDIALOG ++#define QT_NO_WIZARD ++#define QT_NO_EFFECTS ++//#define QT_NO_COMPONENT ++#define QT_NO_DOM ++#define QT_NO_SEMIMODAL ++//#define QT_NO_PROGRESSBAR ++#define QT_NO_SPLITTER ++ ++//#define QT_NO_QWS_SAVEFONTS ++//#define QT_NO_QWS_PROPERTIES ++ ++#define QT_NO_QWS_BEOS_WM_STYLE ++#define QT_NO_QWS_KDE2_WM_STYLE ++#define QT_NO_QWS_KDE_WM_STYLE ++#define QT_NO_QWS_WINDOWS_WM_STYLE ++ diff --git a/packages/qte/qte-2.3.12/qt-visibility.patch b/packages/qte/qte-2.3.12/qt-visibility.patch new file mode 100644 index 0000000000..2b552b293f --- /dev/null +++ b/packages/qte/qte-2.3.12/qt-visibility.patch @@ -0,0 +1,499 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/configure +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/configure 2005-09-21 05:48:39.000000000 +0200 ++++ qt-2.3.10-snapshot-20060120/configure 2006-01-20 20:50:52.536793664 +0100 +@@ -450,6 +450,9 @@ + -tslib) + TSLIB=yes + ;; ++ -visibility-hidden) ++ VISIBILITY=YES ++ ;; + -no-g++-exceptions) + GPLUSPLUS_EXCEPTIONS=no + ;; +@@ -1356,6 +1359,9 @@ + -tslib ............. Enable TSlib (touchscreen library) mouse handler. + See http://arm.linux.org.uk + ++ -visibility-hidden . Use -fvisibility=hidden as default. This requires GCC 4.0 ++ or a special patched GCC to support the visibility attribute ++ + -no-g++-exceptions . Disable exceptions on platforms using the GNU C++ + compiler by using the -fno-exceptions flag. + +@@ -1424,6 +1430,10 @@ + QT_CXX="${QT_CXX} -DQT_QWS_TSLIB" + QT_LIBS="${QT_LIBS} -lts" + fi ++if [ "x$VISIBILITY=" = "xyes" ] ++then ++ QT_CXX="${QT_CXX} -DGCC_SUPPORTS_VISIBILITY -fvisibility=hidden" ++fi + if [ "x$THREAD" = "xyes" ] + then + cat >src-mt.mk <<EOF +Index: qt-2.3.10-snapshot-20060120/src/tools/qglobal.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/tools/qglobal.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/tools/qglobal.h 2006-01-20 20:50:52.537793512 +0100 +@@ -503,6 +503,12 @@ + #undef QT_DLL + #endif + ++#ifdef GCC_SUPPORTS_VISIBILITY ++#ifndef Q_EXPORT ++ #define Q_EXPORT __attribute__((visibility("default"))) ++#endif ++#endif ++ + #ifndef Q_EXPORT + #define Q_EXPORT + #endif +Index: qt-2.3.10-snapshot-20060120/src/widgets/qscrollview.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/widgets/qscrollview.cpp 2006-01-20 01:08:04.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/widgets/qscrollview.cpp 2006-01-20 20:50:52.553791080 +0100 +@@ -703,7 +703,7 @@ + The surrounding environment (or application, if there is no + environment, may set this. Requires Qt >= 2.3.8. + */ +-bool qt_left_hand_scrollbars = FALSE; ++bool Q_EXPORT qt_left_hand_scrollbars = FALSE; + + /*! + Updates scrollbars - all possibilities considered. You should never +Index: qt-2.3.10-snapshot-20060120/src/Makefile.in +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/Makefile.in 2006-01-20 01:09:33.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/Makefile.in 2006-01-20 20:50:52.558790320 +0100 +@@ -652,7 +652,7 @@ + network/qsocket.h \ + network/qsocketdevice.h + echo '#include "kernel/qt.h"' >allmoc.cpp +- $(CXX) -E -DQT_MOC_CPP $(CXXFLAGS) $(INCPATH) >allmoc.h allmoc.cpp ++ $(CXX) -E -DQT_MOC_CPP -DQ_EXPORT="" $(CXXFLAGS) $(INCPATH) >allmoc.h allmoc.cpp + $(MOC) -o allmoc.cpp allmoc.h + perl -pi -e 's{"allmoc.h"}{"kernel/qt.h"}' allmoc.cpp + rm allmoc.h +Index: qt-2.3.10-snapshot-20060120/src/kernel/qcopchannel_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qcopchannel_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qcopchannel_qws.h 2006-01-20 20:50:52.559790168 +0100 +@@ -42,7 +42,7 @@ + class QCopChannelPrivate; + class QWSClient; + +-class QCopChannel : public QObject ++class Q_EXPORT QCopChannel : public QObject + { + Q_OBJECT + public: +Index: qt-2.3.10-snapshot-20060120/src/kernel/qfontmanager_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qfontmanager_qws.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qfontmanager_qws.cpp 2006-01-20 20:50:52.559790168 +0100 +@@ -68,7 +68,7 @@ + return r; + } + +-QFontManager * qt_fontmanager=0; ++QFontManager Q_EXPORT *qt_fontmanager=0; + + /*! + \class QFontManager qfontmanager_qws.h +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfx_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qgfx_qws.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfx_qws.cpp 2006-01-20 20:50:52.560790016 +0100 +@@ -38,10 +38,10 @@ + #include <stdlib.h> + + #ifndef QT_NO_QWS_CURSOR +-bool qt_sw_cursor=false; +-QScreenCursor * qt_screencursor=0; ++bool Q_EXPORT qt_sw_cursor=false; ++QScreenCursor Q_EXPORT * qt_screencursor=0; + #endif +-QScreen * qt_screen=0; ++QScreen Q_EXPORT * qt_screen=0; + + extern bool qws_screen_is_interlaced; //### hack, from qapplication_qws.cpp + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwindowsystem_qws.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp 2006-01-20 20:50:52.562789712 +0100 +@@ -89,7 +89,7 @@ + + extern void qt_setMaxWindowRect(const QRect& r); + +-QWSServer *qwsServer=0; ++QWSServer Q_EXPORT *qwsServer=0; + + #define MOUSE 0 + #define KEY 1 +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsdecoration_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsdecoration_qws.h 2006-01-20 20:49:30.348288216 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsdecoration_qws.h 2006-01-20 20:50:52.562789712 +0100 +@@ -41,7 +41,7 @@ + /* + Implements decoration styles + */ +-class QWSDecoration ++class Q_EXPORT QWSDecoration + { + public: + QWSDecoration() {} +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwindowsystem_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.h 2006-01-20 20:50:52.563789560 +0100 +@@ -69,7 +69,7 @@ + + struct QWSWindowData; + +-class QWSScreenSaver ++class Q_EXPORT QWSScreenSaver + { + public: + virtual ~QWSScreenSaver(); +@@ -77,7 +77,7 @@ + virtual bool save(int level)=0; + }; + +-class QWSWindow ++class Q_EXPORT QWSWindow + { + friend class QWSServer; + public: +@@ -171,9 +171,9 @@ + struct QWSCommandStruct; + + #ifndef QT_NO_QWS_MULTIPROCESS +-class QWSServer : public QWSServerSocket ++class Q_EXPORT QWSServer : public QWSServerSocket + #else +-class QWSServer : public QObject ++class Q_EXPORT QWSServer : public QObject + #endif + { + friend class QCopChannel; +@@ -503,7 +503,7 @@ + + + #ifndef QT_NO_QWS_IM +-class QWSInputMethod : public QObject ++class Q_EXPORT QWSInputMethod : public QObject + { + public: + QWSInputMethod(); +@@ -527,7 +527,7 @@ + #endif + + #ifndef QT_NO_QWS_FSIM +-class QWSGestureMethod : public QObject ++class Q_EXPORT QWSGestureMethod : public QObject + { + public: + QWSGestureMethod(); +@@ -575,7 +575,7 @@ + + typedef QMap<int, QWSCursor*> QWSCursorMap; + +-class QWSClient : public QObject ++class Q_EXPORT QWSClient : public QObject + { + Q_OBJECT + public: +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsdefaultdecoration_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsdefaultdecoration_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsdefaultdecoration_qws.h 2006-01-20 20:50:52.563789560 +0100 +@@ -44,7 +44,7 @@ + + + +-class QWSDefaultDecoration : public QWSDecoration ++class Q_EXPORT QWSDefaultDecoration : public QWSDecoration + { + public: + QWSDefaultDecoration(); +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwscommand_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwscommand_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwscommand_qws.h 2006-01-20 20:50:52.564789408 +0100 +@@ -47,8 +47,8 @@ + * + *********************************************************************/ + #ifndef QT_NO_QWS_MULTIPROCESS +-void qws_write_command( QWSSocket *socket, int type, char *simpleData, int simpleLen, char *rawData, int rawLen ); +-bool qws_read_command( QWSSocket *socket, char *&simpleData, int &simpleLen, char *&rawData, int &rawLen, int &bytesRead ); ++void Q_EXPORT qws_write_command( QWSSocket *socket, int type, char *simpleData, int simpleLen, char *rawData, int rawLen ); ++bool Q_EXPORT qws_read_command( QWSSocket *socket, char *&simpleData, int &simpleLen, char *&rawData, int &rawLen, int &bytesRead ); + #endif + /********************************************************************* + * +@@ -57,7 +57,7 @@ + *********************************************************************/ + + +-struct QWSProtocolItem ++struct Q_EXPORT QWSProtocolItem + { + // ctor - dtor + QWSProtocolItem( int t, int len, char *ptr ) : type( t ), +Index: qt-2.3.10-snapshot-20060120/src/kernel/qfont_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qfont_qws.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qfont_qws.cpp 2006-01-20 20:50:52.565789256 +0100 +@@ -152,7 +152,7 @@ + static QFontCache *fontCache = 0; // cache of loaded fonts + static QFontDict *fontDict = 0; // dict of all loaded fonts + +-void qws_clearLoadedFonts() ++void Q_EXPORT qws_clearLoadedFonts() + { + if (!fontDict) + return; +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwscursor_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwscursor_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwscursor_qws.h 2006-01-20 20:50:52.565789256 +0100 +@@ -37,7 +37,7 @@ + #include <qimage.h> + #endif // QT_H + +-class QWSCursor : public Qt ++class Q_EXPORT QWSCursor : public Qt + { + public: + QWSCursor() {} +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsevent_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsevent_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsevent_qws.h 2006-01-20 20:50:52.566789104 +0100 +@@ -40,7 +40,7 @@ + + struct QWSMouseEvent; + +-struct QWSEvent : QWSProtocolItem { ++struct Q_EXPORT QWSEvent : QWSProtocolItem { + + QWSEvent( int t, int len, char *ptr ) : QWSProtocolItem(t,len,ptr) {} + +@@ -71,7 +71,7 @@ + + //All events must start with windowID + +-struct QWSConnectedEvent : QWSEvent { ++struct Q_EXPORT QWSConnectedEvent : QWSEvent { + QWSConnectedEvent() + : QWSEvent( QWSEvent::Connected, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -90,7 +90,7 @@ + char *display; + }; + +-struct QWSMaxWindowRectEvent : QWSEvent { ++struct Q_EXPORT QWSMaxWindowRectEvent : QWSEvent { + QWSMaxWindowRectEvent() + : QWSEvent( MaxWindowRect, sizeof( simpleData ), (char*)&simpleData ) { } + struct SimpleData { +@@ -99,7 +99,7 @@ + } simpleData; + }; + +-struct QWSMouseEvent : QWSEvent { ++struct Q_EXPORT QWSMouseEvent : QWSEvent { + QWSMouseEvent() + : QWSEvent( QWSEvent::Mouse, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -110,7 +110,7 @@ + } simpleData; + }; + +-struct QWSFocusEvent : QWSEvent { ++struct Q_EXPORT QWSFocusEvent : QWSEvent { + QWSFocusEvent() + : QWSEvent( QWSEvent::Focus, sizeof( simpleData ), (char*)&simpleData ) + { memset((char*)&simpleData,0,sizeof(simpleData)); } +@@ -120,7 +120,7 @@ + } simpleData; + }; + +-struct QWSKeyEvent: QWSEvent { ++struct Q_EXPORT QWSKeyEvent: QWSEvent { + QWSKeyEvent() + : QWSEvent( QWSEvent::Key, sizeof( simpleData ), + (char*)&simpleData ) +@@ -136,7 +136,7 @@ + }; + + +-struct QWSCreationEvent : QWSEvent { ++struct Q_EXPORT QWSCreationEvent : QWSEvent { + QWSCreationEvent() + : QWSEvent( QWSEvent::Creation, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -146,7 +146,7 @@ + }; + + #ifndef QT_NO_QWS_PROPERTIES +-struct QWSPropertyNotifyEvent : QWSEvent { ++struct Q_EXPORT QWSPropertyNotifyEvent : QWSEvent { + QWSPropertyNotifyEvent() + : QWSEvent( QWSEvent::PropertyNotify, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -162,7 +162,7 @@ + }; + #endif + +-struct QWSSelectionClearEvent : QWSEvent { ++struct Q_EXPORT QWSSelectionClearEvent : QWSEvent { + QWSSelectionClearEvent() + : QWSEvent( QWSEvent::SelectionClear, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -171,7 +171,7 @@ + } simpleData; + }; + +-struct QWSSelectionRequestEvent : QWSEvent { ++struct Q_EXPORT QWSSelectionRequestEvent : QWSEvent { + QWSSelectionRequestEvent() + : QWSEvent( QWSEvent::SelectionRequest, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -184,7 +184,7 @@ + } simpleData; + }; + +-struct QWSSelectionNotifyEvent : QWSEvent { ++struct Q_EXPORT QWSSelectionNotifyEvent : QWSEvent { + QWSSelectionNotifyEvent() + : QWSEvent( QWSEvent::SelectionNotify, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -198,7 +198,7 @@ + + //complex events: + +-struct QWSRegionModifiedEvent : QWSEvent { ++struct Q_EXPORT QWSRegionModifiedEvent : QWSEvent { + QWSRegionModifiedEvent() + : QWSEvent( QWSEvent::RegionModified, sizeof( simpleData ), + (char*)&simpleData ) +@@ -218,7 +218,7 @@ + QRect *rectangles; + }; + #ifndef QT_NO_QWS_PROPERTIES +-struct QWSPropertyReplyEvent : QWSEvent { ++struct Q_EXPORT QWSPropertyReplyEvent : QWSEvent { + QWSPropertyReplyEvent() + : QWSEvent( QWSEvent::PropertyReply, sizeof( simpleData ), + (char*)&simpleData ) {} +@@ -238,7 +238,7 @@ + #endif //QT_NO_QWS_PROPERTIES + + #ifndef QT_NO_COP +-struct QWSQCopMessageEvent : QWSEvent { ++struct Q_EXPORT QWSQCopMessageEvent : QWSEvent { + QWSQCopMessageEvent() + : QWSEvent( QWSEvent::QCopMessage, sizeof( simpleData ), + (char*)&simpleData ) +@@ -268,7 +268,7 @@ + + #endif + +-struct QWSWindowOperationEvent : QWSEvent { ++struct Q_EXPORT QWSWindowOperationEvent : QWSEvent { + QWSWindowOperationEvent() + : QWSEvent( WindowOperation, sizeof( simpleData ), (char*)&simpleData ) { } + +@@ -280,7 +280,7 @@ + }; + + #ifndef QT_NO_QWS_IM +-struct QWSIMEvent : QWSEvent { ++struct Q_EXPORT QWSIMEvent : QWSEvent { + QWSIMEvent() + : QWSEvent( IMEvent, sizeof( simpleData ), (char*)&simpleData ) { } + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsmanager_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsmanager_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsmanager_qws.h 2006-01-20 20:50:52.566789104 +0100 +@@ -48,7 +48,7 @@ + class QWSButton; + class QWSManager; + +-class QWSManager : public QObject ++class Q_EXPORT QWSManager : public QObject + { + Q_OBJECT + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsmouse_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.h 2006-01-20 20:50:52.566789104 +0100 +@@ -38,7 +38,7 @@ + #include <qpointarray.h> + #endif // QT_H + +-class QWSPointerCalibrationData ++class Q_EXPORT QWSPointerCalibrationData + { + public: + enum Location { TopLeft = 0, BottomLeft = 1, BottomRight = 2, TopRight = 3, +@@ -47,7 +47,7 @@ + QPoint screenPoints[5]; + }; + +-class QWSMouseHandler : public QObject { ++class Q_EXPORT QWSMouseHandler : public QObject { + Q_OBJECT + public: + QWSMouseHandler(); +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsproperty_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsproperty_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsproperty_qws.h 2006-01-20 20:50:52.598784240 +0100 +@@ -47,7 +47,7 @@ + + class QWSPropertyManagerData; + +-class QWSPropertyManager ++class Q_EXPORT QWSPropertyManager + { + public: + enum Mode { +Index: qt-2.3.10-snapshot-20060120/src/kernel/qlayoutengine.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qlayoutengine.cpp 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qlayoutengine.cpp 2006-01-20 20:50:52.598784240 +0100 +@@ -70,7 +70,7 @@ + pos and space give the interval (relative to parentWidget topLeft.) + */ + +-void qGeomCalc( QArray<QLayoutStruct> &chain, int start, int count, int pos, ++void Q_EXPORT qGeomCalc( QArray<QLayoutStruct> &chain, int start, int count, int pos, + int space, int spacer ) + { + typedef int fixed; +Index: qt-2.3.10-snapshot-20060120/src/kernel/qfontmanager_qws.h +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qfontmanager_qws.h 2006-01-20 01:08:03.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qfontmanager_qws.h 2006-01-20 20:50:52.610782416 +0100 +@@ -84,7 +84,7 @@ + // e.g. Truetype Times, 10 point. There's only one of these though; + // we want to share generated glyphs + +-class QRenderedFont { ++class Q_EXPORT QRenderedFont { + + public: + diff --git a/packages/qte/qte-2.3.12/qtabbar.patch b/packages/qte/qte-2.3.12/qtabbar.patch new file mode 100644 index 0000000000..f1697421f5 --- /dev/null +++ b/packages/qte/qte-2.3.12/qtabbar.patch @@ -0,0 +1,41 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/widgets/qtabbar.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/widgets/qtabbar.cpp 2006-01-20 01:08:04.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/widgets/qtabbar.cpp 2006-01-20 21:03:47.293012816 +0100 +@@ -260,7 +260,6 @@ + lstatic->insert( index, newTab ); + + layoutTabs(); +- updateArrowButtons(); + makeVisible( tab( currentTab() ) ); + + #ifndef QT_NO_ACCEL +@@ -282,7 +281,6 @@ + l->remove( t ); + lstatic->remove( t ); + layoutTabs(); +- updateArrowButtons(); + makeVisible( tab( currentTab() ) ); + update(); + } +@@ -887,6 +885,7 @@ + } + for ( t = lstatic->first(); t; t = lstatic->next() ) + t->r.setHeight( r.height() ); ++ updateArrowButtons(); + } + + /*! +@@ -978,7 +977,6 @@ + d->leftB->setGeometry( width() - 2*arrowWidth, 0, arrowWidth, height() ); + #endif + layoutTabs(); +- updateArrowButtons(); + makeVisible( tab( currentTab() )); + } + diff --git a/packages/qte/qte-2.3.12/qte-fix-iconsize.patch b/packages/qte/qte-2.3.12/qte-fix-iconsize.patch new file mode 100644 index 0000000000..2b44ea69c0 --- /dev/null +++ b/packages/qte/qte-2.3.12/qte-fix-iconsize.patch @@ -0,0 +1,105 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/widgets/qpopupmenu.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/widgets/qpopupmenu.cpp 2006-01-20 01:08:04.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/widgets/qpopupmenu.cpp 2006-01-20 21:06:03.060373040 +0100 +@@ -820,7 +820,7 @@ + mi->custom()->setFont( font() ); + if ( mi->iconSet() != 0) + maxPMWidth = QMAX( maxPMWidth, +- mi->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4 ); ++ mi->iconSet()->pixmap().width() + 4 ); + } + + int dh = QApplication::desktop()->height(); +Index: qt-2.3.10-snapshot-20060120/src/widgets/qtabbar.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/widgets/qtabbar.cpp 2006-01-20 21:03:47.293012816 +0100 ++++ qt-2.3.10-snapshot-20060120/src/widgets/qtabbar.cpp 2006-01-20 21:06:03.061372888 +0100 +@@ -412,8 +412,8 @@ + int iw = 0; + int ih = 0; + if ( t->iconset != 0 ) { +- iw = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).width(); +- ih = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).height(); ++ iw = t->iconset->pixmap().width(); ++ ih = t->iconset->pixmap().height(); + if (!t->label.isEmpty()) + iw +=2; + } +@@ -440,7 +440,11 @@ + ? QIconSet::Normal : QIconSet::Disabled; + if ( mode == QIconSet::Normal && has_focus ) + mode = QIconSet::Active; +- QPixmap pixmap = t->iconset->pixmap( QIconSet::Small, mode ); ++ QPixmap pixmap; ++ if ( mode == QIconSet::Disabled ) ++ pixmap = t->iconset->pixmap( QIconSet::Automatic, QIconSet::Disabled ); ++ else ++ pixmap = t->iconset->pixmap(); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + r.setLeft( r.left() + pixw + 2 ); +@@ -869,8 +873,8 @@ + int iw = 0; + int ih = 0; + if ( t->iconset != 0 ) { +- iw = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).width(); +- ih = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).height(); ++ iw = t->iconset->pixmap().width(); ++ ih = t->iconset->pixmap().height(); + if (!t->label.isNull()) + iw +=2; + } +@@ -914,8 +918,8 @@ + int iw = 0; + int ih = 0; + if ( t->iconset != 0 ) { +- iw = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).width(); +- ih = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).height(); ++ iw = t->iconset->pixmap().width(); ++ ih = t->iconset->pixmap().height(); + if (!t->label.isEmpty()) + iw +=2; + } +@@ -947,8 +951,8 @@ + int iw = 0; + int ih = 0; + if ( t->iconset != 0 ) { +- iw = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).width(); +- ih = t->iconset->pixmap( QIconSet::Small, QIconSet::Normal ).height(); ++ iw = t->iconset->pixmap().width(); ++ ih = t->iconset->pixmap().height(); + if (!t->label.isEmpty()) + iw +=2; + } +Index: qt-2.3.10-snapshot-20060120/src/widgets/qwindowsstyle.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/widgets/qwindowsstyle.cpp 2006-01-20 01:08:04.000000000 +0100 ++++ qt-2.3.10-snapshot-20060120/src/widgets/qwindowsstyle.cpp 2006-01-20 21:06:03.062372736 +0100 +@@ -1182,7 +1182,7 @@ + h = fm.height() + 2*motifItemVMargin + 2*motifItemFrame; + + if ( !mi->isSeparator() && mi->iconSet() != 0 ) { +- h = QMAX( h, mi->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height() + 2*motifItemFrame ); ++ h = QMAX( h, mi->iconSet()->pixmap().height() + 2*motifItemFrame ); + } + if ( mi->custom() ) + h = QMAX( h, mi->custom()->sizeHint().height() + 2*motifItemVMargin + 2*motifItemFrame ); +@@ -1246,7 +1246,11 @@ + QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal; + if (act && !dis ) + mode = QIconSet::Active; +- QPixmap pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); ++ QPixmap pixmap; ++ if ( mode == QIconSet::Disabled ) ++ pixmap = mi->iconSet()->pixmap( QIconSet::Automatic, QIconSet::Disabled ); ++ else ++ pixmap = mi->iconSet()->pixmap(); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + if ( act && !dis ) { diff --git a/packages/qte/qte-4.0.0-snapshot/sharp_char.h b/packages/qte/qte-2.3.12/sharp_char.h index a70f5f690e..a70f5f690e 100644 --- a/packages/qte/qte-4.0.0-snapshot/sharp_char.h +++ b/packages/qte/qte-2.3.12/sharp_char.h diff --git a/packages/qte/qte-2.3.12/simpad-defaultkbd.patch b/packages/qte/qte-2.3.12/simpad-defaultkbd.patch new file mode 100644 index 0000000000..0bfff37ec4 --- /dev/null +++ b/packages/qte/qte-2.3.12/simpad-defaultkbd.patch @@ -0,0 +1,13 @@ +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwindowsystem_qws.cpp 2006-01-20 21:03:08.482912848 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwindowsystem_qws.cpp 2006-01-20 21:11:59.410199632 +0100 +@@ -2922,7 +2922,7 @@ + { + QString keyboards = getenv("QWS_KEYBOARD"); + if ( keyboards.isEmpty() ) { +-#if defined( QT_QWS_CASSIOPEIA ) ++#if defined( QT_QWS_CASSIOPEIA ) || defined( QT_QWS_SIMPAD ) + keyboards = "Buttons"; + #elif !defined(QT_NO_QWS_VFB) + extern bool qvfbEnabled; diff --git a/packages/qte/qte-2.3.12/simpad.patch b/packages/qte/qte-2.3.12/simpad.patch new file mode 100644 index 0000000000..bf4367c319 --- /dev/null +++ b/packages/qte/qte-2.3.12/simpad.patch @@ -0,0 +1,392 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:30:31.073201168 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp 2006-01-20 21:36:45.024351952 +0100 +@@ -37,6 +37,7 @@ + #include <qapplication.h> + #include <qsocketnotifier.h> + #include <qnamespace.h> ++#include <qdatetime.h> + #include <qtimer.h> + + #include <stdlib.h> +@@ -80,6 +81,60 @@ + #include <sys/vt.h> + #endif + ++/* ++ * SIMpad switches handler ++ * (C) 2003-2005 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> ++ */ ++ ++ ++ ++#include <linux/switches.h> ++#define SIMPAD_SWITCHES_DEVICE "/dev/misc/switches" ++ ++// switches from left top to right down over the SIMpad surface ++ ++#define SIMPAD_SWITCH_POWER 0x02 ++#define SIMPAD_SWITCH_UPPER 0x10 ++#define SIMPAD_SWITCH_UP 0x20 ++#define SIMPAD_SWITCH_DOWN 0x40 ++#define SIMPAD_SWITCH_LEFT 0x80 ++#define SIMPAD_SWITCH_RIGHT 0x100 ++#define SIMPAD_SWITCH_LOWER 0x8 ++ ++class QWSsimpadButtonsHandler : public QWSKeyboardHandler ++{ ++ Q_OBJECT ++ ++ public: ++ QWSsimpadButtonsHandler(); ++ virtual ~QWSsimpadButtonsHandler(); ++ ++ bool isOpen() { return fd > 0; } ++ ++ private slots: ++ void readSwitchesData(); ++ void autoRepeat(); ++ ++ private: ++ switches_mask_t switches; ++ ++ int fd; ++ int repeatdelay; ++ int repeatperiod; ++ ++ int lastCode; // last native code ++ int lastPress; // last press/release state ++ ++ int k; // last emitted Qt key code ++ int shiftKeyPressed; // true if one of the SHIFT keys has been pressed and not yet released ++ bool shiftUsed; // true if SHIFT has been used ++ ++ QTime eventTimer; // tracks time between raw events ++ QTimer* repeater; ++ QSocketNotifier *notifier; ++}; ++ ++ + #ifdef QT_QWS_SL5XXX + #include <asm/sharp_char.h> + #endif +@@ -165,9 +220,9 @@ + current = 0; + } + +- void setAutoRepeat(int d, int p) { if ( d > 0 ) repeatdelay=d; ++ void setAutoRepeat(int d, int p) { if ( d > 0 ) repeatdelay=d; + if ( p > 0 ) repeatperiod=p;} +- void getAutoRepeat(int *d ,int *p ) { if (d) *d=repeatdelay; ++ void getAutoRepeat(int *d ,int *p ) { if (d) *d=repeatdelay; + if (p) *p=repeatperiod; } + + void stop() +@@ -551,9 +606,9 @@ + + void doKey(uchar scancode); + +- ++ + void restoreLeds(); +- ++ + private: + bool shift; + bool alt; +@@ -809,7 +864,7 @@ + + #if !defined(QT_QWS_SL5XXX) + if (code == 224 +-#if defined(QT_QWS_IPAQ) ++#if defined(QT_QWS_IPAQ) + && !ipaq_return_pressed + #endif + ) { +@@ -1778,9 +1833,11 @@ + } else { + type = spec; + } +- + if ( type == "Buttons" ) { +-#if defined(QT_QWS_YOPY) ++#if defined(QT_QWS_SIMPAD) ++ qDebug( "QWSKeyboardHandler: using SIMpad switches handler..." ); ++ handler = new QWSsimpadButtonsHandler(); ++#elif defined(QT_QWS_YOPY) + handler = new QWSyopyButtonsHandler(); + #elif defined(QT_QWS_CASSIOPEIA) + handler = new QWSVr41xxButtonsHandler(); +@@ -1815,6 +1872,218 @@ + return keyM; + } + +-#endif // QT_NO_QWS_KEYBOARD + ++/* ++ * SIMpad switches handler ++ * (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> ++ */ ++ ++ ++QWSsimpadButtonsHandler::QWSsimpadButtonsHandler() ++ :QWSKeyboardHandler(), fd( -1 ), ++ repeatdelay( 700 ), repeatperiod( 80 ), ++ lastCode( 0 ), lastPress( 0 ), ++ k( -1 ), shiftKeyPressed( 0 ), shiftUsed( false ) ++{ ++ qDebug( "SimpadButtonsHandler() - V4.1" ); ++ fd = ::open( SIMPAD_SWITCHES_DEVICE, O_RDWR | O_NDELAY, 0 ); ++ if ( fd < 0 ) ++ { ++ qWarning( "SimpadButtonsHandler(): can't open %s", SIMPAD_SWITCHES_DEVICE ); ++ return; ++ } ++ ++ notifier = new QSocketNotifier( fd, QSocketNotifier::Read, this ); ++ connect( notifier, SIGNAL( activated(int) ),this, SLOT( readSwitchesData() ) ); ++ ++ repeater = new QTimer(this); ++ connect(repeater, SIGNAL(timeout()), this, SLOT(autoRepeat())); ++ ++} ++ ++ ++QWSsimpadButtonsHandler::~QWSsimpadButtonsHandler() ++{ ++ qDebug( "~SimpadButtonsHandler()" ); ++ if ( fd > 0 ) ++ { ++ ::close( fd ); ++ fd = -1; ++ } ++} ++ ++ ++void QWSsimpadButtonsHandler::readSwitchesData() ++{ ++ qDebug( "SimpadButtonsHandler() - detected switches action" ); + ++ if ( ::read( fd, &switches, sizeof switches ) < 0 ) ++ { ++ qWarning( "SimpadButtonsHandler() - switches read error!" ); ++ return; ++ } ++ ++ qDebug( "SimpadButtonsHandler() - Shift: %0x [used: %0x] + Event = %0x | %0x", ++ shiftKeyPressed, shiftUsed, switches.events[0], switches.states[0] ); ++ ++ bool press = switches.states[0]; // == switches.event[0]; ++ int code = switches.events[0]; ++ ++ //========================================================================= ++ ++ /** ++ * Work around a bug in the kernel keyboard driver emitting ++ * bogus events when pressing multiple switches at once ++ **/ ++ ++ if ( lastCode == 0 ) ++ { ++ // first press ever ++ eventTimer.start(); ++ lastPress = press; ++ lastCode = code; ++ } ++ else ++ { ++ int interval = eventTimer.restart(); ++ qDebug( "event interval = %d", interval ); ++ if ( code == lastCode && interval < 10 ) ++ { ++ qDebug( "event interval too small - ignoring bogus event" ); ++ qDebug( "did I say i hate buggy kernel drivers? :-D" ); ++ return; ++ } ++ ++ lastPress = press; ++ lastCode = code; ++ } ++ ++ /** ++ * Actually it may also be a hardware problem, but I really don't like ++ * to review kernel code for further inquiry. So just being lazy and ++ * do the workaround in user space :-D ++ **/ ++ ++ //===================================================================== ++ ++ if ( shiftKeyPressed ) ++ { ++ // a shift key obviously is being held ++ qDebug( "while shift key is being held..." ); ++ ++ if ( code != shiftKeyPressed ) ++ { ++ // another key is being touched - that means shift mode for us! ++ qDebug( " another key is being touched -> shift use now = true" ); ++ ++ shiftUsed = true; ++ ++ if ( shiftKeyPressed == SIMPAD_SWITCH_LOWER ) // SHIFT 1 ++ { ++ qDebug( " shift mode 1" ); ++ switch(code) ++ { ++ case SIMPAD_SWITCH_UP: k = Qt::Key_F9; break; // Shift1-Up = Calendar ++ case SIMPAD_SWITCH_DOWN: k = Qt::Key_F10; break; // Shift1-Down = Contacts ++ case SIMPAD_SWITCH_LEFT: k = Qt::Key_F13; break; // Shift1-Left = Mail ++ case SIMPAD_SWITCH_RIGHT: k = Qt::Key_F11; break; // Shift1-Up = Menu ++ case SIMPAD_SWITCH_UPPER: k = Qt::Key_F12; break; // Shift1-Upper = Home ++ default: k=-1; qWarning( "SimpadButtonsHandler() - unhandled event for Shift 1 !" ); break; ++ } ++ } ++ else if ( shiftKeyPressed == SIMPAD_SWITCH_UPPER ) // SHIFT 2 ++ { ++ qDebug( " shift mode 2" ); ++ switch(code) ++ { ++ case SIMPAD_SWITCH_UP: k = Qt::Key_F5; break; // Shift2-Up = F5 ++ case SIMPAD_SWITCH_DOWN: k = Qt::Key_F6; break; // Shift2-Down = F6 ++ case SIMPAD_SWITCH_LEFT: k = Qt::Key_F7; break; // Shift2-Left = F7 ++ case SIMPAD_SWITCH_RIGHT: k = Qt::Key_F8; break; // Shift2-Up = F8 ++ case SIMPAD_SWITCH_LOWER: k = Qt::Key_F9; break; // Shift2-Lower = F9 ++ default: k=-1; qWarning( "SimpadButtonsHandler() - unhandled event for Shift 2!" ); break; ++ } ++ } ++ } ++ else ++ { ++ qDebug( " shift key has been released. checking if being used..." ); ++ shiftKeyPressed = 0; ++ ++ if ( !shiftUsed ) ++ { ++ qDebug( " ... has _not_ being used -> really emit the key" ); ++ k = ( code == SIMPAD_SWITCH_UPPER ? Qt::Key_Escape : Qt::Key_Return ); ++ qDebug( "Emitting key = %d (pressed)", k ); ++ processKeyEvent( 0, k, 0, true, true ); ++ qDebug( "Emitting key = %d (released)", k ); ++ processKeyEvent( 0, k, 0, false, true ); ++ return; ++ } ++ else ++ { ++ qDebug( " ... has being used -> doing nothing" ); ++ return; ++ } ++ } ++ } ++ else ++ { ++ qDebug( "standard mode - no shift yet..." ); ++ ++ switch(code) ++ { ++ case SIMPAD_SWITCH_UP: k = Qt::Key_Up; break; ++ case SIMPAD_SWITCH_DOWN: k = Qt::Key_Down; break; ++ case SIMPAD_SWITCH_LEFT: k = Qt::Key_Left; break; ++ case SIMPAD_SWITCH_RIGHT: k = Qt::Key_Right; break; ++ case SIMPAD_SWITCH_POWER: k = Qt::Key_F34; break; // Power Button ++ ++ case SIMPAD_SWITCH_UPPER: k=-1; shiftKeyPressed = press? code:0; shiftUsed = false; qDebug( "shiftkey pressed now = %d", shiftKeyPressed ); return; ++ case SIMPAD_SWITCH_LOWER: k=-1; shiftKeyPressed = press? code:0; shiftUsed = false; qDebug( "shiftkey pressed now = %d", shiftKeyPressed ); return; ++ ++ default: k=-1; qWarning( "SimpadButtonsHandler() - unhandled event!" ); break; ++ } ++ } ++ ++ if ( k == -1 ) ++ { ++ qDebug( "no key to emit - returning." ); ++ return; ++ } ++ ++ bool repeatable = ( k == Qt::Key_Up || k == Qt::Key_Down || ++ k == Qt::Key_Right || k == Qt::Key_Left ); ++ ++ qDebug( "key to emit = %d [%s] [repeat=%s]", k, ++ press ? "press" : "release", ++ repeatable ? "true":"false" ); ++ ++ if ( qt_screen->isTransformed() && k >= Qt::Key_Left && k <= Qt::Key_Down ) ++ { ++ qDebug( "SimpadButtonsHandler() - We are transformed! Correcting..." ); ++ int oldK = k; ++ k = xform_dirkey( k ); ++ qDebug( "SimpadButtonsHandler() - Old Key: %d - New Key %d", oldK, k ); ++ } ++ ++ if ( repeatable && press ) ++ repeater->start( repeatdelay, true ); ++ else ++ repeater->stop(); ++ ++ qwsServer->processKeyEvent( 0, k, 0, press, false ); ++} ++ ++ ++void QWSsimpadButtonsHandler::autoRepeat() ++{ ++ qDebug( "Emitting key = %d (released)", k ); ++ processKeyEvent( 0, k, 0, false, true ); ++ qDebug( "Emitting key = %d (pressed)", k ); ++ processKeyEvent( 0, k, 0, true, true ); ++ repeater->start(repeatperiod); ++} ++ ++ ++#endif // QT_NO_QWS_KEYBOARD +Index: qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qwsmouse_qws.cpp 2006-01-20 21:30:35.836477040 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qwsmouse_qws.cpp 2006-01-20 21:36:59.160202976 +0100 +@@ -47,6 +47,7 @@ + #include <stdlib.h> + #include <stdio.h> + #include <sys/ioctl.h> ++#include <sys/time.h> + #include <sys/types.h> + #include <sys/stat.h> + #include <fcntl.h> +@@ -73,6 +74,7 @@ + unsigned short x; + unsigned short y; + unsigned short pad; ++ struct timeval stamp; + } TS_EVENT; + #elif defined(QT_QWS_SL5XXX) + #define QT_QWS_SL5XXX_RAW +@@ -1292,6 +1294,8 @@ + #if defined(QT_QWS_IPAQ) + #ifdef QT_QWS_IPAQ_RAW + dev = "/dev/h3600_tsraw"; ++#elif defined(QT_QWS_SIMPAD) ++ dev = "/dev/touchscreen/usb1x00"; + #else + dev = "/dev/h3600_ts"; + #endif +@@ -1322,7 +1326,7 @@ + + QTPanelHandlerPrivate::~QTPanelHandlerPrivate() + { +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) || defined(QT_QWS_SIMPAD) + if (mouseFD >= 0) + close(mouseFD); + #endif +@@ -1330,7 +1334,7 @@ + + void QTPanelHandlerPrivate::readMouseData() + { +-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) ++#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) || defined(QT_QWS_K2) || defined(QT_QWS_SLC700) || defined(QT_QWS_SIMPAD) + if(!qt_screen) + return; + diff --git a/packages/qte/qte-2.3.12/suspend-resume-hooks.patch b/packages/qte/qte-2.3.12/suspend-resume-hooks.patch new file mode 100644 index 0000000000..34e6ba2133 --- /dev/null +++ b/packages/qte/qte-2.3.12/suspend-resume-hooks.patch @@ -0,0 +1,64 @@ +Suspend/Resume hooks for QScreen and usage from QApplication +Manuel Teira <manuel.teira@telefonica.net> + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- qt-2.3.10/src/kernel/qgfx_qws.h~suspend-resume-hooks ++++ qt-2.3.10/src/kernel/qgfx_qws.h +@@ -192,6 +192,8 @@ + virtual int pixmapLinestepAlignment() { return 64; } + + virtual void sync() {} ++ virtual void prepareToSuspend() {} ++ virtual void prepareToResume() {} + virtual bool onCard(unsigned char *) const; + virtual bool onCard(unsigned char *, ulong& out_offset) const; + +--- qt-2.3.10/src/kernel/qapplication_qws.cpp~suspend-resume-hooks ++++ qt-2.3.10/src/kernel/qapplication_qws.cpp +@@ -480,6 +480,7 @@ + int region_offset_window; + #ifndef QT_NO_COP + QWSQCopMessageEvent *qcop_response; ++ bool manageAPMMessage( QWSQCopMessageEvent *e ); + #endif + QWSEvent* current_event; + QValueList<int> unused_identifiers; +@@ -840,7 +841,7 @@ + QWSQCopMessageEvent *pe = (QWSQCopMessageEvent*)e; + if ( pe->simpleData.is_response ) { + qcop_response = pe; +- } else { ++ } else if ( !manageAPMMessage( pe ) ) { + queue.append(e); + } + #endif +@@ -851,6 +852,26 @@ + } + } + ++#ifndef QT_NO_COP ++bool QWSDisplayData::manageAPMMessage( QWSQCopMessageEvent *e ) ++{ ++ if ( e->channel.data() != QCString( "QPE/System" ) ) { ++ return FALSE; ++ } ++ if ( e->message.data() == QCString( "aboutToSuspend()" ) ) { ++ if ( qt_screen ) qt_screen->prepareToSuspend(); ++ delete e; ++ return TRUE; ++ } ++ if ( e->message.data() == QCString( "returnFromSuspend()" ) ) { ++ if ( qt_screen ) qt_screen->prepareToResume(); ++ delete e; ++ return TRUE; ++ } ++ return FALSE; ++} ++#endif ++ + void QWSDisplayData::offsetPendingExpose( int window, const QPoint &offset ) + { + if ( offset.isNull() ) diff --git a/packages/qte/qte-4.0.0-snapshot/switches.h b/packages/qte/qte-2.3.12/switches.h index 37516b4c75..37516b4c75 100644 --- a/packages/qte/qte-4.0.0-snapshot/switches.h +++ b/packages/qte/qte-2.3.12/switches.h diff --git a/packages/qte/qte-2.3.12/tslib.patch b/packages/qte/qte-2.3.12/tslib.patch new file mode 100644 index 0000000000..47837d7a5d --- /dev/null +++ b/packages/qte/qte-2.3.12/tslib.patch @@ -0,0 +1,53 @@ +Index: qt-2.3.10/src/kernel/qwsmouse_qws.cpp +=================================================================== +--- qt-2.3.10.orig/src/kernel/qwsmouse_qws.cpp 2005-02-16 00:53:53.090339898 +0100 ++++ qt-2.3.10/src/kernel/qwsmouse_qws.cpp 2005-02-16 00:54:43.059069292 +0100 +@@ -1878,30 +1878,33 @@ + */ + void QTSLibHandlerPrivate::interpolateSample() { + #ifdef QT_QWS_TSLIB +- static struct ts_sample samples[25]; +- int index = -1; ++#define TSLIB_MAX_SAMPLES 25 ++ static struct ts_sample samples[TSLIB_MAX_SAMPLES]; ++ int index = 0; ++ int read_samples = 0; + int ret; + + do { +- /* fill only the last sample again */ +- if ( index >= 25 ) +- index = 24; +- ++ /* do not access negative arrays */ ++ if ( index < 0 ) ++ index = 0; ++ + /* we're opened non-blocking */ +- if((ret= ts_read_raw(m_ts, &samples[index], 1 ) ) != 1 ) { ++ if((ret= ts_read_raw(m_ts, &samples[index], 1 ) ) != 1 ) + /* no event yet, so try again */ +- if (ret==-1 ) { +- index--; ++ if (ret==-1 ) + continue; +- } +- } +- }while (samples[index++].pressure != 0); ++ ++ read_samples++; ++ index = (index+1)%TSLIB_MAX_SAMPLES; ++ }while (samples[index == 0 ? (TSLIB_MAX_SAMPLES-1) : index-1].pressure != 0); + + /* +- * index is maximal 25 and we at least one sample ++ * If we've wrapped around each sample is used otherwise ++ * we will use the index + */ +- if( index >= 25 ) +- index = 24; ++ index = read_samples >= TSLIB_MAX_SAMPLES ? ++ (TSLIB_MAX_SAMPLES-1 ) : index; + int x, y; + + /* diff --git a/packages/qte/qte-2.3.12/vt-switch.patch b/packages/qte/qte-2.3.12/vt-switch.patch new file mode 100644 index 0000000000..92b8e5436a --- /dev/null +++ b/packages/qte/qte-2.3.12/vt-switch.patch @@ -0,0 +1,184 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +Index: qt-2.3.10-snapshot-20060120/src/kernel/qapplication_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qapplication_qws.cpp 2006-01-20 20:44:13.910394088 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qapplication_qws.cpp 2006-01-20 20:46:52.639263632 +0100 +@@ -125,6 +125,12 @@ + static int qt_thread_pipe[2]; + #endif + ++#if defined(_OS_LINUX_) ++#include <sys/ioctl.h> ++#include <linux/vt.h> ++#include <linux/kd.h> ++#endif ++ + const int qwsSharedRamSize = 32 * 1024; //Small amount to fit on small devices. + + // These are in qapplication.cpp in qt/main +@@ -165,6 +171,8 @@ + bool qws_accel = TRUE; // ### never set + const char *qws_display_spec = ":0"; + int qws_display_id = 0; ++int qws_terminal_id = 0; ++int qws_terminal_old = 0; + int qws_client_id = 0; + QWidget *qt_pressGrab = 0; + QWidget *qt_mouseGrb = 0; +@@ -1702,6 +1710,15 @@ + type = QApplication::GuiServer; + } else if ( arg == "-interlaced" ) { + qws_screen_is_interlaced = TRUE; ++ } else if ( arg == "-terminal" ) { ++ if ( ++i < argc ) ++ { ++ if ( ( qws_terminal_id = atoi( argv[i] ) ) < 1 ) ++ { ++ qWarning( "Ignoring Invalid Terminal Specification." ); ++ qws_terminal_id = 0; ++ } ++ } + } else if ( arg == "-display" ) { + if ( ++i < argc ) + qws_display_spec = argv[i]; +@@ -1727,6 +1744,53 @@ + if ( type == QApplication::GuiServer ) { + qt_appType = type; + qws_single_process = TRUE; ++ ++ /* Allocate a dedicated virtual terminal -- (C) Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> ++ * Added a new command line option which only is relevant if the application is created as a GuiServer. ++ * The option is -terminal <num>, where <num> specifies the virtual terminal to be occupied by the server. ++ * As default in Linux, 0 means the current virtual terminal. ++ */ ++ #if defined(_OS_LINUX_) ++ if ( qws_terminal_id ) ++ { ++ qDebug( "qt_init() - terminal specification is '%d'.", qws_terminal_id ); ++ struct vt_stat console_stat; ++ int console_fd = ::open( QString().sprintf( "/dev/tty%d", qws_terminal_id ).latin1(), O_RDWR ); ++ if ( console_fd == -1) ++ { ++ qWarning( "qt_init() - can't open tty: %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ if ( ioctl( console_fd, VT_GETSTATE, &console_stat ) == -1 ) ++ { ++ qWarning( "qt_init() - can't ioctl(VT_GETSTATE): %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ qws_terminal_old = console_stat.v_active; ++ qDebug( "qt_init() - active vt is #%d, switching to #%d as requested...", qws_terminal_old, qws_terminal_id ); ++ ++ if ( ioctl( console_fd, VT_ACTIVATE, qws_terminal_id ) == -1 ) ++ { ++ qWarning( "qt_init() - can't ioctl(VT_ACTIVATE): %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ if ( ioctl( console_fd, VT_WAITACTIVE, qws_terminal_id ) == -1 ) ++ { ++ qWarning( "qt_init() - can't ioctl(VT_WAITACTIVE): %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ if ( ioctl( console_fd, KDSETMODE, KD_GRAPHICS ) == -1 ) ++ { ++ qWarning( "qt_init() - can't ioctl(KDSETMODE:KD_GRAPHICS): %s", strerror( errno ) ); ++ exit( -1 ); ++ } ++ ::close( console_fd ); ++ } ++ else ++ { ++ qDebug( "QWSApplication::qt_init() - current terminal specified." ); ++ } ++ #endif + QWSServer::startup(flags); + setenv("QWS_DISPLAY", qws_display_spec, 0); + } +@@ -1777,7 +1841,36 @@ + QFontManager::cleanup(); + + if ( qws_single_process ) { +- QWSServer::closedown(); ++ qDebug( "qt_cleanup() - shutting down QWSServer..." ); ++#ifndef QT_NO_QWS_KEYBOARD ++ if ( qwsServer ) ++ qwsServer->closeKeyboard(); ++#endif ++ QWSServer::closedown(); ++#if defined(_OS_LINUX_) ++ if ( qws_terminal_old > 0 ) ++ { ++ qDebug( "qt_cleanup() - switching back to virtual terminal #%d", qws_terminal_old ); ++ ++ int console_fd = ::open( "/dev/tty0", O_RDWR ); ++ if ( console_fd == -1) ++ { ++ qWarning( "qt_init() - can't open tty: %s", strerror( errno ) ); ++ } ++ else ++ { ++ if ( ioctl( console_fd, KDSETMODE, KD_TEXT ) == -1 ) ++ { ++ qWarning( "qt_init() - can't ioctl(KDSETMODE:KD_TEXT): %s", strerror( errno ) ); ++ } ++ if ( ioctl( console_fd, VT_ACTIVATE, qws_terminal_old ) == -1 ) ++ { ++ qWarning( "qt_init() - can't ioctl(VT_ACTIVATE): %s", strerror( errno ) ); ++ } ++ ::close( console_fd ); ++ } ++ } ++#endif + } + if ( qt_is_gui_used ) { + delete qt_fbdpy; +Index: qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qkeyboard_qws.cpp 2006-01-20 20:44:13.911393936 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qkeyboard_qws.cpp 2006-01-20 20:46:52.640263480 +0100 +@@ -1247,6 +1247,24 @@ + { + if (kbdFD >= 0) + { ++ ++#if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_) ++ struct vt_mode vtMode; ++ ioctl(kbdFD, VT_GETMODE, &vtMode); ++ ++ /* Mickey says: "Better give up control of VT switching. ++ * Hey, I really hate that OS-will-reacquire-resources on process-death ++ * kind of thinking! ++ */ ++ vtMode.mode = VT_AUTO; ++ vtMode.relsig = 0; ++ vtMode.acqsig = 0; ++ ioctl(kbdFD, VT_SETMODE, &vtMode); ++ ++ signal(VTSWITCHSIG, 0); ++ qDebug( "~QWSTtyKeyboardHandler() - released VT." ); ++#endif ++ + #if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_) + ioctl(kbdFD, KDSKBMODE, K_XLATE); + #endif +Index: qt-2.3.10-snapshot-20060120/src/kernel/qgfxlinuxfb_qws.cpp +=================================================================== +--- qt-2.3.10-snapshot-20060120.orig/src/kernel/qgfxlinuxfb_qws.cpp 2006-01-20 20:44:13.911393936 +0100 ++++ qt-2.3.10-snapshot-20060120/src/kernel/qgfxlinuxfb_qws.cpp 2006-01-20 20:46:52.641263328 +0100 +@@ -255,9 +255,9 @@ + + bool QLinuxFbScreen::initDevice() + { +- // No blankin' screen, no blinkin' cursor!, no cursor! ++ /* Setting up the VT parameters is done in qapplication_qws.cpp + const char termctl[]="\033[9;0]\033[?33l\033[?25l"; +- writeTerm(termctl,sizeof(termctl)); ++ writeTerm(termctl,sizeof(termctl)); */ + + // Grab current mode so we can reset it + fb_var_screeninfo vinfo; diff --git a/packages/qte/qte-4.0.0-snapshot/add-qatomic.patch b/packages/qte/qte-4.0.0-snapshot/add-qatomic.patch deleted file mode 100644 index 8fea162691..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/add-qatomic.patch +++ /dev/null @@ -1,72 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- /dev/null -+++ qt-embedded-opensource-4.0.0-b1/src/core/arch/arm/qatomic.cpp -@@ -0,0 +1,64 @@ -+#include <qhash.h> -+ -+#define UNLOCKED {-1,-1,-1,-1} -+#define UNLOCKED2 UNLOCKED,UNLOCKED -+#define UNLOCKED4 UNLOCKED2,UNLOCKED2 -+#define UNLOCKED8 UNLOCKED4,UNLOCKED4 -+#define UNLOCKED16 UNLOCKED8,UNLOCKED8 -+#define UNLOCKED32 UNLOCKED16,UNLOCKED16 -+#define UNLOCKED64 UNLOCKED32,UNLOCKED32 -+#define UNLOCKED128 UNLOCKED64,UNLOCKED64 -+#define UNLOCKED256 UNLOCKED128,UNLOCKED128 -+ -+// use a 4k page for locks -+static int locks[256][4] = { UNLOCKED256 }; -+ -+int *getLock(volatile void *addr) -+{ return locks[qHash(const_cast<void *>(addr)) % 256]; } -+ -+static int *align16(int *lock) -+{ -+ ulong off = (((ulong) lock) % 16); -+ return off ? (int *)(ulong(lock) + 16 - off) : lock; -+} -+ -+extern "C" { -+ -+ int q_ldcw(volatile int *addr); -+ -+ void q_atomic_lock(int *lock) -+ { -+ // ldcw requires a 16-byte aligned address -+ volatile int *x = align16(lock); -+ // FIXME WHERE IS q_ldcw ??? while (q_ldcw(x) == 0) -+ ; -+ } -+ -+ void q_atomic_unlock(int *lock) -+ { lock[0] = lock[1] = lock[2] = lock[3] = -1; } -+ -+ int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval) -+ { -+ int *lock = getLock(ptr); -+ q_atomic_lock(lock); -+ if (*reinterpret_cast<void * volatile *>(ptr) == expected) { -+ *reinterpret_cast<void * volatile *>(ptr) = newval; -+ q_atomic_unlock(lock); -+ return 1; -+ } -+ q_atomic_unlock(lock); -+ return 0; -+ } -+ -+ void *q_atomic_set_ptr(volatile void *ptr, void *newval) -+ { -+ int *lock = getLock(ptr); -+ q_atomic_lock(lock); -+ void *oldval = *reinterpret_cast<void * volatile *>(ptr); -+ *reinterpret_cast<void * volatile *>(ptr) = newval; -+ q_atomic_unlock(lock); -+ return oldval; -+ } -+ -+} -+ diff --git a/packages/qte/qte-4.0.0-snapshot/fix-mkspecs.patch b/packages/qte/qte-4.0.0-snapshot/fix-mkspecs.patch deleted file mode 100644 index 4450b26c25..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/fix-mkspecs.patch +++ /dev/null @@ -1,68 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- qt-embedded-opensource-4.0.0-b2-snapshot-20050128/mkspecs/qws/linux-arm-g++/qmake.conf~fix-mkspecs -+++ qt-embedded-opensource-4.0.0-b2-snapshot-20050128/mkspecs/qws/linux-arm-g++/qmake.conf -@@ -8,12 +8,12 @@ - QT += core gui network - QMAKE_INCREMENTAL_STYLE = sublib - --QMAKE_CC = arm-linux-gcc -+QMAKE_CC = $(CCACHE) arm-linux-gcc - QMAKE_LEX = flex - QMAKE_LEXFLAGS = - QMAKE_YACC = yacc - QMAKE_YACCFLAGS = -d --QMAKE_CFLAGS = -pipe -+QMAKE_CFLAGS = -pipe $(EXTRA_CFLAGS) - QMAKE_CFLAGS_WARN_ON = -Wall -W - QMAKE_CFLAGS_WARN_OFF = - QMAKE_CFLAGS_RELEASE = -O2 -@@ -22,8 +22,8 @@ - QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses - QMAKE_CFLAGS_THREAD = -D_REENTRANT - --QMAKE_CXX = arm-linux-g++ --QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -fno-exceptions -fno-rtti -+QMAKE_CXX = $(CCACHE) arm-linux-g++ -+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -fno-exceptions -fno-rtti $(EXTRA_CXXFLAGS) - QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON - QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF - QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE -@@ -45,14 +45,14 @@ - - QMAKE_LINK = arm-linux-g++ - QMAKE_LINK_SHLIB = arm-linux-g++ --QMAKE_LFLAGS = -+QMAKE_LFLAGS = $(EXTRA_LFLAGS) - QMAKE_LFLAGS_RELEASE = - QMAKE_LFLAGS_DEBUG = - QMAKE_LFLAGS_SHLIB = -shared - QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB - QMAKE_LFLAGS_SONAME = -Wl,-soname, - QMAKE_LFLAGS_THREAD = --QMAKE_RPATH = -Wl,-rpath, -+QMAKE_RPATH = -Wl,-rpath-link, - - QMAKE_LIBS = - QMAKE_LIBS_DYNLOAD = -ldl -@@ -66,6 +66,7 @@ - - QMAKE_MOC = $$[QT_INSTALL_BINS]/moc - QMAKE_UIC = $$[QT_INSTALL_BINS]/uic -+QMAKE_RCC = rcc4 - - QMAKE_AR = ar cqs - QMAKE_RANLIB = ---- qt-embedded-opensource-4.0.0-b2-snapshot-20050128/mkspecs/features/resources.prf~fix-mkspecs -+++ qt-embedded-opensource-4.0.0-b2-snapshot-20050128/mkspecs/features/resources.prf -@@ -1,6 +1,6 @@ - isEmpty(QMAKE_RCC) { - win32:QMAKE_RCC = $$[QT_INSTALL_BINS]\rcc.exe -- else:QMAKE_RCC = $$[QT_INSTALL_BINS]/rcc -+ else:QMAKE_RCC = rcc4 - } - - isEmpty(RCC_DIR):RCC_DIR = . diff --git a/packages/qte/qte-4.0.0-snapshot/fix-qwidget.patch b/packages/qte/qte-4.0.0-snapshot/fix-qwidget.patch deleted file mode 100644 index 4cd174f574..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/fix-qwidget.patch +++ /dev/null @@ -1,17 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- qt-embedded-opensource-4.0.0-b1/src/gui/kernel/qwidget.cpp~fix-qwidget -+++ qt-embedded-opensource-4.0.0-b1/src/gui/kernel/qwidget.cpp -@@ -6272,7 +6272,9 @@ - ic->update(); - #endif - // ##### is this correct -+#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged); -+#endif - } - - diff --git a/packages/qte/qte-4.0.0-snapshot/fix-qwsmanager.patch b/packages/qte/qte-4.0.0-snapshot/fix-qwsmanager.patch deleted file mode 100644 index f676f0e09c..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/fix-qwsmanager.patch +++ /dev/null @@ -1,18 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- qt-embedded-opensource-4.0.0-b1/src/gui/kernel/qapplication_p.h~fix-qwsmanager -+++ qt-embedded-opensource-4.0.0-b1/src/gui/kernel/qapplication_p.h -@@ -41,7 +41,9 @@ - #include "qmutex.h" - #include "qtranslator.h" - #include "qshortcutmap_p.h" -- -+#ifdef Q_WS_QWS -+#include "qwsmanager_qws.h" -+#endif - #include <private/qcoreapplication_p.h> - #include "qapplication.h" - #include "qbasictimer.h" diff --git a/packages/qte/qte-4.0.0-snapshot/fix-sl5000driver.patch b/packages/qte/qte-4.0.0-snapshot/fix-sl5000driver.patch deleted file mode 100644 index 8f25031d7d..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/fix-sl5000driver.patch +++ /dev/null @@ -1,29 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- qt-embedded-opensource-4.0.0-b1/src/gui/embedded/qkbdsl5000_qws.cpp~fix-sl5000driver -+++ qt-embedded-opensource-4.0.0-b1/src/gui/embedded/qkbdsl5000_qws.cpp -@@ -219,7 +219,7 @@ - else if (code == 0x44) { unicode='V'-'@'; scan=Qt::Key_V; } // Paste - else if (code == 0x52) { unicode='Z'-'@'; scan=Qt::Key_Z; } // Undo - if (scan) { -- processKeyEvent(unicode, scan, Qt::ControlButton, !release, false); -+ processKeyEvent(unicode, scan, Qt::ControlModifier, !release, false); - return; - } - } -@@ -307,9 +307,9 @@ - } - - modifiers = 0; -- if (bAlt) modifiers |= Qt::AltButton; -- if (bCtrl) modifiers |= Qt::ControlButton; -- if (bShift) modifiers |= Qt::ShiftButton; -+ if (bAlt) modifiers |= Qt::AltModifier; -+ if (bCtrl) modifiers |= Qt::ControlModifier; -+ if (bShift) modifiers |= Qt::ShiftModifier; - - // looks wrong -- WWA - bool repeat = false; diff --git a/packages/qte/qte-4.0.0-snapshot/fix-vncdriver.patch b/packages/qte/qte-4.0.0-snapshot/fix-vncdriver.patch deleted file mode 100644 index 8c48083a8b..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/fix-vncdriver.patch +++ /dev/null @@ -1,16 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- qt-embedded-opensource-4.0.0-b1/src/gui/embedded/qgfxvnc_qws.cpp~fix-vncdriver -+++ qt-embedded-opensource-4.0.0-b1/src/gui/embedded/qgfxvnc_qws.cpp -@@ -31,7 +31,7 @@ - #include "qgfxvnc_qws.h" - #include <private/qsharedmemory_p.h> - #include <stdlib.h> -- -+#include <stdio.h> - extern QString qws_qtePipeFilename(); - - #define MAP_TILE_SIZE 16 diff --git a/packages/qte/qte-4.0.0-snapshot/gcc34.patch b/packages/qte/qte-4.0.0-snapshot/gcc34.patch deleted file mode 100644 index 603e230dd5..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/gcc34.patch +++ /dev/null @@ -1,26 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- qt-embedded-opensource-4.0.0-b1/src/core/tools/qchar.h~gcc34 -+++ qt-embedded-opensource-4.0.0-b1/src/core/tools/qchar.h -@@ -197,7 +197,7 @@ - const char ascii() const; - const char latin1() const; - inline const ushort unicode() const { return ucs; } -- inline ushort &unicode() { return ucs; } -+ inline ushort &unicode() { return *(&ucs); } - - static QChar fromAscii(char c); - static QChar fromLatin1(char c); ---- qt-embedded-opensource-4.0.0-b1/src/gui/embedded/qgfxlinuxfb_qws.cpp~gcc34 -+++ qt-embedded-opensource-4.0.0-b1/src/gui/embedded/qgfxlinuxfb_qws.cpp -@@ -31,6 +31,7 @@ - - #include <unistd.h> - #include <stdlib.h> -+#include <stdio.h> - #include <sys/ioctl.h> - #include <sys/types.h> - #include <sys/stat.h> diff --git a/packages/qte/qte-4.0.0-snapshot/no-moc-no-uic-no-rcc.patch b/packages/qte/qte-4.0.0-snapshot/no-moc-no-uic-no-rcc.patch deleted file mode 100644 index 2f99979319..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/no-moc-no-uic-no-rcc.patch +++ /dev/null @@ -1,25 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- qt-embedded-opensource-4.0.0-b1/src/src.pro~no-moc-no-uic-no-rcc -+++ qt-embedded-opensource-4.0.0-b1/src/src.pro -@@ -3,16 +3,13 @@ - - # this order is important - win32:SUBDIRS += winmain --SUBDIRS += moc core gui sql -+SUBDIRS += core gui sql - contains(QT_CONFIG, opengl): SUBDIRS += opengl - SUBDIRS += xml network - contains(QT_CONFIG, compat): SUBDIRS += compat - - SUBDIRS += plugins - --embedded:SUBDIRS -= opengl --SUBDIRS += tools -- - # This gives us a top level debug/release - unix { - EXTRA_DEBUG_TARGETS = diff --git a/packages/qte/qte-4.0.0-snapshot/update-qtfontdir b/packages/qte/qte-4.0.0-snapshot/update-qtfontdir deleted file mode 100755 index 6df7b503af..0000000000 --- a/packages/qte/qte-4.0.0-snapshot/update-qtfontdir +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh - -usage() -{ - echo "usage: $0 [font directory, defaults to QTDIR/lib/fonts]" - exit 1 -} - -setVar() -{ - eval "$1='$2'" -} - -getVar() -{ - eval "echo \$$1" -} - -handleQPF() -{ - base=`basename $1` - family=`echo $base|cut -d_ -f1` - pt=`echo $base|cut -d_ -f2` - weight=`echo $base|cut -d_ -f3|sed -e 's,i$,,'` - if (echo $base|cut -d_ -f3|grep -q 'i$'); then - italic="y" - else - italic="n" - fi - echo "$family $base.qpf QPF $italic $weight $pt u" -} - -if [ -z "$1" ]; then - if [ -n "$QTDIR" ]; then - fontdir=$QTDIR/lib/fonts - else - fontdir=/opt/QtPalmtop/lib/fonts - fi -else - fontdir=$1 -fi - -if ! [ -d $fontdir ]; then - echo Error: $fontdir not a directory - exit 1 -fi - -if [ -e $fontdir/fontdir ]; then - cat $fontdir/fontdir | grep -v '\.qpf' > $fontdir/fontdir.new -fi - -( - for file in `ls $fontdir/*.qpf|sed -e's,\.qpf$,,; s,_t[^_]*$,,;'|sort -u`; do - handleQPF $file - done -) >> $fontdir/fontdir.new - -mv $fontdir/fontdir.new $fontdir/fontdir - -exit 0 - -# vim:ai:et:sts=4:sw=4:tw=0: diff --git a/packages/qte/qte-common_2.3.10.inc b/packages/qte/qte-common_2.3.10.inc index dafccc0823..822ee2402f 100644 --- a/packages/qte/qte-common_2.3.10.inc +++ b/packages/qte/qte-common_2.3.10.inc @@ -7,7 +7,7 @@ LICENSE = "GPL" DEPENDS = "zlib libpng jpeg tslib uicmoc-native" DEPENDS_mnci = "zlib libpng jpeg uicmoc-native" DEPENDS_append_c7x0 = " sharp-aticore-oss" -PROVIDES = "virtual/qte virtual/libqte2" +PROVIDES = "virtual/libqte2" FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qte-${PV}" diff --git a/packages/qte/qte-common_2.3.12.inc b/packages/qte/qte-common_2.3.12.inc new file mode 100644 index 0000000000..c4d584ac48 --- /dev/null +++ b/packages/qte/qte-common_2.3.12.inc @@ -0,0 +1,162 @@ +DESCRIPTION = "Qt/Embedded Version ${PV}" +SECTION = "libs" +PRIORITY = "optional" +MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" +HOMEPAGE = "http://www.trolltech.com" +LICENSE = "GPL" +DEPENDS = "zlib libpng jpeg tslib uicmoc-native" +DEPENDS_mnci = "zlib libpng jpeg uicmoc-native" +DEPENDS_append_c7x0 = " sharp-aticore-oss" +PROVIDES = "virtual/libqte2" + +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qte-${PV}" + +SRC_URI = "http://ewi546.ewi.utwente.nl/mirror/hrw-oe-sources/qt-embedded-2.3.10-snapshot-20060120.tar.gz \ + file://qpe.patch;patch=1 \ + file://vt-switch.patch;patch=1 \ + file://daemonize.patch;patch=1 \ + file://no-moc.patch;patch=1 \ + file://gcc3.patch;patch=1 \ + file://gcc4.patch;patch=1 \ + file://c700-hardware.patch;patch=1 \ + file://encoding.patch;patch=1 \ + file://fix-qgfxraster.patch;patch=1 \ + file://qt-visibility.patch;patch=1 \ + file://simpad.patch;patch=1 \ + file://handhelds.patch;patch=1 \ + file://qiconview-speed.patch;patch=1 \ + file://qtabbar.patch;patch=1 \ + file://qte-fix-iconsize.patch;patch=1 \ + file://fix-linuxfb-setmode.patch;patch=1 \ + file://fix-linuxfb-offscreenoverflow.patch;patch=1 \ + file://fix-qscreen-sync.patch;patch=1 \ + file://improve-calibration-r0.patch;patch=1 \ + file://key.patch;patch=1 \ + file://bidimetrics.patch;patch=5 \ + file://simpad-defaultkbd.patch;patch=1 \ + file://fix-errno-exception-spec.patch;patch=1 \ + file://sharp_char.h \ + file://switches.h " + +SRC_URI_append_simpad = "file://devfs.patch;patch=1 " +SRC_URI_append_c7x0 = "file://kernel-keymap-corgi.patch;patch=1 \ + file://c7x0-w100-accel.patch;patch=1 file://suspend-resume-hooks.patch;patch=1 " +SRC_URI_append_spitz = "file://kernel-keymap-corgi.patch;patch=1 file://kernel-keymap-CXK.patch;patch=1 " +SRC_URI_append_akita = "file://kernel-keymap-corgi.patch;patch=1 file://kernel-keymap-CXK.patch;patch=1 " +SRC_URI_append_tosa = "file://kernel-keymap-tosa.patch;patch=1 " +SRC_URI_append_jornada7xx = "file://ipaq_sound_fix.patch;patch=1 " +SRC_URI_append_jornada56x = "file://ipaq_sound_fix.patch;patch=1 " +SRC_URI_append_mnci = "file://devfs.patch;patch=1 \ + file://mnci.patch;patch=1 \ + file://mnci-touchscreen.patch;patch=1 \ + file://qkeyboard_qws.h \ + file://qkeyboard_qws.cpp " +SRC_URI_append_h3600 = "file://ipaq-keyboard.patch;patch=1 file://ipaq_sound_fix.patch;patch=1 " +SRC_URI_append_h3900 = "file://ipaq-keyboard.patch;patch=1 file://ipaq_sound_fix.patch;patch=1 " +SRC_URI_append_h1910 = "file://ipaq-keyboard.patch;patch=1 file://ipaq_sound_fix.patch;patch=1 " + +S = "${WORKDIR}/qt-2.3.10-snapshot-20060120" +export QTDIR = "${S}" + +def qte_arch(d): + import bb, re + arch = bb.data.getVar('TARGET_ARCH', d, 1) + if re.match("^i.86$", arch): + arch = "x86" + elif arch == "x86_64": + arch = "x86" + elif arch == "mipsel": + arch = "mips" + return arch + +QTE_ARCH := "${@qte_arch(d)}" + +EXTRA_OECONF_CONFIG = "-qconfig qpe" +EXTRA_OECONF_CONFIG_c7x0 = "-qconfig qpe -accel-w100" +EXTRA_OECONF_CONFIG_native = "-qconfig qpe -qvfb" +EXTRA_OECONF = "-system-jpeg -system-libpng -system-zlib -no-qvfb -no-xft -no-vnc -gif \ + -xplatform ${TARGET_OS}-${QTE_ARCH}-g++ ${EXTRA_OECONF_CONFIG} -depths 8,16,32" +EXTRA_OEMAKE = "-e" + +# +# FIXME: Add more here +# +EXTRA_DEFINES = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DWARNING_UNKNOWN_DEVICE" +EXTRA_DEFINES_collie = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_SL5XXX" +EXTRA_DEFINES_poodle = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_SL5XXX" +EXTRA_DEFINES_tosa = "-DQT_QWS_TSLIB -DQT_QWS_SL5XXX -DQT_QWS_SL6000" +EXTRA_DEFINES_h3600 = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ" +EXTRA_DEFINES_h3900 = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ" +EXTRA_DEFINES_h1910 = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ" +EXTRA_DEFINES_a716 = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ" +EXTRA_DEFINES_jornada56x = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ" +EXTRA_DEFINES_jornada6xx = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ" +EXTRA_DEFINES_jornada7xx = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ" +EXTRA_DEFINES_simpad = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_IPAQ -DQT_QWS_SIMPAD -DQT_QWS_DEVFS" +EXTRA_DEFINES_c7x0 = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_SLC700 -DQT_QWS_SL5XXX" +EXTRA_DEFINES_spitz = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_SLC700 -DQT_QWS_SL5XXX -DQT_QWS_SLCXK" +EXTRA_DEFINES_akita = "-DQT_QWS_TSLIB -DQT_QWS_CUSTOM -DQT_QWS_SLC700 -DQT_QWS_SL5XXX -DQT_QWS_SLCXK" +EXTRA_DEFINES_mnci = " -DQT_QWS_RAMSES -DQT_QWS_DEVFS" + +export SYSCONF_CC = "${CC}" +export SYSCONF_CXX = "${CXX}" +export SYSCONF_LINK = "${CCLD}" +export SYSCONF_SHLIB = "${CCLD}" +export SYSCONF_CFLAGS = "${CFLAGS}" +export SYSCONF_LINK_SHLIB = "${CCLD}" +export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fno-exceptions -fno-rtti -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" +#export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fno-exceptions -fno-rtti -fvisibility=hidden -DGCC_SUPPORTS_VISIBILITY -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" +export SYSCONF_LFLAGS = "${LDFLAGS} -lts" +export SYSCONF_LFLAGS_mnci = "${LDFLAGS}" +export SYSCONF_MOC = "${STAGING_BINDIR}/moc" +export SYSCONF_UIC = "${STAGING_BINDIR}/uic" + +do_configure_prepend_mnci() { + chmod -R a+w ${S}/src/kernel + cp ${WORKDIR}/qkeyboard_qws.h ${S}/src/kernel + cp ${WORKDIR}/qkeyboard_qws.cpp ${S}/src/kernel + mkdir bin + ln -sf ${STAGING_BINDIR}/moc bin/moc + ln -sf ${STAGING_BINDIR}/uic bin/uic +} + +# generate uclibc and eabi configurations +do_configure() { + for f in ${S}/configs/linux-*-g++-shared; do + sed -e 's,-linux-,-linux-uclibc-,g' < $f \ + > `dirname $f`/`basename $f | sed -e 's,linux-,linux-uclibc-,'` + sed -e 's,-linux-,-linux-gnueabi-,g' < $f \ + > `dirname $f`/`basename $f | sed -e 's,linux-,linux-gnueabi-,'` + done + echo yes | ./configure ${EXTRA_OECONF} || die "Configuring qt failed. EXTRA_OECONF was ${EXTRA_OECONF}" +} + +do_compile() { + unset CC LD CCLD CXX RANLIB AR STRIP CFLAGS LDFLAGS CXXFLAGS CPPFLAGS + install -d include/asm/ + install -m 0644 ${WORKDIR}/sharp_char.h include/asm/ + install -d include/linux/ + install -m 0644 ${WORKDIR}/switches.h include/linux/ + + # Create symlinks first and then compile the library + oe_runmake symlinks + oe_runmake src-mt sub-src +} + +do_stage() { + rm -rf ${STAGING_DIR}/${HOST_SYS}/qt2 + install -d ${STAGING_DIR}/${HOST_SYS}/qt2/lib + oe_libinstall -so -C lib lib${PN} ${STAGING_DIR}/${HOST_SYS}/qt2/lib + rm -f include/qxt.h + install -d ${STAGING_DIR}/${HOST_SYS}/qt2/include + cp -pfLR include/* ${STAGING_DIR}/${HOST_SYS}/qt2/include + cp -pPR lib/fonts ${STAGING_DIR}/${HOST_SYS}/qt2/lib/ + install -m 0644 src/kernel/qsnoopdata_qws_p.h ${STAGING_DIR}/${HOST_SYS}/qt2/include/ +} + +do_install() { + oe_libinstall -so -C lib lib${PN} ${D}${palmqtdir}/lib/ +} + +PACKAGE_ARCH = "${MACHINE_ARCH}" +FILES_${PN} = "${palmqtdir}" diff --git a/packages/qte/qte-mt-static_2.3.12.bb b/packages/qte/qte-mt-static_2.3.12.bb new file mode 100644 index 0000000000..ab0844135c --- /dev/null +++ b/packages/qte/qte-mt-static_2.3.12.bb @@ -0,0 +1,23 @@ +require qte-common_${PV}.inc +PR = "r0" + +EXTRA_OECONF += "-thread -static" +export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fexceptions -frtti -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" +#export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fexceptions -frtti -fvisibility=hidden -DGCC_SUPPORTS_VISIBILITY -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" + +do_stage() { + rm -rf ${STAGING_DIR}/${HOST_SYS}/qt2 + install -d ${STAGING_DIR}/${HOST_SYS}/qt2/lib + oe_libinstall -a -C lib libqte-mt ${STAGING_DIR}/${HOST_SYS}/qt2/lib + rm -f include/qxt.h + install -d ${STAGING_DIR}/${HOST_SYS}/qt2/include + cp -pfLR include/* ${STAGING_DIR}/${HOST_SYS}/qt2/include + cp -pPR lib/fonts ${STAGING_DIR}/${HOST_SYS}/qt2/lib/ +} + +do_install() { + : +} + +PACKAGE_ARCH = "${MACHINE_ARCH}" +FILES_${PN} = "${palmqtdir}" diff --git a/packages/qte/qte-mt_2.3.10.bb b/packages/qte/qte-mt_2.3.10.bb index eeed231496..6ca6566458 100644 --- a/packages/qte/qte-mt_2.3.10.bb +++ b/packages/qte/qte-mt_2.3.10.bb @@ -1,9 +1,7 @@ require qte-common_${PV}.inc - PR = "r0" -EXTRA_OECONF = "-system-jpeg -system-libpng -system-zlib -no-qvfb -no-xft -no-vnc -gif -thread -static \ - -xplatform ${TARGET_OS}-${QTE_ARCH}-g++ ${EXTRA_OECONF_CONFIG} -depths 8,16,32" +EXTRA_OECONF += "-thread" export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fexceptions -frtti -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" #export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fexceptions -frtti -fvisibility=hidden -DGCC_SUPPORTS_VISIBILITY -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" diff --git a/packages/qte/qte-mt_2.3.12.bb b/packages/qte/qte-mt_2.3.12.bb new file mode 100644 index 0000000000..6ca6566458 --- /dev/null +++ b/packages/qte/qte-mt_2.3.12.bb @@ -0,0 +1,9 @@ +require qte-common_${PV}.inc +PR = "r0" + +EXTRA_OECONF += "-thread" +export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fexceptions -frtti -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" +#export SYSCONF_CXXFLAGS = "${CXXFLAGS} -pipe -DQWS -fexceptions -frtti -fvisibility=hidden -DGCC_SUPPORTS_VISIBILITY -DNO_DEBUG ${EXTRA_DEFINES} -DUSE_BIDI" + +PACKAGE_ARCH = "${MACHINE_ARCH}" +FILES_${PN} = "${palmqtdir}" diff --git a/packages/qte/qte_2.3.10.bb b/packages/qte/qte_2.3.10.bb index 345a585254..25741931e6 100644 --- a/packages/qte/qte_2.3.10.bb +++ b/packages/qte/qte_2.3.10.bb @@ -1,2 +1,3 @@ require qte-common_${PV}.inc PR = "r40" + diff --git a/packages/qte/qte_4.0.0-snapshot.bb b/packages/qte/qte_4.0.0-snapshot.bb deleted file mode 100644 index 25dc949edd..0000000000 --- a/packages/qte/qte_4.0.0-snapshot.bb +++ /dev/null @@ -1,248 +0,0 @@ -DESCRIPTION = "Qt/Embedded version ${PV}" -SECTION = "libs" -PRIORITY = "optional" -LICENSE = "GPL QPL" -DEPENDS = "zlib libpng jpeg tslib qmake-native-1.08a uicmoc4-native" -PROVIDES = "virtual/qte4 virtual/libqte4" -MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" -PR = "ml1" -HOMEPAGE = "http://www.trolltech.com" - -BROKEN = "1" - -PV = "4.0.0-b2-snapshot-20050128" - -FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qte-4.0.0-snapshot" - -SRC_URI = "ftp://ftp.trolltech.com/pub/qt/snapshots/qt-embedded-opensource-${PV}.tar.bz2 \ - file://gcc34.patch;patch=1 \ - file://add-qatomic.patch;patch=1 \ - file://fix-mkspecs.patch;patch=1 \ - file://fix-qwsmanager.patch;patch=1 \ - file://fix-sl5000driver.patch;patch=1 \ - file://no-moc-no-uic-no-rcc.patch;patch=1 \ - file://sharp_char.h \ - file://switches.h \ - file://update-qtfontdir" -S = "${WORKDIR}/qt-embedded-opensource-${PV}" - -DEFAULT_PREFERENCE = "-1" - -export QTDIR = "${S}" - -def qte_arch(d): - import bb, re - arch = bb.data.getVar('TARGET_ARCH', d, 1) - if re.match("^i.86$", arch): - arch = "x86" - elif arch == "x86_64": - arch = "x86" - elif arch == "mipsel": - arch = "mips" - return arch - -QTE_ARCH := "${@qte_arch(d)}" - -# -# How to build the embedded drivers. Use plugin-<type> or qt-<type>. As for Beta1, that doesn't work :D -# -GFX = "qt-gfx" -KBD = "qt-kbd" -MSE = "qt-mouse" - -# -# Which configuration to build. As for Beta1, this doesn't work :) -# -QCONFIG = "" -# QCONFIG = "-qconfig full" -QDEPTHS = "-depths 8,16,24,32" - -# -# Borken: yopy, busmouse, linuxtp -# - -EXTRA_OECONF = "-embedded ${QTE_ARCH} \ - -system-libjpeg -system-libpng -system-zlib \ - -no-qvfb -no-nis -no-cups -no-stl -no-pch \ - -no-accessibility -no-compat -fast \ - ${QCONFIG} ${QDEPTHS} \ - -qt-gfx-transformed \ - -qt-gfx-vnc \ - -${KBD}-sl5000 \ - -${KBD}-tty \ - -${KBD}-usb \ - -${MSE}-pc \ - " - -EXTRA_OEMAKE = "-e" -PARALLEL_MAKE = "" - -export EXTRA_CFLAGS = "-I${STAGING_INCDIR}" -export EXTRA_CXXFLAGS = "-I${STAGING_INCDIR}" -export EXTRA_LFLAGS = "-L${STAGING_LIBDIR} -Wl,-rpath-link,${STAGING_LIBDIR}" - -do_configure() { - echo "DEFINES -= QT_NO_CAST_TO_ASCII" >>src/qbase.pri - unset QMAKESPEC - echo yes | ./configure ${EXTRA_OECONF} || die "Configuring qt failed. EXTRA_OECONF was ${EXTRA_OECONF}" -} - -do_compile() { - unset CC LD CCLD CXX RANLIB AR STRIP CFLAGS LDFLAGS CXXFLAGS CPPFLAGS LINK - install -m 0755 ${STAGING_BINDIR}/rcc4 ${S}/bin/rcc - install -m 0755 ${STAGING_BINDIR}/moc4 ${S}/bin/moc - install -m 0755 ${STAGING_BINDIR}/uic4 ${S}/bin/uic - - install -d include/asm/ - install -m 0644 ${WORKDIR}/sharp_char.h include/asm/ - install -d include/linux/ - install -m 0644 ${WORKDIR}/switches.h include/linux/ - - oe_runmake -} - -do_stage() { - install -d ${STAGING_DIR}/${HOST_SYS}/qt4/lib - - for lib in Core Gui Network Sql Xml - do - cp -pPR lib/libQt${lib}* ${STAGING_DIR}/${HOST_SYS}/qt4/lib/ - done - - install -d ${STAGING_DIR}/${HOST_SYS}/qt4/include/ - cp -pPR include/* ${STAGING_DIR}/${HOST_SYS}/qt4/include -} - -do_install() { - install -d ${D}${palmtopdir}/bin - install -d ${D}${sbindir}/ - install -m 0755 ${WORKDIR}/update-qtfontdir ${D}${sbindir}/ - install -d ${D}${palmtopdir}/lib/fonts/ - cp -pPR lib/fonts/* ${D}${palmtopdir}/lib/fonts/ - - for lib in Core Gui Network Sql Xml - do - oe_soinstall lib/libQt${lib}.so.4.0.0 ${D}${palmtopdir}/lib - done - - for i in `find . -perm 0755 -type f` - do - install -m 0755 $i ${D}${palmtopdir}/bin/`basename $i` - done -} - -pkg_postinst() { -#!/bin/sh -if [ -n "$D" ]; then exit 1; fi -set -e -. /etc/profile -${sbindir}/update-qtfontdir -} - -pkg_postinst_qte-font-unicode() { -#!/bin/sh -if [ -n "$D" ]; then exit 1; fi -set -e -. /etc/profile -${sbindir}/update-qtfontdir -} - -pkg_postinst_qte-font-lcd () { -#!/bin/sh -if [ -n "$D" ]; then exit 1; fi -set -e -. /etc/profile -${sbindir}/update-qtfontdir -} - -pkg_postinst_qte-font-japanese() { -#!/bin/sh -if [ -n "$D" ]; then exit 1; fi -set -e -. /etc/profile -${sbindir}/update-qtfontdir -} - -pkg_postinst_qte-font-micro() { -#!/bin/sh -if [ -n "$D" ]; then exit 1; fi -set -e -. /etc/profile -${sbindir}/update-qtfontdir -} - -pkg_postinst_qte-font-courier() { -#!/bin/sh -if [ -n "$D" ]; then exit 1; fi -set -e -. /etc/profile -${sbindir}/update-qtfontdir -} - -LIB_PACKAGES = "\ - libqte4-debug \ - libqte4-core \ - libqte4-gui \ - libqte4-network \ - libqte4-sql \ - libqte4-xml \ - " - - -FONT_PACKAGES = "\ - qte-font-fixed \ - qte-font-helvetica-small \ - qte-font-helvetica-large \ - qte-font-smoothtimes \ - qte-font-smallsmooth \ - qte-font-unicode \ - qte-font-lcd \ - qte-font-japanese \ - qte-font-micro \ - qte-font-courier \ - " - -PACKAGES = "${LIB_PACKAGES} ${FONT_PACKAGES} examples" - -PACKAGE_ARCH = "${MACHINE_ARCH}" - -FILES_${PN} = "" -FILES_libqte4-debug = "${palmtopdir}/lib/libQt*_debug.*" -FILES_libqte4-core = "${palmtopdir}/lib/libQtCore.* ${sbindir}/update-qtfontdir" -FILES_libqte4-gui = "${palmtopdir}/lib/libQtGui.*" -FILES_libqte4-network = "${palmtopdir}/lib/libQtNetwork.*" -FILES_libqte4-sql = "${palmtopdir}/lib/libQtSql.*" -FILES_libqte4-xml = "${palmtopdir}/lib/libQtXml.*" -FILES_examples = "${palmtopdir}/bin" - -FILES_qte-font-fixed = "${palmtopdir}/lib/fonts/fixed*" -PACKAGE_ARCH_qte-font-fixed = "all" - -FILES_qte-font-helvetica-small = "${palmtopdir}/lib/fonts/helvetica_80*.qpf \ - ${palmtopdir}/lib/fonts/helvetica_100*.qpf ${palmtopdir}/lib/fonts/helvetica_120*.qpf" -PACKAGE_ARCH_qte-font-helvetica-small = "all" - -FILES_qte-font-helvetica-large = "${palmtopdir}/lib/fonts/helvetica_140*.qpf \ - ${palmtopdir}/lib/fonts/helvetica_180*.qpf ${palmtopdir}/lib/fonts/helvetica_240*.qpf" -PACKAGE_ARCH_qte-font-helvetica-large = "all" - -FILES_qte-font-smoothtimes = "${palmtopdir}/lib/fonts/smoothtimes*" -PACKAGE_ARCH_qte-font-smoothtimes = "all" - -FILES_qte-font-smallsmooth = "${palmtopdir}/lib/fonts/smallsmooth*" -PACKAGE_ARCH_qte-font-smallsmooth = "all" - -FILES_qte-font-unicode = "${palmtopdir}/lib/fonts/unifont*.qpf" -PACKAGE_ARCH_qte-font-unicode = "all" - -FILES_qte-font-lcd = "${palmtopdir}/lib/fonts/lcd*" -PACKAGE_ARCH_qte-font-lcd = "all" - -FILES_qte-font-japanese = "${palmtopdir}/lib/fonts/japanese*" -PACKAGE_ARCH_qte-font-japanese = "all" - -FILES_qte-font-micro = "${palmtopdir}/lib/fonts/micro*.qpf" -PACKAGE_ARCH_qte-font-micro = "all" - -FILES_qte-font-courier = "${palmtopdir}/lib/fonts/cour*" -PACKAGE_ARCH_qte-font-courier = "all" diff --git a/packages/sdlperl/sdl-perl_1.20.3.bb b/packages/sdlperl/sdl-perl_1.20.3.bb index d115f02ce3..80bd899dfc 100644 --- a/packages/sdlperl/sdl-perl_1.20.3.bb +++ b/packages/sdlperl/sdl-perl_1.20.3.bb @@ -1,14 +1,40 @@ -SECTION = "libs" DESCRIPTION = "Perl bindings for SDL" -SRC_URI = "http://bloodgate.com/perl/sdl/pub/SDL_perl-${PV}.tar.gz \ - file://Makefile.patch;patch=1;pnum=0" -S = "${WORKDIR}/SDL_perl-${PV}" +HOMEPAGE = "http://bloodgate.com/perl" +SECTION = "libs" LICENSE = "GPL" DEPENDS = "perl virtual/libsdl libsdl-image libsdl-gfx libsdl-ttf libsdl-mixer libsdl-net smpeg" -inherit sdl +SRC_URI = "http://bloodgate.com/perl/sdl/pub/SDL_perl-${PV}.tar.gz \ + file://Makefile.patch;patch=1;pnum=0" +S = "${WORKDIR}/SDL_perl-${PV}" + +do_configure () { + if [ -x ${S}/configure ] ; then + cfgcmd="${S}/configure \ + -GL -GLU" + oenote "Running $cfgcmd..." + $cfgcmd || oefatal "oe_runconf failed" + if [ "${BUILD_SYS}" != "${HOST_SYS}" ]; then + . ${STAGING_DIR}/${TARGET_SYS}/perl/config.sh + sed -e "s:\(SITELIBEXP = \).*:\1${sitelibexp}:; s:\(SITEARCHEXP = \).*:\1${sitearchexp}:; s:\(INSTALLVENDORLIB = \).*:\1${D}${libdir}/perl5:; s:\(INSTALLVENDORARCH = \).*:\1${D}${libdir}/perl5:" < Makefile > Makefile.new + mv Makefile.new Makefile + fi + else + oefatal "no configure script found" + fi +} do_stage () { - install -d ${STAGING_LIBDIR}/perl5/vendor_perl - install -m 0644 ${S}/lib/SDL.pm ${STAGING_LIBDIR}/perl5/vendor_perl + install -d ${STAGING_LIBDIR}/perl5/vendor_perl + install -m 0644 ${S}/lib/SDL.pm ${STAGING_LIBDIR}/perl5/vendor_perl +} + +do_compile () { + oe_runmake PASTHRU_INC="${CFLAGS}" } + +do_install () { + oe_runmake install_vendor +} + +FILES_${PN} += '${libdir}/perl5' diff --git a/packages/sidplayer/sidplayer_1.5.0.bb b/packages/sidplayer/sidplayer_1.5.0.bb index 1ee1821539..5b2172269d 100644 --- a/packages/sidplayer/sidplayer_1.5.0.bb +++ b/packages/sidplayer/sidplayer_1.5.0.bb @@ -13,7 +13,7 @@ SRC_URI = "http://sidplayer.sourceforge.net/sidplayer.tar.gz \ file://gcc34.patch;patch=1" S = "${WORKDIR}/sidplayer" -EXTRA_QMAKEVARS_PRE = "QMAKE_INCDIR=${STAGING_INCDIR}/sidplay" +EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=${STAGING_INCDIR}/sidplay" inherit palmtop diff --git a/packages/sip/sip-native_3.10.1.bb b/packages/sip/sip-native_3.10.1.bb index b5db3c6b56..1f59d20601 100644 --- a/packages/sip/sip-native_3.10.1.bb +++ b/packages/sip/sip-native_3.10.1.bb @@ -10,4 +10,4 @@ S = "${WORKDIR}/sip-${PV}/sipgen" inherit qmake native QMAKE_PROFILES = "sipgen.pro.in" -EXTRA_QMAKEVARS_POST = "DESTDIR=${STAGING_BINDIR}" +EXTRA_QMAKEVARS_POST += "DESTDIR=${STAGING_BINDIR}" diff --git a/packages/sip/sip-native_4.0.1.bb b/packages/sip/sip-native_4.0.1.bb index 7963c2fa23..06984e00c7 100644 --- a/packages/sip/sip-native_4.0.1.bb +++ b/packages/sip/sip-native_4.0.1.bb @@ -9,7 +9,7 @@ S = "${WORKDIR}/sip-${PV}/sipgen" inherit qmake native -EXTRA_QMAKEVARS_POST = "DESTDIR=${STAGING_BINDIR} CONFIG=console" +EXTRA_QMAKEVARS_POST += "DESTDIR=${STAGING_BINDIR} CONFIG=console" do_configure_prepend() { cat sipgen.sbf | sed s,target,TARGET, | sed s,sources,SOURCES, | sed s,headers,HEADERS, > sipgen.pro diff --git a/packages/sip/sip-native_4.2rc1.bb b/packages/sip/sip-native_4.2rc1.bb deleted file mode 100644 index 1f58bb75ed..0000000000 --- a/packages/sip/sip-native_4.2rc1.bb +++ /dev/null @@ -1,19 +0,0 @@ -DESCRIPTION = "SIP - A Python Wrapper Generator" -SECTION = "base" -PRIORITY = "optional" -MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" -LICENSE = "GPL" - -SRC_URI = "http://www.vanille.de/mirror/sip-${PV}.tar.gz" -S = "${WORKDIR}/sip-${PV}/sipgen" - -inherit qmake native - -DEFAULT_PREFERENCE = "-1" - -EXTRA_QMAKEVARS_POST = "DESTDIR=${STAGING_BINDIR} CONFIG=console" - -do_configure_prepend() { - cat sipgen.sbf | sed s,target,TARGET, | sed s,sources,SOURCES, | sed s,headers,HEADERS, > sipgen.pro -} - diff --git a/packages/sip/sip4-native_4.4.2.bb b/packages/sip/sip4-native_4.4.2.bb new file mode 100644 index 0000000000..395fa15ac7 --- /dev/null +++ b/packages/sip/sip4-native_4.4.2.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "SIP is a C++/Python Wrapper Generator" +SECTION = "base" +HOMEPAGE = "http://www.riverbankcomputing.co.uk/sip" +AUTHOR = "Phil Thompson" +PRIORITY = "optional" +MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" +LICENSE = "GPL" + +SRC_URI = "http://www.riverbankcomputing.com/Downloads/sip4/sip-${PV}.tar.gz" +S = "${WORKDIR}/sip-${PV}/sipgen" + +inherit qmake native + +EXTRA_QMAKEVARS_POST += "DESTDIR=${S} CONFIG=console" + +do_configure_prepend() { + cat sipgen.sbf | sed s,target,TARGET, | sed s,sources,SOURCES, | sed s,headers,HEADERS, > sipgen.pro +} + +do_stage() { + install -m 0755 sip ${STAGING_BINDIR}/sip4 +} + diff --git a/packages/sip/sip_3.10.1.bb b/packages/sip/sip_3.10.1.bb deleted file mode 100644 index db3600f07f..0000000000 --- a/packages/sip/sip_3.10.1.bb +++ /dev/null @@ -1,15 +0,0 @@ -DESCRIPTION = "SIP - A Python Wrapper Generator" -SECTION = "devel" -PRIORITY = "optional" -MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" -LICENSE = "GPL" -DEPENDS = "python-native" - -SRC_URI = "http://www.vanille.de/mirror/sip-${PV}.tar.gz" -S = "${WORKDIR}/sip-${PV}/sipgen" - -inherit qmake - -QMAKE_PROFILES = "sipgen.pro.in" -EXTRA_QMAKEVARS_POST = "DESTDIR=${S}" - diff --git a/packages/slugos-init/files/leds b/packages/slugos-init/files/leds index 433467b96f..f5011f8bad 100644 --- a/packages/slugos-init/files/leds +++ b/packages/slugos-init/files/leds @@ -50,18 +50,20 @@ led_set(){ echo -n timer case "$setting" in - flash) echo -n 0.6;; - blink) echo -n 0.6;; - slow) echo -n 1;; - fast) echo -n 3;; - panic) echo -n 6;; - esac >"$1/frequency" + flash) echo -n 60;; + blink) echo -n 540;; + slow) echo -n 500;; + fast) echo -n 1500;; + panic) echo -n 3000;; + esac >"$1/delay_on" case "$setting" in - flash) echo -n 10;; - blink) echo -n 90;; - *) echo -n 50;; - esac >"$1/duty";; + flash) echo -n 540;; + blink) echo -n 60;; + slow) echo -n 500;; + fast) echo -n 1500;; + panic) echo -n 3000;; + esac >"$1/delay_off";; cpu-idle) echo -n cpu # these settings work well on NSLU2 diff --git a/packages/slugos-init/files/turnup b/packages/slugos-init/files/turnup index b365a49dda..0a51e1abf7 100644 --- a/packages/slugos-init/files/turnup +++ b/packages/slugos-init/files/turnup @@ -84,7 +84,10 @@ get_flash() { return 1 } - ffsdev="$(mtblockdev Flashdisk)" + case "$(machine)" in + nas100d) ffsdev="$(mtblockdev filesystem)";; + *) ffsdev="$(mtblockdev Flashdisk)";; + esac umountflash "$ffsdev" && mountflash "$ffsdev" "$ffsdir" "$@" } diff --git a/packages/slugos-init/slugos-init_0.10.bb b/packages/slugos-init/slugos-init_0.10.bb index 971f6cf288..182d204b15 100644 --- a/packages/slugos-init/slugos-init_0.10.bb +++ b/packages/slugos-init/slugos-init_0.10.bb @@ -4,7 +4,7 @@ PRIORITY = "required" LICENSE = "GPL" DEPENDS = "base-files devio" RDEPENDS = "busybox devio" -PR = "r58" +PR = "r59" SRC_URI = "file://boot/flash \ file://boot/disk \ diff --git a/packages/sysvinit/sysvinit_2.86.bb b/packages/sysvinit/sysvinit_2.86.bb index d15afdfa23..e33e9e8728 100644 --- a/packages/sysvinit/sysvinit_2.86.bb +++ b/packages/sysvinit/sysvinit_2.86.bb @@ -3,7 +3,7 @@ SECTION = "base" LICENSE = "GPL" MAINTAINER = "Chris Larson <kergoth@handhelds.org>" HOMEPAGE = "http://freshmeat.net/projects/sysvinit/" -PR = "r22" +PR = "r23" # USE_VT and SERIAL_CONSOLE are generally defined by the MACHINE .conf. # Set PACKAGE_ARCH appropriately. @@ -17,6 +17,7 @@ FILES_${PN}-inittab = "${sysconfdir}/inittab" CONFFILES_${PN}-inittab = "${sysconfdir}/inittab" USE_VT ?= "1" +SYSVINIT_ENABLED_GETTYS ?= "1" SRC_URI = "ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/sysvinit-2.85.tar.gz \ file://sysvinit-2.86.patch;patch=1 \ @@ -72,11 +73,14 @@ do_install () { # Format: # <id>:<runlevels>:<action>:<process> # -1:2345:respawn:${base_sbindir}/getty 38400 tty1 -# 2:23:respawn:${base_sbindir}/getty 38400 tty2 -# 3:23:respawn:${base_sbindir}/getty 38400 tty3 -# 4:23:respawn:${base_sbindir}/getty 38400 tty4 + EOF + + for n in ${SYSVINIT_ENABLED_GETTYS} + do + echo "$n:2345:respawn:${base_sbindir}/getty 38400 tty$n" >> ${D}${sysconfdir}/inittab + done + echo "" >> ${D}${sysconfdir}/inittab fi install -m 0644 ${WORKDIR}/rcS-default ${D}${sysconfdir}/default/rcS install -m 0755 ${WORKDIR}/rc ${D}${sysconfdir}/init.d diff --git a/packages/ubahnnav/ubahnnav_0.4.1.bb b/packages/ubahnnav/ubahnnav_0.4.1.bb index 16924681db..9d6f85889e 100644 --- a/packages/ubahnnav/ubahnnav_0.4.1.bb +++ b/packages/ubahnnav/ubahnnav_0.4.1.bb @@ -19,7 +19,7 @@ S = "${WORKDIR}/ubahnnav-${PV}" inherit opie export OE_QMAKE_LINK="${CXX}" -EXTRA_QMAKEVARS_POST = "INCLUDEPATH+=${S}/src/libsubwaymap LIBS+=-L${S} LIBS-=-lqtopia" +EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=${S}/src/libsubwaymap LIBS+=-L${S} LIBS-=-lqtopia" do_configure_prepend() { find . -name "Makefile"|xargs rm -f diff --git a/packages/udev/files/network.sh b/packages/udev/files/network.sh index 2cfbfa91b3..5e2bd5799a 100644 --- a/packages/udev/files/network.sh +++ b/packages/udev/files/network.sh @@ -15,7 +15,7 @@ echo "$INTERFACE" | grep -q wifi && exit 0 if grep -q "iface \+$INTERFACE" /etc/network/interfaces; then case $ACTION in add) - ifup $INTERFACE + ifconfig | grep -q "^$INTERFACE" || ifup $INTERFACE ;; remove) ifdown $INTERFACE diff --git a/packages/udev/udev_084.bb b/packages/udev/udev_084.bb index 6ca02a5cfb..0b6274f45d 100644 --- a/packages/udev/udev_084.bb +++ b/packages/udev/udev_084.bb @@ -14,7 +14,7 @@ include udev.inc INITSCRIPT_PARAMS = "start 03 S . start 55 0 6 ." -PR = "r6" +PR = "r8" FILES_${PN} += "${base_libdir}" UDEV_EXTRAS = "extras/firmware/ extras/scsi_id/ extras/volume_id/ extras/run_directory/" diff --git a/packages/vectoroids/vectoroids_1.1.0.bb b/packages/vectoroids/vectoroids_1.1.0.bb index a283b023ce..cd8580d896 100644 --- a/packages/vectoroids/vectoroids_1.1.0.bb +++ b/packages/vectoroids/vectoroids_1.1.0.bb @@ -1,35 +1,31 @@ -DESCRIPTION = "Clone of the classic arcade game Asteroids for Qtopia/Opie - based on SDL" +DESCRIPTION = "Clone of the classic arcade game Asteroids - SDL edition." SECTION = "opie/games" PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>" LICENSE = "GPL" -DEPENDS = "virtual/libqpe libsdl-qpe libsdl-image libsdl-mixer" -PR = "r1" +PR = "r2" + +APPIMAGE = "data/images/icon.png" +APPNAME = "vectoroids-${PV}" SRC_URI = "ftp://ftp.billsgames.com/unix/x/vectoroids/src/vectoroids-${PV}.tar.gz" -inherit palmtop +inherit qmake sdl -EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=${STAGING_INCDIR}/SDL LIBS+=-lSDL LIBS+=-lSDL_mixer \ - LIBS+=-lSDLmain LIBS+=-lSDL_image LIBS+=-lpthread LIBS+=-lqpe CONFIG+=qte" +EXTRA_QMAKEVARS_POST += "INCLUDEPATH+=${STAGING_INCDIR}/SDL CONFIG-=qt \ + LIBS+=-lSDL \ + LIBS+=-lSDL_mixer \ + LIBS+=-lSDL_image \ + LIBS+=-lpthread \ + DEFINES+=DATA_PREFIX=\\"\"${datadir}/vectoroids/\\"\"" do_configure_prepend() { qmake -project vectoroids.pro } do_install() { - install -d ${D}${palmtopdir}/apps/Games \ - ${D}${palmtopdir}/pics \ - ${D}${palmtopdir}/share/vectoroids \ - ${D}${palmtopdir}/bin - install -m 0755 vectoroids-${PV} ${D}${palmtopdir}/bin/vectoroids - install -m 0644 data/images/icon.png ${D}${palmtopdir}/pics/vectoroids.png - cp -pPR data/* ${D}${palmtopdir}/share/vectoroids - - echo "[Desktop Entry]" >${D}${palmtopdir}/apps/Games/vectoroids.desktop - echo "Comment=Asteroids game" >>${D}${palmtopdir}/apps/Games/vectoroids.desktop - echo "Exec=vectoroids" >>${D}${palmtopdir}/apps/Games/vectoroids.desktop - echo "Icon=vectoroids" >>${D}${palmtopdir}/apps/Games/vectoroids.desktop - echo "Type=Application" >>${D}${palmtopdir}/apps/Games/vectoroids.desktop - echo "Name=Vectoroids" >>${D}${palmtopdir}/apps/Games/vectoroids.desktop + install -d ${D}${bindir} + install -m 0755 ${APPNAME} ${D}${bindir} + install -d ${D}${datadir}/vectoroids/ + cp -pPR data/* ${D}${datadir}/vectoroids/ } diff --git a/packages/visiscript/visiscript_0.3.1.bb b/packages/visiscript/visiscript_0.3.1.bb index 948924d597..4124048ea9 100644 --- a/packages/visiscript/visiscript_0.3.1.bb +++ b/packages/visiscript/visiscript_0.3.1.bb @@ -17,7 +17,7 @@ inherit opie QMAKE_PROFILES = "zvisiscript.pro" -EXTRA_QMAKEVARS_POST = "CONFIG-=thread LIBS-=../qscintilla-1.60-gpl-1.3/qt/libqscintilla.a LIBS+=-lqscintilla" +EXTRA_QMAKEVARS_POST += "CONFIG-=thread LIBS-=../qscintilla-1.60-gpl-1.3/qt/libqscintilla.a LIBS+=-lqscintilla" do_install() { install -d ${D}${palmtopdir}/pics/ diff --git a/packages/visiscript/visiscript_0.3.2.bb b/packages/visiscript/visiscript_0.3.2.bb index 23a62cee68..7fcdb1bdd1 100644 --- a/packages/visiscript/visiscript_0.3.2.bb +++ b/packages/visiscript/visiscript_0.3.2.bb @@ -17,7 +17,7 @@ inherit opie QMAKE_PROFILES = "zvisiscript.pro" -EXTRA_QMAKEVARS_POST = "CONFIG-=thread LIBS-=../qscintilla-1.60-gpl-1.3/qt/lib/libqscintilla_arm.a LIBS+=-lqscintilla" +EXTRA_QMAKEVARS_POST += "CONFIG-=thread LIBS-=../qscintilla-1.60-gpl-1.3/qt/lib/libqscintilla_arm.a LIBS+=-lqscintilla" export OE_QMAKE_LINK="${CXX}" do_compile_prepend() { diff --git a/packages/zddice/zddice_1.0.0.bb b/packages/zddice/zddice_1.0.0.bb index f10589c80b..2a58a0a332 100644 --- a/packages/zddice/zddice_1.0.0.bb +++ b/packages/zddice/zddice_1.0.0.bb @@ -11,7 +11,7 @@ S = "${WORKDIR}/zddice-src" inherit palmtop -EXTRA_QMAKEVARS_POST = 'TMAKE_LIBS-="-luuid" TMAKE_LIBS+="-lqpe" CONFIG+=qt CONFIG-=qtopia' +EXTRA_QMAKEVARS_POST += 'TMAKE_LIBS-="-luuid" TMAKE_LIBS+="-lqpe" CONFIG+=qt CONFIG-=qtopia' do_install() { install -d ${D}${palmtopdir}/{bin,pics,apps/Games} diff --git a/packages/zgscore/zgscore_1.0.2.bb b/packages/zgscore/zgscore_1.0.2.bb index e3dc83117c..262902ce2f 100644 --- a/packages/zgscore/zgscore_1.0.2.bb +++ b/packages/zgscore/zgscore_1.0.2.bb @@ -12,7 +12,7 @@ S = "${WORKDIR}/zgscore-src" inherit palmtop -EXTRA_QMAKEVARS_POST = 'TMAKE_LIBS-="-luuid" TMAKE_LIBS+="-lqpe" CONFIG+=qt CONFIG-=qtopia' +EXTRA_QMAKEVARS_POST += 'TMAKE_LIBS-="-luuid" TMAKE_LIBS+="-lqpe" CONFIG+=qt CONFIG-=qtopia' do_install() { install -d ${D}${palmtopdir}/bin \ diff --git a/packages/zlapspeed/zlapspeed_1.0.0.bb b/packages/zlapspeed/zlapspeed_1.0.0.bb index ee0718a02c..cb4b5e5d83 100644 --- a/packages/zlapspeed/zlapspeed_1.0.0.bb +++ b/packages/zlapspeed/zlapspeed_1.0.0.bb @@ -10,7 +10,7 @@ S = "${WORKDIR}/zlaps-src" inherit palmtop -EXTRA_QMAKEVARS_POST = 'TMAKE_LIBS-="-luuid" TMAKE_LIBS+="-lqpe" CONFIG+=qt CONFIG-=qtopia' +EXTRA_QMAKEVARS_POST += 'TMAKE_LIBS-="-luuid" TMAKE_LIBS+="-lqpe" CONFIG+=qt CONFIG-=qtopia' do_install() { install -d ${D}${palmtopdir}/{bin,pics,apps/Applications} diff --git a/packages/zshopi/zshopi_0.2.bb b/packages/zshopi/zshopi_0.2.bb index b393122113..db49069934 100644 --- a/packages/zshopi/zshopi_0.2.bb +++ b/packages/zshopi/zshopi_0.2.bb @@ -23,7 +23,7 @@ FILES_zshopi-i18n-de = "/opt/QtPalmtop/i18n/*" inherit opie -EXTRA_QMAKEVARS_POST = "DEFINES+=QTOPIA LIBS+=-lm LIBS+=-lsqlite LIBS+=-lqpe" +EXTRA_QMAKEVARS_POST += "DEFINES+=QTOPIA LIBS+=-lm LIBS+=-lsqlite LIBS+=-lqpe" OE_QMAKE_CXXFLAGS = "-fno-rtti ${CXXFLAGS}" do_configure_prepend() { |