diff -Nru linux-3.10.11/debian/changelog linux-3.10-3.10.11/debian/changelog --- linux-3.10.11/debian/changelog 2013-09-10 13:13:17.000000000 +0000 +++ linux-3.10-3.10.11/debian/changelog 2014-05-05 11:38:00.000000000 +0000 @@ -1,3 +1,103 @@ +linux-3.10 (3.10.11-1+rpi7) wheezy-staging; urgency=low + + * Update rpi patches + Set CONFIG_HW_RANDOM=m and CONFIG_PPS_CLIENT_GPIO=m (LP: 1275337) + + -- Peter Michael Green Mon, 05 May 2014 11:36:57 +0000 + +linux-3.10 (3.10.11-1+rpi6) wheezy-staging; urgency=low + + * Update rpi patches + Set CONFIG_HW_RANDOM_BCM2708=m (LP: 1275337) + + -- Peter Michael Green Sun, 27 Apr 2014 23:23:31 +0000 + +linux-3.10 (3.10.11-1+rpi5) wheezy-staging; urgency=low + + * Update rpi patches. + * Move rtlwifi related part of + bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch + to new patch + bugfix/all/firmware-remove-redundant-log-messages-from-drivers-rtlwifi.patch + and tweak it for compatibility with rpi patches. + * Remove features/all/rt/md-raid5-percpu-handling-rt-aware.patch and + features/all/rt/rwsem-add-rt-variant.patch from series-rt, they conflict + with the rpi patches and we don't build any rt kernels anyway. + + -- Peter Michael Green Mon, 17 Mar 2014 10:07:26 +0000 + +linux-3.10 (3.10.11-1+rpi4) wheezy-staging; urgency=low + + * Enable I2C stuff + * Update rpi patches. + * Remove features/all/rt/sched-* , peter_zijlstra-frob-migrate_disable*, + features/all/rt/workqueue-distangle-from-rq-lock.patch, + features/all/rt/cpu-rt-rework-cpu-down.patch, + features/all/rt/kernel-cpu-fix-cpu-down-problem-if-kthread-s-cpu-is-.patch, + features/all/rt/*preempt-lazy*, + features/all/rt/completion-use-simple-wait-queues.patch + and features/all/rt/rt-sched-* from series-rt as they fail to apply and + we don't build any rt kernels anyway. + + -- Peter Michael Green Fri, 24 Jan 2014 07:46:57 +0000 + +linux-3.10 (3.10.11-1+rpi3) wheezy-staging; urgency=low + + * Really disable libc-dev package. + * Build in USB storage support to allow USB booting without initrd. + * Disable usb storage modules udeb + + -- Peter Michael Green Wed, 01 Jan 2014 17:58:40 +0000 + +linux-3.10 (3.10.11-1+rpi2) wheezy-staging; urgency=low + + * Copy config tweaks from 3.6 packages + * Disable fat modules udeb as fat is built-in + * Update rpi patches. + + -- Peter Michael Green Tue, 31 Dec 2013 15:17:23 +0000 + +linux-3.10 (3.10.11-1+rpi1) wheezy-staging; urgency=low + + [Vagrant Cascadian ] + * disable other armhf variants. + * disable other armhf debian-installer variants. + * attempt to enable debian-installer udebs for rpi. + * try harder to enable debian-installer udebs. + [Peter Michael Green] + * Include patches to support RaspberryPI from: + https://github.com/raspberrypi/linux.git + branch: rpi-3.10.y + * add script to automatically regenerate rpi patches from git repos + * add hack to allow upgrading of kernel located on fat partition to succeed + * disable features/all/rt/net-another-local-irq-disable-alloc-atomic-headache.patch as it fails to apply + * Fix clean target + * Rename source package and disable libc-dev package to allow coexistance with other versions + * Start rpi patch numbers at 1000 rather than 100 so they sort correctly now we have over 900 patches + * disable debian patches that are or may beduplicates of patches generated from rpi git repo + + bugfix/all/ipv6-remove-max_addresses-check-from-ipv6_create_tem.patch + + bugfix/all/HID-* + + all bugfix patches that are specific to non-arm architectures + + features/all/cgroups-Allow-memory-cgroup-support-to-be-included-b.patch + * Remove changes to arch/x86/kernel/microcode_amd.c from debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch + as they conflict with a later patch we generated. + * disable some patches in the rt series as they fail to apply and we don't + actually build any rt kernels anyway. (note: patches were often disabled in + groups, so not all patches may actually have failed to apply) + features/all/rt/hwlatdetect.patch + features/all/rt/hwlat-detector-Update-hwlat_detector-to-add-outer-lo.patch + features/all/rt/mm-convert-swap-to-percpu-locked.patch + features/all/rt/posix-timers-* + all softirq related rt patches + features/all/rt/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch + all KMAP/HIGHMEM patches + features/all/rt/ipc-sem-rework-semaphore-wakeups.patch + features/all/rt/peterz-srcu-crypto-chain.patch + all the softirq patches. + features/all/rt/move_sched_delayed_work_to_helper.patch + + -- Peter Michael Green Mon, 23 Dec 2013 01:34:25 +0000 + linux (3.10.11-1) unstable; urgency=low * New upstream stable update: diff -Nru linux-3.10.11/debian/config/armhf/config.rpi linux-3.10-3.10.11/debian/config/armhf/config.rpi --- linux-3.10.11/debian/config/armhf/config.rpi 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/config/armhf/config.rpi 2014-05-05 11:38:37.000000000 +0000 @@ -0,0 +1,190 @@ +## +## file: arch/arm/Kconfig +CONFIG_ARCH_BCM2708=y + +# Enable MMC +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_BCM2708=y +CONFIG_MMC_SDHCI_BCM2708_DMA=y +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y + +# +# Boot options +# +CONFIG_CMDLINE_FROM_BOOTLOADER=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y + +# Serial Console +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y + +CONFIG_TTY_PRINTK=y + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_BCM2708=m +CONFIG_I2C_BCM2708_BAUDRATE=100000 + +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BCM2708=m + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y + +CONFIG_THERMAL=y +CONFIG_THERMAL_BCM2835=y + +CONFIG_WATCHDOG=y + +# +# Watchdog Device Drivers +# +CONFIG_BCM2708_WDT=m + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m + +# +# Video decoders +# +CONFIG_VIDEO_SAA711X=m + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +CONFIG_VIDEO_CX25840=m + +# +# MPEG video encoders +# +CONFIG_VIDEO_CX2341X=m + +# +# Graphics support +# +CONFIG_FB=y +##CONFIG_FB_CFB_FILLRECT=y +##CONFIG_FB_CFB_COPYAREA=y +##CONFIG_FB_CFB_IMAGEBLIT=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_BCM2708=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_GENERIC=m + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +## CONFIG_FONTS is not set +##CONFIG_FONT_8x8=y +##CONFIG_FONT_8x16=y + +# Sound +CONFIG_SND_BCM2835=m + +# +# File systems +# +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y + +CONFIG_USB=y + +# USB controller for RPI? +CONFIG_USB_DWCOTG=y + +# USB network for RPI? +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC95XX=y + +# Hopefully make SD card status LED work +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_CLASS=y + +# Build in fat related stuff +CONFIG_VFAT_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_UTF8=y + +# Build in stuff needed for usb keyboard +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_HID_GENERIC=y +CONFIG_HID_WIIMOTE_EXT=y +CONFIG_USB_HID=y +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# build in devtmpfs stuff to allow working without udev +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y + +# build in USB mass storage support at hifi's request. +CONFIG_USB_STORAGE=y + +# I2C stuff requested by Gilligan94 and hifi +CONFIG_REGMAP_I2C=m +CONFIG_INPUT_AD714X_I2C=m +CONFIG_INPUT_ADXL34X_I2C=m +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_BCM2708=m +CONFIG_I2C_BCM2708_BAUDRATE=100000 +CONFIG_I2C_SI470X=m +CONFIG_I2C_SI4713=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_SND_SOC_I2C_AND_SPI=m + +#hardware RNG requested by red ink +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_HW_RANDOM=m + +#for people running timeservers off GPS receivers +CONFIG_PPS_CLIENT_GPIO=m diff -Nru linux-3.10.11/debian/config/armhf/defines linux-3.10-3.10.11/debian/config/armhf/defines --- linux-3.10.11/debian/config/armhf/defines 2013-07-15 01:16:43.000000000 +0000 +++ linux-3.10-3.10.11/debian/config/armhf/defines 2013-12-23 01:34:43.000000000 +0000 @@ -1,9 +1,6 @@ [base] flavours: - armmp - mx5 - omap - vexpress + rpi kernel-arch: arm [image] @@ -43,3 +40,11 @@ hardware: ARM Ltd. Versatile Express hardware-long: ARM Ltd. Versatile Express family of processors +[rpi_build] +image-file: arch/arm/boot/zImage + +[rpi_description] +hardware: RaspberryPI +hardware-long: Raspberry PI + + diff -Nru linux-3.10.11/debian/config.defines.dump linux-3.10-3.10.11/debian/config.defines.dump --- linux-3.10.11/debian/config.defines.dump 2013-09-10 13:13:31.000000000 +0000 +++ linux-3.10-3.10.11/debian/config.defines.dump 2014-05-05 21:50:17.000000000 +0000 @@ -8,1091 +8,1086 @@ dict p3 (dp4 -(S'build' -S's390x' +(S'description' +S'armel' p5 -NS's390x' +NS'iop32x' tp6 (dp7 -S'debug-info' +S'hardware' p8 -I01 +S'IOP32x' +p9 +sS'hardware-long' +p10 +S'IOP32x based systems (Thecus N2100, etc)' +p11 ss(S'image' S'amd64' -p9 -tp10 -(dp11 -S'configs' p12 -(lp13 +tp13 +(dp14 +S'configs' +p15 +(lp16 sS'bootloaders' -p14 -(lp15 +p17 +(lp18 S'grub-pc' -p16 +p19 aS'extlinux' -p17 +p20 aS'lilo' -p18 -ass(S'build' -S'armel' -p19 -NS'ixp4xx' -tp20 -(dp21 -S'image-file' +p21 +ass(S'description' +S'alpha' p22 +NS'alpha-smp' +tp23 +(dp24 +S'hardware' +p25 +S'Alpha SMP' +p26 +sS'hardware-long' +p27 +S'DEC Alpha SMP systems with extended kernel start address (Wildfire, Titan, Marvel)' +p28 +ss(S'build' +g5 +NS'iop32x' +tp29 +(dp30 +S'image-file' +p31 S'arch/arm/boot/zImage' -p23 +p32 ss(S'base' -g9 +g12 S'none' -p24 -tp25 -(dp26 -S'flavours' -p27 -(lp28 -S'amd64' -p29 -ass(S'base' -S'hppa' -p30 -NS'parisc64-smp' -tp31 -(dp32 -S'override-host-type' p33 -S'hppa64-linux-gnu' -p34 -sS'cflags' -p35 -S'-fno-cse-follow-jumps' +tp34 +(dp35 +S'flavours' p36 -ss(S'build' -g19 -NS'iop32x' -tp37 -(dp38 -S'image-file' +(lp37 +S'amd64' +p38 +ass(S'description' +S'ia64' p39 -S'arch/arm/boot/zImage' -p40 -ss(S'image' -S'sparc' -p41 -NS'sparc32' -tp42 -(dp43 -S'image-postproc' -p44 -S'sparc32-image-postproc' -p45 +NS'mckinley' +tp40 +(dp41 +S'hardware' +p42 +S'Itanium II' +p43 ss(S'image' -S'ia64' -p46 -tp47 -(dp48 +g39 +tp44 +(dp45 S'suggests' -p49 +p46 S'fdutils' -p50 +p47 sS'bootloaders' -p51 -(lp52 +p48 +(lp49 S'elilo' -p53 -ass(S'image' -g5 -NS's390x' -tp54 -(dp55 -S'configs' -p56 -(lp57 -S's390/config.s390x' -p58 +p50 ass(S'xen' S'i386' -p59 +p51 S'none' -p60 +p52 S'amd64' -tp61 -(dp62 +tp53 +(dp54 S'flavours' -p63 -(lp64 +p55 +(lp56 S'amd64' -p65 +p57 ass(S'version' -p66 -tp67 -(dp68 +p58 +tp59 +(dp60 S'abiname' -p69 +p61 S'3.10-3' -p70 +p62 sS'source' -p71 -V3.10.11-1 -p72 +p63 +V3.10.11-1+rpi7 +p64 ss(S'description' -g9 -g24 +g12 +g33 S'amd64' -tp73 -(dp74 +tp65 +(dp66 S'parts' -p75 -(lp76 +p67 +(lp68 S'xen' -p77 +p69 ass(S'description' -S'sparc64' -p78 -NS'sparc64-smp' -tp79 -(dp80 -S'hardware' -p81 -S'multiprocessor 64-bit UltraSPARC' -p82 -ss(S'description' -g30 -NS'parisc-smp' -tp83 -(dp84 +g22 +NS'alpha-generic' +tp70 +(dp71 S'hardware' -p85 -S'multiprocessor 32-bit PA-RISC' -p86 -ss(S'image' +p72 +S'Alpha' +p73 +sS'hardware-long' +p74 +S'DEC Alpha systems with extended kernel start address (Wildfire, Titan, Marvel)' +p75 +ss(S'build' S'armhf' +p76 +NS'armmp' +tp77 +(dp78 +S'image-file' +p79 +S'arch/arm/boot/zImage' +p80 +ss(S'base' +g22 +tp81 +(dp82 +S'kernel-arch' +p83 +S'alpha' +p84 +sS'featuresets' +p85 +(lp86 +S'none' p87 -NS'omap' -tp88 -(dp89 -S'recommends' -p90 -S'uboot-mkimage' +ass(S'image' +S'mipsel' +p88 +NS'sb1-bcm91250a' +tp89 +(dp90 +S'configs' p91 -ss(S'description' -S'ppc64' -p92 -NS'powerpc64' -tp93 -(dp94 -S'hardware' -p95 -S'64-bit PowerPC' -p96 -ss(S'base' +(lp92 +S'mips/config.sb1-bcm91250a' +p93 +ass(S'build' +S'sh4' +p94 +NS'sh7751r' +tp95 +(dp96 +S'image-file' p97 -g87 -S'none' +S'arch/sh/boot/zImage' p98 -tp99 -(dp100 +ss(S'base' +p99 +g76 +g87 +tp100 +(dp101 S'implicit-flavour' -p101 +p102 I01 sS'flavours' -p102 -(lp103 -S'armmp' -p104 -aS'mx5' +p103 +(lp104 +S'rpi' p105 -aS'omap' -p106 -aS'vexpress' -p107 -ass(S'description' -g19 -NS'iop32x' -tp108 -(dp109 -S'hardware' +ass(S'image' +g51 +NS'amd64' +tp106 +(dp107 +S'configs' +p108 +(lp109 +S'kernelarch-x86/config-arch-64' p110 -S'IOP32x' +asS'recommends' p111 -sS'hardware-long' +S'libc6-i686' p112 -S'IOP32x based systems (Thecus N2100, etc)' -p113 -ss(S'base' -g59 -S'rt' -tp114 -(dp115 -S'flavours' +ss(S'description' +g76 +NS'vexpress' +tp113 +(dp114 +S'hardware' +p115 +S'ARM Ltd. Versatile Express' p116 -(lp117 -S'686-pae' +sS'hardware-long' +p117 +S'ARM Ltd. Versatile Express family of processors' p118 -ass(S'description' -S'sh4' +ss(S'description' +S'hppa' p119 -NS'sh7785lcr' +NS'parisc64' tp120 (dp121 S'hardware' p122 -S'sh7785lcr' +S'64-bit PA-RISC' p123 -sS'hardware-long' -p124 -S'Renesas SH7785 reference board' -p125 -ss(S'image' -g19 -NS'ixp4xx' -tp126 -(dp127 -S'check-size' +ss(S'base' +g51 +S'rt' +tp124 +(dp125 +S'flavours' +p126 +(lp127 +S'686-pae' p128 -S'1441760' +ass(S'description' +S'powerpc' p129 -sS'configs' -p130 -(lp131 -S'armel/config-reduced' +NS'powerpc' +tp130 +(dp131 +S'hardware' p132 -aS'armel/config.ixp4xx' +S'uniprocessor 32-bit PowerPC' p133 -ass(g97 -S'powerpc' -p134 -g98 -tp135 -(dp136 -g101 -I01 -sg102 -(lp137 -S'powerpc' +ss(S'description' +g88 +NS'loongson-2f' +tp134 +(dp135 +S'hardware' +p136 +S'Loongson 2F' +p137 +sS'hardware-long' p138 -aS'powerpc-smp' +S'Lemote Loongson 2F systems' p139 -aS'powerpc64' -p140 -ass(S'image' -g134 -tp141 -(dp142 -S'suggests' +ss(g99 +g129 +g87 +tp140 +(dp141 +g102 +I01 +sg103 +(lp142 +S'powerpc' p143 -S'mkvmlinuz' +aS'powerpc-smp' p144 +aS'powerpc64' +p145 +ass(S'build' +g76 +NS'omap' +tp146 +(dp147 +S'image-file' +p148 +S'arch/arm/boot/zImage' +p149 ss(S'description' -g134 -NS'powerpc-smp' -tp145 -(dp146 +S'mips' +p150 +NS'r4k-ip22' +tp151 +(dp152 S'hardware' -p147 -S'multiprocessor 32-bit PowerPC' -p148 -ss(S'base' -g9 -S'rt' -tp149 -(dp150 -S'flavours' -p151 -(lp152 -S'amd64' p153 -ass(S'description' -g59 -g60 -S'amd64' -tp154 -(dp155 -S'parts' +S'SGI IP22' +p154 +sS'hardware-long' +p155 +S'SGI IP22 systems (Indy, Indigo2)' p156 -(lp157 -S'xen' -p158 -ass(S'base' -g59 -tp159 -(dp160 -S'kernel-arch' +ss(S'description' +g76 +NS'rpi' +tp157 +(dp158 +S'hardware' +p159 +S'RaspberryPI' +p160 +sS'hardware-long' p161 -S'x86' +S'Raspberry PI' p162 -sS'featuresets' -p163 -(lp164 -S'none' +ss(S'description' +g51 +NS'686-pae' +tp163 +(dp164 +S'hardware' p165 -aS'rt' +S'modern PCs' p166 -ass(S'description' -g30 -NS'parisc64' -tp167 -(dp168 -S'hardware' +sS'parts' +p167 +(lp168 +S'pae' p169 -S'64-bit PA-RISC' +asS'hardware-long' p170 -ss(S'base' -S'mipsel' +S'PCs with one or more processors supporting PAE' p171 +ss(S'base' +g12 +S'rt' tp172 (dp173 -S'kernel-arch' +S'flavours' p174 -S'mips' -p175 -sS'featuresets' +(lp175 +S'amd64' p176 -(lp177 -g98 -ass(S'image' -g19 -NS'orion5x' -tp178 -(dp179 -S'check-size' +ass(S'description' +g94 +NS'sh7785lcr' +tp177 +(dp178 +S'hardware' +p179 +S'sh7785lcr' p180 -S'1572792' +sS'hardware-long' p181 -sS'configs' +S'Renesas SH7785 reference board' p182 -(lp183 -S'armel/config-reduced' -p184 -aS'armel/config.orion5x' +ss(S'description' +g51 +g52 +S'amd64' +tp183 +(dp184 +S'parts' p185 -asS'recommends' -p186 -S'uboot-mkimage' +(lp186 +S'xen' p187 -ss(S'base' -S'powerpcspe' -p188 -tp189 -(dp190 +ass(S'base' +g51 +tp188 +(dp189 S'kernel-arch' +p190 +S'x86' p191 -S'powerpc' +sS'featuresets' p192 -sg176 (lp193 -g98 -ass(g97 -g171 -g98 -tp194 -(dp195 -g101 -I01 -sg102 -(lp196 -S'r5k-cobalt' -p197 -aS'sb1-bcm91250a' +S'none' +p194 +aS'rt' +p195 +ass(S'base' +g88 +tp196 +(dp197 +S'kernel-arch' p198 -aS'sb1a-bcm91480b' +S'mips' p199 -aS'4kc-malta' -p200 -aS'5kc-malta' -p201 -aS'loongson-2f' -p202 -ass(S'description' -S'm68k' +sg85 +(lp200 +g87 +ass(S'base' +tp201 +(dp202 +S'arches' p203 -NS'm68k' -tp204 -(dp205 -S'hardware' +(lp204 +S'alpha' +p205 +aS'amd64' p206 -S'Motorola MC68020+ family' +aS'armel' p207 -ss(S'image' -g9 -NS'amd64' -tp208 -(dp209 -S'configs' +aS'armhf' +p208 +aS'hppa' +p209 +aS'i386' p210 -(lp211 -S'kernelarch-x86/config-arch-64' +aS'ia64' +p211 +aS'm68k' p212 -ass(S'description' -g188 -tp213 -(dp214 -S'hardware' +aS'mips' +p213 +aS'mipsel' +p214 +aS'powerpc' p215 -S'32-bit PowerPC with SPE (instead of AltiVec) with SMP support' +aS'powerpcspe' p216 -ss(S'base' -g30 -NS'parisc64' -tp217 -(dp218 -S'override-host-type' +aS'ppc64' +p217 +aS's390' +p218 +aS's390x' p219 -S'hppa64-linux-gnu' +aS'sh4' p220 -sS'cflags' +aS'sparc' p221 -S'-fno-cse-follow-jumps' +aS'sparc64' p222 -ss(S'image' -g78 -NS'sparc64' -tp223 -(dp224 -S'configs' -p225 -(lp226 -S'sparc/config.sparc64' +aS'x32' +p223 +asS'featuresets' +p224 +(lp225 +S'none' +p226 +aS'rt' p227 -ass(S'description' -g171 -NS'sb1-bcm91250a' -tp228 -(dp229 -S'hardware' -p230 -S'BCM91250A' -p231 -sS'hardware-long' +asS'compiler' +p228 +S'gcc-4.7' +p229 +ss(S'image' +g5 +NS'kirkwood' +tp230 +(dp231 +S'check-size' p232 -S'Broadcom BCM91250A systems (aka SWARM)' +S'2097080' p233 -ss(S'build' -g19 -NS'orion5x' -tp234 -(dp235 -S'image-file' +sS'recommends' +p234 +S'uboot-mkimage' +p235 +ss(S'image' +S'sparc64' p236 -S'arch/arm/boot/zImage' -p237 -ss(S'description' -g46 -NS'mckinley' -tp238 -(dp239 -S'hardware' -p240 -S'Itanium II' +NS'sparc64-smp' +tp237 +(dp238 +S'configs' +p239 +(lp240 +S'sparc/config.sparc64-smp' p241 -ss(S'description' -S'alpha' -p242 -NS'alpha-smp' -tp243 -(dp244 -S'hardware' +ass(g99 +g88 +g87 +tp242 +(dp243 +g102 +I01 +sg103 +(lp244 +S'r5k-cobalt' p245 -S'Alpha SMP' +aS'sb1-bcm91250a' p246 -sS'hardware-long' +aS'sb1a-bcm91480b' p247 -S'DEC Alpha SMP systems with extended kernel start address (Wildfire, Titan, Marvel)' +aS'4kc-malta' p248 -ss(g97 -g119 -g98 -tp249 -(dp250 -g101 -I01 -sg102 -(lp251 -S'sh7751r' -p252 -aS'sh7785lcr' +aS'5kc-malta' +p249 +aS'loongson-2f' +p250 +ass(S'description' +g88 +NS'4kc-malta' +tp251 +(dp252 +S'hardware' p253 -ass(S'build' -g119 -NS'sh7751r' -tp254 -(dp255 -S'image-file' +S'MIPS Malta' +p254 +sS'hardware-long' +p255 +S'MIPS Malta boards' p256 -S'arch/sh/boot/zImage' -p257 ss(S'description' -g19 -NS'mv78xx0' +S'powerpcspe' +p257 tp258 (dp259 S'hardware' p260 -S'Marvell 78xx0' +S'32-bit PowerPC with SPE (instead of AltiVec) with SMP support' p261 -sS'hardware-long' -p262 -S'Marvell DB-78xx0-BP Development Board' -p263 -ss(S'image' -g59 -NS'amd64' -tp264 -(dp265 -S'configs' +ss(S'relations' +tp262 +(dp263 +S'gcc-4.8' +p264 +S'gcc-4.8' +p265 +sS'initramfs-fallback' p266 -(lp267 -S'kernelarch-x86/config-arch-64' +S'linux-initramfs-tool' +p267 +sS'gcc-4.7' p268 -asS'recommends' +S'gcc-4.7' p269 -S'libc6-i686' +sS'gcc-4.6' p270 -ss(S'base' -g19 -tp271 -(dp272 -S'kernel-arch' +S'gcc-4.6' +p271 +sS'gcc-4.4' +p272 +S'gcc-4.4' p273 -S'arm' +sS'initramfs-tools' p274 -sg176 -(lp275 -g98 -ass(S'image' -g78 -NS'sparc64-smp' +S'initramfs-tools (>= 0.110~)' +p275 +ss(S'image' +g12 +NS'amd64' tp276 (dp277 S'configs' p278 (lp279 -S'sparc/config.sparc64-smp' +S'kernelarch-x86/config-arch-64' p280 -ass(S'base' -g41 -tp281 -(dp282 -S'kernel-arch' -p283 -S'sparc' -p284 -sg176 -(lp285 -g98 ass(S'description' -g9 -NS'amd64' +S'ppc64' +p281 +NS'powerpc64' +tp282 +(dp283 +S'hardware' +p284 +S'64-bit PowerPC' +p285 +ss(S'build' +g5 +NS'kirkwood' tp286 (dp287 -S'hardware' +S'image-file' p288 -S'64-bit PCs' +S'arch/arm/boot/zImage' p289 +ss(S'description' +g76 +NS'mx5' +tp290 +(dp291 +S'hardware' +p292 +S'Freescale i.MX51/53' +p293 sS'hardware-long' -p290 -S'PCs with AMD64, Intel 64 or VIA Nano processors' -p291 -ss(S'base' -g242 -tp292 -(dp293 -S'kernel-arch' p294 -S'alpha' +S'Freescale i.MX51 or i.MX53 based systems' p295 -sg176 -(lp296 -g98 -ass(S'base' +ss(g99 +g94 g87 -tp297 -(dp298 -S'kernel-arch' +tp296 +(dp297 +g102 +I01 +sg103 +(lp298 +S'sh7751r' p299 -S'arm' +aS'sh7785lcr' p300 -sg176 -(lp301 -g98 -ass(S'description' -S'mips' -p302 -NS'4kc-malta' -tp303 -(dp304 -S'hardware' -p305 -S'MIPS Malta' -p306 -sS'hardware-long' +ass(S'build' +g5 +NS'orion5x' +tp301 +(dp302 +S'image-file' +p303 +S'arch/arm/boot/zImage' +p304 +ss(S'base' +g5 +tp305 +(dp306 +S'kernel-arch' p307 -S'MIPS Malta boards' +S'arm' p308 -ss(S'description' -NS'rt' -p309 -tp310 -(dp311 -S'part-long-rt' -p312 -S'This kernel includes the PREEMPT_RT realtime patch set.' +sg85 +(lp309 +g87 +ass(S'base' +S'sparc' +p310 +tp311 +(dp312 +S'kernel-arch' p313 -sS'parts' +S'sparc' p314 +sg85 (lp315 -S'rt' -p316 -asS'part-short-rt' -p317 -S'PREEMPT_RT' +g87 +ass(S'base' +g257 +tp316 +(dp317 +S'kernel-arch' p318 -ss(g97 -S's390' +S'powerpc' p319 -g98 -tp320 -(dp321 -g101 -I01 -sg102 -(lp322 -S's390x' +sg85 +(lp320 +g87 +ass(S'description' +g129 +NS'powerpc-smp' +tp321 +(dp322 +S'hardware' p323 -ass(g97 -g5 -g98 -tp324 -(dp325 -g101 -I01 -sg102 -(lp326 -S's390x' +S'multiprocessor 32-bit PowerPC' +p324 +ss(S'description' +g12 +NS'amd64' +tp325 +(dp326 +S'hardware' p327 -ass(S'base' -g302 -tp328 -(dp329 -S'kernel-arch' +S'64-bit PCs' +p328 +sS'hardware-long' +p329 +S'PCs with AMD64, Intel 64 or VIA Nano processors' p330 -S'mips' +ss(g99 +S's390' p331 -sg176 -(lp332 -g98 +g87 +tp332 +(dp333 +g102 +I01 +sg103 +(lp334 +S's390x' +p335 ass(S'description' -g319 -NS's390' -tp333 -(dp334 +g310 +NS'sparc64' +tp336 +(dp337 S'hardware' -p335 -S'IBM S/390' -p336 -ss(S'build' -g9 -tp337 -(dp338 -S'debug-info' +p338 +S'uniprocessor 64-bit UltraSPARC' p339 +ss(g99 +S's390x' +p340 +g87 +tp341 +(dp342 +g102 I01 -ss(S'image' -g59 -NS'486' -tp340 -(dp341 -S'configs' -p342 +sg103 (lp343 -S'kernelarch-x86/config-arch-32' +S's390x' p344 -aS'i386/config.486' -p345 -ass(S'build' -g119 -NS'sh7785lcr' -tp346 -(dp347 -S'image-file' +ass(S'base' +g150 +tp345 +(dp346 +S'kernel-arch' +p347 +S'mips' p348 -S'arch/sh/boot/zImage' -p349 -ss(S'description' -g46 -NS'itanium' +sg85 +(lp349 +g87 +ass(S'build' +g12 tp350 (dp351 -S'hardware' +S'debug-info' p352 -S'Itanium' -p353 +I01 ss(S'image' -g171 -tp354 -(dp355 +g88 +tp353 +(dp354 S'initramfs' -p356 +p355 I00 +ss(S'description' +g150 +NS'5kc-malta' +tp356 +(dp357 +S'hardware' +p358 +S'MIPS Malta (64-bit)' +p359 +sS'hardware-long' +p360 +S'MIPS Malta boards (64-bit)' +p361 +ss(S'description' +g39 +NS'itanium' +tp362 +(dp363 +S'hardware' +p364 +S'Itanium' +p365 ss(S'xen' -g59 -g60 +g51 +g52 S'686-pae' -tp357 -(dp358 +tp366 +(dp367 S'flavours' -p359 -(lp360 +p368 +(lp369 S'i386' -p361 +p370 aS'amd64' -p362 +p371 ass(S'description' -g134 -NS'powerpc64' -tp363 -(dp364 -S'hardware' -p365 -S'64-bit PowerPC' -p366 -ss(S'build' -g87 -NS'omap' -tp367 -(dp368 -S'image-file' -p369 -S'arch/arm/boot/zImage' -p370 -ss(S'description' -g302 -NS'5kc-malta' -tp371 -(dp372 +g5 +NS'kirkwood' +tp372 +(dp373 S'hardware' -p373 -S'MIPS Malta (64-bit)' p374 -sS'hardware-long' +S'Marvell Kirkwood' p375 -S'MIPS Malta boards (64-bit)' +sS'hardware-long' p376 +S'Marvell Kirkwood based systems (SheevaPlug, QNAP TS-119/TS-219, etc)' +p377 +ss(S'description' +g5 +NS'mv78xx0' +tp378 +(dp379 +S'hardware' +p380 +S'Marvell 78xx0' +p381 +sS'hardware-long' +p382 +S'Marvell DB-78xx0-BP Development Board' +p383 ss(S'base' -g9 -tp377 -(dp378 +g12 +tp384 +(dp385 S'kernel-arch' -p379 +p386 S'x86' -p380 +p387 sS'featuresets' -p381 -(lp382 +p388 +(lp389 S'none' -p383 +p390 aS'rt' -p384 +p391 ass(S'base' -g46 -tp385 -(dp386 +g39 +tp392 +(dp393 S'kernel-arch' -p387 +p394 S'ia64' -p388 -sg176 -(lp389 -g98 -ass(S'description' -g41 -NS'sparc32' -tp390 -(dp391 -S'hardware' -p392 -S'uniprocessor sparc32 (sun4m)' -p393 -ss(S'description' +p395 +sg85 +(lp396 g87 -NS'omap' -tp394 -(dp395 -S'hardware' -p396 -S'TI OMAP3+' -p397 -sS'hardware-long' -p398 -S'Texas Instruments OMAP3 or OMAP4 based systems' +ass(S'image' +g94 +NS'sh7785lcr' +tp397 +(dp398 +S'check-size' p399 +S'4194304' +p400 +sS'recommends' +p401 +S'uboot-mkimage' +p402 ss(S'description' -g59 -NS'amd64' -tp400 -(dp401 +g119 +NS'parisc64-smp' +tp403 +(dp404 S'hardware' -p402 -S'64-bit PCs' -p403 -sS'parts' -p404 -(lp405 -S'xen' +p405 +S'multiprocessor 64-bit PA-RISC' p406 -asS'hardware-long' -p407 -S'PCs with AMD64, Intel 64 or VIA Nano processors' -p408 -ss(g97 -g92 -g98 -tp409 -(dp410 -g101 +ss(S'image' +g310 +NS'sparc32' +tp407 +(dp408 +S'image-postproc' +p409 +S'sparc32-image-postproc' +p410 +ss(g99 +g281 +g87 +tp411 +(dp412 +g102 I01 -sg102 -(lp411 +sg103 +(lp413 S'powerpc64' -p412 +p414 ass(S'base' -g319 -tp413 -(dp414 +g331 +tp415 +(dp416 S'kernel-arch' -p415 +p417 S's390' -p416 -sg176 -(lp417 -g98 -ass(g97 -g19 -g98 -tp418 -(dp419 -g101 +p418 +sg85 +(lp419 +g87 +ass(g99 +g5 +g87 +tp420 +(dp421 +g102 I01 -sg102 -(lp420 +sg103 +(lp422 S'iop32x' -p421 +p423 aS'ixp4xx' -p422 +p424 aS'kirkwood' -p423 +p425 aS'mv78xx0' -p424 +p426 aS'orion5x' -p425 +p427 aS'versatile' -p426 -ass(S'description' -g5 +p428 +ass(S'image' +g340 NS's390x' -tp427 -(dp428 -S'hardware' -p429 -S'IBM zSeries' -p430 -ss(S'image' -g19 -NS'iop32x' -tp431 -(dp432 -S'check-size' +tp429 +(dp430 +S'configs' +p431 +(lp432 +S's390/config.s390x' p433 -S'1441784' -p434 -sS'configs' -p435 -(lp436 -S'armel/config-reduced' -p437 -aS'armel/config.iop32x' +ass(S'image' +g51 +NS'686-pae' +tp434 +(dp435 +S'configs' +p436 +(lp437 +S'kernelarch-x86/config-arch-32' p438 -ass(S'description' -g302 -NS'sb1a-bcm91480b' -tp439 -(dp440 -S'hardware' +aS'i386/config.686-pae' +p439 +asS'recommends' +p440 +S'libc6-i686' p441 -S'BCM91480B' -p442 -sS'hardware-long' -p443 -S'Broadcom BCM91480B systems (aka BigSur)' -p444 ss(S'description' -g59 -tp445 -(dp446 -S'part-long-pae' +g94 +NS'sh7751r' +tp442 +(dp443 +S'hardware' +p444 +S'sh7751r' +p445 +sS'hardware-long' +p446 +S'Renesas SH7751R R2D plus board' p447 -S'This kernel requires PAE (Physical Address Extension).\nThis feature is supported by the Intel Pentium Pro/II/III/4/4M/D, Xeon,\nCore and Atom; AMD Geode NX, Athlon (K7), Duron, Opteron, Sempron,\nTurion or Phenom; Transmeta Efficeon; VIA C7; and some other processors.' -p448 -ss(S'relations' -tp449 -(dp450 -S'gcc-4.8' +ss(S'description' +g88 +NS'sb1-bcm91250a' +tp448 +(dp449 +S'hardware' +p450 +S'BCM91250A' p451 -S'gcc-4.8' +sS'hardware-long' p452 -sS'initramfs-fallback' +S'Broadcom BCM91250A systems (aka SWARM)' p453 -S'linux-initramfs-tool' -p454 -sS'gcc-4.7' -p455 -S'gcc-4.7' +ss(S'description' +g51 +tp454 +(dp455 +S'part-long-pae' p456 -sS'gcc-4.6' +S'This kernel requires PAE (Physical Address Extension).\nThis feature is supported by the Intel Pentium Pro/II/III/4/4M/D, Xeon,\nCore and Atom; AMD Geode NX, Athlon (K7), Duron, Opteron, Sempron,\nTurion or Phenom; Transmeta Efficeon; VIA C7; and some other processors.' p457 -S'gcc-4.6' -p458 -sS'gcc-4.4' -p459 -S'gcc-4.4' +ss(S'base' +g51 +g52 +tp458 +(dp459 +S'flavours' p460 -sS'initramfs-tools' -p461 -S'initramfs-tools (>= 0.110~)' +(lp461 +S'486' p462 -ss(S'image' -g87 -tp463 -(dp464 -S'suggests' -p465 -S'fdutils' -p466 -sS'configs' -p467 -(lp468 -S'armel/config' -p469 -aS'armhf/config' -p470 +aS'686-pae' +p463 +aS'amd64' +p464 ass(S'xen' -g9 -g24 +g12 +g33 S'amd64' -tp471 -(dp472 +tp465 +(dp466 S'flavours' -p473 -(lp474 +p467 +(lp468 S'amd64' -p475 +p469 ass(S'image' -g19 -tp476 -(dp477 +g5 +tp470 +(dp471 S'suggests' -p478 +p472 S'fdutils' -p479 +p473 ss(S'image' -g319 -tp480 -(dp481 +g331 +tp474 +(dp475 S'bootloaders' -p482 -(lp483 +p476 +(lp477 S's390-tools' -p484 +p478 ass(S'image' -g30 -tp485 -(dp486 -S'suggests' +g88 +NS'loongson-2f' +tp479 +(dp480 +S'recommends' +p481 +S'libc6-loongson2f' +p482 +ss(S'description' +NS'rt' +p483 +tp484 +(dp485 +S'part-long-rt' +p486 +S'This kernel includes the PREEMPT_RT realtime patch set.' p487 -S'palo' +sS'parts' p488 -ss(S'image' -g188 -tp489 -(dp490 -S'suggests' +(lp489 +S'rt' +p490 +asS'part-short-rt' p491 -S'mkvmlinuz' +S'PREEMPT_RT' p492 -sS'configs' -p493 -(lp494 -S'powerpc/config' +ss(S'image' +g119 +tp493 +(dp494 +S'suggests' p495 -aS'powerpcspe/config.powerpcspe' +S'palo' p496 -ass(S'relations' -g30 +ss(S'description' +g129 +NS'powerpc64' tp497 (dp498 -S'gcc-4.4' +S'hardware' p499 -S'gcc-4.4, binutils-hppa64, gcc-4.4-hppa64' +S'64-bit PowerPC' p500 ss(S'image' -g171 -NS'loongson-2f' +g257 tp501 (dp502 -S'recommends' +S'suggests' p503 -S'libc6-loongson2f' +S'mkvmlinuz' p504 -ss(S'description' -g171 -NS'5kc-malta' -tp505 -(dp506 -S'hardware' +sS'configs' +p505 +(lp506 +S'powerpc/config' p507 -S'MIPS Malta (64-bit)' +aS'powerpcspe/config.powerpcspe' p508 -sS'hardware-long' -p509 -S'MIPS Malta boards (64-bit)' -p510 +ass(S'relations' +g119 +tp509 +(dp510 +S'gcc-4.4' +p511 +S'gcc-4.4, binutils-hppa64, gcc-4.4-hppa64' +p512 +ss(S'build' +g76 +NS'vexpress' +tp513 +(dp514 +S'image-file' +p515 +S'arch/arm/boot/zImage' +p516 ss(S'image' -g171 -NS'sb1a-bcm91480b' -tp511 -(dp512 +g51 +NS'486' +tp517 +(dp518 S'configs' -p513 -(lp514 -S'mips/config.sb1a-bcm91480b' -p515 -ass(S'build' -g319 -NS's390x' -tp516 -(dp517 -S'debug-info' -p518 -I01 -ss(S'description' -g78 -NS'sparc64' -tp519 -(dp520 -S'hardware' +p519 +(lp520 +S'kernelarch-x86/config-arch-32' p521 -S'uniprocessor 64-bit UltraSPARC' +aS'i386/config.486' p522 -ss(g97 -g30 -g98 +ass(g99 +g119 +g87 tp523 (dp524 -g101 +g102 I01 -sg102 +sg103 (lp525 S'parisc' p526 @@ -1103,895 +1098,916 @@ aS'parisc64-smp' p529 ass(S'description' -g87 -NS'vexpress' +g88 +NS'sb1a-bcm91480b' tp530 (dp531 S'hardware' p532 -S'ARM Ltd. Versatile Express' +S'BCM91480B' p533 sS'hardware-long' p534 -S'ARM Ltd. Versatile Express family of processors' +S'Broadcom BCM91480B systems (aka BigSur)' p535 ss(S'image' -g242 +g22 tp536 (dp537 S'suggests' p538 S'aboot, fdutils' p539 -ss(S'description' -g302 -NS'r5k-ip32' +ss(S'image' +g281 +NS'powerpc64' tp540 (dp541 -S'hardware' +S'configs' p542 -S'SGI IP32' -p543 -sS'hardware-long' +(lp543 +S'powerpc/config.powerpc64' p544 -S'SGI IP32 systems (O2)' -p545 -ss(S'description' -g41 -NS'sparc64-smp' -tp546 -(dp547 -S'hardware' +ass(S'base' +g236 +tp545 +(dp546 +S'kernel-arch' +p547 +S'sparc' p548 -S'multiprocessor 64-bit UltraSPARC' -p549 -ss(S'image' -g59 -NS'686-pae' +sg85 +(lp549 +g87 +ass(S'description' +g51 +NS'486' tp550 (dp551 -S'configs' +S'hardware' p552 -(lp553 -S'kernelarch-x86/config-arch-32' +S'older PCs' +p553 +sS'parts' p554 -aS'i386/config.686-pae' -p555 -asS'recommends' +(lp555 +S'up' p556 -S'libc6-i686' +asS'hardware-long' p557 -ss(S'base' -g78 -tp558 -(dp559 -S'kernel-arch' -p560 -S'sparc' -p561 -sg176 -(lp562 -g98 -ass(S'description' -g19 -NS'versatile' -tp563 -(dp564 +S'PCs with a single processor not supporting PAE' +p558 +ss(S'description' +g5 +NS'ixp4xx' +tp559 +(dp560 S'hardware' -p565 -S'Versatile' -p566 +p561 +S'IXP4xx' +p562 sS'hardware-long' +p563 +S'IXP4xx based systems (Linksys NSLU2, etc)' +p564 +ss(S'description' +g150 +NS'r5k-ip32' +tp565 +(dp566 +S'hardware' p567 -S'Versatile systems (PB, AB, Qemu)' +S'SGI IP32' p568 -ss(S'build' -g87 -NS'armmp' -tp569 -(dp570 -S'image-file' +sS'hardware-long' +p569 +S'SGI IP32 systems (O2)' +p570 +ss(S'description' +S'm68k' p571 -S'arch/arm/boot/zImage' -p572 +NS'm68k' +tp572 +(dp573 +S'hardware' +p574 +S'Motorola MC68020+ family' +p575 ss(S'base' -g5 -tp573 -(dp574 +g340 +tp576 +(dp577 S'kernel-arch' -p575 +p578 S's390' -p576 -sg176 -(lp577 -g98 -ass(S'build' +p579 +sg85 +(lp580 g87 -NS'vexpress' -tp578 -(dp579 -S'image-file' -p580 -S'arch/arm/boot/zImage' -p581 -ss(S'description' -g171 -NS'r5k-cobalt' -tp582 -(dp583 -S'hardware' -p584 -S'Cobalt' +ass(S'image' +g88 +NS'4kc-malta' +tp581 +(dp582 +S'configs' +p583 +(lp584 +S'mips/config.4kc-malta' p585 -sS'hardware-long' -p586 -S'Cobalt systems (Qube, RaQ, Qube2, RaQ2)' -p587 -ss(S'description' -g242 -NS'alpha-generic' -tp588 -(dp589 +ass(S'description' +g331 +NS's390x' +tp586 +(dp587 S'hardware' -p590 -S'Alpha' -p591 -sS'hardware-long' -p592 -S'DEC Alpha systems with extended kernel start address (Wildfire, Titan, Marvel)' -p593 +p588 +S'IBM zSeries' +p589 ss(S'image' -g92 -tp594 -(dp595 +g281 +tp590 +(dp591 S'suggests' -p596 +p592 S'mkvmlinuz' -p597 +p593 sS'configs' -p598 -(lp599 +p594 +(lp595 S'powerpc/config' -p600 +p596 ass(S'image' -g302 -tp601 -(dp602 +g150 +tp597 +(dp598 S'initramfs' -p603 +p599 I00 ss(S'image' -g59 -tp604 -(dp605 +g236 +NS'sparc64' +tp600 +(dp601 S'configs' -p606 +p602 +(lp603 +S'sparc/config.sparc64' +p604 +ass(g99 +g310 +g87 +tp605 +(dp606 +g102 +I01 +sg103 (lp607 -sS'bootloaders' +S'sparc64' p608 -(lp609 -S'grub-pc' -p610 -aS'extlinux' -p611 -aS'lilo' +aS'sparc64-smp' +p609 +ass(S'base' +g281 +tp610 +(dp611 +S'kernel-arch' p612 -ass(g97 -g41 -g98 -tp613 -(dp614 -g101 +S'powerpc' +p613 +sg85 +(lp614 +g87 +ass(g99 +g150 +g87 +tp615 +(dp616 +g102 I01 -sg102 -(lp615 -S'sparc64' -p616 -aS'sparc64-smp' -p617 -ass(S'description' -g19 -NS'orion5x' -tp618 -(dp619 -S'hardware' +sg103 +(lp617 +S'r4k-ip22' +p618 +aS'r5k-ip32' +p619 +aS'sb1-bcm91250a' p620 -S'Marvell Orion' +aS'sb1a-bcm91480b' p621 -sS'hardware-long' +aS'4kc-malta' p622 -S'Marvell Orion 5181, 5182 and 5281 based systems (QNAP TS-109/TS-209, etc)' +aS'5kc-malta' p623 -ss(S'base' -g92 -tp624 -(dp625 -S'kernel-arch' -p626 -S'powerpc' +aS'octeon' +p624 +ass(S'description' +g51 +g52 +S'686-pae' +tp625 +(dp626 +S'parts' p627 -sg176 (lp628 -g98 -ass(g97 -g242 -g98 -tp629 -(dp630 -g101 +S'xen' +p629 +ass(g99 +g39 +g87 +tp630 +(dp631 +g102 I01 -sg102 -(lp631 -S'alpha-generic' -p632 -aS'alpha-smp' +sg103 +(lp632 +S'itanium' p633 -aS'alpha-legacy' +aS'mckinley' p634 -ass(S'description' -g59 -g60 -S'686-pae' +ass(g99 +g22 +g87 tp635 (dp636 -S'parts' -p637 -(lp638 -S'xen' -p639 -ass(g97 -g46 -g98 -tp640 -(dp641 -g101 +g102 I01 -sg102 -(lp642 -S'itanium' +sg103 +(lp637 +S'alpha-generic' +p638 +aS'alpha-smp' +p639 +aS'alpha-legacy' +p640 +ass(S'base' +g119 +NS'parisc64-smp' +tp641 +(dp642 +S'override-host-type' p643 -aS'mckinley' +S'hppa64-linux-gnu' p644 -ass(g97 -g302 -g98 -tp645 -(dp646 -g101 -I01 -sg102 -(lp647 -S'r4k-ip22' -p648 -aS'r5k-ip32' +sS'cflags' +p645 +S'-fno-cse-follow-jumps' +p646 +ss(S'description' +g88 +NS'r5k-cobalt' +tp647 +(dp648 +S'hardware' p649 -aS'sb1-bcm91250a' +S'Cobalt' p650 -aS'sb1a-bcm91480b' +sS'hardware-long' p651 -aS'4kc-malta' +S'Cobalt systems (Qube, RaQ, Qube2, RaQ2)' p652 -aS'5kc-malta' -p653 -aS'octeon' -p654 -ass(S'image' -g19 -NS'kirkwood' -tp655 -(dp656 -S'check-size' -p657 -S'2097080' -p658 -sS'recommends' -p659 -S'uboot-mkimage' -p660 +ss(S'build' +g76 +NS'rpi' +tp653 +(dp654 +S'image-file' +p655 +S'arch/arm/boot/zImage' +p656 ss(S'description' -g302 -NS'sb1-bcm91250a' -tp661 -(dp662 +g22 +NS'alpha-legacy' +tp657 +(dp658 S'hardware' -p663 -S'BCM91250A' -p664 +p659 +S'Alpha Legacy' +p660 sS'hardware-long' +p661 +S'DEC Alpha systems with legacy kernel start address' +p662 +ss(S'base' +S'x32' +tp663 +(dp664 +S'kernel-arch' p665 -S'Broadcom BCM91250A systems (aka SWARM)' +S'x86' p666 +sS'featuresets' +p667 +(lp668 ss(S'image' -g134 -NS'powerpc-smp' -tp667 -(dp668 -S'configs' -p669 -(lp670 -S'powerpc/config.powerpc' +g571 +tp669 +(dp670 +S'suggests' p671 -aS'powerpc/config.powerpc-smp' +S'vmelilo, fdutils' p672 -ass(S'base' -S'x32' +ss(S'description' +g5 +NS'orion5x' tp673 (dp674 -S'kernel-arch' +S'hardware' p675 -S'x86' +S'Marvell Orion' p676 -sS'featuresets' +sS'hardware-long' p677 -(lp678 +S'Marvell Orion 5181, 5182 and 5281 based systems (QNAP TS-109/TS-209, etc)' +p678 ss(S'base' -NS'rt' +g76 tp679 (dp680 -S'enabled' +S'kernel-arch' p681 +S'arm' +p682 +sg85 +(lp683 +g87 +ass(S'build' +g51 +NS'686-pae' +tp684 +(dp685 +S'debug-info' +p686 I01 ss(S'image' -g203 -tp682 -(dp683 +g94 +tp687 +(dp688 S'suggests' -p684 -S'vmelilo, fdutils' -p685 -ss(S'description' -g19 -NS'ixp4xx' -tp686 -(dp687 -S'hardware' -p688 -S'IXP4xx' p689 -sS'hardware-long' +S'fdutils' p690 -S'IXP4xx based systems (Linksys NSLU2, etc)' -p691 -ss(S'description' -g30 -NS'parisc64-smp' -tp692 -(dp693 -S'hardware' -p694 -S'multiprocessor 64-bit PA-RISC' -p695 -ss(S'description' +ss(S'base' g119 -NS'sh7751r' -tp696 -(dp697 -S'hardware' -p698 -S'sh7751r' -p699 -sS'hardware-long' +tp691 +(dp692 +S'kernel-arch' +p693 +S'parisc' +p694 +sg85 +(lp695 +g87 +asS'compiler' +p696 +S'gcc-4.4' +p697 +ss(S'build' +g340 +NS's390x' +tp698 +(dp699 +S'debug-info' p700 -S'Renesas SH7751R R2D plus board' -p701 +I01 ss(S'description' -g171 -NS'4kc-malta' -tp702 -(dp703 +g150 +NS'sb1-bcm91250a' +tp701 +(dp702 S'hardware' +p703 +S'BCM91250A' p704 -S'MIPS Malta' -p705 sS'hardware-long' +p705 +S'Broadcom BCM91250A systems (aka SWARM)' p706 -S'MIPS Malta boards' -p707 -ss(S'image' -g171 -NS'sb1-bcm91250a' -tp708 -(dp709 -S'configs' +ss(S'description' +g150 +NS'octeon' +tp707 +(dp708 +S'hardware' +p709 +S'Octeon' p710 -(lp711 -S'mips/config.sb1-bcm91250a' +sS'hardware-long' +p711 +S'Cavium Networks Octeon' p712 -ass(S'description' -g302 -NS'octeon' +ss(S'base' +g94 tp713 (dp714 -S'hardware' +S'kernel-arch' p715 -S'Octeon' +S'sh' p716 -sS'hardware-long' -p717 -S'Cavium Networks Octeon' -p718 +sg85 +(lp717 +g87 +ass(S'build' +g5 +NS'ixp4xx' +tp718 +(dp719 +S'image-file' +p720 +S'arch/arm/boot/zImage' +p721 ss(S'image' -g119 -tp719 -(dp720 +g310 +tp722 +(dp723 S'suggests' -p721 -S'fdutils' -p722 -ss(S'base' -g30 -tp723 -(dp724 -S'kernel-arch' +p724 +S'silo, fdutils' p725 -S'parisc' -p726 -sg176 -(lp727 -g98 -asS'compiler' +ss(S'image' +g5 +NS'ixp4xx' +tp726 +(dp727 +S'check-size' p728 -S'gcc-4.4' +S'1441760' p729 -ss(S'base' -g119 -tp730 -(dp731 -S'kernel-arch' +sS'configs' +p730 +(lp731 +S'armel/config-reduced' p732 -S'sh' +aS'armel/config.ixp4xx' p733 -sg176 -(lp734 -g98 -ass(S'image' -g41 -tp735 -(dp736 -S'suggests' -p737 -S'silo, fdutils' -p738 -ss(S'description' -tp739 -(dp740 +ass(S'description' +tp734 +(dp735 S'part-long-up' -p741 +p736 S'This kernel is not suitable for SMP (multi-processor,\nmulti-core or hyper-threaded) systems.' -p742 +p737 sS'part-long-xen' -p743 +p738 S'This kernel also runs on a Xen hypervisor.\nIt supports both privileged (dom0) and unprivileged (domU) operation.' -p744 +p739 ss(S'description' -g171 -NS'loongson-2f' -tp745 -(dp746 +g236 +NS'sparc64-smp' +tp740 +(dp741 S'hardware' -p747 -S'Loongson 2F' -p748 -sS'hardware-long' -p749 -S'Lemote Loongson 2F systems' +p742 +S'multiprocessor 64-bit UltraSPARC' +p743 +ss(S'abi' +Ng483 +tp744 +(dp745 +S'ignore-changes' +p746 +(lp747 +S'*' +ass(S'image' +g5 +NS'iop32x' +tp748 +(dp749 +S'check-size' p750 -ss(S'description' -g41 -NS'sparc64' -tp751 -(dp752 -S'hardware' -p753 -S'uniprocessor 64-bit UltraSPARC' +S'1441784' +p751 +sS'configs' +p752 +(lp753 +S'armel/config-reduced' p754 -ss(S'description' -g134 -NS'powerpc' -tp755 -(dp756 +aS'armel/config.iop32x' +p755 +ass(S'description' +g51 +NS'amd64' +tp756 +(dp757 S'hardware' -p757 -S'uniprocessor 32-bit PowerPC' p758 -ss(S'build' -g87 -NS'mx5' -tp759 -(dp760 -S'image-file' -p761 -S'arch/arm/boot/zImage' +S'64-bit PCs' +p759 +sS'parts' +p760 +(lp761 +S'xen' p762 +asS'hardware-long' +p763 +S'PCs with AMD64, Intel 64 or VIA Nano processors' +p764 ss(S'image' -g78 -tp763 -(dp764 +g236 +tp765 +(dp766 S'suggests' -p765 +p767 S'silo, fdutils' -p766 +p768 sS'configs' -p767 -(lp768 -S'sparc/config' p769 +(lp770 +S'sparc/config' +p771 ass(S'description' -g59 -NS'686-pae' -tp770 -(dp771 +g119 +NS'parisc-smp' +tp772 +(dp773 S'hardware' -p772 -S'modern PCs' -p773 -sS'parts' p774 -(lp775 -S'pae' -p776 -asS'hardware-long' -p777 -S'PCs with one or more processors supporting PAE' -p778 +S'multiprocessor 32-bit PA-RISC' +p775 ss(S'base' -g134 -tp779 -(dp780 +g129 +tp776 +(dp777 S'kernel-arch' -p781 +p778 S'powerpc' -p782 -sg176 -(lp783 -g98 -ass(S'abi' -tp784 -(dp785 -S'abiname' -p786 -S'3' +p779 +sg85 +(lp780 +g87 +ass(S'description' +g340 +NS's390x' +tp781 +(dp782 +S'hardware' +p783 +S'IBM zSeries' +p784 ss(S'description' -g30 -NS'parisc' -tp787 -(dp788 +g76 +NS'armmp' +tp785 +(dp786 S'hardware' +p787 +S'ARMv7 multiplatform compatible SoCs' +p788 +sS'hardware-long' p789 -S'32-bit PA-RISC' +S'ARMv7 multiplatform kernel for Marvell Armada 370/xp, Freescale iMX5x/iMX6' p790 -ss(S'description' -g242 -NS'alpha-legacy' +ss(S'base' +NS'rt' tp791 (dp792 -S'hardware' +S'enabled' p793 -S'Alpha Legacy' -p794 -sS'hardware-long' -p795 -S'DEC Alpha systems with legacy kernel start address' +I01 +ss(S'description' +g310 +NS'sparc32' +tp794 +(dp795 +S'hardware' p796 -ss(S'build' -g19 -NS'kirkwood' -tp797 -(dp798 -S'image-file' -p799 -S'arch/arm/boot/zImage' -p800 +S'uniprocessor sparc32 (sun4m)' +p797 ss(S'description' -g302 -NS'r4k-ip22' -tp801 -(dp802 +g119 +NS'parisc' +tp798 +(dp799 S'hardware' -p803 -S'SGI IP22' +p800 +S'32-bit PA-RISC' +p801 +ss(S'image' +g129 +NS'powerpc-smp' +tp802 +(dp803 +S'configs' p804 -sS'hardware-long' -p805 -S'SGI IP22 systems (Indy, Indigo2)' +(lp805 +S'powerpc/config.powerpc' p806 -ss(g97 -g188 -g98 -tp807 -(dp808 -g101 -I01 -sg102 -(lp809 -S'powerpcspe' +aS'powerpc/config.powerpc-smp' +p807 +ass(S'description' +g5 +NS'versatile' +tp808 +(dp809 +S'hardware' p810 -ass(g97 -g203 -g98 -tp811 -(dp812 -g101 -I01 -sg102 -(lp813 -S'm68k' -p814 -ass(S'base' -g59 -g60 -tp815 -(dp816 -S'flavours' +S'Versatile' +p811 +sS'hardware-long' +p812 +S'Versatile systems (PB, AB, Qemu)' +p813 +ss(S'build' +g94 +NS'sh7785lcr' +tp814 +(dp815 +S'image-file' +p816 +S'arch/sh/boot/zImage' p817 -(lp818 -S'486' -p819 -aS'686-pae' +ss(S'image' +g76 +tp818 +(dp819 +S'suggests' p820 -aS'amd64' +S'fdutils' p821 -ass(S'base' -tp822 -(dp823 -S'arches' +sS'configs' +p822 +(lp823 +S'armel/config' p824 -(lp825 -S'alpha' -p826 -aS'amd64' -p827 -aS'armel' +aS'armhf/config' +p825 +ass(S'abi' +tp826 +(dp827 +S'abiname' p828 -aS'armhf' -p829 -aS'hppa' -p830 -aS'i386' +S'3' +ss(S'image' +g76 +NS'omap' +tp829 +(dp830 +S'recommends' p831 -aS'ia64' +S'uboot-mkimage' p832 -aS'm68k' -p833 -aS'mips' -p834 -aS'mipsel' -p835 -aS'powerpc' +ss(g99 +g257 +g87 +tp833 +(dp834 +g102 +I01 +sg103 +(lp835 +S'powerpcspe' p836 -aS'powerpcspe' -p837 -aS'ppc64' -p838 -aS's390' +ass(S'base' +g119 +NS'parisc64' +tp837 +(dp838 +S'override-host-type' p839 -aS's390x' +S'hppa64-linux-gnu' p840 -aS'sh4' +sS'cflags' p841 -aS'sparc' +S'-fno-cse-follow-jumps' p842 -aS'sparc64' -p843 -aS'x32' -p844 -asS'featuresets' -p845 -(lp846 -S'none' -p847 -aS'rt' -p848 -asS'compiler' +ss(g99 +g571 +g87 +tp843 +(dp844 +g102 +I01 +sg103 +(lp845 +S'm68k' +p846 +ass(S'build' +g331 +NS's390x' +tp847 +(dp848 +S'debug-info' p849 -S'gcc-4.7' -p850 +I01 ss(S'description' -g59 -NS'486' -tp851 -(dp852 +g331 +NS's390' +tp850 +(dp851 S'hardware' +p852 +S'IBM S/390' p853 -S'older PCs' -p854 -sS'parts' -p855 -(lp856 -S'up' +ss(S'description' +g76 +NS'omap' +tp854 +(dp855 +S'hardware' +p856 +S'TI OMAP3+' p857 -asS'hardware-long' +sS'hardware-long' p858 -S'PCs with a single processor not supporting PAE' +S'Texas Instruments OMAP3 or OMAP4 based systems' p859 ss(S'description' -g87 -NS'mx5' +g310 +NS'sparc64-smp' tp860 (dp861 S'hardware' p862 -S'Freescale i.MX51/53' +S'multiprocessor 64-bit UltraSPARC' p863 -sS'hardware-long' -p864 -S'Freescale i.MX51 or i.MX53 based systems' -p865 -ss(S'base' -g203 -tp866 -(dp867 -S'kernel-arch' +ss(S'image' +g5 +NS'orion5x' +tp864 +(dp865 +S'check-size' +p866 +S'1572792' +p867 +sS'configs' p868 -S'm68k' -p869 -sg176 -(lp870 -g98 -asS'cflags' +(lp869 +S'armel/config-reduced' +p870 +aS'armel/config.orion5x' p871 -S'-ffreestanding' +asS'recommends' p872 -sS'compiler' +S'uboot-mkimage' p873 -S'gcc-4.8' -p874 -ss(S'image' -tp875 -(dp876 -S'initramfs-generators' +ss(S'base' +g571 +tp874 +(dp875 +S'kernel-arch' +p876 +S'm68k' p877 +sg85 (lp878 -S'initramfs-tools' +g87 +asS'cflags' p879 -aS'initramfs-fallback' +S'-ffreestanding' p880 -asS'type' +sS'compiler' p881 -S'plain' +S'gcc-4.8' p882 ss(S'image' -g119 -NS'sh7785lcr' +g88 +NS'sb1a-bcm91480b' tp883 (dp884 -S'check-size' +S'configs' p885 -S'4194304' -p886 -sS'recommends' +(lp886 +S'mips/config.sb1a-bcm91480b' p887 -S'uboot-mkimage' -p888 -ss(g97 -g78 -g98 -tp889 -(dp890 -g101 -I01 -sg102 +ass(S'image' +tp888 +(dp889 +S'initramfs-generators' +p890 (lp891 -S'sparc64' +S'initramfs-tools' p892 -aS'sparc64-smp' +aS'initramfs-fallback' p893 -ass(S'description' -g171 -NS'sb1a-bcm91480b' -tp894 -(dp895 +asS'type' +p894 +S'plain' +p895 +ss(S'description' +g236 +NS'sparc64' +tp896 +(dp897 S'hardware' -p896 -S'BCM91480B' -p897 -sS'hardware-long' p898 -S'Broadcom BCM91480B systems (aka BigSur)' +S'uniprocessor 64-bit UltraSPARC' p899 -ss(S'build' -g19 -NS'mv78xx0' +ss(g99 +g236 +g87 tp900 (dp901 -S'image-file' -p902 -S'arch/arm/boot/zImage' +g102 +I01 +sg103 +(lp902 +S'sparc64' p903 -ss(S'abi' -Ng309 -tp904 -(dp905 -S'ignore-changes' -p906 -(lp907 -S'*' +aS'sparc64-smp' +p904 ass(S'image' -g171 -NS'4kc-malta' -tp908 -(dp909 -S'configs' -p910 -(lp911 -S'mips/config.4kc-malta' +g129 +tp905 +(dp906 +S'suggests' +p907 +S'mkvmlinuz' +p908 +ss(S'description' +g150 +NS'sb1a-bcm91480b' +tp909 +(dp910 +S'hardware' +p911 +S'BCM91480B' p912 -ass(S'image' -g5 -tp913 -(dp914 -S'configs' -p915 -(lp916 -S's390/config' +sS'hardware-long' +p913 +S'Broadcom BCM91480B systems (aka BigSur)' +p914 +ss(S'description' +g88 +NS'5kc-malta' +tp915 +(dp916 +S'hardware' p917 -asS'bootloaders' +S'MIPS Malta (64-bit)' p918 -(lp919 -S's390-tools' +sS'hardware-long' +p919 +S'MIPS Malta boards (64-bit)' p920 -ass(S'description' -g87 -NS'armmp' +ss(S'image' +g340 tp921 (dp922 -S'hardware' +S'configs' p923 -S'ARMv7 multiplatform compatible SoCs' -p924 -sS'hardware-long' +(lp924 +S's390/config' p925 -S'ARMv7 multiplatform kernel for Marvell Armada 370/xp, Freescale iMX5x/iMX6' +asS'bootloaders' p926 -ss(S'description' -g19 -NS'kirkwood' -tp927 -(dp928 -S'hardware' -p929 -S'Marvell Kirkwood' -p930 -sS'hardware-long' -p931 -S'Marvell Kirkwood based systems (SheevaPlug, QNAP TS-119/TS-219, etc)' -p932 -ss(S'image' -g171 -NS'5kc-malta' -tp933 -(dp934 +(lp927 +S's390-tools' +p928 +ass(S'image' +g51 +tp929 +(dp930 S'configs' +p931 +(lp932 +sS'bootloaders' +p933 +(lp934 +S'grub-pc' p935 -(lp936 -S'mips/config.5kc-malta' +aS'extlinux' +p936 +aS'lilo' p937 -ass(S'build' -g59 -NS'686-pae' +ass(S'image' +g88 +NS'5kc-malta' tp938 (dp939 -S'debug-info' -p940 -I01 -ss(S'image' -g92 -NS'powerpc64' -tp941 -(dp942 S'configs' -p943 -(lp944 -S'powerpc/config.powerpc64' -p945 +p940 +(lp941 +S'mips/config.5kc-malta' +p942 ass(S'description' -g319 -NS's390x' -tp946 -(dp947 +g150 +NS'4kc-malta' +tp943 +(dp944 S'hardware' +p945 +S'MIPS Malta' +p946 +sS'hardware-long' +p947 +S'MIPS Malta boards' p948 -S'IBM zSeries' -p949 -sstRp950 +ss(S'build' +g5 +NS'mv78xx0' +tp949 +(dp950 +S'image-file' +p951 +S'arch/arm/boot/zImage' +p952 +ss(S'build' +g76 +NS'mx5' +tp953 +(dp954 +S'image-file' +p955 +S'arch/arm/boot/zImage' +p956 +sstRp957 . \ No newline at end of file diff -Nru linux-3.10.11/debian/control linux-3.10-3.10.11/debian/control --- linux-3.10.11/debian/control 2013-09-10 13:13:31.000000000 +0000 +++ linux-3.10-3.10.11/debian/control 2014-05-05 21:50:18.000000000 +0000 @@ -1,4 +1,4 @@ -Source: linux +Source: linux-3.10 Section: kernel Priority: optional Maintainer: Debian Kernel Team @@ -194,8 +194,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: nic-modules-3.10-3-amd64-di Architecture: amd64 @@ -206,8 +206,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: nic-wireless-modules-3.10-3-amd64-di Architecture: amd64 @@ -218,8 +218,8 @@ Description: Wireless NIC drivers This package contains wireless NIC drivers for the kernel. Includes crypto modules only needed for wireless (WEP, WPA). -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: nic-shared-modules-3.10-3-amd64-di Architecture: amd64 @@ -230,8 +230,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: serial-modules-3.10-3-amd64-di Architecture: amd64 @@ -241,8 +241,8 @@ Depends: kernel-image-3.10-3-amd64-di, pcmcia-modules-3.10-3-amd64-di Description: Serial drivers This package contains serial drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: usb-serial-modules-3.10-3-amd64-di Architecture: amd64 @@ -252,8 +252,8 @@ Depends: kernel-image-3.10-3-amd64-di, usb-modules-3.10-3-amd64-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: ppp-modules-3.10-3-amd64-di Architecture: amd64 @@ -263,8 +263,8 @@ Depends: kernel-image-3.10-3-amd64-di, serial-modules-3.10-3-amd64-di, zlib-modules-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: pata-modules-3.10-3-amd64-di Architecture: amd64 @@ -274,8 +274,8 @@ Depends: kernel-image-3.10-3-amd64-di, ata-modules-3.10-3-amd64-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: cdrom-core-modules-3.10-3-amd64-di Architecture: amd64 @@ -285,8 +285,8 @@ Depends: kernel-image-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di, isofs-modules-3.10-3-amd64-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: firewire-core-modules-3.10-3-amd64-di Architecture: amd64 @@ -296,8 +296,8 @@ Depends: kernel-image-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: scsi-core-modules-3.10-3-amd64-di Architecture: amd64 @@ -307,8 +307,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: scsi-modules-3.10-3-amd64-di Architecture: amd64 @@ -318,8 +318,8 @@ Depends: kernel-image-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di, scsi-common-modules-3.10-3-amd64-di, cdrom-core-modules-3.10-3-amd64-di, core-modules-3.10-3-amd64-di, ata-modules-3.10-3-amd64-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: scsi-common-modules-3.10-3-amd64-di Architecture: amd64 @@ -329,8 +329,8 @@ Depends: kernel-image-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di, cdrom-core-modules-3.10-3-amd64-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: scsi-extra-modules-3.10-3-amd64-di Architecture: amd64 @@ -341,8 +341,8 @@ Description: Uncommon SCSI drivers This package contains uncommon SCSI drivers for the kernel. This includes SCSI RAID drivers, and some of the less common SCSI controllers. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: loop-modules-3.10-3-amd64-di Architecture: amd64 @@ -352,8 +352,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: btrfs-modules-3.10-3-amd64-di Architecture: amd64 @@ -363,8 +363,8 @@ Depends: kernel-image-3.10-3-amd64-di, core-modules-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di, zlib-modules-3.10-3-amd64-di, md-modules-3.10-3-amd64-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: ext2-modules-3.10-3-amd64-di Architecture: amd64 @@ -374,8 +374,8 @@ Depends: kernel-image-3.10-3-amd64-di, core-modules-3.10-3-amd64-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: ext3-modules-3.10-3-amd64-di Architecture: amd64 @@ -385,8 +385,8 @@ Depends: kernel-image-3.10-3-amd64-di, core-modules-3.10-3-amd64-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: ext4-modules-3.10-3-amd64-di Architecture: amd64 @@ -396,8 +396,8 @@ Depends: kernel-image-3.10-3-amd64-di, core-modules-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: isofs-modules-3.10-3-amd64-di Architecture: amd64 @@ -407,8 +407,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: jfs-modules-3.10-3-amd64-di Architecture: amd64 @@ -418,8 +418,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: ntfs-modules-3.10-3-amd64-di Architecture: amd64 @@ -429,8 +429,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: NTFS filesystem support This package contains the NTFS file system module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: xfs-modules-3.10-3-amd64-di Architecture: amd64 @@ -440,8 +440,8 @@ Depends: kernel-image-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: fat-modules-3.10-3-amd64-di Architecture: amd64 @@ -451,8 +451,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: md-modules-3.10-3-amd64-di Architecture: amd64 @@ -462,8 +462,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: multipath-modules-3.10-3-amd64-di Architecture: amd64 @@ -473,8 +473,8 @@ Depends: kernel-image-3.10-3-amd64-di, md-modules-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: usb-modules-3.10-3-amd64-di Architecture: amd64 @@ -484,8 +484,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: usb-storage-modules-3.10-3-amd64-di Architecture: amd64 @@ -495,8 +495,8 @@ Depends: kernel-image-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di, usb-modules-3.10-3-amd64-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: pcmcia-storage-modules-3.10-3-amd64-di Architecture: amd64 @@ -506,8 +506,8 @@ Depends: kernel-image-3.10-3-amd64-di, cdrom-core-modules-3.10-3-amd64-di, pcmcia-modules-3.10-3-amd64-di, ata-modules-3.10-3-amd64-di Description: PCMCIA storage drivers This package contains PCMCIA storage drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: fb-modules-3.10-3-amd64-di Architecture: amd64 @@ -517,8 +517,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: Frame buffer support This package contains Frame buffer drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: input-modules-3.10-3-amd64-di Architecture: amd64 @@ -528,8 +528,8 @@ Depends: kernel-image-3.10-3-amd64-di, usb-modules-3.10-3-amd64-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: event-modules-3.10-3-amd64-di Architecture: amd64 @@ -539,8 +539,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: mouse-modules-3.10-3-amd64-di Architecture: amd64 @@ -550,8 +550,8 @@ Depends: kernel-image-3.10-3-amd64-di, event-modules-3.10-3-amd64-di, input-modules-3.10-3-amd64-di, usb-modules-3.10-3-amd64-di Description: Mouse support This package contains mouse drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: nic-pcmcia-modules-3.10-3-amd64-di Architecture: amd64 @@ -561,8 +561,8 @@ Depends: kernel-image-3.10-3-amd64-di, nic-shared-modules-3.10-3-amd64-di, nic-wireless-modules-3.10-3-amd64-di, pcmcia-modules-3.10-3-amd64-di, mmc-core-modules-3.10-3-amd64-di Description: Common PCMCIA NIC drivers This package contains common PCMCIA NIC drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: pcmcia-modules-3.10-3-amd64-di Architecture: amd64 @@ -572,8 +572,8 @@ Depends: kernel-image-3.10-3-amd64-di, core-modules-3.10-3-amd64-di Description: Common PCMCIA drivers This package contains common PCMCIA drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: nic-usb-modules-3.10-3-amd64-di Architecture: amd64 @@ -583,8 +583,8 @@ Depends: kernel-image-3.10-3-amd64-di, nic-shared-modules-3.10-3-amd64-di, nic-wireless-modules-3.10-3-amd64-di, usb-modules-3.10-3-amd64-di, core-modules-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: sata-modules-3.10-3-amd64-di Architecture: amd64 @@ -594,8 +594,8 @@ Depends: kernel-image-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di, ata-modules-3.10-3-amd64-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: core-modules-3.10-3-amd64-di Architecture: amd64 @@ -606,8 +606,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: acpi-modules-3.10-3-amd64-di Architecture: amd64 @@ -617,8 +617,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: ACPI support modules This package contains kernel modules for ACPI. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: i2c-modules-3.10-3-amd64-di Architecture: amd64 @@ -628,8 +628,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: i2c support modules This package contains basic i2c support modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: crc-modules-3.10-3-amd64-di Architecture: amd64 @@ -639,8 +639,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: crypto-modules-3.10-3-amd64-di Architecture: amd64 @@ -650,8 +650,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: crypto-dm-modules-3.10-3-amd64-di Architecture: amd64 @@ -661,8 +661,8 @@ Depends: kernel-image-3.10-3-amd64-di, md-modules-3.10-3-amd64-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: efi-modules-3.10-3-amd64-di Architecture: amd64 @@ -672,8 +672,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: EFI modules This package contains EFI modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: ata-modules-3.10-3-amd64-di Architecture: amd64 @@ -684,8 +684,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: mmc-core-modules-3.10-3-amd64-di Architecture: amd64 @@ -695,8 +695,8 @@ Depends: kernel-image-3.10-3-amd64-di, core-modules-3.10-3-amd64-di Description: MMC/SD/SDIO core modules This package contains core modules for MMC/SD/SDIO support. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: mmc-modules-3.10-3-amd64-di Architecture: amd64 @@ -707,8 +707,8 @@ Description: MMC/SD card modules This package contains modules needed to support MMC (multimedia) and SD cards. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: nbd-modules-3.10-3-amd64-di Architecture: amd64 @@ -719,8 +719,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: squashfs-modules-3.10-3-amd64-di Architecture: amd64 @@ -730,8 +730,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: speakup-modules-3.10-3-amd64-di Architecture: amd64 @@ -741,8 +741,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: speakup modules This package contains speakup modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: virtio-modules-3.10-3-amd64-di Architecture: amd64 @@ -752,8 +752,8 @@ Depends: kernel-image-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: uinput-modules-3.10-3-amd64-di Architecture: amd64 @@ -763,8 +763,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: sound-modules-3.10-3-amd64-di Architecture: amd64 @@ -774,8 +774,8 @@ Depends: kernel-image-3.10-3-amd64-di, core-modules-3.10-3-amd64-di, i2c-modules-3.10-3-amd64-di, usb-modules-3.10-3-amd64-di, pcmcia-modules-3.10-3-amd64-di, firewire-core-modules-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di Description: sound support This package contains sound modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: zlib-modules-3.10-3-amd64-di Architecture: amd64 @@ -785,8 +785,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: hyperv-modules-3.10-3-amd64-di Architecture: amd64 @@ -796,8 +796,8 @@ Depends: kernel-image-3.10-3-amd64-di, input-modules-3.10-3-amd64-di, scsi-core-modules-3.10-3-amd64-di Description: Hyper-V modules This package contains Hyper-V paravirtualised drivers for the kernel. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: udf-modules-3.10-3-amd64-di Architecture: amd64 @@ -807,8 +807,8 @@ Depends: kernel-image-3.10-3-amd64-di, crc-modules-3.10-3-amd64-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: fuse-modules-3.10-3-amd64-di Architecture: amd64 @@ -818,8 +818,8 @@ Depends: kernel-image-3.10-3-amd64-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-amd64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-amd64 Package: linux-image-3.10-3-amd64 Architecture: amd64 i386 @@ -926,8 +926,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: nic-modules-3.10-3-iop32x-di Architecture: armel @@ -938,8 +938,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: nic-shared-modules-3.10-3-iop32x-di Architecture: armel @@ -950,8 +950,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: usb-serial-modules-3.10-3-iop32x-di Architecture: armel @@ -961,8 +961,8 @@ Depends: kernel-image-3.10-3-iop32x-di, usb-modules-3.10-3-iop32x-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: ppp-modules-3.10-3-iop32x-di Architecture: armel @@ -972,8 +972,8 @@ Depends: kernel-image-3.10-3-iop32x-di, zlib-modules-3.10-3-iop32x-di, crc-modules-3.10-3-iop32x-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: pata-modules-3.10-3-iop32x-di Architecture: armel @@ -983,8 +983,8 @@ Depends: kernel-image-3.10-3-iop32x-di, ata-modules-3.10-3-iop32x-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: cdrom-core-modules-3.10-3-iop32x-di Architecture: armel @@ -994,8 +994,8 @@ Depends: kernel-image-3.10-3-iop32x-di, scsi-core-modules-3.10-3-iop32x-di, isofs-modules-3.10-3-iop32x-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: scsi-core-modules-3.10-3-iop32x-di Architecture: armel @@ -1005,8 +1005,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: loop-modules-3.10-3-iop32x-di Architecture: armel @@ -1016,8 +1016,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: ipv6-modules-3.10-3-iop32x-di Architecture: armel @@ -1027,8 +1027,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: IPv6 driver This package contains the IPv6 driver for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: btrfs-modules-3.10-3-iop32x-di Architecture: armel @@ -1038,8 +1038,8 @@ Depends: kernel-image-3.10-3-iop32x-di, core-modules-3.10-3-iop32x-di, crc-modules-3.10-3-iop32x-di, zlib-modules-3.10-3-iop32x-di, md-modules-3.10-3-iop32x-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: ext2-modules-3.10-3-iop32x-di Architecture: armel @@ -1049,8 +1049,8 @@ Depends: kernel-image-3.10-3-iop32x-di, core-modules-3.10-3-iop32x-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: ext3-modules-3.10-3-iop32x-di Architecture: armel @@ -1060,8 +1060,8 @@ Depends: kernel-image-3.10-3-iop32x-di, core-modules-3.10-3-iop32x-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: ext4-modules-3.10-3-iop32x-di Architecture: armel @@ -1071,8 +1071,8 @@ Depends: kernel-image-3.10-3-iop32x-di, core-modules-3.10-3-iop32x-di, crc-modules-3.10-3-iop32x-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: isofs-modules-3.10-3-iop32x-di Architecture: armel @@ -1082,8 +1082,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: jffs2-modules-3.10-3-iop32x-di Architecture: armel @@ -1093,8 +1093,8 @@ Depends: kernel-image-3.10-3-iop32x-di, zlib-modules-3.10-3-iop32x-di Description: JFFS2 filesystem support This package contains the JFFS2 filesystem module for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: jfs-modules-3.10-3-iop32x-di Architecture: armel @@ -1104,8 +1104,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: fat-modules-3.10-3-iop32x-di Architecture: armel @@ -1115,8 +1115,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: md-modules-3.10-3-iop32x-di Architecture: armel @@ -1126,8 +1126,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: multipath-modules-3.10-3-iop32x-di Architecture: armel @@ -1137,8 +1137,8 @@ Depends: kernel-image-3.10-3-iop32x-di, md-modules-3.10-3-iop32x-di, scsi-core-modules-3.10-3-iop32x-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: usb-modules-3.10-3-iop32x-di Architecture: armel @@ -1148,8 +1148,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: usb-storage-modules-3.10-3-iop32x-di Architecture: armel @@ -1159,8 +1159,8 @@ Depends: kernel-image-3.10-3-iop32x-di, scsi-core-modules-3.10-3-iop32x-di, usb-modules-3.10-3-iop32x-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: event-modules-3.10-3-iop32x-di Architecture: armel @@ -1170,8 +1170,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: nic-usb-modules-3.10-3-iop32x-di Architecture: armel @@ -1181,8 +1181,8 @@ Depends: kernel-image-3.10-3-iop32x-di, nic-shared-modules-3.10-3-iop32x-di, usb-modules-3.10-3-iop32x-di, core-modules-3.10-3-iop32x-di, crc-modules-3.10-3-iop32x-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: sata-modules-3.10-3-iop32x-di Architecture: armel @@ -1192,8 +1192,8 @@ Depends: kernel-image-3.10-3-iop32x-di, scsi-core-modules-3.10-3-iop32x-di, ata-modules-3.10-3-iop32x-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: core-modules-3.10-3-iop32x-di Architecture: armel @@ -1204,8 +1204,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: crc-modules-3.10-3-iop32x-di Architecture: armel @@ -1215,8 +1215,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: crypto-modules-3.10-3-iop32x-di Architecture: armel @@ -1226,8 +1226,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: crypto-dm-modules-3.10-3-iop32x-di Architecture: armel @@ -1237,8 +1237,8 @@ Depends: kernel-image-3.10-3-iop32x-di, md-modules-3.10-3-iop32x-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: ata-modules-3.10-3-iop32x-di Architecture: armel @@ -1249,8 +1249,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: nbd-modules-3.10-3-iop32x-di Architecture: armel @@ -1261,8 +1261,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: squashfs-modules-3.10-3-iop32x-di Architecture: armel @@ -1272,8 +1272,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: zlib-modules-3.10-3-iop32x-di Architecture: armel @@ -1283,8 +1283,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: udf-modules-3.10-3-iop32x-di Architecture: armel @@ -1294,8 +1294,8 @@ Depends: kernel-image-3.10-3-iop32x-di, crc-modules-3.10-3-iop32x-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: fuse-modules-3.10-3-iop32x-di Architecture: armel @@ -1305,8 +1305,8 @@ Depends: kernel-image-3.10-3-iop32x-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-iop32x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-iop32x Package: kernel-image-3.10-3-kirkwood-di Architecture: armel @@ -1317,8 +1317,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: nic-modules-3.10-3-kirkwood-di Architecture: armel @@ -1329,8 +1329,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: nic-shared-modules-3.10-3-kirkwood-di Architecture: armel @@ -1341,8 +1341,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: usb-serial-modules-3.10-3-kirkwood-di Architecture: armel @@ -1352,8 +1352,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, usb-modules-3.10-3-kirkwood-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: ppp-modules-3.10-3-kirkwood-di Architecture: armel @@ -1363,8 +1363,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, crc-modules-3.10-3-kirkwood-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: cdrom-core-modules-3.10-3-kirkwood-di Architecture: armel @@ -1374,8 +1374,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, scsi-core-modules-3.10-3-kirkwood-di, isofs-modules-3.10-3-kirkwood-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: scsi-core-modules-3.10-3-kirkwood-di Architecture: armel @@ -1385,8 +1385,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: loop-modules-3.10-3-kirkwood-di Architecture: armel @@ -1396,8 +1396,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: btrfs-modules-3.10-3-kirkwood-di Architecture: armel @@ -1407,8 +1407,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, core-modules-3.10-3-kirkwood-di, crc-modules-3.10-3-kirkwood-di, md-modules-3.10-3-kirkwood-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: ext2-modules-3.10-3-kirkwood-di Architecture: armel @@ -1418,8 +1418,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, core-modules-3.10-3-kirkwood-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: ext3-modules-3.10-3-kirkwood-di Architecture: armel @@ -1429,8 +1429,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, core-modules-3.10-3-kirkwood-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: ext4-modules-3.10-3-kirkwood-di Architecture: armel @@ -1440,8 +1440,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, core-modules-3.10-3-kirkwood-di, crc-modules-3.10-3-kirkwood-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: isofs-modules-3.10-3-kirkwood-di Architecture: armel @@ -1451,8 +1451,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: jfs-modules-3.10-3-kirkwood-di Architecture: armel @@ -1462,8 +1462,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: fat-modules-3.10-3-kirkwood-di Architecture: armel @@ -1473,8 +1473,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: minix-modules-3.10-3-kirkwood-di Architecture: armel @@ -1484,8 +1484,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: Minix filesystem support This package contains the Minix filesystem module for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: md-modules-3.10-3-kirkwood-di Architecture: armel @@ -1495,8 +1495,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: multipath-modules-3.10-3-kirkwood-di Architecture: armel @@ -1506,8 +1506,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, md-modules-3.10-3-kirkwood-di, scsi-core-modules-3.10-3-kirkwood-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: usb-modules-3.10-3-kirkwood-di Architecture: armel @@ -1517,8 +1517,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: usb-storage-modules-3.10-3-kirkwood-di Architecture: armel @@ -1528,8 +1528,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, scsi-core-modules-3.10-3-kirkwood-di, usb-modules-3.10-3-kirkwood-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: fb-modules-3.10-3-kirkwood-di Architecture: armel @@ -1539,8 +1539,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, usb-modules-3.10-3-kirkwood-di Description: Frame buffer support This package contains Frame buffer drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: input-modules-3.10-3-kirkwood-di Architecture: armel @@ -1550,8 +1550,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, usb-modules-3.10-3-kirkwood-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: event-modules-3.10-3-kirkwood-di Architecture: armel @@ -1561,8 +1561,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: mouse-modules-3.10-3-kirkwood-di Architecture: armel @@ -1572,8 +1572,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, event-modules-3.10-3-kirkwood-di, input-modules-3.10-3-kirkwood-di, usb-modules-3.10-3-kirkwood-di Description: Mouse support This package contains mouse drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: nic-usb-modules-3.10-3-kirkwood-di Architecture: armel @@ -1583,8 +1583,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, nic-shared-modules-3.10-3-kirkwood-di, usb-modules-3.10-3-kirkwood-di, core-modules-3.10-3-kirkwood-di, crc-modules-3.10-3-kirkwood-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: sata-modules-3.10-3-kirkwood-di Architecture: armel @@ -1594,8 +1594,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, scsi-core-modules-3.10-3-kirkwood-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: core-modules-3.10-3-kirkwood-di Architecture: armel @@ -1606,8 +1606,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: crc-modules-3.10-3-kirkwood-di Architecture: armel @@ -1617,8 +1617,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: crypto-modules-3.10-3-kirkwood-di Architecture: armel @@ -1628,8 +1628,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: crypto-dm-modules-3.10-3-kirkwood-di Architecture: armel @@ -1639,8 +1639,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, md-modules-3.10-3-kirkwood-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: mmc-modules-3.10-3-kirkwood-di Architecture: armel @@ -1651,8 +1651,8 @@ Description: MMC/SD card modules This package contains modules needed to support MMC (multimedia) and SD cards. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: nbd-modules-3.10-3-kirkwood-di Architecture: armel @@ -1663,8 +1663,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: squashfs-modules-3.10-3-kirkwood-di Architecture: armel @@ -1674,8 +1674,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: uinput-modules-3.10-3-kirkwood-di Architecture: armel @@ -1685,8 +1685,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: leds-modules-3.10-3-kirkwood-di Architecture: armel @@ -1696,8 +1696,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: LED modules This package contains LED modules. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: udf-modules-3.10-3-kirkwood-di Architecture: armel @@ -1707,8 +1707,8 @@ Depends: kernel-image-3.10-3-kirkwood-di, crc-modules-3.10-3-kirkwood-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: fuse-modules-3.10-3-kirkwood-di Architecture: armel @@ -1718,8 +1718,8 @@ Depends: kernel-image-3.10-3-kirkwood-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-kirkwood -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-kirkwood Package: kernel-image-3.10-3-orion5x-di Architecture: armel @@ -1730,8 +1730,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: nic-modules-3.10-3-orion5x-di Architecture: armel @@ -1742,8 +1742,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: nic-shared-modules-3.10-3-orion5x-di Architecture: armel @@ -1754,8 +1754,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: usb-serial-modules-3.10-3-orion5x-di Architecture: armel @@ -1765,8 +1765,8 @@ Depends: kernel-image-3.10-3-orion5x-di, usb-modules-3.10-3-orion5x-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: ppp-modules-3.10-3-orion5x-di Architecture: armel @@ -1776,8 +1776,8 @@ Depends: kernel-image-3.10-3-orion5x-di, zlib-modules-3.10-3-orion5x-di, crc-modules-3.10-3-orion5x-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: cdrom-core-modules-3.10-3-orion5x-di Architecture: armel @@ -1787,8 +1787,8 @@ Depends: kernel-image-3.10-3-orion5x-di, scsi-core-modules-3.10-3-orion5x-di, isofs-modules-3.10-3-orion5x-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: scsi-core-modules-3.10-3-orion5x-di Architecture: armel @@ -1798,8 +1798,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: loop-modules-3.10-3-orion5x-di Architecture: armel @@ -1809,8 +1809,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: ipv6-modules-3.10-3-orion5x-di Architecture: armel @@ -1820,8 +1820,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: IPv6 driver This package contains the IPv6 driver for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: btrfs-modules-3.10-3-orion5x-di Architecture: armel @@ -1831,8 +1831,8 @@ Depends: kernel-image-3.10-3-orion5x-di, core-modules-3.10-3-orion5x-di, crc-modules-3.10-3-orion5x-di, zlib-modules-3.10-3-orion5x-di, md-modules-3.10-3-orion5x-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: ext2-modules-3.10-3-orion5x-di Architecture: armel @@ -1842,8 +1842,8 @@ Depends: kernel-image-3.10-3-orion5x-di, core-modules-3.10-3-orion5x-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: ext3-modules-3.10-3-orion5x-di Architecture: armel @@ -1853,8 +1853,8 @@ Depends: kernel-image-3.10-3-orion5x-di, core-modules-3.10-3-orion5x-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: ext4-modules-3.10-3-orion5x-di Architecture: armel @@ -1864,8 +1864,8 @@ Depends: kernel-image-3.10-3-orion5x-di, core-modules-3.10-3-orion5x-di, crc-modules-3.10-3-orion5x-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: isofs-modules-3.10-3-orion5x-di Architecture: armel @@ -1875,8 +1875,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: jffs2-modules-3.10-3-orion5x-di Architecture: armel @@ -1886,8 +1886,8 @@ Depends: kernel-image-3.10-3-orion5x-di, zlib-modules-3.10-3-orion5x-di Description: JFFS2 filesystem support This package contains the JFFS2 filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: jfs-modules-3.10-3-orion5x-di Architecture: armel @@ -1897,8 +1897,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: fat-modules-3.10-3-orion5x-di Architecture: armel @@ -1908,8 +1908,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: minix-modules-3.10-3-orion5x-di Architecture: armel @@ -1919,8 +1919,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: Minix filesystem support This package contains the Minix filesystem module for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: md-modules-3.10-3-orion5x-di Architecture: armel @@ -1930,8 +1930,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: multipath-modules-3.10-3-orion5x-di Architecture: armel @@ -1941,8 +1941,8 @@ Depends: kernel-image-3.10-3-orion5x-di, md-modules-3.10-3-orion5x-di, scsi-core-modules-3.10-3-orion5x-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: usb-modules-3.10-3-orion5x-di Architecture: armel @@ -1952,8 +1952,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: usb-storage-modules-3.10-3-orion5x-di Architecture: armel @@ -1963,8 +1963,8 @@ Depends: kernel-image-3.10-3-orion5x-di, scsi-core-modules-3.10-3-orion5x-di, usb-modules-3.10-3-orion5x-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: event-modules-3.10-3-orion5x-di Architecture: armel @@ -1974,8 +1974,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: nic-usb-modules-3.10-3-orion5x-di Architecture: armel @@ -1985,8 +1985,8 @@ Depends: kernel-image-3.10-3-orion5x-di, nic-shared-modules-3.10-3-orion5x-di, usb-modules-3.10-3-orion5x-di, core-modules-3.10-3-orion5x-di, crc-modules-3.10-3-orion5x-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: sata-modules-3.10-3-orion5x-di Architecture: armel @@ -1996,8 +1996,8 @@ Depends: kernel-image-3.10-3-orion5x-di, scsi-core-modules-3.10-3-orion5x-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: core-modules-3.10-3-orion5x-di Architecture: armel @@ -2008,8 +2008,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: crc-modules-3.10-3-orion5x-di Architecture: armel @@ -2019,8 +2019,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: crypto-modules-3.10-3-orion5x-di Architecture: armel @@ -2030,8 +2030,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: crypto-dm-modules-3.10-3-orion5x-di Architecture: armel @@ -2041,8 +2041,8 @@ Depends: kernel-image-3.10-3-orion5x-di, md-modules-3.10-3-orion5x-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: nbd-modules-3.10-3-orion5x-di Architecture: armel @@ -2053,8 +2053,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: squashfs-modules-3.10-3-orion5x-di Architecture: armel @@ -2064,8 +2064,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: zlib-modules-3.10-3-orion5x-di Architecture: armel @@ -2075,8 +2075,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: udf-modules-3.10-3-orion5x-di Architecture: armel @@ -2086,8 +2086,8 @@ Depends: kernel-image-3.10-3-orion5x-di, crc-modules-3.10-3-orion5x-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: fuse-modules-3.10-3-orion5x-di Architecture: armel @@ -2097,8 +2097,8 @@ Depends: kernel-image-3.10-3-orion5x-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-orion5x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-orion5x Package: kernel-image-3.10-3-versatile-di Architecture: armel @@ -2109,8 +2109,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: nic-modules-3.10-3-versatile-di Architecture: armel @@ -2121,8 +2121,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: nic-shared-modules-3.10-3-versatile-di Architecture: armel @@ -2133,8 +2133,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: usb-serial-modules-3.10-3-versatile-di Architecture: armel @@ -2144,8 +2144,8 @@ Depends: kernel-image-3.10-3-versatile-di, usb-modules-3.10-3-versatile-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: ppp-modules-3.10-3-versatile-di Architecture: armel @@ -2155,8 +2155,8 @@ Depends: kernel-image-3.10-3-versatile-di, zlib-modules-3.10-3-versatile-di, crc-modules-3.10-3-versatile-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: cdrom-core-modules-3.10-3-versatile-di Architecture: armel @@ -2166,8 +2166,8 @@ Depends: kernel-image-3.10-3-versatile-di, scsi-core-modules-3.10-3-versatile-di, isofs-modules-3.10-3-versatile-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: scsi-core-modules-3.10-3-versatile-di Architecture: armel @@ -2177,8 +2177,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: scsi-common-modules-3.10-3-versatile-di Architecture: armel @@ -2188,8 +2188,8 @@ Depends: kernel-image-3.10-3-versatile-di, scsi-core-modules-3.10-3-versatile-di, cdrom-core-modules-3.10-3-versatile-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: loop-modules-3.10-3-versatile-di Architecture: armel @@ -2199,8 +2199,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: btrfs-modules-3.10-3-versatile-di Architecture: armel @@ -2210,8 +2210,8 @@ Depends: kernel-image-3.10-3-versatile-di, core-modules-3.10-3-versatile-di, crc-modules-3.10-3-versatile-di, zlib-modules-3.10-3-versatile-di, md-modules-3.10-3-versatile-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: ext2-modules-3.10-3-versatile-di Architecture: armel @@ -2221,8 +2221,8 @@ Depends: kernel-image-3.10-3-versatile-di, core-modules-3.10-3-versatile-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: ext3-modules-3.10-3-versatile-di Architecture: armel @@ -2232,8 +2232,8 @@ Depends: kernel-image-3.10-3-versatile-di, core-modules-3.10-3-versatile-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: ext4-modules-3.10-3-versatile-di Architecture: armel @@ -2243,8 +2243,8 @@ Depends: kernel-image-3.10-3-versatile-di, core-modules-3.10-3-versatile-di, crc-modules-3.10-3-versatile-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: isofs-modules-3.10-3-versatile-di Architecture: armel @@ -2254,8 +2254,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: fat-modules-3.10-3-versatile-di Architecture: armel @@ -2265,8 +2265,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: md-modules-3.10-3-versatile-di Architecture: armel @@ -2276,8 +2276,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: multipath-modules-3.10-3-versatile-di Architecture: armel @@ -2287,8 +2287,8 @@ Depends: kernel-image-3.10-3-versatile-di, md-modules-3.10-3-versatile-di, scsi-core-modules-3.10-3-versatile-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: usb-modules-3.10-3-versatile-di Architecture: armel @@ -2298,8 +2298,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: usb-storage-modules-3.10-3-versatile-di Architecture: armel @@ -2309,8 +2309,8 @@ Depends: kernel-image-3.10-3-versatile-di, scsi-core-modules-3.10-3-versatile-di, usb-modules-3.10-3-versatile-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: nic-usb-modules-3.10-3-versatile-di Architecture: armel @@ -2320,8 +2320,8 @@ Depends: kernel-image-3.10-3-versatile-di, nic-shared-modules-3.10-3-versatile-di, usb-modules-3.10-3-versatile-di, core-modules-3.10-3-versatile-di, crc-modules-3.10-3-versatile-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: sata-modules-3.10-3-versatile-di Architecture: armel @@ -2331,8 +2331,8 @@ Depends: kernel-image-3.10-3-versatile-di, scsi-core-modules-3.10-3-versatile-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: core-modules-3.10-3-versatile-di Architecture: armel @@ -2343,8 +2343,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: crc-modules-3.10-3-versatile-di Architecture: armel @@ -2354,8 +2354,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: crypto-modules-3.10-3-versatile-di Architecture: armel @@ -2365,8 +2365,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: crypto-dm-modules-3.10-3-versatile-di Architecture: armel @@ -2376,8 +2376,8 @@ Depends: kernel-image-3.10-3-versatile-di, md-modules-3.10-3-versatile-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: nbd-modules-3.10-3-versatile-di Architecture: armel @@ -2388,8 +2388,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: squashfs-modules-3.10-3-versatile-di Architecture: armel @@ -2399,8 +2399,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: virtio-modules-3.10-3-versatile-di Architecture: armel @@ -2410,8 +2410,8 @@ Depends: kernel-image-3.10-3-versatile-di, scsi-core-modules-3.10-3-versatile-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: zlib-modules-3.10-3-versatile-di Architecture: armel @@ -2421,8 +2421,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: udf-modules-3.10-3-versatile-di Architecture: armel @@ -2432,8 +2432,8 @@ Depends: kernel-image-3.10-3-versatile-di, crc-modules-3.10-3-versatile-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: fuse-modules-3.10-3-versatile-di Architecture: armel @@ -2443,8 +2443,8 @@ Depends: kernel-image-3.10-3-versatile-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-versatile -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-versatile Package: linux-image-3.10-3-iop32x Architecture: armel @@ -2592,13 +2592,13 @@ Package: linux-headers-3.10-3-all-armhf Architecture: armhf -Depends: ${misc:Depends}, linux-headers-3.10-3-armmp (= ${binary:Version}), linux-headers-3.10-3-mx5 (= ${binary:Version}), linux-headers-3.10-3-omap (= ${binary:Version}), linux-headers-3.10-3-vexpress (= ${binary:Version}) +Depends: ${misc:Depends}, linux-headers-3.10-3-rpi (= ${binary:Version}) Description: All header files for Linux 3.10 (meta-package) This package depends against all architecture-specific kernel header files for Linux kernel version 3.10, generally used for building out-of-tree kernel modules. -Package: kernel-image-3.10-3-armmp-di +Package: kernel-image-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra @@ -2607,1146 +2607,251 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: nic-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-modules, nic-extra-modules -Depends: kernel-image-3.10-3-armmp-di, nic-shared-modules-3.10-3-armmp-di, core-modules-3.10-3-armmp-di, crc-modules-3.10-3-armmp-di -Description: NIC drivers - This package contains Ethernet and some paravirtualised network drivers - for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: nic-wireless-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-wireless-modules -Depends: kernel-image-3.10-3-armmp-di, nic-shared-modules-3.10-3-armmp-di, core-modules-3.10-3-armmp-di, usb-modules-3.10-3-armmp-di, mmc-modules-3.10-3-armmp-di, crc-modules-3.10-3-armmp-di -Description: Wireless NIC drivers - This package contains wireless NIC drivers for the kernel. Includes - crypto modules only needed for wireless (WEP, WPA). -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: nic-shared-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-shared-modules -Depends: kernel-image-3.10-3-armmp-di -Description: Shared NIC drivers - This package contains NIC drivers needed by combinations of nic-modules, - nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: pata-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: pata-modules -Depends: kernel-image-3.10-3-armmp-di, ata-modules-3.10-3-armmp-di -Description: PATA drivers - This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: scsi-core-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: scsi-core-modules -Depends: kernel-image-3.10-3-armmp-di -Description: Core SCSI subsystem - This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: loop-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: loop-modules -Depends: kernel-image-3.10-3-armmp-di -Description: Loopback filesystem support - This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: btrfs-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: btrfs-modules -Depends: kernel-image-3.10-3-armmp-di, core-modules-3.10-3-armmp-di, crc-modules-3.10-3-armmp-di, md-modules-3.10-3-armmp-di -Description: BTRFS filesystem support - This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: ext2-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: ext2-modules -Depends: kernel-image-3.10-3-armmp-di, core-modules-3.10-3-armmp-di -Description: EXT2 filesystem support - This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: ext3-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: ext3-modules -Depends: kernel-image-3.10-3-armmp-di, core-modules-3.10-3-armmp-di -Description: EXT3 filesystem support - This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: ext4-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: ext4-modules -Depends: kernel-image-3.10-3-armmp-di, core-modules-3.10-3-armmp-di, crc-modules-3.10-3-armmp-di -Description: EXT4 filesystem support - This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: isofs-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: isofs-modules -Depends: kernel-image-3.10-3-armmp-di -Description: ISOFS filesystem support - This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: jfs-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: jfs-modules -Depends: kernel-image-3.10-3-armmp-di -Description: JFS filesystem support - This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: fat-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: fat-modules -Depends: kernel-image-3.10-3-armmp-di -Description: FAT filesystem support - This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: md-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: md-modules -Depends: kernel-image-3.10-3-armmp-di -Description: RAID and LVM support - This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: multipath-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: multipath-modules -Depends: kernel-image-3.10-3-armmp-di, md-modules-3.10-3-armmp-di, scsi-core-modules-3.10-3-armmp-di -Description: Multipath support - This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: usb-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: usb-modules -Depends: kernel-image-3.10-3-armmp-di -Description: USB support - This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: usb-storage-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: usb-storage-modules -Depends: kernel-image-3.10-3-armmp-di, scsi-core-modules-3.10-3-armmp-di, usb-modules-3.10-3-armmp-di -Description: USB storage support - This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: input-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: input-modules -Depends: kernel-image-3.10-3-armmp-di, usb-modules-3.10-3-armmp-di -Description: Input devices support - This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: event-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: event-modules -Depends: kernel-image-3.10-3-armmp-di -Description: Event support - This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: nic-usb-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-usb-modules -Depends: kernel-image-3.10-3-armmp-di, nic-shared-modules-3.10-3-armmp-di, nic-wireless-modules-3.10-3-armmp-di, usb-modules-3.10-3-armmp-di, core-modules-3.10-3-armmp-di, crc-modules-3.10-3-armmp-di -Description: USB NIC drivers - This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: sata-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: sata-modules -Depends: kernel-image-3.10-3-armmp-di, scsi-core-modules-3.10-3-armmp-di, ata-modules-3.10-3-armmp-di -Description: SATA drivers - This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: core-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: core-modules -Depends: kernel-image-3.10-3-armmp-di -Description: Core modules - This package contains core modules for the kernel, that will almost - always be needed. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: crc-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: crc-modules -Depends: kernel-image-3.10-3-armmp-di -Description: CRC modules - This package contains CRC support modules. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: crypto-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: crypto-modules -Depends: kernel-image-3.10-3-armmp-di -Description: crypto modules - This package contains crypto modules. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: crypto-dm-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: crypto-dm-modules -Depends: kernel-image-3.10-3-armmp-di, md-modules-3.10-3-armmp-di -Description: devicemapper crypto module - This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: ata-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: ata-modules -Depends: kernel-image-3.10-3-armmp-di, scsi-core-modules-3.10-3-armmp-di -Description: ATA disk modules - This package contains core ATA disk modules used by both PATA and SATA - disk drivers. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: mmc-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: mmc-modules -Depends: kernel-image-3.10-3-armmp-di, core-modules-3.10-3-armmp-di -Description: MMC/SD card modules - This package contains modules needed to support MMC (multimedia) and SD - cards. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: nbd-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: nbd-modules -Depends: kernel-image-3.10-3-armmp-di -Description: Network Block Device modules - This package contains the modules required for support of the Network - Block Device -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: squashfs-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: squashfs-modules -Depends: kernel-image-3.10-3-armmp-di -Description: squashfs modules - This package contains squashfs modules. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: uinput-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: uinput-modules -Depends: kernel-image-3.10-3-armmp-di -Description: uinput support - This package contains the uinput module. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: udf-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: udf-modules -Depends: kernel-image-3.10-3-armmp-di, crc-modules-3.10-3-armmp-di -Description: UDF modules - This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: fuse-modules-3.10-3-armmp-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: fuse-modules -Depends: kernel-image-3.10-3-armmp-di -Description: FUSE modules - This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-armmp -Package-Type: udeb - -Package: kernel-image-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: kernel-image, rtc-modules -Description: Linux kernel binary image for the Debian installer - This package contains the kernel image for the Debian installer boot - images. It does _not_ provide a usable kernel for your full Debian - system. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: nic-wireless-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-wireless-modules -Depends: kernel-image-3.10-3-mx5-di, nic-shared-modules-3.10-3-mx5-di, core-modules-3.10-3-mx5-di, mmc-modules-3.10-3-mx5-di, crc-modules-3.10-3-mx5-di -Description: Wireless NIC drivers - This package contains wireless NIC drivers for the kernel. Includes - crypto modules only needed for wireless (WEP, WPA). -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: nic-shared-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-shared-modules -Depends: kernel-image-3.10-3-mx5-di -Description: Shared NIC drivers - This package contains NIC drivers needed by combinations of nic-modules, - nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: pata-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: pata-modules -Depends: kernel-image-3.10-3-mx5-di, ata-modules-3.10-3-mx5-di -Description: PATA drivers - This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: scsi-core-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: scsi-core-modules -Depends: kernel-image-3.10-3-mx5-di -Description: Core SCSI subsystem - This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: loop-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: loop-modules -Depends: kernel-image-3.10-3-mx5-di -Description: Loopback filesystem support - This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: btrfs-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: btrfs-modules -Depends: kernel-image-3.10-3-mx5-di, core-modules-3.10-3-mx5-di, crc-modules-3.10-3-mx5-di, md-modules-3.10-3-mx5-di -Description: BTRFS filesystem support - This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: ext2-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: ext2-modules -Depends: kernel-image-3.10-3-mx5-di, core-modules-3.10-3-mx5-di -Description: EXT2 filesystem support - This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: ext3-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: ext3-modules -Depends: kernel-image-3.10-3-mx5-di, core-modules-3.10-3-mx5-di -Description: EXT3 filesystem support - This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: ext4-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: ext4-modules -Depends: kernel-image-3.10-3-mx5-di, core-modules-3.10-3-mx5-di, crc-modules-3.10-3-mx5-di -Description: EXT4 filesystem support - This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: isofs-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: isofs-modules -Depends: kernel-image-3.10-3-mx5-di -Description: ISOFS filesystem support - This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: jfs-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: jfs-modules -Depends: kernel-image-3.10-3-mx5-di -Description: JFS filesystem support - This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: fat-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: fat-modules -Depends: kernel-image-3.10-3-mx5-di -Description: FAT filesystem support - This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: minix-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: minix-modules -Depends: kernel-image-3.10-3-mx5-di -Description: Minix filesystem support - This package contains the Minix filesystem module for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: md-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: md-modules -Depends: kernel-image-3.10-3-mx5-di -Description: RAID and LVM support - This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: multipath-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: multipath-modules -Depends: kernel-image-3.10-3-mx5-di, md-modules-3.10-3-mx5-di, scsi-core-modules-3.10-3-mx5-di -Description: Multipath support - This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: usb-storage-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: usb-storage-modules -Depends: kernel-image-3.10-3-mx5-di, scsi-core-modules-3.10-3-mx5-di -Description: USB storage support - This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: input-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: input-modules -Depends: kernel-image-3.10-3-mx5-di -Description: Input devices support - This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: nic-usb-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-usb-modules -Depends: kernel-image-3.10-3-mx5-di, nic-shared-modules-3.10-3-mx5-di, nic-wireless-modules-3.10-3-mx5-di, core-modules-3.10-3-mx5-di, crc-modules-3.10-3-mx5-di -Description: USB NIC drivers - This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: sata-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: sata-modules -Depends: kernel-image-3.10-3-mx5-di, scsi-core-modules-3.10-3-mx5-di, ata-modules-3.10-3-mx5-di -Description: SATA drivers - This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: core-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: core-modules -Depends: kernel-image-3.10-3-mx5-di -Description: Core modules - This package contains core modules for the kernel, that will almost - always be needed. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: crc-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: crc-modules -Depends: kernel-image-3.10-3-mx5-di -Description: CRC modules - This package contains CRC support modules. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: crypto-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: crypto-modules -Depends: kernel-image-3.10-3-mx5-di -Description: crypto modules - This package contains crypto modules. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: crypto-dm-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: crypto-dm-modules -Depends: kernel-image-3.10-3-mx5-di, md-modules-3.10-3-mx5-di -Description: devicemapper crypto module - This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: ata-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: ata-modules -Depends: kernel-image-3.10-3-mx5-di, scsi-core-modules-3.10-3-mx5-di -Description: ATA disk modules - This package contains core ATA disk modules used by both PATA and SATA - disk drivers. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: mmc-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: mmc-modules -Depends: kernel-image-3.10-3-mx5-di, core-modules-3.10-3-mx5-di -Description: MMC/SD card modules - This package contains modules needed to support MMC (multimedia) and SD - cards. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: nbd-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: nbd-modules -Depends: kernel-image-3.10-3-mx5-di -Description: Network Block Device modules - This package contains the modules required for support of the Network - Block Device -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: squashfs-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: squashfs-modules -Depends: kernel-image-3.10-3-mx5-di -Description: squashfs modules - This package contains squashfs modules. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: uinput-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: uinput-modules -Depends: kernel-image-3.10-3-mx5-di -Description: uinput support - This package contains the uinput module. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: udf-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: udf-modules -Depends: kernel-image-3.10-3-mx5-di, crc-modules-3.10-3-mx5-di -Description: UDF modules - This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: fuse-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: fuse-modules -Depends: kernel-image-3.10-3-mx5-di -Description: FUSE modules - This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: mtd-modules-3.10-3-mx5-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: mtd-modules -Depends: kernel-image-3.10-3-mx5-di -Description: MTD modules - This package contains MTD modules. -Kernel-Version: 3.10-3-mx5 -Package-Type: udeb - -Package: kernel-image-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: kernel-image, rtc-modules -Description: Linux kernel binary image for the Debian installer - This package contains the kernel image for the Debian installer boot - images. It does _not_ provide a usable kernel for your full Debian - system. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: nic-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-modules, nic-extra-modules -Depends: kernel-image-3.10-3-vexpress-di, nic-shared-modules-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di, crc-modules-3.10-3-vexpress-di -Description: NIC drivers - This package contains Ethernet and some paravirtualised network drivers - for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: nic-wireless-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-wireless-modules -Depends: kernel-image-3.10-3-vexpress-di, nic-shared-modules-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di, usb-modules-3.10-3-vexpress-di, mmc-modules-3.10-3-vexpress-di, crc-modules-3.10-3-vexpress-di -Description: Wireless NIC drivers - This package contains wireless NIC drivers for the kernel. Includes - crypto modules only needed for wireless (WEP, WPA). -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: nic-shared-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: nic-shared-modules -Depends: kernel-image-3.10-3-vexpress-di -Description: Shared NIC drivers - This package contains NIC drivers needed by combinations of nic-modules, - nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: scsi-core-modules-3.10-3-vexpress-di +Package: scsi-core-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: standard Provides: scsi-core-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: loop-modules-3.10-3-vexpress-di +Package: loop-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: standard Provides: loop-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: btrfs-modules-3.10-3-vexpress-di +Package: btrfs-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: btrfs-modules -Depends: kernel-image-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di, crc-modules-3.10-3-vexpress-di, md-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di, crc-modules-3.10-3-rpi-di, md-modules-3.10-3-rpi-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: ext2-modules-3.10-3-vexpress-di +Package: ext2-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: standard Provides: ext2-modules -Depends: kernel-image-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: ext3-modules-3.10-3-vexpress-di +Package: ext3-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: standard Provides: ext3-modules -Depends: kernel-image-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: ext4-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: ext4-modules -Depends: kernel-image-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di, crc-modules-3.10-3-vexpress-di -Description: EXT4 filesystem support - This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: isofs-modules-3.10-3-vexpress-di +Package: isofs-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: standard Provides: isofs-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: jfs-modules-3.10-3-vexpress-di +Package: jfs-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: standard Provides: jfs-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: fat-modules-3.10-3-vexpress-di +Package: minix-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra -Provides: fat-modules -Depends: kernel-image-3.10-3-vexpress-di -Description: FAT filesystem support - This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +Provides: minix-modules +Depends: kernel-image-3.10-3-rpi-di +Description: Minix filesystem support + This package contains the Minix filesystem module for the kernel. +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: md-modules-3.10-3-vexpress-di +Package: md-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: md-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: multipath-modules-3.10-3-vexpress-di +Package: multipath-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: multipath-modules -Depends: kernel-image-3.10-3-vexpress-di, md-modules-3.10-3-vexpress-di, scsi-core-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di, md-modules-3.10-3-rpi-di, scsi-core-modules-3.10-3-rpi-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: usb-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: usb-modules -Depends: kernel-image-3.10-3-vexpress-di -Description: USB support - This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: usb-storage-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: usb-storage-modules -Depends: kernel-image-3.10-3-vexpress-di, scsi-core-modules-3.10-3-vexpress-di, usb-modules-3.10-3-vexpress-di -Description: USB storage support - This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: input-modules-3.10-3-vexpress-di +Package: input-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: input-modules -Depends: kernel-image-3.10-3-vexpress-di, usb-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: nic-usb-modules-3.10-3-vexpress-di +Package: nic-usb-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: standard Provides: nic-usb-modules -Depends: kernel-image-3.10-3-vexpress-di, nic-shared-modules-3.10-3-vexpress-di, nic-wireless-modules-3.10-3-vexpress-di, usb-modules-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di, crc-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di, crc-modules-3.10-3-rpi-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: core-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: standard -Provides: core-modules -Depends: kernel-image-3.10-3-vexpress-di -Description: Core modules - This package contains core modules for the kernel, that will almost - always be needed. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: crc-modules-3.10-3-vexpress-di +Package: crc-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: crc-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: crypto-modules-3.10-3-vexpress-di +Package: crypto-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: crypto-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: crypto-dm-modules-3.10-3-vexpress-di +Package: crypto-dm-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: crypto-dm-modules -Depends: kernel-image-3.10-3-vexpress-di, md-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di, md-modules-3.10-3-rpi-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: mmc-modules-3.10-3-vexpress-di -Architecture: armhf -Section: debian-installer -Priority: extra -Provides: mmc-modules -Depends: kernel-image-3.10-3-vexpress-di, core-modules-3.10-3-vexpress-di -Description: MMC/SD card modules - This package contains modules needed to support MMC (multimedia) and SD - cards. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: nbd-modules-3.10-3-vexpress-di +Package: nbd-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: nbd-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: squashfs-modules-3.10-3-vexpress-di +Package: squashfs-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: squashfs-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: uinput-modules-3.10-3-vexpress-di +Package: uinput-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: uinput-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: udf-modules-3.10-3-vexpress-di +Package: udf-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: udf-modules -Depends: kernel-image-3.10-3-vexpress-di, crc-modules-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di, crc-modules-3.10-3-rpi-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: fuse-modules-3.10-3-vexpress-di +Package: fuse-modules-3.10-3-rpi-di Architecture: armhf Section: debian-installer Priority: extra Provides: fuse-modules -Depends: kernel-image-3.10-3-vexpress-di +Depends: kernel-image-3.10-3-rpi-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-vexpress -Package-Type: udeb - -Package: linux-image-3.10-3-armmp -Architecture: armhf -Provides: linux-image, linux-modules-3.10-3-armmp -Pre-Depends: debconf | debconf-2.0 -Depends: kmod | module-init-tools, linux-base (>= 3~), ${misc:Depends}, initramfs-tools (>= 0.110~) [armhf] | linux-initramfs-tool [armhf] -Recommends: firmware-linux-free (>= 3~) -Suggests: linux-doc-3.10, debian-kernel-handbook, fdutils [armhf] -Breaks: at (<< 3.1.12-1+squeeze1), initramfs-tools (<< 0.110~) -Description: Linux 3.10 for ARMv7 multiplatform compatible SoCs - The Linux kernel 3.10 and modules for use on ARMv7 multiplatform kernel - for Marvell Armada 370/xp, Freescale iMX5x/iMX6. - -Package: linux-headers-3.10-3-armmp -Architecture: armhf -Provides: linux-headers -Depends: linux-headers-3.10-3-common (= ${binary:Version}), linux-kbuild-3.10, ${misc:Depends}, gcc-4.7 -Description: Header files for Linux 3.10-3-armmp - This package provides the architecture-specific kernel header files for - Linux kernel 3.10-3-armmp, generally used for building out-of-tree kernel - modules. These files are going to be installed into - /usr/src/linux-headers-3.10-3-armmp, and can be used for building modules - that load into the kernel provided by the linux-image-3.10-3-armmp - package. +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-rpi -Package: linux-image-3.10-3-mx5 +Package: linux-image-3.10-3-rpi Architecture: armhf -Provides: linux-image, linux-modules-3.10-3-mx5 +Provides: linux-image, linux-modules-3.10-3-rpi Pre-Depends: debconf | debconf-2.0 Depends: kmod | module-init-tools, linux-base (>= 3~), ${misc:Depends}, initramfs-tools (>= 0.110~) [armhf] | linux-initramfs-tool [armhf] Recommends: firmware-linux-free (>= 3~) Suggests: linux-doc-3.10, debian-kernel-handbook, fdutils [armhf] Breaks: at (<< 3.1.12-1+squeeze1), initramfs-tools (<< 0.110~) -Description: Linux 3.10 for Freescale i.MX51/53 - The Linux kernel 3.10 and modules for use on Freescale i.MX51 or i.MX53 - based systems. - -Package: linux-headers-3.10-3-mx5 -Architecture: armhf -Provides: linux-headers -Depends: linux-headers-3.10-3-common (= ${binary:Version}), linux-kbuild-3.10, ${misc:Depends}, gcc-4.7 -Description: Header files for Linux 3.10-3-mx5 - This package provides the architecture-specific kernel header files for - Linux kernel 3.10-3-mx5, generally used for building out-of-tree kernel - modules. These files are going to be installed into - /usr/src/linux-headers-3.10-3-mx5, and can be used for building modules - that load into the kernel provided by the linux-image-3.10-3-mx5 package. - -Package: linux-image-3.10-3-omap -Architecture: armhf -Provides: linux-image, linux-modules-3.10-3-omap -Pre-Depends: debconf | debconf-2.0 -Depends: kmod | module-init-tools, linux-base (>= 3~), ${misc:Depends}, initramfs-tools (>= 0.110~) [armhf] | linux-initramfs-tool [armhf] -Recommends: firmware-linux-free (>= 3~), uboot-mkimage [armhf] -Suggests: linux-doc-3.10, debian-kernel-handbook, fdutils [armhf] -Breaks: at (<< 3.1.12-1+squeeze1), initramfs-tools (<< 0.110~) -Description: Linux 3.10 for TI OMAP3+ - The Linux kernel 3.10 and modules for use on Texas Instruments OMAP3 or - OMAP4 based systems. +Description: Linux 3.10 for RaspberryPI + The Linux kernel 3.10 and modules for use on Raspberry PI. -Package: linux-headers-3.10-3-omap +Package: linux-headers-3.10-3-rpi Architecture: armhf Provides: linux-headers Depends: linux-headers-3.10-3-common (= ${binary:Version}), linux-kbuild-3.10, ${misc:Depends}, gcc-4.7 -Description: Header files for Linux 3.10-3-omap +Description: Header files for Linux 3.10-3-rpi This package provides the architecture-specific kernel header files for - Linux kernel 3.10-3-omap, generally used for building out-of-tree kernel + Linux kernel 3.10-3-rpi, generally used for building out-of-tree kernel modules. These files are going to be installed into - /usr/src/linux-headers-3.10-3-omap, and can be used for building modules - that load into the kernel provided by the linux-image-3.10-3-omap package. - -Package: linux-image-3.10-3-vexpress -Architecture: armhf -Provides: linux-image, linux-modules-3.10-3-vexpress -Pre-Depends: debconf | debconf-2.0 -Depends: kmod | module-init-tools, linux-base (>= 3~), ${misc:Depends}, initramfs-tools (>= 0.110~) [armhf] | linux-initramfs-tool [armhf] -Recommends: firmware-linux-free (>= 3~) -Suggests: linux-doc-3.10, debian-kernel-handbook, fdutils [armhf] -Breaks: at (<< 3.1.12-1+squeeze1), initramfs-tools (<< 0.110~) -Description: Linux 3.10 for ARM Ltd. Versatile Express - The Linux kernel 3.10 and modules for use on ARM Ltd. Versatile Express - family of processors. - -Package: linux-headers-3.10-3-vexpress -Architecture: armhf -Provides: linux-headers -Depends: linux-headers-3.10-3-common (= ${binary:Version}), linux-kbuild-3.10, ${misc:Depends}, gcc-4.7 -Description: Header files for Linux 3.10-3-vexpress - This package provides the architecture-specific kernel header files for - Linux kernel 3.10-3-vexpress, generally used for building out-of-tree - kernel modules. These files are going to be installed into - /usr/src/linux-headers-3.10-3-vexpress, and can be used for building - modules that load into the kernel provided by the - linux-image-3.10-3-vexpress package. + /usr/src/linux-headers-3.10-3-rpi, and can be used for building modules + that load into the kernel provided by the linux-image-3.10-3-rpi package. Package: linux-headers-3.10-3-all-hppa Architecture: hppa @@ -3765,8 +2870,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: nic-modules-3.10-3-parisc-di Architecture: hppa @@ -3777,8 +2882,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: ppp-modules-3.10-3-parisc-di Architecture: hppa @@ -3788,8 +2893,8 @@ Depends: kernel-image-3.10-3-parisc-di, zlib-modules-3.10-3-parisc-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: pata-modules-3.10-3-parisc-di Architecture: hppa @@ -3799,8 +2904,8 @@ Depends: kernel-image-3.10-3-parisc-di, scsi-core-modules-3.10-3-parisc-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: cdrom-core-modules-3.10-3-parisc-di Architecture: hppa @@ -3810,8 +2915,8 @@ Depends: kernel-image-3.10-3-parisc-di, scsi-core-modules-3.10-3-parisc-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: scsi-core-modules-3.10-3-parisc-di Architecture: hppa @@ -3821,8 +2926,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: scsi-modules-3.10-3-parisc-di Architecture: hppa @@ -3832,8 +2937,8 @@ Depends: kernel-image-3.10-3-parisc-di, scsi-core-modules-3.10-3-parisc-di, cdrom-core-modules-3.10-3-parisc-di, core-modules-3.10-3-parisc-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: loop-modules-3.10-3-parisc-di Architecture: hppa @@ -3843,8 +2948,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: btrfs-modules-3.10-3-parisc-di Architecture: hppa @@ -3854,8 +2959,8 @@ Depends: kernel-image-3.10-3-parisc-di, core-modules-3.10-3-parisc-di, zlib-modules-3.10-3-parisc-di, md-modules-3.10-3-parisc-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: ext3-modules-3.10-3-parisc-di Architecture: hppa @@ -3865,8 +2970,8 @@ Depends: kernel-image-3.10-3-parisc-di, core-modules-3.10-3-parisc-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: ext4-modules-3.10-3-parisc-di Architecture: hppa @@ -3876,8 +2981,8 @@ Depends: kernel-image-3.10-3-parisc-di, core-modules-3.10-3-parisc-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: fat-modules-3.10-3-parisc-di Architecture: hppa @@ -3887,8 +2992,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: md-modules-3.10-3-parisc-di Architecture: hppa @@ -3898,8 +3003,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: multipath-modules-3.10-3-parisc-di Architecture: hppa @@ -3909,8 +3014,8 @@ Depends: kernel-image-3.10-3-parisc-di, md-modules-3.10-3-parisc-di, scsi-core-modules-3.10-3-parisc-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: usb-modules-3.10-3-parisc-di Architecture: hppa @@ -3920,8 +3025,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: usb-storage-modules-3.10-3-parisc-di Architecture: hppa @@ -3931,8 +3036,8 @@ Depends: kernel-image-3.10-3-parisc-di, scsi-modules-3.10-3-parisc-di, usb-modules-3.10-3-parisc-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: input-modules-3.10-3-parisc-di Architecture: hppa @@ -3942,8 +3047,8 @@ Depends: kernel-image-3.10-3-parisc-di, usb-modules-3.10-3-parisc-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: core-modules-3.10-3-parisc-di Architecture: hppa @@ -3954,8 +3059,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: crypto-modules-3.10-3-parisc-di Architecture: hppa @@ -3965,8 +3070,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: crypto-dm-modules-3.10-3-parisc-di Architecture: hppa @@ -3976,8 +3081,8 @@ Depends: kernel-image-3.10-3-parisc-di, md-modules-3.10-3-parisc-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: nbd-modules-3.10-3-parisc-di Architecture: hppa @@ -3988,8 +3093,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: zlib-modules-3.10-3-parisc-di Architecture: hppa @@ -3999,8 +3104,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: fuse-modules-3.10-3-parisc-di Architecture: hppa @@ -4010,8 +3115,8 @@ Depends: kernel-image-3.10-3-parisc-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-parisc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc Package: kernel-image-3.10-3-parisc64-di Architecture: hppa @@ -4022,8 +3127,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: nic-modules-3.10-3-parisc64-di Architecture: hppa @@ -4034,8 +3139,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: ppp-modules-3.10-3-parisc64-di Architecture: hppa @@ -4045,8 +3150,8 @@ Depends: kernel-image-3.10-3-parisc64-di, zlib-modules-3.10-3-parisc64-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: pata-modules-3.10-3-parisc64-di Architecture: hppa @@ -4056,8 +3161,8 @@ Depends: kernel-image-3.10-3-parisc64-di, scsi-core-modules-3.10-3-parisc64-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: cdrom-core-modules-3.10-3-parisc64-di Architecture: hppa @@ -4067,8 +3172,8 @@ Depends: kernel-image-3.10-3-parisc64-di, scsi-core-modules-3.10-3-parisc64-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: scsi-core-modules-3.10-3-parisc64-di Architecture: hppa @@ -4078,8 +3183,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: scsi-modules-3.10-3-parisc64-di Architecture: hppa @@ -4089,8 +3194,8 @@ Depends: kernel-image-3.10-3-parisc64-di, scsi-core-modules-3.10-3-parisc64-di, cdrom-core-modules-3.10-3-parisc64-di, core-modules-3.10-3-parisc64-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: loop-modules-3.10-3-parisc64-di Architecture: hppa @@ -4100,8 +3205,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: btrfs-modules-3.10-3-parisc64-di Architecture: hppa @@ -4111,8 +3216,8 @@ Depends: kernel-image-3.10-3-parisc64-di, core-modules-3.10-3-parisc64-di, zlib-modules-3.10-3-parisc64-di, md-modules-3.10-3-parisc64-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: ext3-modules-3.10-3-parisc64-di Architecture: hppa @@ -4122,8 +3227,8 @@ Depends: kernel-image-3.10-3-parisc64-di, core-modules-3.10-3-parisc64-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: ext4-modules-3.10-3-parisc64-di Architecture: hppa @@ -4133,8 +3238,8 @@ Depends: kernel-image-3.10-3-parisc64-di, core-modules-3.10-3-parisc64-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: fat-modules-3.10-3-parisc64-di Architecture: hppa @@ -4144,8 +3249,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: md-modules-3.10-3-parisc64-di Architecture: hppa @@ -4155,8 +3260,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: multipath-modules-3.10-3-parisc64-di Architecture: hppa @@ -4166,8 +3271,8 @@ Depends: kernel-image-3.10-3-parisc64-di, md-modules-3.10-3-parisc64-di, scsi-core-modules-3.10-3-parisc64-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: usb-modules-3.10-3-parisc64-di Architecture: hppa @@ -4177,8 +3282,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: usb-storage-modules-3.10-3-parisc64-di Architecture: hppa @@ -4188,8 +3293,8 @@ Depends: kernel-image-3.10-3-parisc64-di, scsi-modules-3.10-3-parisc64-di, usb-modules-3.10-3-parisc64-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: input-modules-3.10-3-parisc64-di Architecture: hppa @@ -4199,8 +3304,8 @@ Depends: kernel-image-3.10-3-parisc64-di, usb-modules-3.10-3-parisc64-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: core-modules-3.10-3-parisc64-di Architecture: hppa @@ -4211,8 +3316,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: crypto-modules-3.10-3-parisc64-di Architecture: hppa @@ -4222,8 +3327,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: crypto-dm-modules-3.10-3-parisc64-di Architecture: hppa @@ -4233,8 +3338,8 @@ Depends: kernel-image-3.10-3-parisc64-di, md-modules-3.10-3-parisc64-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: nbd-modules-3.10-3-parisc64-di Architecture: hppa @@ -4245,8 +3350,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: zlib-modules-3.10-3-parisc64-di Architecture: hppa @@ -4256,8 +3361,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: fuse-modules-3.10-3-parisc64-di Architecture: hppa @@ -4267,8 +3372,8 @@ Depends: kernel-image-3.10-3-parisc64-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-parisc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-parisc64 Package: linux-image-3.10-3-parisc Architecture: hppa @@ -4381,8 +3486,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: nic-modules-3.10-3-486-di Architecture: i386 @@ -4393,8 +3498,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: nic-wireless-modules-3.10-3-486-di Architecture: i386 @@ -4405,8 +3510,8 @@ Description: Wireless NIC drivers This package contains wireless NIC drivers for the kernel. Includes crypto modules only needed for wireless (WEP, WPA). -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: nic-shared-modules-3.10-3-486-di Architecture: i386 @@ -4417,8 +3522,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: serial-modules-3.10-3-486-di Architecture: i386 @@ -4428,8 +3533,8 @@ Depends: kernel-image-3.10-3-486-di, pcmcia-modules-3.10-3-486-di Description: Serial drivers This package contains serial drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: usb-serial-modules-3.10-3-486-di Architecture: i386 @@ -4439,8 +3544,8 @@ Depends: kernel-image-3.10-3-486-di, usb-modules-3.10-3-486-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: ppp-modules-3.10-3-486-di Architecture: i386 @@ -4450,8 +3555,8 @@ Depends: kernel-image-3.10-3-486-di, serial-modules-3.10-3-486-di, zlib-modules-3.10-3-486-di, crc-modules-3.10-3-486-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: pata-modules-3.10-3-486-di Architecture: i386 @@ -4461,8 +3566,8 @@ Depends: kernel-image-3.10-3-486-di, ata-modules-3.10-3-486-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: cdrom-core-modules-3.10-3-486-di Architecture: i386 @@ -4472,8 +3577,8 @@ Depends: kernel-image-3.10-3-486-di, scsi-core-modules-3.10-3-486-di, isofs-modules-3.10-3-486-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: firewire-core-modules-3.10-3-486-di Architecture: i386 @@ -4483,8 +3588,8 @@ Depends: kernel-image-3.10-3-486-di, scsi-core-modules-3.10-3-486-di, crc-modules-3.10-3-486-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: scsi-core-modules-3.10-3-486-di Architecture: i386 @@ -4494,8 +3599,8 @@ Depends: kernel-image-3.10-3-486-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: scsi-modules-3.10-3-486-di Architecture: i386 @@ -4505,8 +3610,8 @@ Depends: kernel-image-3.10-3-486-di, scsi-core-modules-3.10-3-486-di, cdrom-core-modules-3.10-3-486-di, core-modules-3.10-3-486-di, ata-modules-3.10-3-486-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: scsi-common-modules-3.10-3-486-di Architecture: i386 @@ -4516,8 +3621,8 @@ Depends: kernel-image-3.10-3-486-di, scsi-core-modules-3.10-3-486-di, cdrom-core-modules-3.10-3-486-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: scsi-extra-modules-3.10-3-486-di Architecture: i386 @@ -4528,8 +3633,8 @@ Description: Uncommon SCSI drivers This package contains uncommon SCSI drivers for the kernel. This includes SCSI RAID drivers, and some of the less common SCSI controllers. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: loop-modules-3.10-3-486-di Architecture: i386 @@ -4539,8 +3644,8 @@ Depends: kernel-image-3.10-3-486-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: btrfs-modules-3.10-3-486-di Architecture: i386 @@ -4550,8 +3655,8 @@ Depends: kernel-image-3.10-3-486-di, core-modules-3.10-3-486-di, crc-modules-3.10-3-486-di, zlib-modules-3.10-3-486-di, md-modules-3.10-3-486-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: ext2-modules-3.10-3-486-di Architecture: i386 @@ -4561,8 +3666,8 @@ Depends: kernel-image-3.10-3-486-di, core-modules-3.10-3-486-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: ext3-modules-3.10-3-486-di Architecture: i386 @@ -4572,8 +3677,8 @@ Depends: kernel-image-3.10-3-486-di, core-modules-3.10-3-486-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: ext4-modules-3.10-3-486-di Architecture: i386 @@ -4583,8 +3688,8 @@ Depends: kernel-image-3.10-3-486-di, core-modules-3.10-3-486-di, crc-modules-3.10-3-486-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: isofs-modules-3.10-3-486-di Architecture: i386 @@ -4594,8 +3699,8 @@ Depends: kernel-image-3.10-3-486-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: jfs-modules-3.10-3-486-di Architecture: i386 @@ -4605,8 +3710,8 @@ Depends: kernel-image-3.10-3-486-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: ntfs-modules-3.10-3-486-di Architecture: i386 @@ -4616,8 +3721,8 @@ Depends: kernel-image-3.10-3-486-di Description: NTFS filesystem support This package contains the NTFS file system module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: xfs-modules-3.10-3-486-di Architecture: i386 @@ -4627,8 +3732,8 @@ Depends: kernel-image-3.10-3-486-di, crc-modules-3.10-3-486-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: fat-modules-3.10-3-486-di Architecture: i386 @@ -4638,8 +3743,8 @@ Depends: kernel-image-3.10-3-486-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: md-modules-3.10-3-486-di Architecture: i386 @@ -4649,8 +3754,8 @@ Depends: kernel-image-3.10-3-486-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: multipath-modules-3.10-3-486-di Architecture: i386 @@ -4660,8 +3765,8 @@ Depends: kernel-image-3.10-3-486-di, md-modules-3.10-3-486-di, scsi-core-modules-3.10-3-486-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: usb-modules-3.10-3-486-di Architecture: i386 @@ -4671,8 +3776,8 @@ Depends: kernel-image-3.10-3-486-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: usb-storage-modules-3.10-3-486-di Architecture: i386 @@ -4682,8 +3787,8 @@ Depends: kernel-image-3.10-3-486-di, scsi-core-modules-3.10-3-486-di, usb-modules-3.10-3-486-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: pcmcia-storage-modules-3.10-3-486-di Architecture: i386 @@ -4693,8 +3798,8 @@ Depends: kernel-image-3.10-3-486-di, cdrom-core-modules-3.10-3-486-di, pcmcia-modules-3.10-3-486-di, ata-modules-3.10-3-486-di Description: PCMCIA storage drivers This package contains PCMCIA storage drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: fb-modules-3.10-3-486-di Architecture: i386 @@ -4704,8 +3809,8 @@ Depends: kernel-image-3.10-3-486-di, i2c-modules-3.10-3-486-di Description: Frame buffer support This package contains Frame buffer drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: input-modules-3.10-3-486-di Architecture: i386 @@ -4715,8 +3820,8 @@ Depends: kernel-image-3.10-3-486-di, usb-modules-3.10-3-486-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: event-modules-3.10-3-486-di Architecture: i386 @@ -4726,8 +3831,8 @@ Depends: kernel-image-3.10-3-486-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: mouse-modules-3.10-3-486-di Architecture: i386 @@ -4737,8 +3842,8 @@ Depends: kernel-image-3.10-3-486-di, event-modules-3.10-3-486-di, input-modules-3.10-3-486-di, usb-modules-3.10-3-486-di Description: Mouse support This package contains mouse drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: nic-pcmcia-modules-3.10-3-486-di Architecture: i386 @@ -4748,8 +3853,8 @@ Depends: kernel-image-3.10-3-486-di, nic-shared-modules-3.10-3-486-di, nic-wireless-modules-3.10-3-486-di, pcmcia-modules-3.10-3-486-di, mmc-core-modules-3.10-3-486-di Description: Common PCMCIA NIC drivers This package contains common PCMCIA NIC drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: pcmcia-modules-3.10-3-486-di Architecture: i386 @@ -4759,8 +3864,8 @@ Depends: kernel-image-3.10-3-486-di, core-modules-3.10-3-486-di Description: Common PCMCIA drivers This package contains common PCMCIA drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: nic-usb-modules-3.10-3-486-di Architecture: i386 @@ -4770,8 +3875,8 @@ Depends: kernel-image-3.10-3-486-di, nic-shared-modules-3.10-3-486-di, nic-wireless-modules-3.10-3-486-di, usb-modules-3.10-3-486-di, core-modules-3.10-3-486-di, crc-modules-3.10-3-486-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: sata-modules-3.10-3-486-di Architecture: i386 @@ -4781,8 +3886,8 @@ Depends: kernel-image-3.10-3-486-di, scsi-core-modules-3.10-3-486-di, ata-modules-3.10-3-486-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: core-modules-3.10-3-486-di Architecture: i386 @@ -4793,8 +3898,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: acpi-modules-3.10-3-486-di Architecture: i386 @@ -4804,8 +3909,8 @@ Depends: kernel-image-3.10-3-486-di Description: ACPI support modules This package contains kernel modules for ACPI. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: i2c-modules-3.10-3-486-di Architecture: i386 @@ -4815,8 +3920,8 @@ Depends: kernel-image-3.10-3-486-di Description: i2c support modules This package contains basic i2c support modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: crc-modules-3.10-3-486-di Architecture: i386 @@ -4826,8 +3931,8 @@ Depends: kernel-image-3.10-3-486-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: crypto-modules-3.10-3-486-di Architecture: i386 @@ -4837,8 +3942,8 @@ Depends: kernel-image-3.10-3-486-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: crypto-dm-modules-3.10-3-486-di Architecture: i386 @@ -4848,8 +3953,8 @@ Depends: kernel-image-3.10-3-486-di, md-modules-3.10-3-486-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: efi-modules-3.10-3-486-di Architecture: i386 @@ -4859,8 +3964,8 @@ Depends: kernel-image-3.10-3-486-di Description: EFI modules This package contains EFI modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: ata-modules-3.10-3-486-di Architecture: i386 @@ -4871,8 +3976,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: mmc-core-modules-3.10-3-486-di Architecture: i386 @@ -4882,8 +3987,8 @@ Depends: kernel-image-3.10-3-486-di, core-modules-3.10-3-486-di Description: MMC/SD/SDIO core modules This package contains core modules for MMC/SD/SDIO support. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: mmc-modules-3.10-3-486-di Architecture: i386 @@ -4894,8 +3999,8 @@ Description: MMC/SD card modules This package contains modules needed to support MMC (multimedia) and SD cards. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: nbd-modules-3.10-3-486-di Architecture: i386 @@ -4906,8 +4011,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: squashfs-modules-3.10-3-486-di Architecture: i386 @@ -4917,8 +4022,8 @@ Depends: kernel-image-3.10-3-486-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: speakup-modules-3.10-3-486-di Architecture: i386 @@ -4928,8 +4033,8 @@ Depends: kernel-image-3.10-3-486-di Description: speakup modules This package contains speakup modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: virtio-modules-3.10-3-486-di Architecture: i386 @@ -4939,8 +4044,8 @@ Depends: kernel-image-3.10-3-486-di, scsi-core-modules-3.10-3-486-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: uinput-modules-3.10-3-486-di Architecture: i386 @@ -4950,8 +4055,8 @@ Depends: kernel-image-3.10-3-486-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: sound-modules-3.10-3-486-di Architecture: i386 @@ -4961,8 +4066,8 @@ Depends: kernel-image-3.10-3-486-di, core-modules-3.10-3-486-di, i2c-modules-3.10-3-486-di, usb-modules-3.10-3-486-di, pcmcia-modules-3.10-3-486-di, firewire-core-modules-3.10-3-486-di, crc-modules-3.10-3-486-di Description: sound support This package contains sound modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: zlib-modules-3.10-3-486-di Architecture: i386 @@ -4972,8 +4077,8 @@ Depends: kernel-image-3.10-3-486-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: hyperv-modules-3.10-3-486-di Architecture: i386 @@ -4983,8 +4088,8 @@ Depends: kernel-image-3.10-3-486-di, input-modules-3.10-3-486-di, scsi-core-modules-3.10-3-486-di Description: Hyper-V modules This package contains Hyper-V paravirtualised drivers for the kernel. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: udf-modules-3.10-3-486-di Architecture: i386 @@ -4994,8 +4099,8 @@ Depends: kernel-image-3.10-3-486-di, crc-modules-3.10-3-486-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: fuse-modules-3.10-3-486-di Architecture: i386 @@ -5005,8 +4110,8 @@ Depends: kernel-image-3.10-3-486-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-486 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-486 Package: kernel-image-3.10-3-686-pae-di Architecture: i386 @@ -5017,8 +4122,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: nic-modules-3.10-3-686-pae-di Architecture: i386 @@ -5029,8 +4134,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: nic-wireless-modules-3.10-3-686-pae-di Architecture: i386 @@ -5041,8 +4146,8 @@ Description: Wireless NIC drivers This package contains wireless NIC drivers for the kernel. Includes crypto modules only needed for wireless (WEP, WPA). -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: nic-shared-modules-3.10-3-686-pae-di Architecture: i386 @@ -5053,8 +4158,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: serial-modules-3.10-3-686-pae-di Architecture: i386 @@ -5064,8 +4169,8 @@ Depends: kernel-image-3.10-3-686-pae-di, pcmcia-modules-3.10-3-686-pae-di Description: Serial drivers This package contains serial drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: usb-serial-modules-3.10-3-686-pae-di Architecture: i386 @@ -5075,8 +4180,8 @@ Depends: kernel-image-3.10-3-686-pae-di, usb-modules-3.10-3-686-pae-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: ppp-modules-3.10-3-686-pae-di Architecture: i386 @@ -5086,8 +4191,8 @@ Depends: kernel-image-3.10-3-686-pae-di, serial-modules-3.10-3-686-pae-di, zlib-modules-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: pata-modules-3.10-3-686-pae-di Architecture: i386 @@ -5097,8 +4202,8 @@ Depends: kernel-image-3.10-3-686-pae-di, ata-modules-3.10-3-686-pae-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: cdrom-core-modules-3.10-3-686-pae-di Architecture: i386 @@ -5108,8 +4213,8 @@ Depends: kernel-image-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di, isofs-modules-3.10-3-686-pae-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: firewire-core-modules-3.10-3-686-pae-di Architecture: i386 @@ -5119,8 +4224,8 @@ Depends: kernel-image-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: scsi-core-modules-3.10-3-686-pae-di Architecture: i386 @@ -5130,8 +4235,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: scsi-modules-3.10-3-686-pae-di Architecture: i386 @@ -5141,8 +4246,8 @@ Depends: kernel-image-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di, cdrom-core-modules-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di, ata-modules-3.10-3-686-pae-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: scsi-common-modules-3.10-3-686-pae-di Architecture: i386 @@ -5152,8 +4257,8 @@ Depends: kernel-image-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di, cdrom-core-modules-3.10-3-686-pae-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: scsi-extra-modules-3.10-3-686-pae-di Architecture: i386 @@ -5164,8 +4269,8 @@ Description: Uncommon SCSI drivers This package contains uncommon SCSI drivers for the kernel. This includes SCSI RAID drivers, and some of the less common SCSI controllers. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: loop-modules-3.10-3-686-pae-di Architecture: i386 @@ -5175,8 +4280,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: btrfs-modules-3.10-3-686-pae-di Architecture: i386 @@ -5186,8 +4291,8 @@ Depends: kernel-image-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di, zlib-modules-3.10-3-686-pae-di, md-modules-3.10-3-686-pae-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: ext2-modules-3.10-3-686-pae-di Architecture: i386 @@ -5197,8 +4302,8 @@ Depends: kernel-image-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: ext3-modules-3.10-3-686-pae-di Architecture: i386 @@ -5208,8 +4313,8 @@ Depends: kernel-image-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: ext4-modules-3.10-3-686-pae-di Architecture: i386 @@ -5219,8 +4324,8 @@ Depends: kernel-image-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: isofs-modules-3.10-3-686-pae-di Architecture: i386 @@ -5230,8 +4335,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: jfs-modules-3.10-3-686-pae-di Architecture: i386 @@ -5241,8 +4346,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: ntfs-modules-3.10-3-686-pae-di Architecture: i386 @@ -5252,8 +4357,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: NTFS filesystem support This package contains the NTFS file system module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: xfs-modules-3.10-3-686-pae-di Architecture: i386 @@ -5263,8 +4368,8 @@ Depends: kernel-image-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: fat-modules-3.10-3-686-pae-di Architecture: i386 @@ -5274,8 +4379,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: md-modules-3.10-3-686-pae-di Architecture: i386 @@ -5285,8 +4390,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: multipath-modules-3.10-3-686-pae-di Architecture: i386 @@ -5296,8 +4401,8 @@ Depends: kernel-image-3.10-3-686-pae-di, md-modules-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: usb-modules-3.10-3-686-pae-di Architecture: i386 @@ -5307,8 +4412,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: usb-storage-modules-3.10-3-686-pae-di Architecture: i386 @@ -5318,8 +4423,8 @@ Depends: kernel-image-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di, usb-modules-3.10-3-686-pae-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: pcmcia-storage-modules-3.10-3-686-pae-di Architecture: i386 @@ -5329,8 +4434,8 @@ Depends: kernel-image-3.10-3-686-pae-di, cdrom-core-modules-3.10-3-686-pae-di, pcmcia-modules-3.10-3-686-pae-di, ata-modules-3.10-3-686-pae-di Description: PCMCIA storage drivers This package contains PCMCIA storage drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: fb-modules-3.10-3-686-pae-di Architecture: i386 @@ -5340,8 +4445,8 @@ Depends: kernel-image-3.10-3-686-pae-di, i2c-modules-3.10-3-686-pae-di Description: Frame buffer support This package contains Frame buffer drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: input-modules-3.10-3-686-pae-di Architecture: i386 @@ -5351,8 +4456,8 @@ Depends: kernel-image-3.10-3-686-pae-di, usb-modules-3.10-3-686-pae-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: event-modules-3.10-3-686-pae-di Architecture: i386 @@ -5362,8 +4467,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: mouse-modules-3.10-3-686-pae-di Architecture: i386 @@ -5373,8 +4478,8 @@ Depends: kernel-image-3.10-3-686-pae-di, event-modules-3.10-3-686-pae-di, input-modules-3.10-3-686-pae-di, usb-modules-3.10-3-686-pae-di Description: Mouse support This package contains mouse drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: nic-pcmcia-modules-3.10-3-686-pae-di Architecture: i386 @@ -5384,8 +4489,8 @@ Depends: kernel-image-3.10-3-686-pae-di, nic-shared-modules-3.10-3-686-pae-di, nic-wireless-modules-3.10-3-686-pae-di, pcmcia-modules-3.10-3-686-pae-di, mmc-core-modules-3.10-3-686-pae-di Description: Common PCMCIA NIC drivers This package contains common PCMCIA NIC drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: pcmcia-modules-3.10-3-686-pae-di Architecture: i386 @@ -5395,8 +4500,8 @@ Depends: kernel-image-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di Description: Common PCMCIA drivers This package contains common PCMCIA drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: nic-usb-modules-3.10-3-686-pae-di Architecture: i386 @@ -5406,8 +4511,8 @@ Depends: kernel-image-3.10-3-686-pae-di, nic-shared-modules-3.10-3-686-pae-di, nic-wireless-modules-3.10-3-686-pae-di, usb-modules-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: sata-modules-3.10-3-686-pae-di Architecture: i386 @@ -5417,8 +4522,8 @@ Depends: kernel-image-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di, ata-modules-3.10-3-686-pae-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: core-modules-3.10-3-686-pae-di Architecture: i386 @@ -5429,8 +4534,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: acpi-modules-3.10-3-686-pae-di Architecture: i386 @@ -5440,8 +4545,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: ACPI support modules This package contains kernel modules for ACPI. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: i2c-modules-3.10-3-686-pae-di Architecture: i386 @@ -5451,8 +4556,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: i2c support modules This package contains basic i2c support modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: crc-modules-3.10-3-686-pae-di Architecture: i386 @@ -5462,8 +4567,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: crypto-modules-3.10-3-686-pae-di Architecture: i386 @@ -5473,8 +4578,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: crypto-dm-modules-3.10-3-686-pae-di Architecture: i386 @@ -5484,8 +4589,8 @@ Depends: kernel-image-3.10-3-686-pae-di, md-modules-3.10-3-686-pae-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: efi-modules-3.10-3-686-pae-di Architecture: i386 @@ -5495,8 +4600,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: EFI modules This package contains EFI modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: ata-modules-3.10-3-686-pae-di Architecture: i386 @@ -5507,8 +4612,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: mmc-core-modules-3.10-3-686-pae-di Architecture: i386 @@ -5518,8 +4623,8 @@ Depends: kernel-image-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di Description: MMC/SD/SDIO core modules This package contains core modules for MMC/SD/SDIO support. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: mmc-modules-3.10-3-686-pae-di Architecture: i386 @@ -5530,8 +4635,8 @@ Description: MMC/SD card modules This package contains modules needed to support MMC (multimedia) and SD cards. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: nbd-modules-3.10-3-686-pae-di Architecture: i386 @@ -5542,8 +4647,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: squashfs-modules-3.10-3-686-pae-di Architecture: i386 @@ -5553,8 +4658,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: speakup-modules-3.10-3-686-pae-di Architecture: i386 @@ -5564,8 +4669,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: speakup modules This package contains speakup modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: virtio-modules-3.10-3-686-pae-di Architecture: i386 @@ -5575,8 +4680,8 @@ Depends: kernel-image-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: uinput-modules-3.10-3-686-pae-di Architecture: i386 @@ -5586,8 +4691,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: sound-modules-3.10-3-686-pae-di Architecture: i386 @@ -5597,8 +4702,8 @@ Depends: kernel-image-3.10-3-686-pae-di, core-modules-3.10-3-686-pae-di, i2c-modules-3.10-3-686-pae-di, usb-modules-3.10-3-686-pae-di, pcmcia-modules-3.10-3-686-pae-di, firewire-core-modules-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di Description: sound support This package contains sound modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: zlib-modules-3.10-3-686-pae-di Architecture: i386 @@ -5608,8 +4713,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: hyperv-modules-3.10-3-686-pae-di Architecture: i386 @@ -5619,8 +4724,8 @@ Depends: kernel-image-3.10-3-686-pae-di, input-modules-3.10-3-686-pae-di, scsi-core-modules-3.10-3-686-pae-di Description: Hyper-V modules This package contains Hyper-V paravirtualised drivers for the kernel. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: udf-modules-3.10-3-686-pae-di Architecture: i386 @@ -5630,8 +4735,8 @@ Depends: kernel-image-3.10-3-686-pae-di, crc-modules-3.10-3-686-pae-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: fuse-modules-3.10-3-686-pae-di Architecture: i386 @@ -5641,8 +4746,8 @@ Depends: kernel-image-3.10-3-686-pae-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-686-pae -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-686-pae Package: linux-image-3.10-3-486 Architecture: i386 @@ -5775,8 +4880,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: nic-modules-3.10-3-itanium-di Architecture: ia64 @@ -5787,8 +4892,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: nic-shared-modules-3.10-3-itanium-di Architecture: ia64 @@ -5799,8 +4904,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: serial-modules-3.10-3-itanium-di Architecture: ia64 @@ -5810,8 +4915,8 @@ Depends: kernel-image-3.10-3-itanium-di, pcmcia-modules-3.10-3-itanium-di, sn-modules-3.10-3-itanium-di Description: Serial drivers This package contains serial drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ppp-modules-3.10-3-itanium-di Architecture: ia64 @@ -5821,8 +4926,8 @@ Depends: kernel-image-3.10-3-itanium-di, serial-modules-3.10-3-itanium-di, zlib-modules-3.10-3-itanium-di, crc-modules-3.10-3-itanium-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: pata-modules-3.10-3-itanium-di Architecture: ia64 @@ -5832,8 +4937,8 @@ Depends: kernel-image-3.10-3-itanium-di, ata-modules-3.10-3-itanium-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: cdrom-core-modules-3.10-3-itanium-di Architecture: ia64 @@ -5843,8 +4948,8 @@ Depends: kernel-image-3.10-3-itanium-di, scsi-core-modules-3.10-3-itanium-di, ide-modules-3.10-3-itanium-di, isofs-modules-3.10-3-itanium-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: firewire-core-modules-3.10-3-itanium-di Architecture: ia64 @@ -5854,8 +4959,8 @@ Depends: kernel-image-3.10-3-itanium-di, scsi-core-modules-3.10-3-itanium-di, crc-modules-3.10-3-itanium-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: scsi-core-modules-3.10-3-itanium-di Architecture: ia64 @@ -5865,8 +4970,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: scsi-modules-3.10-3-itanium-di Architecture: ia64 @@ -5876,8 +4981,8 @@ Depends: kernel-image-3.10-3-itanium-di, scsi-core-modules-3.10-3-itanium-di, cdrom-core-modules-3.10-3-itanium-di, core-modules-3.10-3-itanium-di, ata-modules-3.10-3-itanium-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: loop-modules-3.10-3-itanium-di Architecture: ia64 @@ -5887,8 +4992,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: btrfs-modules-3.10-3-itanium-di Architecture: ia64 @@ -5898,8 +5003,8 @@ Depends: kernel-image-3.10-3-itanium-di, core-modules-3.10-3-itanium-di, crc-modules-3.10-3-itanium-di, zlib-modules-3.10-3-itanium-di, md-modules-3.10-3-itanium-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ext2-modules-3.10-3-itanium-di Architecture: ia64 @@ -5909,8 +5014,8 @@ Depends: kernel-image-3.10-3-itanium-di, core-modules-3.10-3-itanium-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ext3-modules-3.10-3-itanium-di Architecture: ia64 @@ -5920,8 +5025,8 @@ Depends: kernel-image-3.10-3-itanium-di, core-modules-3.10-3-itanium-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ext4-modules-3.10-3-itanium-di Architecture: ia64 @@ -5931,8 +5036,8 @@ Depends: kernel-image-3.10-3-itanium-di, core-modules-3.10-3-itanium-di, crc-modules-3.10-3-itanium-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: isofs-modules-3.10-3-itanium-di Architecture: ia64 @@ -5942,8 +5047,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: jfs-modules-3.10-3-itanium-di Architecture: ia64 @@ -5953,8 +5058,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ntfs-modules-3.10-3-itanium-di Architecture: ia64 @@ -5964,8 +5069,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: NTFS filesystem support This package contains the NTFS file system module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: xfs-modules-3.10-3-itanium-di Architecture: ia64 @@ -5975,8 +5080,8 @@ Depends: kernel-image-3.10-3-itanium-di, crc-modules-3.10-3-itanium-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: fat-modules-3.10-3-itanium-di Architecture: ia64 @@ -5986,8 +5091,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: md-modules-3.10-3-itanium-di Architecture: ia64 @@ -5997,8 +5102,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: multipath-modules-3.10-3-itanium-di Architecture: ia64 @@ -6008,8 +5113,8 @@ Depends: kernel-image-3.10-3-itanium-di, md-modules-3.10-3-itanium-di, scsi-core-modules-3.10-3-itanium-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: usb-modules-3.10-3-itanium-di Architecture: ia64 @@ -6019,8 +5124,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: usb-storage-modules-3.10-3-itanium-di Architecture: ia64 @@ -6030,8 +5135,8 @@ Depends: kernel-image-3.10-3-itanium-di, scsi-core-modules-3.10-3-itanium-di, usb-modules-3.10-3-itanium-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: fb-modules-3.10-3-itanium-di Architecture: ia64 @@ -6041,8 +5146,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: Frame buffer support This package contains Frame buffer drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: input-modules-3.10-3-itanium-di Architecture: ia64 @@ -6052,8 +5157,8 @@ Depends: kernel-image-3.10-3-itanium-di, usb-modules-3.10-3-itanium-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: event-modules-3.10-3-itanium-di Architecture: ia64 @@ -6063,8 +5168,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: mouse-modules-3.10-3-itanium-di Architecture: ia64 @@ -6074,8 +5179,8 @@ Depends: kernel-image-3.10-3-itanium-di, event-modules-3.10-3-itanium-di, input-modules-3.10-3-itanium-di, usb-modules-3.10-3-itanium-di Description: Mouse support This package contains mouse drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: pcmcia-modules-3.10-3-itanium-di Architecture: ia64 @@ -6085,8 +5190,8 @@ Depends: kernel-image-3.10-3-itanium-di, core-modules-3.10-3-itanium-di Description: Common PCMCIA drivers This package contains common PCMCIA drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: nic-usb-modules-3.10-3-itanium-di Architecture: ia64 @@ -6096,8 +5201,8 @@ Depends: kernel-image-3.10-3-itanium-di, nic-shared-modules-3.10-3-itanium-di, usb-modules-3.10-3-itanium-di, core-modules-3.10-3-itanium-di, crc-modules-3.10-3-itanium-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: sata-modules-3.10-3-itanium-di Architecture: ia64 @@ -6107,8 +5212,8 @@ Depends: kernel-image-3.10-3-itanium-di, scsi-core-modules-3.10-3-itanium-di, ata-modules-3.10-3-itanium-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: core-modules-3.10-3-itanium-di Architecture: ia64 @@ -6119,8 +5224,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: crc-modules-3.10-3-itanium-di Architecture: ia64 @@ -6130,8 +5235,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: crypto-modules-3.10-3-itanium-di Architecture: ia64 @@ -6141,8 +5246,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: crypto-dm-modules-3.10-3-itanium-di Architecture: ia64 @@ -6152,8 +5257,8 @@ Depends: kernel-image-3.10-3-itanium-di, md-modules-3.10-3-itanium-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ata-modules-3.10-3-itanium-di Architecture: ia64 @@ -6164,8 +5269,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: nbd-modules-3.10-3-itanium-di Architecture: ia64 @@ -6176,8 +5281,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: squashfs-modules-3.10-3-itanium-di Architecture: ia64 @@ -6187,8 +5292,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: uinput-modules-3.10-3-itanium-di Architecture: ia64 @@ -6198,8 +5303,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: zlib-modules-3.10-3-itanium-di Architecture: ia64 @@ -6209,8 +5314,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: udf-modules-3.10-3-itanium-di Architecture: ia64 @@ -6220,8 +5325,8 @@ Depends: kernel-image-3.10-3-itanium-di, crc-modules-3.10-3-itanium-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: fuse-modules-3.10-3-itanium-di Architecture: ia64 @@ -6231,8 +5336,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ide-core-modules-3.10-3-itanium-di Architecture: ia64 @@ -6242,8 +5347,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: IDE support This package contains core IDE support for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: ide-modules-3.10-3-itanium-di Architecture: ia64 @@ -6253,8 +5358,8 @@ Depends: kernel-image-3.10-3-itanium-di, ide-core-modules-3.10-3-itanium-di, sn-modules-3.10-3-itanium-di Description: IDE drivers This package contains IDE drivers for the kernel. -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: sn-modules-3.10-3-itanium-di Architecture: ia64 @@ -6264,8 +5369,8 @@ Depends: kernel-image-3.10-3-itanium-di Description: SN modules This package contains SN modules for Altix systems -Kernel-Version: 3.10-3-itanium -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-itanium Package: linux-image-3.10-3-itanium Architecture: ia64 @@ -6330,8 +5435,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: nic-shared-modules-3.10-3-m68k-di Architecture: m68k @@ -6342,8 +5447,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: ppp-modules-3.10-3-m68k-di Architecture: m68k @@ -6353,8 +5458,8 @@ Depends: kernel-image-3.10-3-m68k-di, zlib-modules-3.10-3-m68k-di, crc-modules-3.10-3-m68k-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: cdrom-core-modules-3.10-3-m68k-di Architecture: m68k @@ -6364,8 +5469,8 @@ Depends: kernel-image-3.10-3-m68k-di, isofs-modules-3.10-3-m68k-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: scsi-modules-3.10-3-m68k-di Architecture: m68k @@ -6375,8 +5480,8 @@ Depends: kernel-image-3.10-3-m68k-di, cdrom-core-modules-3.10-3-m68k-di, core-modules-3.10-3-m68k-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: btrfs-modules-3.10-3-m68k-di Architecture: m68k @@ -6386,8 +5491,8 @@ Depends: kernel-image-3.10-3-m68k-di, core-modules-3.10-3-m68k-di, crc-modules-3.10-3-m68k-di, zlib-modules-3.10-3-m68k-di, md-modules-3.10-3-m68k-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: ext2-modules-3.10-3-m68k-di Architecture: m68k @@ -6397,8 +5502,8 @@ Depends: kernel-image-3.10-3-m68k-di, core-modules-3.10-3-m68k-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: ext3-modules-3.10-3-m68k-di Architecture: m68k @@ -6408,8 +5513,8 @@ Depends: kernel-image-3.10-3-m68k-di, core-modules-3.10-3-m68k-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: ext4-modules-3.10-3-m68k-di Architecture: m68k @@ -6419,8 +5524,8 @@ Depends: kernel-image-3.10-3-m68k-di, core-modules-3.10-3-m68k-di, crc-modules-3.10-3-m68k-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: isofs-modules-3.10-3-m68k-di Architecture: m68k @@ -6430,8 +5535,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: fat-modules-3.10-3-m68k-di Architecture: m68k @@ -6441,8 +5546,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: md-modules-3.10-3-m68k-di Architecture: m68k @@ -6452,8 +5557,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: core-modules-3.10-3-m68k-di Architecture: m68k @@ -6464,8 +5569,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: crc-modules-3.10-3-m68k-di Architecture: m68k @@ -6475,8 +5580,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: crypto-modules-3.10-3-m68k-di Architecture: m68k @@ -6486,8 +5591,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: nbd-modules-3.10-3-m68k-di Architecture: m68k @@ -6498,8 +5603,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: squashfs-modules-3.10-3-m68k-di Architecture: m68k @@ -6509,8 +5614,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: zlib-modules-3.10-3-m68k-di Architecture: m68k @@ -6520,8 +5625,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: udf-modules-3.10-3-m68k-di Architecture: m68k @@ -6531,8 +5636,8 @@ Depends: kernel-image-3.10-3-m68k-di, crc-modules-3.10-3-m68k-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: fuse-modules-3.10-3-m68k-di Architecture: m68k @@ -6542,8 +5647,8 @@ Depends: kernel-image-3.10-3-m68k-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-m68k -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-m68k Package: linux-image-3.10-3-m68k Architecture: m68k @@ -6584,8 +5689,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: nic-shared-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6596,8 +5701,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: ppp-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6607,8 +5712,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, zlib-modules-3.10-3-sb1-bcm91250a-di, crc-modules-3.10-3-sb1-bcm91250a-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: cdrom-core-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6618,8 +5723,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, scsi-core-modules-3.10-3-sb1-bcm91250a-di, isofs-modules-3.10-3-sb1-bcm91250a-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: scsi-core-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6629,8 +5734,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: scsi-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6640,8 +5745,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, scsi-core-modules-3.10-3-sb1-bcm91250a-di, cdrom-core-modules-3.10-3-sb1-bcm91250a-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: scsi-common-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6651,8 +5756,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, scsi-core-modules-3.10-3-sb1-bcm91250a-di, cdrom-core-modules-3.10-3-sb1-bcm91250a-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: loop-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6662,8 +5767,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: btrfs-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6673,8 +5778,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, crc-modules-3.10-3-sb1-bcm91250a-di, zlib-modules-3.10-3-sb1-bcm91250a-di, md-modules-3.10-3-sb1-bcm91250a-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: isofs-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6684,8 +5789,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: jfs-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6695,8 +5800,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: xfs-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6706,8 +5811,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, crc-modules-3.10-3-sb1-bcm91250a-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: fat-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6717,8 +5822,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: md-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6728,8 +5833,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: multipath-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6739,8 +5844,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, md-modules-3.10-3-sb1-bcm91250a-di, scsi-core-modules-3.10-3-sb1-bcm91250a-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: usb-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6750,8 +5855,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: usb-storage-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6761,8 +5866,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, scsi-core-modules-3.10-3-sb1-bcm91250a-di, usb-modules-3.10-3-sb1-bcm91250a-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: fb-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6772,8 +5877,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: Frame buffer support This package contains Frame buffer drivers for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: input-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6783,8 +5888,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, usb-modules-3.10-3-sb1-bcm91250a-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: sata-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6794,8 +5899,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, scsi-core-modules-3.10-3-sb1-bcm91250a-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: crc-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6805,8 +5910,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: crypto-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6816,8 +5921,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: crypto-dm-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6827,8 +5932,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, md-modules-3.10-3-sb1-bcm91250a-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: nbd-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6839,8 +5944,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: squashfs-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6850,8 +5955,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: rtc-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6861,8 +5966,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: RTC modules This package contains RTC modules. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: zlib-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6872,8 +5977,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: udf-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6883,8 +5988,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di, crc-modules-3.10-3-sb1-bcm91250a-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: fuse-modules-3.10-3-sb1-bcm91250a-di Architecture: mips mipsel @@ -6894,8 +5999,8 @@ Depends: kernel-image-3.10-3-sb1-bcm91250a-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-sb1-bcm91250a -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sb1-bcm91250a Package: kernel-image-3.10-3-r4k-ip22-di Architecture: mips @@ -6906,8 +6011,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: nic-shared-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6918,8 +6023,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: loop-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6929,8 +6034,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: btrfs-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6940,8 +6045,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di, crc-modules-3.10-3-r4k-ip22-di, zlib-modules-3.10-3-r4k-ip22-di, md-modules-3.10-3-r4k-ip22-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: isofs-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6951,8 +6056,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: jfs-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6962,8 +6067,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: xfs-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6973,8 +6078,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di, crc-modules-3.10-3-r4k-ip22-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: md-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6984,8 +6089,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: multipath-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -6995,8 +6100,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di, md-modules-3.10-3-r4k-ip22-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: crc-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7006,8 +6111,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: crypto-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7017,8 +6122,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: crypto-dm-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7028,8 +6133,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di, md-modules-3.10-3-r4k-ip22-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: nbd-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7040,8 +6145,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: squashfs-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7051,8 +6156,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: zlib-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7062,8 +6167,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: udf-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7073,8 +6178,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di, crc-modules-3.10-3-r4k-ip22-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: fuse-modules-3.10-3-r4k-ip22-di Architecture: mips @@ -7084,8 +6189,8 @@ Depends: kernel-image-3.10-3-r4k-ip22-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-r4k-ip22 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r4k-ip22 Package: kernel-image-3.10-3-r5k-ip32-di Architecture: mips @@ -7096,8 +6201,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: nic-shared-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7108,8 +6213,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: loop-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7119,8 +6224,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: btrfs-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7130,8 +6235,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di, crc-modules-3.10-3-r5k-ip32-di, zlib-modules-3.10-3-r5k-ip32-di, md-modules-3.10-3-r5k-ip32-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: isofs-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7141,8 +6246,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: jfs-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7152,8 +6257,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: xfs-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7163,8 +6268,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di, crc-modules-3.10-3-r5k-ip32-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: md-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7174,8 +6279,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: multipath-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7185,8 +6290,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di, md-modules-3.10-3-r5k-ip32-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: crc-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7196,8 +6301,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: crypto-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7207,8 +6312,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: crypto-dm-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7218,8 +6323,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di, md-modules-3.10-3-r5k-ip32-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: nbd-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7230,8 +6335,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: squashfs-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7241,8 +6346,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: zlib-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7252,8 +6357,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: udf-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7263,8 +6368,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di, crc-modules-3.10-3-r5k-ip32-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: fuse-modules-3.10-3-r5k-ip32-di Architecture: mips @@ -7274,8 +6379,8 @@ Depends: kernel-image-3.10-3-r5k-ip32-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-r5k-ip32 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-ip32 Package: kernel-image-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7286,8 +6391,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: ppp-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7297,8 +6402,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, zlib-modules-3.10-3-4kc-malta-di, crc-modules-3.10-3-4kc-malta-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: cdrom-core-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7308,8 +6413,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, isofs-modules-3.10-3-4kc-malta-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: loop-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7319,8 +6424,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: btrfs-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7330,8 +6435,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, crc-modules-3.10-3-4kc-malta-di, zlib-modules-3.10-3-4kc-malta-di, md-modules-3.10-3-4kc-malta-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: isofs-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7341,8 +6446,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: jfs-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7352,8 +6457,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: xfs-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7363,8 +6468,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, crc-modules-3.10-3-4kc-malta-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: fat-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7374,8 +6479,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: md-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7385,8 +6490,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: multipath-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7396,8 +6501,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, md-modules-3.10-3-4kc-malta-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: usb-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7407,8 +6512,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: usb-storage-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7418,8 +6523,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, usb-modules-3.10-3-4kc-malta-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: input-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7429,8 +6534,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, usb-modules-3.10-3-4kc-malta-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: sata-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7440,8 +6545,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: crc-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7451,8 +6556,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: crypto-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7462,8 +6567,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: crypto-dm-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7473,8 +6578,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, md-modules-3.10-3-4kc-malta-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: nbd-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7485,8 +6590,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: squashfs-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7496,8 +6601,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: virtio-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7507,8 +6612,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: zlib-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7518,8 +6623,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: udf-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7529,8 +6634,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di, crc-modules-3.10-3-4kc-malta-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: fuse-modules-3.10-3-4kc-malta-di Architecture: mips mipsel @@ -7540,8 +6645,8 @@ Depends: kernel-image-3.10-3-4kc-malta-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-4kc-malta -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-4kc-malta Package: linux-image-3.10-3-r4k-ip22 Architecture: mips @@ -7724,8 +6829,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: nic-shared-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7736,8 +6841,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: ppp-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7747,8 +6852,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di, zlib-modules-3.10-3-r5k-cobalt-di, crc-modules-3.10-3-r5k-cobalt-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: loop-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7758,8 +6863,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: btrfs-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7769,8 +6874,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di, crc-modules-3.10-3-r5k-cobalt-di, zlib-modules-3.10-3-r5k-cobalt-di, md-modules-3.10-3-r5k-cobalt-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: jfs-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7780,8 +6885,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: xfs-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7791,8 +6896,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di, crc-modules-3.10-3-r5k-cobalt-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: fat-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7802,8 +6907,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: nfs-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7813,8 +6918,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: NFS filesystem support This package contains the NFS filesystem module for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: md-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7824,8 +6929,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: multipath-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7835,8 +6940,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di, md-modules-3.10-3-r5k-cobalt-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: crc-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7846,8 +6951,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: crypto-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7857,8 +6962,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: crypto-dm-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7868,8 +6973,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di, md-modules-3.10-3-r5k-cobalt-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: nbd-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7880,8 +6985,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: squashfs-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7891,8 +6996,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: zlib-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7902,8 +7007,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: fuse-modules-3.10-3-r5k-cobalt-di Architecture: mipsel @@ -7913,8 +7018,8 @@ Depends: kernel-image-3.10-3-r5k-cobalt-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-r5k-cobalt -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-r5k-cobalt Package: kernel-image-3.10-3-loongson-2f-di Architecture: mipsel @@ -7925,8 +7030,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: nic-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -7937,8 +7042,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: nic-shared-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -7949,8 +7054,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: ppp-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -7960,8 +7065,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, zlib-modules-3.10-3-loongson-2f-di, crc-modules-3.10-3-loongson-2f-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: cdrom-core-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -7971,8 +7076,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, isofs-modules-3.10-3-loongson-2f-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: loop-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -7982,8 +7087,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: btrfs-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -7993,8 +7098,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, crc-modules-3.10-3-loongson-2f-di, zlib-modules-3.10-3-loongson-2f-di, md-modules-3.10-3-loongson-2f-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: isofs-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8004,8 +7109,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: jfs-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8015,8 +7120,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: xfs-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8026,8 +7131,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, crc-modules-3.10-3-loongson-2f-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: fat-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8037,8 +7142,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: md-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8048,8 +7153,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: multipath-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8059,8 +7164,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, md-modules-3.10-3-loongson-2f-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: usb-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8070,8 +7175,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: usb-storage-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8081,8 +7186,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, usb-modules-3.10-3-loongson-2f-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: input-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8092,8 +7197,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, usb-modules-3.10-3-loongson-2f-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: nic-usb-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8103,8 +7208,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, nic-shared-modules-3.10-3-loongson-2f-di, usb-modules-3.10-3-loongson-2f-di, crc-modules-3.10-3-loongson-2f-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: sata-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8114,8 +7219,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: crc-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8125,8 +7230,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: crypto-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8136,8 +7241,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: crypto-dm-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8147,8 +7252,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, md-modules-3.10-3-loongson-2f-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: nbd-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8159,8 +7264,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: squashfs-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8170,8 +7275,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: virtio-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8181,8 +7286,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: zlib-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8192,8 +7297,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: udf-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8203,8 +7308,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di, crc-modules-3.10-3-loongson-2f-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: fuse-modules-3.10-3-loongson-2f-di Architecture: mipsel @@ -8214,8 +7319,8 @@ Depends: kernel-image-3.10-3-loongson-2f-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-loongson-2f -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-loongson-2f Package: linux-image-3.10-3-r5k-cobalt Architecture: mipsel @@ -8281,8 +7386,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: nic-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8293,8 +7398,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: nic-shared-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8305,8 +7410,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: serial-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8316,8 +7421,8 @@ Depends: kernel-image-3.10-3-powerpc-di, pcmcia-modules-3.10-3-powerpc-di Description: Serial drivers This package contains serial drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: usb-serial-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8327,8 +7432,8 @@ Depends: kernel-image-3.10-3-powerpc-di, usb-modules-3.10-3-powerpc-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: ppp-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8338,8 +7443,8 @@ Depends: kernel-image-3.10-3-powerpc-di, serial-modules-3.10-3-powerpc-di, zlib-modules-3.10-3-powerpc-di, crc-modules-3.10-3-powerpc-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: pata-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8349,8 +7454,8 @@ Depends: kernel-image-3.10-3-powerpc-di, ata-modules-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: cdrom-core-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8360,8 +7465,8 @@ Depends: kernel-image-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di, isofs-modules-3.10-3-powerpc-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: firewire-core-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8371,8 +7476,8 @@ Depends: kernel-image-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di, crc-modules-3.10-3-powerpc-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: scsi-core-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8382,8 +7487,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: scsi-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8393,8 +7498,8 @@ Depends: kernel-image-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di, cdrom-core-modules-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di, ata-modules-3.10-3-powerpc-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: scsi-common-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8404,8 +7509,8 @@ Depends: kernel-image-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di, cdrom-core-modules-3.10-3-powerpc-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: scsi-extra-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8416,8 +7521,8 @@ Description: Uncommon SCSI drivers This package contains uncommon SCSI drivers for the kernel. This includes SCSI RAID drivers, and some of the less common SCSI controllers. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: loop-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8427,8 +7532,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: btrfs-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8438,8 +7543,8 @@ Depends: kernel-image-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di, crc-modules-3.10-3-powerpc-di, zlib-modules-3.10-3-powerpc-di, md-modules-3.10-3-powerpc-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: ext2-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8449,8 +7554,8 @@ Depends: kernel-image-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: ext3-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8460,8 +7565,8 @@ Depends: kernel-image-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: ext4-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8471,8 +7576,8 @@ Depends: kernel-image-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di, crc-modules-3.10-3-powerpc-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: isofs-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8482,8 +7587,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: jfs-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8493,8 +7598,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: xfs-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8504,8 +7609,8 @@ Depends: kernel-image-3.10-3-powerpc-di, crc-modules-3.10-3-powerpc-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: fat-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8515,8 +7620,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: hfs-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8526,8 +7631,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: HFS filesystem support This package contains the HFS and HFS+ filesystem modules for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: affs-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8537,8 +7642,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: Amiga filesystem support This package contains the Amiga filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: md-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8548,8 +7653,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: multipath-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8559,8 +7664,8 @@ Depends: kernel-image-3.10-3-powerpc-di, md-modules-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: usb-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8570,8 +7675,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: usb-storage-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8581,8 +7686,8 @@ Depends: kernel-image-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di, usb-modules-3.10-3-powerpc-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: pcmcia-storage-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8592,8 +7697,8 @@ Depends: kernel-image-3.10-3-powerpc-di, cdrom-core-modules-3.10-3-powerpc-di, pcmcia-modules-3.10-3-powerpc-di, ata-modules-3.10-3-powerpc-di Description: PCMCIA storage drivers This package contains PCMCIA storage drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: input-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8603,8 +7708,8 @@ Depends: kernel-image-3.10-3-powerpc-di, usb-modules-3.10-3-powerpc-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: event-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8614,8 +7719,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: mouse-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8625,8 +7730,8 @@ Depends: kernel-image-3.10-3-powerpc-di, event-modules-3.10-3-powerpc-di, input-modules-3.10-3-powerpc-di, usb-modules-3.10-3-powerpc-di Description: Mouse support This package contains mouse drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: nic-pcmcia-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8636,8 +7741,8 @@ Depends: kernel-image-3.10-3-powerpc-di, nic-modules-3.10-3-powerpc-di, nic-shared-modules-3.10-3-powerpc-di, pcmcia-modules-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di Description: Common PCMCIA NIC drivers This package contains common PCMCIA NIC drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: pcmcia-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8647,8 +7752,8 @@ Depends: kernel-image-3.10-3-powerpc-di, core-modules-3.10-3-powerpc-di Description: Common PCMCIA drivers This package contains common PCMCIA drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: sata-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8658,8 +7763,8 @@ Depends: kernel-image-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di, ata-modules-3.10-3-powerpc-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: core-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8670,8 +7775,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: crc-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8681,8 +7786,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: crypto-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8692,8 +7797,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: crypto-dm-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8703,8 +7808,8 @@ Depends: kernel-image-3.10-3-powerpc-di, md-modules-3.10-3-powerpc-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: ata-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8715,8 +7820,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: nbd-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8727,8 +7832,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: squashfs-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8738,8 +7843,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: virtio-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8749,8 +7854,8 @@ Depends: kernel-image-3.10-3-powerpc-di, scsi-core-modules-3.10-3-powerpc-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: uinput-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8760,8 +7865,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: zlib-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8771,8 +7876,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: udf-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8782,8 +7887,8 @@ Depends: kernel-image-3.10-3-powerpc-di, crc-modules-3.10-3-powerpc-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: fuse-modules-3.10-3-powerpc-di Architecture: powerpc @@ -8793,8 +7898,8 @@ Depends: kernel-image-3.10-3-powerpc-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-powerpc -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc Package: kernel-image-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8805,8 +7910,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: nic-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8817,8 +7922,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: nic-shared-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8829,8 +7934,8 @@ Description: Shared NIC drivers This package contains NIC drivers needed by combinations of nic-modules, nic-pcmcia-modules, nic-usb-modules and nic-wireless-modules. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: serial-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8840,8 +7945,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, pcmcia-modules-3.10-3-powerpc64-di Description: Serial drivers This package contains serial drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: usb-serial-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8851,8 +7956,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, usb-modules-3.10-3-powerpc64-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: ppp-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8862,8 +7967,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, serial-modules-3.10-3-powerpc64-di, crc-modules-3.10-3-powerpc64-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: pata-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8873,8 +7978,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, ata-modules-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: cdrom-core-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8884,8 +7989,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di, isofs-modules-3.10-3-powerpc64-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: firewire-core-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8895,8 +8000,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di, crc-modules-3.10-3-powerpc64-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: scsi-core-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8906,8 +8011,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: scsi-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8917,8 +8022,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di, cdrom-core-modules-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di, ata-modules-3.10-3-powerpc64-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: scsi-common-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8928,8 +8033,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di, cdrom-core-modules-3.10-3-powerpc64-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: scsi-extra-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8940,8 +8045,8 @@ Description: Uncommon SCSI drivers This package contains uncommon SCSI drivers for the kernel. This includes SCSI RAID drivers, and some of the less common SCSI controllers. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: loop-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8951,8 +8056,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: btrfs-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8962,8 +8067,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di, crc-modules-3.10-3-powerpc64-di, md-modules-3.10-3-powerpc64-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: ext2-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8973,8 +8078,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: ext3-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8984,8 +8089,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: ext4-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -8995,8 +8100,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di, crc-modules-3.10-3-powerpc64-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: isofs-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9006,8 +8111,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: jfs-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9017,8 +8122,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: xfs-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9028,8 +8133,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, crc-modules-3.10-3-powerpc64-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: fat-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9039,8 +8144,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: hfs-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9050,8 +8155,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: HFS filesystem support This package contains the HFS and HFS+ filesystem modules for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: affs-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9061,8 +8166,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: Amiga filesystem support This package contains the Amiga filesystem module for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: md-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9072,8 +8177,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: multipath-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9083,8 +8188,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, md-modules-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: usb-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9094,8 +8199,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: usb-storage-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9105,8 +8210,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di, usb-modules-3.10-3-powerpc64-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: pcmcia-storage-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9116,8 +8221,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, cdrom-core-modules-3.10-3-powerpc64-di, pcmcia-modules-3.10-3-powerpc64-di, ata-modules-3.10-3-powerpc64-di Description: PCMCIA storage drivers This package contains PCMCIA storage drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: input-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9127,8 +8232,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, usb-modules-3.10-3-powerpc64-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: event-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9138,8 +8243,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: Event support This package contains event drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: mouse-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9149,8 +8254,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, event-modules-3.10-3-powerpc64-di, input-modules-3.10-3-powerpc64-di, usb-modules-3.10-3-powerpc64-di Description: Mouse support This package contains mouse drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: nic-pcmcia-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9160,8 +8265,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, nic-modules-3.10-3-powerpc64-di, nic-shared-modules-3.10-3-powerpc64-di, pcmcia-modules-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di Description: Common PCMCIA NIC drivers This package contains common PCMCIA NIC drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: pcmcia-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9171,8 +8276,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, core-modules-3.10-3-powerpc64-di Description: Common PCMCIA drivers This package contains common PCMCIA drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: sata-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9182,8 +8287,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di, ata-modules-3.10-3-powerpc64-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: core-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9194,8 +8299,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: crc-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9205,8 +8310,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: crypto-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9216,8 +8321,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: crypto-dm-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9227,8 +8332,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, md-modules-3.10-3-powerpc64-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: ata-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9239,8 +8344,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: nbd-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9251,8 +8356,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: squashfs-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9262,8 +8367,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: virtio-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9273,8 +8378,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, scsi-core-modules-3.10-3-powerpc64-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: uinput-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9284,8 +8389,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: uinput support This package contains the uinput module. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: udf-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9295,8 +8400,8 @@ Depends: kernel-image-3.10-3-powerpc64-di, crc-modules-3.10-3-powerpc64-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: fuse-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9306,8 +8411,8 @@ Depends: kernel-image-3.10-3-powerpc64-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: hypervisor-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9318,8 +8423,8 @@ Description: IBM 64bit hypervisor console modules Contains drivers for the hypervisor console, used as console for linux running in logical partitions of IBM hardware supporting it. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: fancontrol-modules-3.10-3-powerpc64-di Architecture: powerpc ppc64 @@ -9331,8 +8436,8 @@ Contains drivers for macintosh i2c bus as well as for the monitoring devices connected to it. This allows to control the fans during installation. -Kernel-Version: 3.10-3-powerpc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-powerpc64 Package: linux-image-3.10-3-powerpc Architecture: powerpc @@ -9461,8 +8566,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: nic-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9473,8 +8578,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: scsi-core-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9484,8 +8589,8 @@ Depends: kernel-image-3.10-3-s390x-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: scsi-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9495,8 +8600,8 @@ Depends: kernel-image-3.10-3-s390x-di, scsi-core-modules-3.10-3-s390x-di, core-modules-3.10-3-s390x-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: ext2-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9506,8 +8611,8 @@ Depends: kernel-image-3.10-3-s390x-di, core-modules-3.10-3-s390x-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: ext3-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9517,8 +8622,8 @@ Depends: kernel-image-3.10-3-s390x-di, core-modules-3.10-3-s390x-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: ext4-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9528,8 +8633,8 @@ Depends: kernel-image-3.10-3-s390x-di, core-modules-3.10-3-s390x-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: xfs-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9539,8 +8644,8 @@ Depends: kernel-image-3.10-3-s390x-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: fat-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9550,8 +8655,8 @@ Depends: kernel-image-3.10-3-s390x-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: md-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9561,8 +8666,8 @@ Depends: kernel-image-3.10-3-s390x-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: multipath-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9572,8 +8677,8 @@ Depends: kernel-image-3.10-3-s390x-di, md-modules-3.10-3-s390x-di, scsi-core-modules-3.10-3-s390x-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: core-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9584,8 +8689,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: crypto-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9595,8 +8700,8 @@ Depends: kernel-image-3.10-3-s390x-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: crypto-dm-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9606,8 +8711,8 @@ Depends: kernel-image-3.10-3-s390x-di, md-modules-3.10-3-s390x-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: nbd-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9618,8 +8723,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: virtio-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9629,8 +8734,8 @@ Depends: kernel-image-3.10-3-s390x-di, scsi-core-modules-3.10-3-s390x-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: fuse-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9640,8 +8745,8 @@ Depends: kernel-image-3.10-3-s390x-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: dasd-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9651,8 +8756,8 @@ Depends: kernel-image-3.10-3-s390x-di Description: dasd modules This package contains dasd modules. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: dasd-extra-modules-3.10-3-s390x-di Architecture: s390 s390x @@ -9664,8 +8769,8 @@ This package contains the module for dasd DIAG support. The udeb is not loaded by default as the installer does not actually support this. It can however be useful to have available in rescue situations. -Kernel-Version: 3.10-3-s390x -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-s390x Package: linux-image-3.10-3-s390x Architecture: s390 s390x @@ -9724,8 +8829,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: nic-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9736,8 +8841,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: usb-serial-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9747,8 +8852,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: ppp-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9758,8 +8863,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, zlib-modules-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: pata-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9769,8 +8874,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: cdrom-core-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9780,8 +8885,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, scsi-core-modules-3.10-3-sh7751r-di, isofs-modules-3.10-3-sh7751r-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: firewire-core-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9791,8 +8896,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, scsi-core-modules-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: scsi-core-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9802,8 +8907,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: loop-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9813,8 +8918,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: btrfs-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9824,8 +8929,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di, zlib-modules-3.10-3-sh7751r-di, md-modules-3.10-3-sh7751r-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: ext2-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9835,8 +8940,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: ext4-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9846,8 +8951,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: isofs-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9857,8 +8962,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: jfs-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9868,8 +8973,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: xfs-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9879,8 +8984,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: fat-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9890,8 +8995,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: minix-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9901,8 +9006,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: Minix filesystem support This package contains the Minix filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: md-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9912,8 +9017,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: multipath-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9923,8 +9028,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, md-modules-3.10-3-sh7751r-di, scsi-core-modules-3.10-3-sh7751r-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: usb-storage-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9934,8 +9039,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, scsi-core-modules-3.10-3-sh7751r-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: nic-usb-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9945,8 +9050,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: sata-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9956,8 +9061,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, scsi-core-modules-3.10-3-sh7751r-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: i2c-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9967,8 +9072,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: i2c support modules This package contains basic i2c support modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: crc-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9978,8 +9083,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: crypto-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -9989,8 +9094,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: crypto-dm-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10000,8 +9105,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, md-modules-3.10-3-sh7751r-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: nbd-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10012,8 +9117,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: squashfs-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10023,8 +9128,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: speakup-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10034,8 +9139,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: speakup modules This package contains speakup modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: virtio-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10045,8 +9150,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, scsi-core-modules-3.10-3-sh7751r-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: sound-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10056,8 +9161,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, i2c-modules-3.10-3-sh7751r-di, firewire-core-modules-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di Description: sound support This package contains sound modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: zlib-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10067,8 +9172,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: udf-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10078,8 +9183,8 @@ Depends: kernel-image-3.10-3-sh7751r-di, crc-modules-3.10-3-sh7751r-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: fuse-modules-3.10-3-sh7751r-di Architecture: sh4 @@ -10089,8 +9194,8 @@ Depends: kernel-image-3.10-3-sh7751r-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-sh7751r -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7751r Package: kernel-image-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10101,8 +9206,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: nic-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10113,8 +9218,8 @@ Description: NIC drivers This package contains Ethernet and some paravirtualised network drivers for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: usb-serial-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10124,8 +9229,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: USB serial drivers This package contains USB serial drivers for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: ppp-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10135,8 +9240,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, zlib-modules-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: pata-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10146,8 +9251,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: cdrom-core-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10157,8 +9262,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, scsi-core-modules-3.10-3-sh7785lcr-di, isofs-modules-3.10-3-sh7785lcr-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: firewire-core-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10168,8 +9273,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, scsi-core-modules-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di Description: Core FireWire drivers This package contains core FireWire drivers for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: scsi-core-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10179,8 +9284,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: loop-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10190,8 +9295,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: Loopback filesystem support This package contains loopback filesystem support for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: btrfs-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10201,8 +9306,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di, zlib-modules-3.10-3-sh7785lcr-di, md-modules-3.10-3-sh7785lcr-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: ext2-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10212,8 +9317,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: ext4-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10223,8 +9328,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: isofs-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10234,8 +9339,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: jfs-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10245,8 +9350,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: xfs-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10256,8 +9361,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: fat-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10267,8 +9372,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: minix-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10278,8 +9383,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: Minix filesystem support This package contains the Minix filesystem module for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: md-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10289,8 +9394,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: multipath-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10300,8 +9405,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, md-modules-3.10-3-sh7785lcr-di, scsi-core-modules-3.10-3-sh7785lcr-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: nic-usb-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10311,8 +9416,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di Description: USB NIC drivers This package contains USB network adapter drivers for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: sata-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10322,8 +9427,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, scsi-core-modules-3.10-3-sh7785lcr-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: crc-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10333,8 +9438,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: crypto-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10344,8 +9449,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: crypto-dm-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10355,8 +9460,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, md-modules-3.10-3-sh7785lcr-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: nbd-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10367,8 +9472,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: squashfs-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10378,8 +9483,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: speakup-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10389,8 +9494,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: speakup modules This package contains speakup modules. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: sound-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10400,8 +9505,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, firewire-core-modules-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di Description: sound support This package contains sound modules. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: zlib-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10411,8 +9516,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: udf-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10422,8 +9527,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di, crc-modules-3.10-3-sh7785lcr-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: fuse-modules-3.10-3-sh7785lcr-di Architecture: sh4 @@ -10433,8 +9538,8 @@ Depends: kernel-image-3.10-3-sh7785lcr-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-sh7785lcr -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sh7785lcr Package: linux-image-3.10-3-sh7751r Architecture: sh4 @@ -10501,8 +9606,8 @@ This package contains the kernel image for the Debian installer boot images. It does _not_ provide a usable kernel for your full Debian system. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: nic-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10517,8 +9622,8 @@ . Do not install this package on a real Debian system! You probably want a kernel-image package instead. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: ppp-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10528,8 +9633,8 @@ Depends: kernel-image-3.10-3-sparc64-di, zlib-modules-3.10-3-sparc64-di, crc-modules-3.10-3-sparc64-di Description: PPP drivers This package contains PPP drivers for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: pata-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10539,8 +9644,8 @@ Depends: kernel-image-3.10-3-sparc64-di, ata-modules-3.10-3-sparc64-di Description: PATA drivers This package contains PATA drivers for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: cdrom-core-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10550,8 +9655,8 @@ Depends: kernel-image-3.10-3-sparc64-di, scsi-core-modules-3.10-3-sparc64-di, isofs-modules-3.10-3-sparc64-di Description: CDROM support This package contains core CDROM support for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: scsi-core-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10561,8 +9666,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: Core SCSI subsystem This package contains the core SCSI subsystem for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: scsi-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10572,8 +9677,8 @@ Depends: kernel-image-3.10-3-sparc64-di, scsi-core-modules-3.10-3-sparc64-di, cdrom-core-modules-3.10-3-sparc64-di, core-modules-3.10-3-sparc64-di, ata-modules-3.10-3-sparc64-di Description: SCSI drivers This package contains SCSI drivers for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: scsi-common-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10583,8 +9688,8 @@ Depends: kernel-image-3.10-3-sparc64-di, scsi-core-modules-3.10-3-sparc64-di, cdrom-core-modules-3.10-3-sparc64-di Description: Very common SCSI drivers This package contains very common SCSI drivers for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: btrfs-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10594,8 +9699,8 @@ Depends: kernel-image-3.10-3-sparc64-di, core-modules-3.10-3-sparc64-di, crc-modules-3.10-3-sparc64-di, zlib-modules-3.10-3-sparc64-di, md-modules-3.10-3-sparc64-di Description: BTRFS filesystem support This package contains the BTRFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: ext2-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10605,8 +9710,8 @@ Depends: kernel-image-3.10-3-sparc64-di, core-modules-3.10-3-sparc64-di Description: EXT2 filesystem support This package contains the EXT2 filesystem module for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: ext3-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10616,8 +9721,8 @@ Depends: kernel-image-3.10-3-sparc64-di, core-modules-3.10-3-sparc64-di Description: EXT3 filesystem support This package contains the EXT3 filesystem module for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: ext4-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10627,8 +9732,8 @@ Depends: kernel-image-3.10-3-sparc64-di, core-modules-3.10-3-sparc64-di, crc-modules-3.10-3-sparc64-di Description: EXT4 filesystem support This package contains the EXT4 filesystem module for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: isofs-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10638,8 +9743,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: ISOFS filesystem support This package contains the ISOFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: jfs-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10649,8 +9754,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: JFS filesystem support This package contains the JFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: xfs-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10660,8 +9765,8 @@ Depends: kernel-image-3.10-3-sparc64-di, crc-modules-3.10-3-sparc64-di Description: XFS filesystem support This package contains the XFS filesystem module for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: fat-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10671,8 +9776,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: FAT filesystem support This package contains the FAT and VFAT filesystem modules for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: md-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10682,8 +9787,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: RAID and LVM support This package contains RAID and LVM modules for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: multipath-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10693,8 +9798,8 @@ Depends: kernel-image-3.10-3-sparc64-di, md-modules-3.10-3-sparc64-di, scsi-core-modules-3.10-3-sparc64-di Description: Multipath support This package contains DM-Multipath modules for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: usb-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10704,8 +9809,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: USB support This package contains core USB drivers for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: usb-storage-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10715,8 +9820,8 @@ Depends: kernel-image-3.10-3-sparc64-di, scsi-core-modules-3.10-3-sparc64-di, usb-modules-3.10-3-sparc64-di Description: USB storage support This package contains the USB storage driver for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: input-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10726,8 +9831,8 @@ Depends: kernel-image-3.10-3-sparc64-di, usb-modules-3.10-3-sparc64-di Description: Input devices support This package contains input device drivers for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: sata-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10737,8 +9842,8 @@ Depends: kernel-image-3.10-3-sparc64-di, scsi-core-modules-3.10-3-sparc64-di, ata-modules-3.10-3-sparc64-di Description: SATA drivers This package contains SATA drivers for the kernel. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: core-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10749,8 +9854,8 @@ Description: Core modules This package contains core modules for the kernel, that will almost always be needed. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: crc-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10760,8 +9865,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: CRC modules This package contains CRC support modules. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: crypto-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10771,8 +9876,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: crypto modules This package contains crypto modules. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: crypto-dm-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10782,8 +9887,8 @@ Depends: kernel-image-3.10-3-sparc64-di, md-modules-3.10-3-sparc64-di Description: devicemapper crypto module This package contains the devicemapper crypto (dm-crypt) module. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: ata-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10794,8 +9899,8 @@ Description: ATA disk modules This package contains core ATA disk modules used by both PATA and SATA disk drivers. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: nbd-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10806,8 +9911,8 @@ Description: Network Block Device modules This package contains the modules required for support of the Network Block Device -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: squashfs-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10817,8 +9922,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: squashfs modules This package contains squashfs modules. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: virtio-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10828,8 +9933,8 @@ Depends: kernel-image-3.10-3-sparc64-di, scsi-core-modules-3.10-3-sparc64-di Description: virtio modules This package contains virtio modules. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: zlib-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10839,8 +9944,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: zlib modules This package contains zlib modules. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: udf-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10850,8 +9955,8 @@ Depends: kernel-image-3.10-3-sparc64-di, crc-modules-3.10-3-sparc64-di Description: UDF modules This package contains the UDF filesystem module. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: fuse-modules-3.10-3-sparc64-di Architecture: sparc sparc64 @@ -10861,8 +9966,8 @@ Depends: kernel-image-3.10-3-sparc64-di Description: FUSE modules This package contains the Filesystem in Userspace (FUSE) module. -Kernel-Version: 3.10-3-sparc64 -Package-Type: udeb +XC-Package-Type: udeb +XB-Kernel-Version: 3.10-3-sparc64 Package: linux-image-3.10-3-sparc64 Architecture: sparc sparc64 diff -Nru linux-3.10.11/debian/control.md5sum linux-3.10-3.10.11/debian/control.md5sum --- linux-3.10.11/debian/control.md5sum 2013-09-10 13:13:31.000000000 +0000 +++ linux-3.10-3.10.11/debian/control.md5sum 2014-05-05 21:50:18.000000000 +0000 @@ -1,5 +1,5 @@ 3e9ea9910531a747f9534a1f59846407 debian/bin/gencontrol.py -aa8fb65df0b8ea8e0c0f8e689d62203c debian/changelog +872aef4da4c97ebf68792e7b54efeea3 debian/changelog d253b8a3cc1ffc2054b1d485facc490a debian/templates/control.headers.arch.in d60e1ee86882c530ea74bfbb684a506e debian/templates/control.headers.featureset.in 3a8040742dfc77adae08116a336e98c3 debian/templates/control.headers.in @@ -15,7 +15,7 @@ 7805244237b17ec0c1e068c364136ee1 debian/config/alpha/defines 4ec8a85fa1b2821b4f3ed529ac912b29 debian/config/amd64/defines 416305ac0017e35ba0365d784c72e074 debian/config/armel/defines -e74dac997472afc09463de5eb4fcfe84 debian/config/armhf/defines +70e9761864c63f600cbc2d408960efe6 debian/config/armhf/defines 366b94d652a66b437eabcd165bcc9610 debian/config/featureset-rt/defines 7663688e373ff5b5857c15e69a7c1d3e debian/config/hppa/defines 86de41b9179ecf6fcca1ecf675cc2175 debian/config/i386/defines @@ -29,8 +29,8 @@ dc714f9f7a1624d1e1b518e60f0a529a debian/config/s390/defines dafb9c298ce03193b334ab168a0824e3 debian/config/s390x/defines 4f654b0507024e4483289a749a17d8cb debian/config/sh4/defines -1c43428cadb9eab47cee4e1efec554ff debian/config/sparc64/defines 7d9b29bf50681e32b95fc148252f0520 debian/config/sparc/defines +1c43428cadb9eab47cee4e1efec554ff debian/config/sparc64/defines f4b2921156e7b1a038862f848fdfe48f debian/config/x32/defines 040c78b69c26232e49b8fa5cbd86129e debian/config/amd64/none/defines 7dc981827930ed6844a731ed954b9b9d debian/config/amd64/rt/defines @@ -38,20 +38,20 @@ 7146ff53fc4f9fbb49948225d8589b69 debian/config/i386/rt/defines 7ecaa8334419297fe6715afadae794c6 debian/installer/amd64/kernel-versions 07c9cbe632c22b1a4d696e305a43dd79 debian/installer/armel/kernel-versions -22abf5e8f80b321f1141566a0afd5c58 debian/installer/armhf/kernel-versions +147116108018adaf3158829a801a395c debian/installer/armhf/kernel-versions fb5fd18c89403e59d2df08c6b261ba87 debian/installer/hppa/kernel-versions 967797430d58c1aeecac819cd6c23bd8 debian/installer/i386/kernel-versions 3003a272236f91494508a5f7e9c9b467 debian/installer/ia64/kernel-versions 8aba4204e5bc4edcfd9790294b8808ec debian/installer/m68k/kernel-versions -44e67e915e0d96d2c7a96db7a56ef9d5 debian/installer/mipsel/kernel-versions 0ef9abd87751a54fd67da5fa7ad15cfe debian/installer/mips/kernel-versions +44e67e915e0d96d2c7a96db7a56ef9d5 debian/installer/mipsel/kernel-versions 42aaaa53f3ecb95030e1a33654db6f8e debian/installer/powerpc/kernel-versions 0cb3424304d9602f321919da020eef8c debian/installer/ppc64/kernel-versions e5cf40c78e83c648c5f14f0531210b07 debian/installer/s390/kernel-versions f8348b90fe2b9e1e75bddda4dbb832c4 debian/installer/s390x/kernel-versions 49f36561dee0396410815d4e92beb01e debian/installer/sh4/kernel-versions -61a070b81f93d4c9e955dc90587702f3 debian/installer/sparc64/kernel-versions 98d2665cd87a45bb5d956bc5c415c928 debian/installer/sparc/kernel-versions +61a070b81f93d4c9e955dc90587702f3 debian/installer/sparc64/kernel-versions 7d5cb8a10076491fbcf136b5f548dcb4 debian/installer/amd64/package-list 42fba89c75a5028a203bb80b5d274fcd debian/installer/armel/package-list 165eedcd9ae7bd6e545589422fabc773 debian/installer/armhf/package-list @@ -59,13 +59,13 @@ 42b43a38e9deb951968a87f1fef3e60b debian/installer/i386/package-list c3a84196d56d3a4247bdc0aaac4e7908 debian/installer/ia64/package-list ef7ef282db90dad652dcdf5e96c0a107 debian/installer/m68k/package-list -53b5d0c9fad2263b374e0c26d7ba99e5 debian/installer/mipsel/package-list 848a9b53a08ff2575ecb4b41e3c1d92f debian/installer/mips/package-list +53b5d0c9fad2263b374e0c26d7ba99e5 debian/installer/mipsel/package-list 8b7d23c8cd92a63434be9319b47d23e9 debian/installer/powerpc/package-list 8b7d23c8cd92a63434be9319b47d23e9 debian/installer/ppc64/package-list 4c1bf26b971d89864682040568fa388e debian/installer/s390/package-list 4c1bf26b971d89864682040568fa388e debian/installer/s390x/package-list 71aedaa083596572b15f780a27343723 debian/installer/sh4/package-list -b9df39e550a637012ccd5b1ddaa4b74a debian/installer/sparc64/package-list b9df39e550a637012ccd5b1ddaa4b74a debian/installer/sparc/package-list +b9df39e550a637012ccd5b1ddaa4b74a debian/installer/sparc64/package-list f61a2bc61a6cba3e8a4141f374fa33ab debian/installer/package-list diff -Nru linux-3.10.11/debian/dummy.patch linux-3.10-3.10.11/debian/dummy.patch --- linux-3.10.11/debian/dummy.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/dummy.patch 2013-12-23 07:40:09.000000000 +0000 @@ -0,0 +1,5 @@ +diff -urN test1/999-dummy.txt test2/999-dummy.txt +--- test1/999-dummy.txt 1970-01-01 00:00:00.000000000 +0000 ++++ test2/999-dummy.txt 2013-07-20 14:46:08.000000000 +0000 +@@ -0,0 +1 @@ ++This is a dummy file to make sure rpi_999_other_changes.patch is not empty as empty patches confuse quilt. diff -Nru linux-3.10.11/debian/installer/armhf/kernel-versions linux-3.10-3.10.11/debian/installer/armhf/kernel-versions --- linux-3.10.11/debian/installer/armhf/kernel-versions 2013-09-07 21:48:51.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/kernel-versions 2013-12-27 14:03:32.000000000 +0000 @@ -1,4 +1,2 @@ # arch version flavour installedname suffix build-depends -armhf - armmp - y - -armhf - mx5 - y - -armhf - vexpress - y - +armhf - rpi - y - diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/btrfs-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/btrfs-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/btrfs-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/btrfs-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/crc-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/crc-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/crc-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/crc-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-dm-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-dm-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-dm-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-dm-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/crypto-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext2-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext2-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext2-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext2-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext3-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext3-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext3-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/ext3-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/fuse-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/fuse-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/fuse-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/fuse-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/input-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/input-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/input-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/input-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1,4 @@ +#include +usbhid - +usbmouse - +usbkbd - diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/isofs-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/isofs-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/isofs-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/isofs-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/jfs-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/jfs-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/jfs-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/jfs-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/kernel-image linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/kernel-image --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/kernel-image 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/kernel-image 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +# empty diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/loop-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/loop-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/loop-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/loop-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/md-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/md-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/md-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/md-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/minix-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/minix-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/minix-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/minix-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/multipath-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/multipath-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/multipath-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/multipath-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/nbd-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/nbd-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/nbd-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/nbd-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/nic-usb-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/nic-usb-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/nic-usb-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/nic-usb-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/reiserfs-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/reiserfs-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/reiserfs-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/reiserfs-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/scsi-core-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/scsi-core-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/scsi-core-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/scsi-core-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1,3 @@ +#include +scsi_mod - +sd_mod - diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/squashfs-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/squashfs-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/squashfs-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/squashfs-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/udf-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/udf-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/udf-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/udf-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/uinput-modules linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/uinput-modules --- linux-3.10.11/debian/installer/armhf/modules/armhf-rpi/uinput-modules 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/installer/armhf/modules/armhf-rpi/uinput-modules 2013-12-23 01:34:43.000000000 +0000 @@ -0,0 +1 @@ +#include diff -Nru linux-3.10.11/debian/patches/bugfix/all/alx-fix-100mbit-half-duplex-speed-translation.patch linux-3.10-3.10.11/debian/patches/bugfix/all/alx-fix-100mbit-half-duplex-speed-translation.patch --- linux-3.10.11/debian/patches/bugfix/all/alx-fix-100mbit-half-duplex-speed-translation.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/alx-fix-100mbit-half-duplex-speed-translation.patch 2014-05-05 12:42:53.000000000 +0000 @@ -12,11 +12,11 @@ drivers/net/ethernet/atheros/alx/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/net/ethernet/atheros/alx/hw.c b/drivers/net/ethernet/atheros/alx/hw.c -index 220a16a..dc71cfb 100644 ---- a/drivers/net/ethernet/atheros/alx/hw.c -+++ b/drivers/net/ethernet/atheros/alx/hw.c -@@ -1134,7 +1134,7 @@ static inline u32 alx_speed_to_ethadv(int speed) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 11:52:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 12:42:52.000000000 +0000 +@@ -1134,7 +1134,7 @@ case SPEED_100 + DUPLEX_FULL: return ADVERTISED_100baseT_Full; case SPEED_100 + DUPLEX_HALF: diff -Nru linux-3.10.11/debian/patches/bugfix/all/alx-fix-ethtool-support-code.patch linux-3.10-3.10.11/debian/patches/bugfix/all/alx-fix-ethtool-support-code.patch --- linux-3.10.11/debian/patches/bugfix/all/alx-fix-ethtool-support-code.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/alx-fix-ethtool-support-code.patch 2014-05-05 12:42:56.000000000 +0000 @@ -14,10 +14,10 @@ drivers/net/ethernet/atheros/alx/ethtool.c | 64 ++++++++++++++---------------- 1 file changed, 29 insertions(+), 35 deletions(-) -diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c -index 5e19e08..9261006 100644 ---- a/drivers/net/ethernet/atheros/alx/ethtool.c -+++ b/drivers/net/ethernet/atheros/alx/ethtool.c +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 12:42:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 12:42:56.000000000 +0000 @@ -46,21 +46,37 @@ #include "reg.h" #include "hw.h" @@ -62,7 +62,7 @@ ecmd->advertising = ADVERTISED_TP; if (hw->adv_cfg & ADVERTISED_Autoneg) -@@ -68,6 +84,7 @@ static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +@@ -68,6 +84,7 @@ ecmd->port = PORT_TP; ecmd->phy_address = 0; @@ -70,7 +70,7 @@ if (hw->adv_cfg & ADVERTISED_Autoneg) ecmd->autoneg = AUTONEG_ENABLE; else -@@ -100,7 +117,7 @@ static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +@@ -100,7 +117,7 @@ ASSERT_RTNL(); if (ecmd->autoneg == AUTONEG_ENABLE) { @@ -79,7 +79,7 @@ return -EINVAL; adv_cfg = ecmd->advertising | ADVERTISED_Autoneg; } else { -@@ -121,21 +138,10 @@ static void alx_get_pauseparam(struct net_device *netdev, +@@ -121,21 +138,10 @@ struct alx_priv *alx = netdev_priv(netdev); struct alx_hw *hw = &alx->hw; @@ -105,7 +105,7 @@ } -@@ -214,8 +220,7 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +@@ -214,8 +220,7 @@ struct alx_priv *alx = netdev_priv(netdev); struct alx_hw *hw = &alx->hw; @@ -115,7 +115,7 @@ return -EOPNOTSUPP; hw->sleep_ctrl = 0; -@@ -230,22 +235,11 @@ static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +@@ -230,22 +235,11 @@ return 0; } diff -Nru linux-3.10.11/debian/patches/bugfix/all/alx-fix-MAC-address-alignment-problem.patch linux-3.10-3.10.11/debian/patches/bugfix/all/alx-fix-MAC-address-alignment-problem.patch --- linux-3.10.11/debian/patches/bugfix/all/alx-fix-MAC-address-alignment-problem.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/alx-fix-MAC-address-alignment-problem.patch 2014-05-05 12:42:56.000000000 +0000 @@ -14,11 +14,11 @@ drivers/net/ethernet/atheros/alx/hw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) -diff --git a/drivers/net/ethernet/atheros/alx/hw.c b/drivers/net/ethernet/atheros/alx/hw.c -index aed48a7..ea99e5d 100644 ---- a/drivers/net/ethernet/atheros/alx/hw.c -+++ b/drivers/net/ethernet/atheros/alx/hw.c -@@ -282,8 +282,8 @@ static bool alx_read_macaddr(struct alx_hw *hw, u8 *addr) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 12:42:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 12:42:55.000000000 +0000 +@@ -282,8 +282,8 @@ mac1 = alx_read_mem32(hw, ALX_STAD1); /* addr should be big-endian */ @@ -29,7 +29,7 @@ return is_valid_ether_addr(addr); } -@@ -326,9 +326,9 @@ void alx_set_macaddr(struct alx_hw *hw, const u8 *addr) +@@ -326,9 +326,9 @@ u32 val; /* for example: 00-0B-6A-F6-00-DC * STAD0=6AF600DC, STAD1=000B */ diff -Nru linux-3.10.11/debian/patches/bugfix/all/alx-make-sizes-unsigned.patch linux-3.10-3.10.11/debian/patches/bugfix/all/alx-make-sizes-unsigned.patch --- linux-3.10.11/debian/patches/bugfix/all/alx-make-sizes-unsigned.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/alx-make-sizes-unsigned.patch 2014-05-05 12:42:54.000000000 +0000 @@ -12,11 +12,11 @@ drivers/net/ethernet/atheros/alx/alx.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) -diff --git a/drivers/net/ethernet/atheros/alx/alx.h b/drivers/net/ethernet/atheros/alx/alx.h -index 50b3ae2..d71103d 100644 ---- a/drivers/net/ethernet/atheros/alx/alx.h -+++ b/drivers/net/ethernet/atheros/alx/alx.h -@@ -85,16 +85,16 @@ struct alx_priv { +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/alx.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/alx.h 2014-05-05 11:52:08.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/alx.h 2014-05-05 12:42:53.000000000 +0000 +@@ -85,16 +85,16 @@ struct { dma_addr_t dma; void *virt; diff -Nru linux-3.10.11/debian/patches/bugfix/all/alx-remove-WoL-support.patch linux-3.10-3.10.11/debian/patches/bugfix/all/alx-remove-WoL-support.patch --- linux-3.10.11/debian/patches/bugfix/all/alx-remove-WoL-support.patch 2013-07-15 01:38:16.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/alx-remove-WoL-support.patch 2014-05-05 12:42:57.000000000 +0000 @@ -16,11 +16,11 @@ drivers/net/ethernet/atheros/alx/main.c | 142 +++----------------------- 4 files changed, 15 insertions(+), 323 deletions(-) -diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c -index 9261006..45b3650 100644 ---- a/drivers/net/ethernet/atheros/alx/ethtool.c -+++ b/drivers/net/ethernet/atheros/alx/ethtool.c -@@ -201,40 +201,6 @@ static void alx_set_msglevel(struct net_device *netdev, u32 data) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 12:42:56.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 12:42:56.000000000 +0000 +@@ -201,40 +201,6 @@ alx->msg_enable = data; } @@ -61,7 +61,7 @@ const struct ethtool_ops alx_ethtool_ops = { .get_settings = alx_get_settings, .set_settings = alx_set_settings, -@@ -242,7 +208,5 @@ const struct ethtool_ops alx_ethtool_ops = { +@@ -242,7 +208,5 @@ .set_pauseparam = alx_set_pauseparam, .get_msglevel = alx_get_msglevel, .set_msglevel = alx_set_msglevel, @@ -69,11 +69,11 @@ - .set_wol = alx_set_wol, .get_link = ethtool_op_get_link, }; -diff --git a/drivers/net/ethernet/atheros/alx/hw.c b/drivers/net/ethernet/atheros/alx/hw.c -index ea99e5d..1e8c24a 100644 ---- a/drivers/net/ethernet/atheros/alx/hw.c -+++ b/drivers/net/ethernet/atheros/alx/hw.c -@@ -332,16 +332,6 @@ void alx_set_macaddr(struct alx_hw *hw, const u8 *addr) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 12:42:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 12:42:56.000000000 +0000 +@@ -332,16 +332,6 @@ alx_write_mem32(hw, ALX_STAD1, val); } @@ -90,7 +90,7 @@ static void alx_reset_osc(struct alx_hw *hw, u8 rev) { u32 val, val2; -@@ -858,66 +848,6 @@ void alx_post_phy_link(struct alx_hw *hw) +@@ -858,66 +848,6 @@ } } @@ -157,7 +157,7 @@ bool alx_phy_configured(struct alx_hw *hw) { u32 cfg, hw_cfg; -@@ -990,26 +920,6 @@ int alx_clear_phy_intr(struct alx_hw *hw) +@@ -990,26 +920,6 @@ return alx_read_phy_reg(hw, ALX_MII_ISR, &isr); } @@ -184,7 +184,7 @@ void alx_disable_rss(struct alx_hw *hw) { u32 ctrl = alx_read_mem32(hw, ALX_RXQ0); -@@ -1121,71 +1031,6 @@ void alx_configure_basic(struct alx_hw *hw) +@@ -1121,71 +1031,6 @@ alx_write_mem32(hw, ALX_WRR, val); } @@ -256,11 +256,11 @@ bool alx_get_phy_info(struct alx_hw *hw) { u16 devs1, devs2; -diff --git a/drivers/net/ethernet/atheros/alx/hw.h b/drivers/net/ethernet/atheros/alx/hw.h -index a60e35c..96f3b43 100644 ---- a/drivers/net/ethernet/atheros/alx/hw.h -+++ b/drivers/net/ethernet/atheros/alx/hw.h -@@ -418,8 +418,6 @@ struct alx_hw { +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/hw.h 2014-05-05 12:42:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.h 2014-05-05 12:42:56.000000000 +0000 +@@ -418,8 +418,6 @@ u8 flowctrl; u32 adv_cfg; @@ -269,7 +269,7 @@ spinlock_t mdio_lock; struct mdio_if_info mdio; u16 phy_id[2]; -@@ -479,14 +477,12 @@ void alx_reset_pcie(struct alx_hw *hw); +@@ -479,14 +477,12 @@ void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en); int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl); void alx_post_phy_link(struct alx_hw *hw); @@ -284,7 +284,7 @@ void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc); void alx_start_mac(struct alx_hw *hw); int alx_reset_mac(struct alx_hw *hw); -@@ -494,7 +490,6 @@ void alx_set_macaddr(struct alx_hw *hw, const u8 *addr); +@@ -494,7 +490,6 @@ bool alx_phy_configured(struct alx_hw *hw); void alx_configure_basic(struct alx_hw *hw); void alx_disable_rss(struct alx_hw *hw); @@ -292,11 +292,11 @@ bool alx_get_phy_info(struct alx_hw *hw); static inline u32 alx_speed_to_ethadv(int speed, u8 duplex) -diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c -index 148b4b9..0e0b242 100644 ---- a/drivers/net/ethernet/atheros/alx/main.c -+++ b/drivers/net/ethernet/atheros/alx/main.c -@@ -706,7 +706,6 @@ static int alx_init_sw(struct alx_priv *alx) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/main.c 2014-05-05 12:42:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/main.c 2014-05-05 12:42:56.000000000 +0000 +@@ -706,7 +706,6 @@ alx->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8); alx->tx_ringsz = 256; alx->rx_ringsz = 512; @@ -304,7 +304,7 @@ hw->imt = 200; alx->int_mask = ALX_ISR_MISC; hw->dma_chnl = hw->max_dma_chnl; -@@ -961,66 +960,6 @@ static int alx_stop(struct net_device *netdev) +@@ -961,66 +960,6 @@ return 0; } @@ -371,7 +371,7 @@ static void alx_link_check(struct work_struct *work) { struct alx_priv *alx; -@@ -1399,8 +1338,6 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +@@ -1398,8 +1337,6 @@ goto out_unmap; } @@ -380,7 +380,7 @@ netdev_info(netdev, "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n", netdev->dev_addr); -@@ -1445,22 +1382,12 @@ static void alx_remove(struct pci_dev *pdev) +@@ -1444,22 +1381,12 @@ static int alx_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); @@ -408,7 +408,7 @@ return 0; } -@@ -1468,49 +1395,20 @@ static int alx_resume(struct device *dev) +@@ -1467,49 +1394,20 @@ { struct pci_dev *pdev = to_pci_dev(dev); struct alx_priv *alx = pci_get_drvdata(pdev); @@ -468,7 +468,7 @@ static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { -@@ -1553,8 +1451,6 @@ static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev) +@@ -1552,8 +1450,6 @@ } pci_set_master(pdev); @@ -477,7 +477,7 @@ alx_reset_pcie(hw); if (!alx_reset_mac(hw)) -@@ -1590,13 +1486,6 @@ static const struct pci_error_handlers alx_err_handlers = { +@@ -1589,13 +1485,6 @@ .resume = alx_pci_error_resume, }; @@ -491,7 +491,7 @@ static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = { { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8161), .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, -@@ -1614,7 +1503,6 @@ static struct pci_driver alx_driver = { +@@ -1613,7 +1502,6 @@ .id_table = alx_pci_tbl, .probe = alx_probe, .remove = alx_remove, diff -Nru linux-3.10.11/debian/patches/bugfix/all/alx-separate-link-speed-duplex-fields.patch linux-3.10-3.10.11/debian/patches/bugfix/all/alx-separate-link-speed-duplex-fields.patch --- linux-3.10.11/debian/patches/bugfix/all/alx-separate-link-speed-duplex-fields.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/alx-separate-link-speed-duplex-fields.patch 2014-05-05 12:42:55.000000000 +0000 @@ -16,11 +16,11 @@ drivers/net/ethernet/atheros/alx/main.c | 37 ++++---- 4 files changed, 106 insertions(+), 125 deletions(-) -diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c -index 50a91d0..5e19e08 100644 ---- a/drivers/net/ethernet/atheros/alx/ethtool.c -+++ b/drivers/net/ethernet/atheros/alx/ethtool.c -@@ -85,14 +85,8 @@ static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 12:42:52.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 12:42:54.000000000 +0000 +@@ -85,14 +85,8 @@ } } @@ -37,12 +37,14 @@ return 0; } -@@ -110,24 +104,11 @@ static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +@@ -110,24 +104,11 @@ return -EINVAL; adv_cfg = ecmd->advertising | ADVERTISED_Autoneg; } else { - int speed = ethtool_cmd_speed(ecmd); -- ++ adv_cfg = alx_speed_to_ethadv(ethtool_cmd_speed(ecmd), ++ ecmd->duplex); + - switch (speed + ecmd->duplex) { - case SPEED_10 + DUPLEX_HALF: - adv_cfg = ADVERTISED_10baseT_Half; @@ -57,20 +59,17 @@ - adv_cfg = ADVERTISED_100baseT_Full; - break; - default: -+ adv_cfg = alx_speed_to_ethadv(ethtool_cmd_speed(ecmd), -+ ecmd->duplex); -+ + if (!adv_cfg || adv_cfg == ADVERTISED_1000baseT_Full) return -EINVAL; - } } hw->adv_cfg = adv_cfg; -diff --git a/drivers/net/ethernet/atheros/alx/hw.c b/drivers/net/ethernet/atheros/alx/hw.c -index dc71cfb..aed48a7 100644 ---- a/drivers/net/ethernet/atheros/alx/hw.c -+++ b/drivers/net/ethernet/atheros/alx/hw.c -@@ -624,12 +624,12 @@ void alx_start_mac(struct alx_hw *hw) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 12:42:52.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.c 2014-05-05 12:42:54.000000000 +0000 +@@ -624,12 +624,12 @@ alx_write_mem32(hw, ALX_TXQ0, txq | ALX_TXQ0_EN); mac = hw->rx_ctrl; @@ -85,7 +84,7 @@ ALX_MAC_CTRL_SPEED_10_100); mac |= ALX_MAC_CTRL_TX_EN | ALX_MAC_CTRL_RX_EN; hw->rx_ctrl = mac; -@@ -790,28 +790,22 @@ void alx_post_phy_link(struct alx_hw *hw) +@@ -790,28 +790,22 @@ u16 phy_val, len, agc; u8 revid = alx_hw_revision(hw); bool adj_th = revid == ALX_REV_B0; @@ -117,7 +116,7 @@ (len > ALX_CLDCTRL6_CAB_LEN_SHORT100M || (len == 0 && agc > ALX_AGC_LONG100M_LIMT)))) { alx_write_phy_dbg(hw, ALX_MIIDBG_AZ_ANADECT, -@@ -831,10 +825,10 @@ void alx_post_phy_link(struct alx_hw *hw) +@@ -831,10 +825,10 @@ /* threshold adjust */ if (adj_th && hw->lnk_patch) { @@ -130,7 +129,7 @@ /* * Giga link threshold, raise the tolerance of * noise 50% -@@ -869,7 +863,7 @@ void alx_post_phy_link(struct alx_hw *hw) +@@ -869,7 +863,7 @@ * 1. phy link must be established before calling this function * 2. wol option (pattern,magic,link,etc.) is configed before call it. */ @@ -139,7 +138,7 @@ { u32 master, mac, phy, val; int err = 0; -@@ -897,9 +891,9 @@ int alx_pre_suspend(struct alx_hw *hw, int speed) +@@ -897,9 +891,9 @@ mac |= ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_BRD_EN; if (hw->sleep_ctrl & ALX_SLEEP_CIFS) mac |= ALX_MAC_CTRL_TX_EN; @@ -151,7 +150,7 @@ ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, ALX_MAC_CTRL_SPEED_1000); phy |= ALX_PHY_CTRL_DSPRST_OUT; -@@ -938,7 +932,7 @@ bool alx_phy_configured(struct alx_hw *hw) +@@ -938,7 +932,7 @@ return cfg == hw_cfg; } @@ -160,7 +159,7 @@ { struct pci_dev *pdev = hw->pdev; u16 bmsr, giga; -@@ -953,7 +947,8 @@ int alx_get_phy_link(struct alx_hw *hw, int *speed) +@@ -953,7 +947,8 @@ return err; if (!(bmsr & BMSR_LSTATUS)) { @@ -170,7 +169,7 @@ return 0; } -@@ -967,20 +962,20 @@ int alx_get_phy_link(struct alx_hw *hw, int *speed) +@@ -967,20 +962,20 @@ switch (giga & ALX_GIGA_PSSR_SPEED) { case ALX_GIGA_PSSR_1000MBS: @@ -196,7 +195,7 @@ wrong_speed: dev_err(&pdev->dev, "invalid PHY speed/duplex: 0x%x\n", giga); -@@ -1126,81 +1121,67 @@ void alx_configure_basic(struct alx_hw *hw) +@@ -1126,81 +1121,67 @@ alx_write_mem32(hw, ALX_WRR, val); } @@ -256,18 +255,6 @@ - *speed = SPEED_100 + DUPLEX_FULL; - else - *speed = SPEED_100 + DUPLEX_HALF; -- -- if (*speed != spd) { -- err = alx_write_phy_reg(hw, ALX_MII_IER, 0); -- if (err) -- return err; -- err = alx_setup_speed_duplex(hw, -- alx_speed_to_ethadv(*speed) | -- ADVERTISED_Autoneg, -- ALX_FC_ANEG | ALX_FC_RX | -- ALX_FC_TX); -- if (err) -- return err; + if (lpa & LPA_10FULL) { + *speed = SPEED_10; + *duplex = DUPLEX_FULL; @@ -282,9 +269,17 @@ + *duplex = DUPLEX_HALF; + } -- /* wait for linkup */ -- for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) { -- int speed2; +- if (*speed != spd) { +- err = alx_write_phy_reg(hw, ALX_MII_IER, 0); +- if (err) +- return err; +- err = alx_setup_speed_duplex(hw, +- alx_speed_to_ethadv(*speed) | +- ADVERTISED_Autoneg, +- ALX_FC_ANEG | ALX_FC_RX | +- ALX_FC_TX); +- if (err) +- return err; + if (*speed == hw->link_speed && *duplex == hw->duplex) + return 0; + err = alx_write_phy_reg(hw, ALX_MII_IER, 0); @@ -296,11 +291,12 @@ + if (err) + return err; +- /* wait for linkup */ +- for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) { +- int speed2; +- - msleep(100); -+ /* wait for linkup */ -+ for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) { -+ msleep(100); - +- - err = alx_get_phy_link(hw, &speed2); - if (err < 0) - return err; @@ -309,6 +305,10 @@ - } - if (i == ALX_MAX_SETUP_LNK_CYCLE) - return -ETIMEDOUT; ++ /* wait for linkup */ ++ for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) { ++ msleep(100); ++ + err = alx_read_phy_link(hw); + if (err < 0) + return err; @@ -320,11 +320,11 @@ return 0; } -diff --git a/drivers/net/ethernet/atheros/alx/hw.h b/drivers/net/ethernet/atheros/alx/hw.h -index 65e723d..a60e35c 100644 ---- a/drivers/net/ethernet/atheros/alx/hw.h -+++ b/drivers/net/ethernet/atheros/alx/hw.h -@@ -412,10 +412,11 @@ struct alx_hw { +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/hw.h 2014-05-05 11:52:08.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/hw.h 2014-05-05 12:42:54.000000000 +0000 +@@ -412,10 +412,11 @@ u32 smb_timer; /* SPEED_* + DUPLEX_*, SPEED_UNKNOWN if link is down */ int link_speed; @@ -337,7 +337,7 @@ u32 sleep_ctrl; -@@ -478,12 +479,12 @@ void alx_reset_pcie(struct alx_hw *hw); +@@ -478,12 +479,12 @@ void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en); int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl); void alx_post_phy_link(struct alx_hw *hw); @@ -352,7 +352,7 @@ int alx_clear_phy_intr(struct alx_hw *hw); int alx_config_wol(struct alx_hw *hw); void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc); -@@ -493,7 +494,22 @@ void alx_set_macaddr(struct alx_hw *hw, const u8 *addr); +@@ -493,7 +494,22 @@ bool alx_phy_configured(struct alx_hw *hw); void alx_configure_basic(struct alx_hw *hw); void alx_disable_rss(struct alx_hw *hw); @@ -376,11 +376,11 @@ +} + #endif -diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c -index 418de8b..148b4b9 100644 ---- a/drivers/net/ethernet/atheros/alx/main.c -+++ b/drivers/net/ethernet/atheros/alx/main.c -@@ -712,6 +712,7 @@ static int alx_init_sw(struct alx_priv *alx) +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/main.c 2014-05-05 11:52:08.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/main.c 2014-05-05 12:42:54.000000000 +0000 +@@ -712,6 +712,7 @@ hw->dma_chnl = hw->max_dma_chnl; hw->ith_tpd = alx->tx_ringsz / 3; hw->link_speed = SPEED_UNKNOWN; @@ -388,7 +388,7 @@ hw->adv_cfg = ADVERTISED_Autoneg | ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | -@@ -758,6 +759,7 @@ static void alx_halt(struct alx_priv *alx) +@@ -758,6 +759,7 @@ alx_netif_stop(alx); hw->link_speed = SPEED_UNKNOWN; @@ -396,7 +396,7 @@ alx_reset_mac(hw); -@@ -869,18 +871,18 @@ static void __alx_stop(struct alx_priv *alx) +@@ -869,18 +871,18 @@ alx_free_rings(alx); } @@ -422,7 +422,7 @@ return "10 Mbps Half"; default: return "Unknown speed"; -@@ -891,7 +893,8 @@ static void alx_check_link(struct alx_priv *alx) +@@ -891,7 +893,8 @@ { struct alx_hw *hw = &alx->hw; unsigned long flags; @@ -432,7 +432,7 @@ int err; /* clear PHY internal interrupt status, otherwise the main -@@ -899,7 +902,9 @@ static void alx_check_link(struct alx_priv *alx) +@@ -899,7 +902,9 @@ */ alx_clear_phy_intr(hw); @@ -443,7 +443,7 @@ if (err < 0) goto reset; -@@ -908,15 +913,12 @@ static void alx_check_link(struct alx_priv *alx) +@@ -908,15 +913,12 @@ alx_write_mem32(hw, ALX_IMR, alx->int_mask); spin_unlock_irqrestore(&alx->irq_lock, flags); @@ -462,7 +462,7 @@ alx_post_phy_link(hw); alx_enable_aspm(hw, true, true); alx_start_mac(hw); -@@ -965,6 +967,7 @@ static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en) +@@ -965,6 +967,7 @@ struct net_device *netdev = alx->dev; struct alx_hw *hw = &alx->hw; int err, speed; @@ -470,7 +470,7 @@ netif_device_detach(netdev); -@@ -977,13 +980,13 @@ static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en) +@@ -977,13 +980,13 @@ return err; #endif diff -Nru linux-3.10.11/debian/patches/bugfix/all/alx-treat-flow-control-correctly-in-alx_set_pausepar.patch linux-3.10-3.10.11/debian/patches/bugfix/all/alx-treat-flow-control-correctly-in-alx_set_pausepar.patch --- linux-3.10.11/debian/patches/bugfix/all/alx-treat-flow-control-correctly-in-alx_set_pausepar.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/alx-treat-flow-control-correctly-in-alx_set_pausepar.patch 2014-05-05 12:42:52.000000000 +0000 @@ -17,11 +17,11 @@ drivers/net/ethernet/atheros/alx/ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c -index 6fa2aec..50a91d0 100644 ---- a/drivers/net/ethernet/atheros/alx/ethtool.c -+++ b/drivers/net/ethernet/atheros/alx/ethtool.c -@@ -187,7 +187,8 @@ static int alx_set_pauseparam(struct net_device *netdev, +Index: linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 11:52:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/atheros/alx/ethtool.c 2014-05-05 12:42:52.000000000 +0000 +@@ -187,7 +187,8 @@ if (reconfig_phy) { err = alx_setup_speed_duplex(hw, hw->adv_cfg, fc); diff -Nru linux-3.10.11/debian/patches/bugfix/all/ath6kl-do-not-use-virt_addr_valid.patch linux-3.10-3.10.11/debian/patches/bugfix/all/ath6kl-do-not-use-virt_addr_valid.patch --- linux-3.10.11/debian/patches/bugfix/all/ath6kl-do-not-use-virt_addr_valid.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/ath6kl-do-not-use-virt_addr_valid.patch 2014-05-05 12:42:34.000000000 +0000 @@ -16,9 +16,11 @@ a heap-allocated buffer and it's the one case where the performance benefit of DMA matters. ---- a/drivers/net/wireless/ath/ath6kl/sdio.c -+++ b/drivers/net/wireless/ath/ath6kl/sdio.c -@@ -79,17 +79,6 @@ static inline struct ath6kl_sdio *ath6kl +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/ath6kl/sdio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/ath6kl/sdio.c 2014-05-05 11:52:16.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/ath6kl/sdio.c 2014-05-05 12:42:34.000000000 +0000 +@@ -80,17 +80,6 @@ return ar->hif_priv; } @@ -36,7 +38,7 @@ static void ath6kl_sdio_set_mbox_info(struct ath6kl *ar) { struct ath6kl_mbox_info *mbox_info = &ar->mbox_info; -@@ -394,8 +383,8 @@ static int ath6kl_sdio_alloc_prep_scat_r +@@ -404,8 +393,8 @@ return 0; } @@ -47,7 +49,7 @@ { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); u8 *tbuf = NULL; -@@ -405,7 +394,10 @@ static int ath6kl_sdio_read_write_sync(s +@@ -415,7 +404,10 @@ if (request & HIF_BLOCK_BASIS) len = round_down(len, HIF_MBOX_BLOCK_SIZE); @@ -59,7 +61,7 @@ if (!ar_sdio->dma_buffer) return -ENOMEM; mutex_lock(&ar_sdio->dma_buffer_mutex); -@@ -428,6 +420,13 @@ static int ath6kl_sdio_read_write_sync(s +@@ -438,6 +430,13 @@ return ret; } @@ -73,7 +75,7 @@ static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio, struct bus_request *req) { -@@ -437,9 +436,9 @@ static void __ath6kl_sdio_write_async(st +@@ -447,9 +446,9 @@ void *context; int status; diff -Nru linux-3.10.11/debian/patches/bugfix/all/cassini-Make-missing-firmware-non-fatal.patch linux-3.10-3.10.11/debian/patches/bugfix/all/cassini-Make-missing-firmware-non-fatal.patch --- linux-3.10.11/debian/patches/bugfix/all/cassini-Make-missing-firmware-non-fatal.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/cassini-Make-missing-firmware-non-fatal.patch 2014-05-05 12:41:37.000000000 +0000 @@ -16,11 +16,11 @@ drivers/net/ethernet/sun/cassini.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) -diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c -index 4c682a3..759441b 100644 ---- a/drivers/net/ethernet/sun/cassini.c -+++ b/drivers/net/ethernet/sun/cassini.c -@@ -808,44 +808,43 @@ static int cas_reset_mii_phy(struct cas *cp) +Index: linux-3.10-3.10.11/drivers/net/ethernet/sun/cassini.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/sun/cassini.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/sun/cassini.c 2014-05-05 12:41:37.000000000 +0000 +@@ -808,44 +808,43 @@ return limit <= 0; } @@ -72,7 +72,7 @@ cas_phy_powerdown(cp); /* expanded memory access mode */ -@@ -5083,8 +5082,7 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +@@ -5083,8 +5082,7 @@ if (cas_check_invariants(cp)) goto err_out_iounmap; if (cp->cas_flags & CAS_FLAG_SATURN) diff -Nru linux-3.10.11/debian/patches/bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch linux-3.10-3.10.11/debian/patches/bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch --- linux-3.10.11/debian/patches/bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch 2014-05-05 12:42:33.000000000 +0000 @@ -23,9 +23,11 @@ Signed-off-by: Ben Hutchings --- ---- a/drivers/md/dm-table.c -+++ b/drivers/md/dm-table.c -@@ -536,13 +536,15 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, +Index: linux-3.10-3.10.11/drivers/md/dm-table.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/dm-table.c 2014-05-05 11:52:16.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/dm-table.c 2014-05-05 12:42:32.000000000 +0000 +@@ -537,13 +537,15 @@ (unsigned long long) start << SECTOR_SHIFT); /* diff -Nru linux-3.10.11/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch linux-3.10-3.10.11/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch --- linux-3.10.11/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch 2014-05-05 12:41:38.000000000 +0000 @@ -18,9 +18,11 @@ This makes many error messages in drivers redundant, which will be removed in later patches. ---- a/drivers/base/firmware_class.c -+++ b/drivers/base/firmware_class.c -@@ -619,14 +619,23 @@ static ssize_t firmware_loading_store(st +Index: linux-3.10-3.10.11/drivers/base/firmware_class.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/base/firmware_class.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/base/firmware_class.c 2014-05-05 12:41:38.000000000 +0000 +@@ -619,14 +619,23 @@ * is completed. * */ fw_map_pages_buf(fw_buf); @@ -46,7 +48,7 @@ fw_load_abort(fw_priv); break; } -@@ -792,6 +801,9 @@ static void firmware_class_timeout_work( +@@ -792,6 +801,9 @@ struct firmware_priv, timeout_work.work); mutex_lock(&fw_lock); @@ -56,7 +58,7 @@ fw_load_abort(fw_priv); mutex_unlock(&fw_lock); } -@@ -843,25 +855,28 @@ static int _request_firmware_load(struct +@@ -843,25 +855,28 @@ retval = device_add(f_dev); if (retval) { @@ -89,7 +91,7 @@ if (timeout != MAX_SCHEDULE_TIMEOUT) schedule_delayed_work(&fw_priv->timeout_work, timeout); -@@ -949,7 +964,8 @@ _request_firmware_prepare(struct firmwar +@@ -949,7 +964,8 @@ } if (fw_get_builtin_firmware(firmware, name)) { @@ -99,7 +101,7 @@ return 0; /* assigned */ } -@@ -979,9 +995,16 @@ static int assign_firmware_buf(struct fi +@@ -979,9 +995,16 @@ struct firmware_buf *buf = fw->priv; mutex_lock(&fw_lock); @@ -117,7 +119,7 @@ } /* -@@ -1030,7 +1053,7 @@ _request_firmware(const struct firmware +@@ -1030,7 +1053,7 @@ if (nowait) { timeout = usermodehelper_read_lock_wait(timeout); if (!timeout) { @@ -126,7 +128,7 @@ name); ret = -EBUSY; goto out; -@@ -1056,6 +1079,9 @@ _request_firmware(const struct firmware +@@ -1056,6 +1079,9 @@ if (ret < 0) { release_firmware(fw); fw = NULL; diff -Nru linux-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch linux-3.10-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch --- linux-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch 2014-05-05 12:41:59.000000000 +0000 @@ -9,9 +9,11 @@ This will probably need to be split up into multiple patches prior to upstream submission. ---- a/arch/arm/mach-netx/xc.c -+++ b/arch/arm/mach-netx/xc.c -@@ -127,10 +127,8 @@ int xc_request_firmware(struct xc *x) +Index: linux-3.10-3.10.11/arch/arm/mach-netx/xc.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mach-netx/xc.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-netx/xc.c 2014-05-05 12:41:39.000000000 +0000 +@@ -127,10 +127,8 @@ ret = request_firmware(&fw, name, x->dev); @@ -23,9 +25,11 @@ head = (struct fw_header *)fw->data; if (head->magic != 0x4e657458) { ---- a/arch/cris/arch-v32/drivers/iop_fw_load.c -+++ b/arch/cris/arch-v32/drivers/iop_fw_load.c -@@ -74,12 +74,7 @@ int iop_fw_load_spu(const unsigned char +Index: linux-3.10-3.10.11/arch/cris/arch-v32/drivers/iop_fw_load.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/cris/arch-v32/drivers/iop_fw_load.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/arch/cris/arch-v32/drivers/iop_fw_load.c 2014-05-05 12:41:39.000000000 +0000 +@@ -74,12 +74,7 @@ fw_name, &iop_spu_device[spu_inst]); if (retval != 0) @@ -38,7 +42,7 @@ data = (u32 *) fw_entry->data; /* acquire ownership of memory controller */ -@@ -137,12 +132,7 @@ int iop_fw_load_mpu(unsigned char *fw_na +@@ -137,12 +132,7 @@ /* get firmware */ retval = request_firmware(&fw_entry, fw_name, &iop_mpu_device); if (retval != 0) @@ -51,23 +55,11 @@ data = (u32 *) fw_entry->data; /* disable MPU */ ---- a/arch/x86/kernel/microcode_amd.c -+++ b/arch/x86/kernel/microcode_amd.c -@@ -429,10 +429,8 @@ static enum ucode_state request_microcod - if (c->x86 >= 0x15) - snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); - -- if (request_firmware(&fw, (const char *)fw_name, device)) { -- pr_err("failed to load file %s\n", fw_name); -+ if (request_firmware(&fw, (const char *)fw_name, device)) - goto out; -- } - - ret = UCODE_ERROR; - if (*(u32 *)fw->data != UCODE_MAGIC) { ---- a/drivers/atm/ambassador.c -+++ b/drivers/atm/ambassador.c -@@ -1929,10 +1929,8 @@ static int ucode_init(loader_block *lb, +Index: linux-3.10-3.10.11/drivers/atm/ambassador.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/atm/ambassador.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/atm/ambassador.c 2014-05-05 12:41:39.000000000 +0000 +@@ -1929,10 +1929,8 @@ int res; res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); @@ -79,9 +71,11 @@ /* First record contains just the start address */ rec = (const struct ihex_binrec *)fw->data; ---- a/drivers/atm/fore200e.c -+++ b/drivers/atm/fore200e.c -@@ -2505,10 +2505,9 @@ static int fore200e_load_and_start_fw(st +Index: linux-3.10-3.10.11/drivers/atm/fore200e.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/atm/fore200e.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/atm/fore200e.c 2014-05-05 12:41:39.000000000 +0000 +@@ -2505,10 +2505,9 @@ return err; sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT); @@ -94,9 +88,11 @@ fw_data = (__le32 *) firmware->data; fw_size = firmware->size / sizeof(u32); ---- a/drivers/bluetooth/ath3k.c -+++ b/drivers/bluetooth/ath3k.c -@@ -327,10 +327,8 @@ static int ath3k_load_patch(struct usb_d +Index: linux-3.10-3.10.11/drivers/bluetooth/ath3k.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/ath3k.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/ath3k.c 2014-05-05 12:41:39.000000000 +0000 +@@ -355,10 +355,8 @@ fw_version.rom_version); ret = request_firmware(&firmware, filename, &udev->dev); @@ -108,7 +104,7 @@ pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); pt_version.build_version = *(int *) -@@ -389,10 +387,8 @@ static int ath3k_load_syscfg(struct usb_ +@@ -417,10 +415,8 @@ fw_version.rom_version, clk_value, ".dfu"); ret = request_firmware(&firmware, filename, &udev->dev); @@ -120,9 +116,11 @@ ret = ath3k_load_fwfile(udev, firmware); release_firmware(firmware); ---- a/drivers/bluetooth/bcm203x.c -+++ b/drivers/bluetooth/bcm203x.c -@@ -193,7 +193,6 @@ static int bcm203x_probe(struct usb_inte +Index: linux-3.10-3.10.11/drivers/bluetooth/bcm203x.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/bcm203x.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/bcm203x.c 2014-05-05 12:41:39.000000000 +0000 +@@ -193,7 +193,6 @@ } if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { @@ -130,7 +128,7 @@ usb_free_urb(data->urb); return -EIO; } -@@ -218,7 +217,6 @@ static int bcm203x_probe(struct usb_inte +@@ -218,7 +217,6 @@ release_firmware(firmware); if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) { @@ -138,9 +136,11 @@ usb_free_urb(data->urb); kfree(data->buffer); return -EIO; ---- a/drivers/bluetooth/bfusb.c -+++ b/drivers/bluetooth/bfusb.c -@@ -672,10 +672,8 @@ static int bfusb_probe(struct usb_interf +Index: linux-3.10-3.10.11/drivers/bluetooth/bfusb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/bfusb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/bfusb.c 2014-05-05 12:41:39.000000000 +0000 +@@ -672,10 +672,8 @@ skb_queue_head_init(&data->pending_q); skb_queue_head_init(&data->completed_q); @@ -152,9 +152,11 @@ BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); ---- a/drivers/bluetooth/bt3c_cs.c -+++ b/drivers/bluetooth/bt3c_cs.c -@@ -585,10 +585,8 @@ static int bt3c_open(bt3c_info_t *info) +Index: linux-3.10-3.10.11/drivers/bluetooth/bt3c_cs.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/bt3c_cs.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/bt3c_cs.c 2014-05-05 12:41:39.000000000 +0000 +@@ -585,10 +585,8 @@ /* Load firmware */ err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev); @@ -166,9 +168,11 @@ err = bt3c_load_firmware(info, firmware->data, firmware->size); ---- a/drivers/bluetooth/btmrvl_sdio.c -+++ b/drivers/bluetooth/btmrvl_sdio.c -@@ -288,8 +288,6 @@ static int btmrvl_sdio_download_helper(s +Index: linux-3.10-3.10.11/drivers/bluetooth/btmrvl_sdio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/btmrvl_sdio.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/btmrvl_sdio.c 2014-05-05 12:41:39.000000000 +0000 +@@ -288,8 +288,6 @@ ret = request_firmware(&fw_helper, card->helper, &card->func->dev); if ((ret < 0) || !fw_helper) { @@ -177,7 +181,7 @@ ret = -ENOENT; goto done; } -@@ -388,8 +386,6 @@ static int btmrvl_sdio_download_fw_w_hel +@@ -388,8 +386,6 @@ ret = request_firmware(&fw_firmware, card->firmware, &card->func->dev); if ((ret < 0) || !fw_firmware) { @@ -186,9 +190,11 @@ ret = -ENOENT; goto done; } ---- a/drivers/char/dsp56k.c -+++ b/drivers/char/dsp56k.c -@@ -140,11 +140,8 @@ static int dsp56k_upload(u_char __user * +Index: linux-3.10-3.10.11/drivers/char/dsp56k.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/char/dsp56k.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/char/dsp56k.c 2014-05-05 12:41:39.000000000 +0000 +@@ -140,11 +140,8 @@ } err = request_firmware(&fw, fw_name, &pdev->dev); platform_device_unregister(pdev); @@ -201,9 +207,11 @@ if (fw->size % 3) { printk(KERN_ERR "Bogus length %d in image \"%s\"\n", fw->size, fw_name); ---- a/drivers/dma/imx-sdma.c -+++ b/drivers/dma/imx-sdma.c -@@ -1163,10 +1163,8 @@ static void sdma_load_firmware(const str +Index: linux-3.10-3.10.11/drivers/dma/imx-sdma.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/dma/imx-sdma.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/dma/imx-sdma.c 2014-05-05 12:41:39.000000000 +0000 +@@ -1163,10 +1163,8 @@ const struct sdma_script_start_addrs *addr; unsigned short *ram_code; @@ -215,9 +223,11 @@ if (fw->size < sizeof(*header)) goto err_firmware; ---- a/drivers/gpu/drm/mga/mga_warp.c -+++ b/drivers/gpu/drm/mga/mga_warp.c -@@ -79,11 +79,8 @@ int mga_warp_install_microcode(drm_mga_p +Index: linux-3.10-3.10.11/drivers/gpu/drm/mga/mga_warp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/mga/mga_warp.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/mga/mga_warp.c 2014-05-05 12:41:39.000000000 +0000 +@@ -79,11 +79,8 @@ } rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); platform_device_unregister(pdev); @@ -230,9 +240,11 @@ size = 0; where = 0; ---- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c -+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c -@@ -513,10 +513,8 @@ nvc0_graph_ctor_fw(struct nvc0_graph_pri +Index: linux-3.10-3.10.11/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c 2014-05-05 12:41:39.000000000 +0000 +@@ -513,10 +513,8 @@ if (ret) { snprintf(f, sizeof(f), "nouveau/%s", fwname); ret = request_firmware(&fw, f, &device->pdev->dev); @@ -244,9 +256,11 @@ } fuc->size = fw->size; ---- a/drivers/gpu/drm/r128/r128_cce.c -+++ b/drivers/gpu/drm/r128/r128_cce.c -@@ -154,11 +154,8 @@ static int r128_cce_load_microcode(drm_r +Index: linux-3.10-3.10.11/drivers/gpu/drm/r128/r128_cce.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/r128/r128_cce.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/r128/r128_cce.c 2014-05-05 12:41:39.000000000 +0000 +@@ -154,11 +154,8 @@ } rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev); platform_device_unregister(pdev); @@ -259,9 +273,11 @@ if (fw->size != 256 * 8) { printk(KERN_ERR ---- a/drivers/gpu/drm/radeon/ni.c -+++ b/drivers/gpu/drm/radeon/ni.c -@@ -676,10 +676,6 @@ out: +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/ni.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/ni.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/ni.c 2014-05-05 12:41:39.000000000 +0000 +@@ -676,10 +676,6 @@ platform_device_unregister(pdev); if (err) { @@ -272,9 +288,11 @@ release_firmware(rdev->pfp_fw); rdev->pfp_fw = NULL; release_firmware(rdev->me_fw); ---- a/drivers/gpu/drm/radeon/r100.c -+++ b/drivers/gpu/drm/radeon/r100.c -@@ -1044,10 +1044,7 @@ static int r100_cp_init_microcode(struct +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/r100.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/r100.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/r100.c 2014-05-05 12:41:39.000000000 +0000 +@@ -1044,10 +1044,7 @@ err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); platform_device_unregister(pdev); @@ -286,9 +304,11 @@ printk(KERN_ERR "radeon_cp: Bogus length %zu in firmware \"%s\"\n", rdev->me_fw->size, fw_name); ---- a/drivers/gpu/drm/radeon/r600.c -+++ b/drivers/gpu/drm/radeon/r600.c -@@ -2291,10 +2291,6 @@ out: +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/r600.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600.c 2014-05-05 12:41:39.000000000 +0000 +@@ -2291,10 +2291,6 @@ platform_device_unregister(pdev); if (err) { @@ -299,9 +319,11 @@ release_firmware(rdev->pfp_fw); rdev->pfp_fw = NULL; release_firmware(rdev->me_fw); ---- a/drivers/gpu/drm/radeon/r600_cp.c -+++ b/drivers/gpu/drm/radeon/r600_cp.c -@@ -376,10 +376,6 @@ out: +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600_cp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/r600_cp.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600_cp.c 2014-05-05 12:41:39.000000000 +0000 +@@ -376,10 +376,6 @@ platform_device_unregister(pdev); if (err) { @@ -312,9 +334,11 @@ release_firmware(dev_priv->pfp_fw); dev_priv->pfp_fw = NULL; release_firmware(dev_priv->me_fw); ---- a/drivers/gpu/drm/radeon/radeon_cp.c -+++ b/drivers/gpu/drm/radeon/radeon_cp.c -@@ -530,10 +530,7 @@ static int radeon_cp_init_microcode(drm_ +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_cp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_cp.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_cp.c 2014-05-05 12:41:39.000000000 +0000 +@@ -530,10 +530,7 @@ err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev); platform_device_unregister(pdev); @@ -326,9 +350,11 @@ printk(KERN_ERR "radeon_cp: Bogus length %zu in firmware \"%s\"\n", dev_priv->me_fw->size, fw_name); ---- a/drivers/infiniband/hw/qib/qib_sd7220.c -+++ b/drivers/infiniband/hw/qib/qib_sd7220.c -@@ -405,10 +405,8 @@ int qib_sd7220_init(struct qib_devdata * +Index: linux-3.10-3.10.11/drivers/infiniband/hw/qib/qib_sd7220.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/infiniband/hw/qib/qib_sd7220.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/infiniband/hw/qib/qib_sd7220.c 2014-05-05 12:41:39.000000000 +0000 +@@ -405,10 +405,8 @@ } ret = request_firmware(&fw, SD7220_FW_NAME, &dd->pcidev->dev); @@ -340,9 +366,11 @@ /* Substitute our deduced value for was_reset */ ret = qib_ibsd_ucode_loaded(dd->pport, fw); ---- a/drivers/input/touchscreen/atmel_mxt_ts.c -+++ b/drivers/input/touchscreen/atmel_mxt_ts.c -@@ -986,10 +986,8 @@ static int mxt_load_fw(struct device *de +Index: linux-3.10-3.10.11/drivers/input/touchscreen/atmel_mxt_ts.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/input/touchscreen/atmel_mxt_ts.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/input/touchscreen/atmel_mxt_ts.c 2014-05-05 12:41:39.000000000 +0000 +@@ -986,10 +986,8 @@ int ret; ret = request_firmware(&fw, fn, dev); @@ -354,9 +382,11 @@ /* Change to the bootloader mode */ mxt_write_object(data, MXT_GEN_COMMAND_T6, ---- a/drivers/isdn/hardware/mISDN/speedfax.c -+++ b/drivers/isdn/hardware/mISDN/speedfax.c -@@ -392,11 +392,8 @@ setup_instance(struct sfax_hw *card) +Index: linux-3.10-3.10.11/drivers/isdn/hardware/mISDN/speedfax.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/isdn/hardware/mISDN/speedfax.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/isdn/hardware/mISDN/speedfax.c 2014-05-05 12:41:39.000000000 +0000 +@@ -392,11 +392,8 @@ card->isar.owner = THIS_MODULE; err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev); @@ -369,9 +399,11 @@ if (debug & DEBUG_HW) pr_notice("%s: got firmware %zu bytes\n", card->name, firmware->size); ---- a/drivers/media/tuners/tuner-xc2028.c -+++ b/drivers/media/tuners/tuner-xc2028.c -@@ -1349,7 +1349,6 @@ static void load_firmware_cb(const struc +Index: linux-3.10-3.10.11/drivers/media/tuners/tuner-xc2028.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/tuners/tuner-xc2028.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/tuners/tuner-xc2028.c 2014-05-05 12:41:40.000000000 +0000 +@@ -1349,7 +1349,6 @@ tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); if (!fw) { @@ -379,9 +411,11 @@ priv->state = XC2028_NODEV; return; } ---- a/drivers/media/usb/dvb-usb/dib0700_devices.c -+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c -@@ -2256,12 +2256,9 @@ static int stk9090m_frontend_attach(stru +Index: linux-3.10-3.10.11/drivers/media/usb/dvb-usb/dib0700_devices.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/dvb-usb/dib0700_devices.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/dvb-usb/dib0700_devices.c 2014-05-05 12:41:40.000000000 +0000 +@@ -2256,12 +2256,9 @@ dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80); @@ -396,7 +430,7 @@ stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size; stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data; -@@ -2322,12 +2319,9 @@ static int nim9090md_frontend_attach(str +@@ -2322,12 +2319,9 @@ msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); @@ -411,9 +445,11 @@ nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size; nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data; nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size; ---- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c -+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c -@@ -80,14 +80,9 @@ int dvb_usb_download_firmware(struct usb +Index: linux-3.10-3.10.11/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 2014-05-05 12:41:40.000000000 +0000 +@@ -80,14 +80,9 @@ int ret; const struct firmware *fw = NULL; @@ -430,9 +466,11 @@ switch (props->usb_ctrl) { case CYPRESS_AN2135: ---- a/drivers/media/usb/dvb-usb/gp8psk.c -+++ b/drivers/media/usb/dvb-usb/gp8psk.c -@@ -116,20 +116,14 @@ static int gp8psk_load_bcm4500fw(struct +Index: linux-3.10-3.10.11/drivers/media/usb/dvb-usb/gp8psk.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/dvb-usb/gp8psk.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/dvb-usb/gp8psk.c 2014-05-05 12:41:40.000000000 +0000 +@@ -116,20 +116,14 @@ const u8 *ptr; u8 *buf; if ((ret = request_firmware(&fw, bcm4500_firmware, @@ -454,9 +492,11 @@ ptr = fw->data; buf = kmalloc(64, GFP_KERNEL | GFP_DMA); if (!buf) { ---- a/drivers/media/usb/dvb-usb/opera1.c -+++ b/drivers/media/usb/dvb-usb/opera1.c -@@ -452,9 +452,6 @@ static int opera1_xilinx_load_firmware(s +Index: linux-3.10-3.10.11/drivers/media/usb/dvb-usb/opera1.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/dvb-usb/opera1.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/dvb-usb/opera1.c 2014-05-05 12:41:40.000000000 +0000 +@@ -452,9 +452,6 @@ info("start downloading fpga firmware %s",filename); if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { @@ -466,9 +506,11 @@ return ret; } else { p = kmalloc(fw->size, GFP_KERNEL); ---- a/drivers/media/dvb-frontends/af9013.c -+++ b/drivers/media/dvb-frontends/af9013.c -@@ -1363,16 +1363,8 @@ static int af9013_download_firmware(stru +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/af9013.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/af9013.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/af9013.c 2014-05-05 12:41:40.000000000 +0000 +@@ -1363,16 +1363,8 @@ /* request the firmware, this will block and timeout */ ret = request_firmware(&fw, fw_file, state->i2c->dev.parent); @@ -486,9 +528,11 @@ /* calc checksum */ for (i = 0; i < fw->size; i++) ---- a/drivers/media/dvb-frontends/bcm3510.c -+++ b/drivers/media/dvb-frontends/bcm3510.c -@@ -622,10 +622,9 @@ static int bcm3510_download_firmware(str +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/bcm3510.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/bcm3510.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/bcm3510.c 2014-05-05 12:41:40.000000000 +0000 +@@ -622,10 +622,9 @@ int ret,i; deb_info("requesting firmware\n"); @@ -501,9 +545,11 @@ deb_info("got firmware: %zd\n",fw->size); b = fw->data; ---- a/drivers/media/dvb-frontends/cx24116.c -+++ b/drivers/media/dvb-frontends/cx24116.c -@@ -493,13 +493,8 @@ static int cx24116_firmware_ondemand(str +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/cx24116.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/cx24116.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/cx24116.c 2014-05-05 12:41:40.000000000 +0000 +@@ -493,13 +493,8 @@ __func__, CX24116_DEFAULT_FIRMWARE); ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, state->i2c->dev.parent); @@ -518,9 +564,11 @@ /* Make sure we don't recurse back through here * during loading */ ---- a/drivers/media/dvb-frontends/drxd_hard.c -+++ b/drivers/media/dvb-frontends/drxd_hard.c -@@ -909,10 +909,8 @@ static int load_firmware(struct drxd_sta +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/drxd_hard.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/drxd_hard.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/drxd_hard.c 2014-05-05 12:41:40.000000000 +0000 +@@ -909,10 +909,8 @@ { const struct firmware *fw; @@ -532,9 +580,11 @@ state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL); if (state->microcode == NULL) { ---- a/drivers/media/dvb-frontends/drxk_hard.c -+++ b/drivers/media/dvb-frontends/drxk_hard.c -@@ -6229,12 +6229,6 @@ static void load_firmware_cb(const struc +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/drxk_hard.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/drxk_hard.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/drxk_hard.c 2014-05-05 12:41:40.000000000 +0000 +@@ -6229,12 +6229,6 @@ dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); if (!fw) { @@ -547,9 +597,11 @@ state->microcode_name = NULL; /* ---- a/drivers/media/dvb-frontends/ds3000.c -+++ b/drivers/media/dvb-frontends/ds3000.c -@@ -362,12 +362,8 @@ static int ds3000_firmware_ondemand(stru +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/ds3000.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/ds3000.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/ds3000.c 2014-05-05 12:41:40.000000000 +0000 +@@ -362,12 +362,8 @@ DS3000_DEFAULT_FIRMWARE); ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE, state->i2c->dev.parent); @@ -563,9 +615,11 @@ ret = ds3000_load_firmware(fe, fw); if (ret) ---- a/drivers/media/dvb-frontends/nxt200x.c -+++ b/drivers/media/dvb-frontends/nxt200x.c -@@ -882,12 +882,8 @@ static int nxt2002_init(struct dvb_front +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/nxt200x.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/nxt200x.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/nxt200x.c 2014-05-05 12:41:40.000000000 +0000 +@@ -882,12 +882,8 @@ __func__, NXT2002_DEFAULT_FIRMWARE); ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, state->i2c->dev.parent); @@ -579,7 +633,7 @@ ret = nxt2002_load_firmware(fe, fw); release_firmware(fw); -@@ -949,12 +945,8 @@ static int nxt2004_init(struct dvb_front +@@ -949,12 +945,8 @@ __func__, NXT2004_DEFAULT_FIRMWARE); ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, state->i2c->dev.parent); @@ -593,9 +647,11 @@ ret = nxt2004_load_firmware(fe, fw); release_firmware(fw); ---- a/drivers/media/dvb-frontends/or51132.c -+++ b/drivers/media/dvb-frontends/or51132.c -@@ -341,11 +341,8 @@ static int or51132_set_parameters(struct +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/or51132.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/or51132.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/or51132.c 2014-05-05 12:41:40.000000000 +0000 +@@ -341,11 +341,8 @@ printk("or51132: Waiting for firmware upload(%s)...\n", fwname); ret = request_firmware(&fw, fwname, state->i2c->dev.parent); @@ -608,9 +664,11 @@ ret = or51132_load_firmware(fe, fw); release_firmware(fw); if (ret) { ---- a/drivers/media/dvb-frontends/or51211.c -+++ b/drivers/media/dvb-frontends/or51211.c -@@ -375,12 +375,8 @@ static int or51211_init(struct dvb_front +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/or51211.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/or51211.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/or51211.c 2014-05-05 12:41:40.000000000 +0000 +@@ -375,12 +375,8 @@ OR51211_DEFAULT_FIRMWARE); ret = config->request_firmware(fe, &fw, OR51211_DEFAULT_FIRMWARE); @@ -624,9 +682,11 @@ ret = or51211_load_firmware(fe, fw); release_firmware(fw); ---- a/drivers/media/dvb-frontends/sp8870.c -+++ b/drivers/media/dvb-frontends/sp8870.c -@@ -315,10 +315,8 @@ static int sp8870_init (struct dvb_front +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/sp8870.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/sp8870.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/sp8870.c 2014-05-05 12:41:40.000000000 +0000 +@@ -315,10 +315,8 @@ /* request the firmware, this will block until someone uploads it */ printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE); @@ -638,9 +698,11 @@ if (sp8870_firmware_upload(state, fw)) { printk("sp8870: writing firmware to device failed\n"); ---- a/drivers/media/dvb-frontends/sp887x.c -+++ b/drivers/media/dvb-frontends/sp887x.c -@@ -527,10 +527,8 @@ static int sp887x_init(struct dvb_fronte +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/sp887x.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/sp887x.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/sp887x.c 2014-05-05 12:41:40.000000000 +0000 +@@ -527,10 +527,8 @@ /* request the firmware, this will block until someone uploads it */ printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE); ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE); @@ -652,9 +714,11 @@ ret = sp887x_initial_setup(fe, fw); release_firmware(fw); ---- a/drivers/media/dvb-frontends/tda10048.c -+++ b/drivers/media/dvb-frontends/tda10048.c -@@ -495,8 +495,6 @@ static int tda10048_firmware_upload(stru +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/tda10048.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/tda10048.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/tda10048.c 2014-05-05 12:41:40.000000000 +0000 +@@ -495,8 +495,6 @@ ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, state->i2c->dev.parent); if (ret) { @@ -663,9 +727,11 @@ return -EIO; } else { printk(KERN_INFO "%s: firmware read %Zu bytes.\n", ---- a/drivers/media/dvb-frontends/tda1004x.c -+++ b/drivers/media/dvb-frontends/tda1004x.c -@@ -401,10 +401,8 @@ static int tda10045_fwupload(struct dvb_ +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/tda1004x.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/tda1004x.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/tda1004x.c 2014-05-05 12:41:40.000000000 +0000 +@@ -401,10 +401,8 @@ /* request the firmware, this will block until someone uploads it */ printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); @@ -677,7 +743,7 @@ /* reset chip */ tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); -@@ -545,7 +543,6 @@ static int tda10046_fwupload(struct dvb_ +@@ -545,7 +543,6 @@ /* remain compatible to old bug: try to load with tda10045 image name */ ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); if (ret) { @@ -685,9 +751,11 @@ return ret; } else { printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n", ---- a/drivers/media/dvb-frontends/tda10071.c -+++ b/drivers/media/dvb-frontends/tda10071.c -@@ -941,14 +941,8 @@ static int tda10071_init(struct dvb_fron +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/tda10071.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/tda10071.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/tda10071.c 2014-05-05 12:41:40.000000000 +0000 +@@ -941,14 +941,8 @@ /* request the firmware, this will block and timeout */ ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); @@ -703,9 +771,11 @@ /* init */ for (i = 0; i < ARRAY_SIZE(tab2); i++) { ---- a/drivers/media/pci/ngene/ngene-core.c -+++ b/drivers/media/pci/ngene/ngene-core.c -@@ -1266,13 +1266,8 @@ static int ngene_load_firm(struct ngene +Index: linux-3.10-3.10.11/drivers/media/pci/ngene/ngene-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/ngene/ngene-core.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/ngene/ngene-core.c 2014-05-05 12:41:40.000000000 +0000 +@@ -1266,13 +1266,8 @@ break; } @@ -720,7 +790,7 @@ if (size == 0) size = fw->size; if (size != fw->size) { -@@ -1280,8 +1275,6 @@ static int ngene_load_firm(struct ngene +@@ -1280,8 +1275,6 @@ ": Firmware %s has invalid size!", fw_name); err = -1; } else { @@ -729,9 +799,11 @@ ngene_fw = (u8 *) fw->data; err = ngene_command_load_firmware(dev, ngene_fw, size); } ---- a/drivers/media/common/siano/smscoreapi.c -+++ b/drivers/media/common/siano/smscoreapi.c -@@ -1164,10 +1164,8 @@ static int smscore_load_firmware_from_fi +Index: linux-3.10-3.10.11/drivers/media/common/siano/smscoreapi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/common/siano/smscoreapi.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/common/siano/smscoreapi.c 2014-05-05 12:41:40.000000000 +0000 +@@ -1164,10 +1164,8 @@ return -EINVAL; rc = request_firmware(&fw, fw_filename, coredev->device); @@ -743,9 +815,11 @@ sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size); fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); ---- a/drivers/media/pci/ttpci/av7110.c -+++ b/drivers/media/pci/ttpci/av7110.c -@@ -1531,16 +1531,9 @@ static int get_firmware(struct av7110* a +Index: linux-3.10-3.10.11/drivers/media/pci/ttpci/av7110.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/ttpci/av7110.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/ttpci/av7110.c 2014-05-05 12:41:40.000000000 +0000 +@@ -1531,16 +1531,9 @@ /* request the av7110 firmware, this will block until someone uploads it */ ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); if (ret) { @@ -764,9 +838,11 @@ return -EINVAL; } ---- a/drivers/media/pci/ttpci/av7110_hw.c -+++ b/drivers/media/pci/ttpci/av7110_hw.c -@@ -243,11 +243,8 @@ int av7110_bootarm(struct av7110 *av7110 +Index: linux-3.10-3.10.11/drivers/media/pci/ttpci/av7110_hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/ttpci/av7110_hw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/ttpci/av7110_hw.c 2014-05-05 12:41:40.000000000 +0000 +@@ -243,11 +243,8 @@ //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); ret = request_firmware(&fw, fw_name, &dev->pci->dev); @@ -779,9 +855,11 @@ mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size); release_firmware(fw); ---- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c -+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c -@@ -296,10 +296,8 @@ static int ttusb_boot_dsp(struct ttusb * +Index: linux-3.10-3.10.11/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c 2014-05-05 12:41:40.000000000 +0000 +@@ -296,10 +296,8 @@ err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin", &ttusb->dev->dev); @@ -793,9 +871,11 @@ /* BootBlock */ b[0] = 0xaa; ---- a/drivers/media/usb/ttusb-dec/ttusb_dec.c -+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c -@@ -1293,11 +1293,8 @@ static int ttusb_dec_boot_dsp(struct ttu +Index: linux-3.10-3.10.11/drivers/media/usb/ttusb-dec/ttusb_dec.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/ttusb-dec/ttusb_dec.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/ttusb-dec/ttusb_dec.c 2014-05-05 12:41:40.000000000 +0000 +@@ -1293,11 +1293,8 @@ dprintk("%s\n", __func__); @@ -808,9 +888,11 @@ firmware = fw_entry->data; firmware_size = fw_entry->size; ---- a/drivers/media/radio/radio-wl1273.c -+++ b/drivers/media/radio/radio-wl1273.c -@@ -512,11 +512,8 @@ static int wl1273_fm_upload_firmware_pat +Index: linux-3.10-3.10.11/drivers/media/radio/radio-wl1273.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/radio/radio-wl1273.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/radio/radio-wl1273.c 2014-05-05 12:41:40.000000000 +0000 +@@ -512,11 +512,8 @@ * Uploading the firmware patch is not always necessary, * so we only print an info message. */ @@ -823,9 +905,11 @@ ptr = (__u8 *) fw_p->data; packet_num = ptr[0]; ---- a/drivers/media/radio/wl128x/fmdrv_common.c -+++ b/drivers/media/radio/wl128x/fmdrv_common.c -@@ -1248,10 +1248,8 @@ static int fm_download_firmware(struct f +Index: linux-3.10-3.10.11/drivers/media/radio/wl128x/fmdrv_common.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/radio/wl128x/fmdrv_common.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/radio/wl128x/fmdrv_common.c 2014-05-05 12:41:40.000000000 +0000 +@@ -1248,10 +1248,8 @@ ret = request_firmware(&fw_entry, fw_name, &fmdev->radio_dev->dev); @@ -837,9 +921,11 @@ fmdbg("Firmware(%s) length : %d bytes\n", fw_name, fw_entry->size); fw_data = (void *)fw_entry->data; ---- a/drivers/media/pci/bt8xx/bttv-cards.c -+++ b/drivers/media/pci/bt8xx/bttv-cards.c -@@ -3759,10 +3759,8 @@ static int pvr_boot(struct bttv *btv) +Index: linux-3.10-3.10.11/drivers/media/pci/bt8xx/bttv-cards.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/bt8xx/bttv-cards.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/bt8xx/bttv-cards.c 2014-05-05 12:41:40.000000000 +0000 +@@ -3759,10 +3759,8 @@ int rc; rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); @@ -851,9 +937,11 @@ rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); pr_info("%d: altera firmware upload %s\n", btv->c.nr, (rc < 0) ? "failed" : "ok"); ---- a/drivers/media/usb/cpia2/cpia2_core.c -+++ b/drivers/media/usb/cpia2/cpia2_core.c -@@ -907,11 +907,8 @@ static int apply_vp_patch(struct camera_ +Index: linux-3.10-3.10.11/drivers/media/usb/cpia2/cpia2_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/cpia2/cpia2_core.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/cpia2/cpia2_core.c 2014-05-05 12:41:41.000000000 +0000 +@@ -907,11 +907,8 @@ struct cpia2_command cmd; ret = request_firmware(&fw, fw_name, &cam->dev->dev); @@ -866,9 +954,11 @@ cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP; cmd.direction = TRANSFER_WRITE; ---- a/drivers/media/pci/cx18/cx18-av-firmware.c -+++ b/drivers/media/pci/cx18/cx18-av-firmware.c -@@ -85,10 +85,8 @@ int cx18_av_loadfw(struct cx18 *cx) +Index: linux-3.10-3.10.11/drivers/media/pci/cx18/cx18-av-firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/cx18/cx18-av-firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/cx18/cx18-av-firmware.c 2014-05-05 12:41:41.000000000 +0000 +@@ -85,10 +85,8 @@ int i; int retries1 = 0; @@ -880,9 +970,11 @@ /* The firmware load often has byte errors, so allow for several retries, both at byte level and at the firmware load level. */ ---- a/drivers/media/pci/cx18/cx18-dvb.c -+++ b/drivers/media/pci/cx18/cx18-dvb.c -@@ -141,9 +141,7 @@ static int yuan_mpc718_mt352_reqfw(struc +Index: linux-3.10-3.10.11/drivers/media/pci/cx18/cx18-dvb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/cx18/cx18-dvb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/cx18/cx18-dvb.c 2014-05-05 12:41:41.000000000 +0000 +@@ -141,9 +141,7 @@ int ret; ret = request_firmware(fw, fn, &cx->pci_dev->dev); @@ -893,7 +985,7 @@ size_t sz = (*fw)->size; if (sz < 2 || sz > 64 || (sz % 2) != 0) { CX18_ERR("Firmware %s has a bad size: %lu bytes\n", -@@ -156,7 +154,7 @@ static int yuan_mpc718_mt352_reqfw(struc +@@ -156,7 +154,7 @@ if (ret) { CX18_ERR("The MPC718 board variant with the MT352 DVB-T" @@ -902,9 +994,11 @@ CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware " "mpc718' if you need the firmware\n"); } ---- a/drivers/media/pci/cx18/cx18-firmware.c -+++ b/drivers/media/pci/cx18/cx18-firmware.c -@@ -106,11 +106,8 @@ static int load_cpu_fw_direct(const char +Index: linux-3.10-3.10.11/drivers/media/pci/cx18/cx18-firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/cx18/cx18-firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/cx18/cx18-firmware.c 2014-05-05 12:41:41.000000000 +0000 +@@ -106,11 +106,8 @@ u32 __iomem *dst = (u32 __iomem *)mem; const u32 *src; @@ -917,7 +1011,7 @@ src = (const u32 *)fw->data; -@@ -151,8 +148,6 @@ static int load_apu_fw_direct(const char +@@ -151,8 +148,6 @@ int sz; if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { @@ -926,9 +1020,11 @@ cx18_setup_page(cx, 0); return -ENOMEM; } ---- a/drivers/media/usb/cx231xx/cx231xx-417.c -+++ b/drivers/media/usb/cx231xx/cx231xx-417.c -@@ -995,12 +995,8 @@ static int cx231xx_load_firmware(struct +Index: linux-3.10-3.10.11/drivers/media/usb/cx231xx/cx231xx-417.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/cx231xx/cx231xx-417.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/cx231xx/cx231xx-417.c 2014-05-05 12:41:41.000000000 +0000 +@@ -995,12 +995,8 @@ retval = request_firmware(&firmware, CX231xx_FIRM_IMAGE_NAME, &dev->udev->dev); @@ -942,9 +1038,11 @@ if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { pr_err("ERROR: Firmware size mismatch (have %zd, expected %d)\n", ---- a/drivers/media/pci/cx23885/cx23885-417.c -+++ b/drivers/media/pci/cx23885/cx23885-417.c -@@ -930,14 +930,8 @@ static int cx23885_load_firmware(struct +Index: linux-3.10-3.10.11/drivers/media/pci/cx23885/cx23885-417.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/cx23885/cx23885-417.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/cx23885/cx23885-417.c 2014-05-05 12:41:41.000000000 +0000 +@@ -930,14 +930,8 @@ retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME, &dev->pci->dev); @@ -960,9 +1058,11 @@ if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { printk(KERN_ERR "ERROR: Firmware size mismatch " ---- a/drivers/media/pci/cx23885/cx23885-cards.c -+++ b/drivers/media/pci/cx23885/cx23885-cards.c -@@ -1795,11 +1795,7 @@ void cx23885_card_setup(struct cx23885_d +Index: linux-3.10-3.10.11/drivers/media/pci/cx23885/cx23885-cards.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/cx23885/cx23885-cards.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/cx23885/cx23885-cards.c 2014-05-05 12:41:41.000000000 +0000 +@@ -1795,11 +1795,7 @@ cinfo.rev, filename); ret = request_firmware(&fw, filename, &dev->pci->dev); @@ -975,9 +1075,11 @@ altera_init(&netup_config, fw); release_firmware(fw); ---- a/drivers/media/i2c/cx25840/cx25840-firmware.c -+++ b/drivers/media/i2c/cx25840/cx25840-firmware.c -@@ -127,10 +127,8 @@ int cx25840_loadfw(struct i2c_client *cl +Index: linux-3.10-3.10.11/drivers/media/i2c/cx25840/cx25840-firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/i2c/cx25840/cx25840-firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/i2c/cx25840/cx25840-firmware.c 2014-05-05 12:41:41.000000000 +0000 +@@ -127,10 +127,8 @@ MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ } @@ -989,9 +1091,11 @@ start_fw_load(client); ---- a/drivers/media/pci/cx88/cx88-blackbird.c -+++ b/drivers/media/pci/cx88/cx88-blackbird.c -@@ -448,13 +448,8 @@ static int blackbird_load_firmware(struc +Index: linux-3.10-3.10.11/drivers/media/pci/cx88/cx88-blackbird.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/cx88/cx88-blackbird.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/cx88/cx88-blackbird.c 2014-05-05 12:41:41.000000000 +0000 +@@ -448,13 +448,8 @@ &dev->pci->dev); @@ -1006,9 +1110,11 @@ if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n", ---- a/drivers/media/usb/gspca/vicam.c -+++ b/drivers/media/usb/gspca/vicam.c -@@ -244,10 +244,8 @@ static int sd_init(struct gspca_dev *gsp +Index: linux-3.10-3.10.11/drivers/media/usb/gspca/vicam.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/gspca/vicam.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/gspca/vicam.c 2014-05-05 12:41:41.000000000 +0000 +@@ -244,10 +244,8 @@ ret = request_ihex_firmware(&fw, VICAM_FIRMWARE, &gspca_dev->dev->dev); @@ -1020,9 +1126,11 @@ firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!firmware_buf) { ---- a/drivers/media/pci/ivtv/ivtv-firmware.c -+++ b/drivers/media/pci/ivtv/ivtv-firmware.c -@@ -80,8 +80,6 @@ retry: +Index: linux-3.10-3.10.11/drivers/media/pci/ivtv/ivtv-firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/ivtv/ivtv-firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/ivtv/ivtv-firmware.c 2014-05-05 12:41:41.000000000 +0000 +@@ -80,8 +80,6 @@ release_firmware(fw); return size; } @@ -1031,9 +1139,11 @@ return -ENOMEM; } ---- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c -+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c -@@ -1382,29 +1382,6 @@ static int pvr2_locate_firmware(struct p +Index: linux-3.10-3.10.11/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/pvrusb2/pvrusb2-hdw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/pvrusb2/pvrusb2-hdw.c 2014-05-05 12:41:41.000000000 +0000 +@@ -1382,29 +1382,6 @@ "request_firmware fatal error with code=%d",ret); return ret; } @@ -1063,9 +1173,11 @@ return ret; } ---- a/drivers/media/usb/s2255/s2255drv.c -+++ b/drivers/media/usb/s2255/s2255drv.c -@@ -2568,10 +2568,8 @@ static int s2255_probe(struct usb_interf +Index: linux-3.10-3.10.11/drivers/media/usb/s2255/s2255drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/s2255/s2255drv.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/s2255/s2255drv.c 2014-05-05 12:41:41.000000000 +0000 +@@ -2568,10 +2568,8 @@ } /* load the first chunk */ if (request_firmware(&dev->fw_data->fw, @@ -1077,9 +1189,11 @@ /* check the firmware is valid */ fw_size = dev->fw_data->fw->size; pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8]; ---- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c -+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c -@@ -88,10 +88,8 @@ int s5p_mfc_load_firmware(struct s5p_mfc +Index: linux-3.10-3.10.11/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c 2014-05-05 12:41:41.000000000 +0000 +@@ -88,10 +88,8 @@ err = request_firmware((const struct firmware **)&fw_blob, dev->variant->fw_name, dev->v4l2_dev.dev); @@ -1091,7 +1205,7 @@ if (fw_blob->size > dev->fw_size) { mfc_err("MFC firmware is too big to be loaded\n"); release_firmware(fw_blob); -@@ -121,10 +119,8 @@ int s5p_mfc_reload_firmware(struct s5p_m +@@ -121,10 +119,8 @@ err = request_firmware((const struct firmware **)&fw_blob, dev->variant->fw_name, dev->v4l2_dev.dev); @@ -1103,9 +1217,11 @@ if (fw_blob->size > dev->fw_size) { mfc_err("MFC firmware is too big to be loaded\n"); release_firmware(fw_blob); ---- a/drivers/media/pci/saa7164/saa7164-fw.c -+++ b/drivers/media/pci/saa7164/saa7164-fw.c -@@ -420,11 +420,8 @@ int saa7164_downloadfirmware(struct saa7 +Index: linux-3.10-3.10.11/drivers/media/pci/saa7164/saa7164-fw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/saa7164/saa7164-fw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/saa7164/saa7164-fw.c 2014-05-05 12:41:41.000000000 +0000 +@@ -420,11 +420,8 @@ __func__, fwname); ret = request_firmware(&fw, fwname, &dev->pci->dev); @@ -1118,9 +1234,11 @@ printk(KERN_INFO "%s() firmware read %Zu bytes.\n", __func__, fw->size); ---- a/drivers/media/usb/tlg2300/pd-main.c -+++ b/drivers/media/usb/tlg2300/pd-main.c -@@ -219,10 +219,8 @@ static int firmware_download(struct usb_ +Index: linux-3.10-3.10.11/drivers/media/usb/tlg2300/pd-main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/tlg2300/pd-main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/tlg2300/pd-main.c 2014-05-05 12:41:41.000000000 +0000 +@@ -219,10 +219,8 @@ size_t max_packet_size; ret = request_firmware(&fw, firmware_name, &udev->dev); @@ -1132,9 +1250,11 @@ fwlength = fw->size; ---- a/drivers/misc/ti-st/st_kim.c -+++ b/drivers/misc/ti-st/st_kim.c -@@ -301,11 +301,8 @@ static long download_firmware(struct kim +Index: linux-3.10-3.10.11/drivers/misc/ti-st/st_kim.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/ti-st/st_kim.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/ti-st/st_kim.c 2014-05-05 12:41:41.000000000 +0000 +@@ -301,11 +301,8 @@ request_firmware(&kim_gdata->fw_entry, bts_scr_name, &kim_gdata->kim_pdev->dev); if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) || @@ -1147,9 +1267,11 @@ ptr = (void *)kim_gdata->fw_entry->data; len = kim_gdata->fw_entry->size; /* bts_header to remove out magic number and ---- a/drivers/net/can/softing/softing_fw.c -+++ b/drivers/net/can/softing/softing_fw.c -@@ -238,11 +238,8 @@ int softing_load_app_fw(const char *file +Index: linux-3.10-3.10.11/drivers/net/can/softing/softing_fw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/can/softing/softing_fw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/can/softing/softing_fw.c 2014-05-05 12:41:41.000000000 +0000 +@@ -238,11 +238,8 @@ int8_t type_end = 0, type_entrypoint = 0; ret = request_firmware(&fw, file, &card->pdev->dev); @@ -1162,9 +1284,11 @@ dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", file, (unsigned long)fw->size); /* parse the firmware */ ---- a/drivers/net/ethernet/3com/typhoon.c -+++ b/drivers/net/ethernet/3com/typhoon.c -@@ -1279,11 +1279,8 @@ typhoon_request_firmware(struct typhoon +Index: linux-3.10-3.10.11/drivers/net/ethernet/3com/typhoon.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/3com/typhoon.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/3com/typhoon.c 2014-05-05 12:41:41.000000000 +0000 +@@ -1279,11 +1279,8 @@ return 0; err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev); @@ -1177,9 +1301,11 @@ image_data = (u8 *) typhoon_fw->data; remaining = typhoon_fw->size; ---- a/drivers/net/ethernet/adaptec/starfire.c -+++ b/drivers/net/ethernet/adaptec/starfire.c -@@ -1017,11 +1017,8 @@ static int netdev_open(struct net_device +Index: linux-3.10-3.10.11/drivers/net/ethernet/adaptec/starfire.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/adaptec/starfire.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/adaptec/starfire.c 2014-05-05 12:41:41.000000000 +0000 +@@ -1017,11 +1017,8 @@ #endif /* VLAN_SUPPORT */ retval = request_firmware(&fw_rx, FIRMWARE_RX, &np->pci_dev->dev); @@ -1192,7 +1318,7 @@ if (fw_rx->size % 4) { printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", fw_rx->size, FIRMWARE_RX); -@@ -1029,11 +1026,8 @@ static int netdev_open(struct net_device +@@ -1029,11 +1026,8 @@ goto out_rx; } retval = request_firmware(&fw_tx, FIRMWARE_TX, &np->pci_dev->dev); @@ -1205,9 +1331,11 @@ if (fw_tx->size % 4) { printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", fw_tx->size, FIRMWARE_TX); ---- a/drivers/net/ethernet/alteon/acenic.c -+++ b/drivers/net/ethernet/alteon/acenic.c -@@ -2902,11 +2902,8 @@ static int ace_load_firmware(struct net_ +Index: linux-3.10-3.10.11/drivers/net/ethernet/alteon/acenic.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/alteon/acenic.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/alteon/acenic.c 2014-05-05 12:41:41.000000000 +0000 +@@ -2902,11 +2902,8 @@ fw_name = "acenic/tg1.bin"; ret = request_firmware(&fw, fw_name, &ap->pdev->dev); @@ -1220,9 +1348,11 @@ fw_data = (void *)fw->data; ---- a/drivers/net/ethernet/broadcom/bnx2.c -+++ b/drivers/net/ethernet/broadcom/bnx2.c -@@ -3679,16 +3679,13 @@ static int bnx2_request_uncached_firmwar +Index: linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bnx2.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/broadcom/bnx2.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bnx2.c 2014-05-05 12:41:41.000000000 +0000 +@@ -3679,16 +3679,13 @@ } rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev); @@ -1242,9 +1372,11 @@ mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data; rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data; if (bp->mips_firmware->size < sizeof(*mips_fw) || ---- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c -+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c -@@ -12258,11 +12258,8 @@ static int bnx2x_init_firmware(struct bn +Index: linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 2014-05-05 12:41:42.000000000 +0000 +@@ -12258,11 +12258,8 @@ BNX2X_DEV_INFO("Loading %s\n", fw_file_name); rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); @@ -1257,9 +1389,11 @@ rc = bnx2x_check_firmware(bp); if (rc) { ---- a/drivers/net/ethernet/broadcom/tg3.c -+++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -11016,11 +11016,8 @@ static int tg3_request_firmware(struct t +Index: linux-3.10-3.10.11/drivers/net/ethernet/broadcom/tg3.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/broadcom/tg3.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/broadcom/tg3.c 2014-05-05 12:41:42.000000000 +0000 +@@ -11052,11 +11052,8 @@ { const struct tg3_firmware_hdr *fw_hdr; @@ -1272,9 +1406,11 @@ fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; ---- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c -+++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c -@@ -30,10 +30,8 @@ cna_read_firmware(struct pci_dev *pdev, +Index: linux-3.10-3.10.11/drivers/net/ethernet/brocade/bna/cna_fwimg.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/brocade/bna/cna_fwimg.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/brocade/bna/cna_fwimg.c 2014-05-05 12:41:42.000000000 +0000 +@@ -30,10 +30,8 @@ { const struct firmware *fw; @@ -1286,9 +1422,11 @@ *bfi_image = (u32 *)fw->data; *bfi_image_size = fw->size/sizeof(u32); ---- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c -+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c -@@ -1034,12 +1034,8 @@ int t3_get_edc_fw(struct cphy *phy, int +Index: linux-3.10-3.10.11/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c 2014-05-05 12:41:42.000000000 +0000 +@@ -1034,12 +1034,8 @@ snprintf(buf, sizeof(buf), get_edc_fw_name(edc_idx)); ret = request_firmware(&fw, buf, &adapter->pdev->dev); @@ -1302,7 +1440,7 @@ /* check size, take checksum in account */ if (fw->size > size + 4) { -@@ -1076,11 +1072,8 @@ static int upgrade_fw(struct adapter *ad +@@ -1076,11 +1072,8 @@ struct device *dev = &adap->pdev->dev; ret = request_firmware(&fw, FW_FNAME, dev); @@ -1315,7 +1453,7 @@ ret = t3_load_fw(adap, fw->data, fw->size); release_firmware(fw); -@@ -1125,11 +1118,8 @@ static int update_tpsram(struct adapter +@@ -1125,11 +1118,8 @@ snprintf(buf, sizeof(buf), TPSRAM_NAME, rev); ret = request_firmware(&tpsram, buf, dev); @@ -1328,9 +1466,11 @@ ret = t3_check_tpsram(adap, tpsram->data, tpsram->size); if (ret) ---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c -+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c -@@ -1089,11 +1089,8 @@ static int upgrade_fw(struct adapter *ad +Index: linux-3.10-3.10.11/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 2014-05-05 12:41:42.000000000 +0000 +@@ -1089,11 +1089,8 @@ } ret = request_firmware(&fw, fw_file_name, dev); @@ -1343,9 +1483,11 @@ hdr = (const struct fw_hdr *)fw->data; vers = ntohl(hdr->fw_ver); ---- a/drivers/net/ethernet/intel/e100.c -+++ b/drivers/net/ethernet/intel/e100.c -@@ -1293,9 +1293,6 @@ static const struct firmware *e100_reque +Index: linux-3.10-3.10.11/drivers/net/ethernet/intel/e100.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/intel/e100.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/intel/e100.c 2014-05-05 12:41:42.000000000 +0000 +@@ -1293,9 +1293,6 @@ if (err) { if (required) { @@ -1355,9 +1497,11 @@ return ERR_PTR(err); } else { netif_info(nic, probe, nic->netdev, ---- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c -+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c -@@ -584,8 +584,6 @@ static int myri10ge_load_hotplug_firmwar +Index: linux-3.10-3.10.11/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/myricom/myri10ge/myri10ge.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/myricom/myri10ge/myri10ge.c 2014-05-05 12:41:42.000000000 +0000 +@@ -584,8 +584,6 @@ unsigned i; if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { @@ -1366,9 +1510,11 @@ status = -EINVAL; goto abort_with_nothing; } ---- a/drivers/net/ethernet/smsc/smc91c92_cs.c -+++ b/drivers/net/ethernet/smsc/smc91c92_cs.c -@@ -648,10 +648,8 @@ static int osi_load_firmware(struct pcmc +Index: linux-3.10-3.10.11/drivers/net/ethernet/smsc/smc91c92_cs.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/smsc/smc91c92_cs.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/smsc/smc91c92_cs.c 2014-05-05 12:41:42.000000000 +0000 +@@ -648,10 +648,8 @@ int i, err; err = request_firmware(&fw, FIRMWARE_NAME, &link->dev); @@ -1380,9 +1526,11 @@ /* Download the Seven of Diamonds firmware */ for (i = 0; i < fw->size; i++) { ---- a/drivers/net/ethernet/sun/cassini.c -+++ b/drivers/net/ethernet/sun/cassini.c -@@ -818,11 +818,8 @@ static void cas_saturn_firmware_init(str +Index: linux-3.10-3.10.11/drivers/net/ethernet/sun/cassini.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/sun/cassini.c 2014-05-05 12:41:37.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/sun/cassini.c 2014-05-05 12:41:42.000000000 +0000 +@@ -818,11 +818,8 @@ return; err = request_firmware(&fw, fw_name, &cp->pdev->dev); @@ -1395,9 +1543,11 @@ if (fw->size < 2) { pr_err("bogus length %zu in \"%s\"\n", fw->size, fw_name); ---- a/drivers/net/hamradio/yam.c -+++ b/drivers/net/hamradio/yam.c -@@ -372,11 +372,8 @@ static unsigned char *add_mcs(unsigned c +Index: linux-3.10-3.10.11/drivers/net/hamradio/yam.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/hamradio/yam.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/hamradio/yam.c 2014-05-05 12:41:42.000000000 +0000 +@@ -372,11 +372,8 @@ } err = request_firmware(&fw, fw_name[predef], &pdev->dev); platform_device_unregister(pdev); @@ -1410,9 +1560,11 @@ if (fw->size != YAM_FPGA_SIZE) { printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n", fw->size, fw_name[predef]); ---- a/drivers/net/usb/kaweth.c -+++ b/drivers/net/usb/kaweth.c -@@ -398,10 +398,8 @@ static int kaweth_download_firmware(stru +Index: linux-3.10-3.10.11/drivers/net/usb/kaweth.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/usb/kaweth.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/usb/kaweth.c 2014-05-05 12:41:42.000000000 +0000 +@@ -398,10 +398,8 @@ int ret; ret = request_firmware(&fw, fwname, &kaweth->dev->dev); @@ -1424,9 +1576,11 @@ if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n", ---- a/drivers/net/wimax/i2400m/fw.c -+++ b/drivers/net/wimax/i2400m/fw.c -@@ -1582,11 +1582,8 @@ int i2400m_dev_bootstrap(struct i2400m * +Index: linux-3.10-3.10.11/drivers/net/wimax/i2400m/fw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wimax/i2400m/fw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wimax/i2400m/fw.c 2014-05-05 12:41:42.000000000 +0000 +@@ -1582,11 +1582,8 @@ } d_printf(1, dev, "trying firmware %s (%d)\n", fw_name, itr); ret = request_firmware(&fw, fw_name, dev); @@ -1439,7 +1593,7 @@ i2400m->fw_name = fw_name; ret = i2400m_fw_bootstrap(i2400m, fw, flags); release_firmware(fw); -@@ -1629,8 +1626,6 @@ void i2400m_fw_cache(struct i2400m *i240 +@@ -1629,8 +1626,6 @@ kref_init(&i2400m_fw->kref); result = request_firmware(&i2400m_fw->fw, i2400m->fw_name, dev); if (result < 0) { @@ -1448,9 +1602,11 @@ kfree(i2400m_fw); i2400m_fw = (void *) ~0; } else ---- a/drivers/net/wireless/at76c50x-usb.c -+++ b/drivers/net/wireless/at76c50x-usb.c -@@ -1553,13 +1553,8 @@ static struct fwentry *at76_load_firmwar +Index: linux-3.10-3.10.11/drivers/net/wireless/at76c50x-usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/at76c50x-usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/at76c50x-usb.c 2014-05-05 12:41:42.000000000 +0000 +@@ -1553,13 +1553,8 @@ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); @@ -1465,9 +1621,11 @@ at76_dbg(DBG_FW, "got it."); fwh = (struct at76_fw_header *)(fwe->fw->data); ---- a/drivers/net/wireless/ath/ath9k/hif_usb.c -+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c -@@ -1092,12 +1092,8 @@ static void ath9k_hif_usb_firmware_cb(co +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/hif_usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/ath9k/hif_usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/hif_usb.c 2014-05-05 12:41:42.000000000 +0000 +@@ -1092,12 +1092,8 @@ struct hif_device_usb *hif_dev = context; int ret; @@ -1481,9 +1639,11 @@ hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, &hif_dev->udev->dev); ---- a/drivers/net/wireless/ath/carl9170/usb.c -+++ b/drivers/net/wireless/ath/carl9170/usb.c -@@ -1025,7 +1025,6 @@ static void carl9170_usb_firmware_step2( +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/carl9170/usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/carl9170/usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/carl9170/usb.c 2014-05-05 12:41:42.000000000 +0000 +@@ -1025,7 +1025,6 @@ return; } @@ -1491,9 +1651,11 @@ carl9170_usb_firmware_failed(ar); } ---- a/drivers/net/wireless/atmel.c -+++ b/drivers/net/wireless/atmel.c -@@ -3928,12 +3928,8 @@ static int reset_atmel_card(struct net_d +Index: linux-3.10-3.10.11/drivers/net/wireless/atmel.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/atmel.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/atmel.c 2014-05-05 12:41:42.000000000 +0000 +@@ -3928,12 +3928,8 @@ strcpy(priv->firmware_id, "atmel_at76c502.bin"); } err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev); @@ -1507,9 +1669,11 @@ } else { int fw_index = 0; int success = 0; ---- a/drivers/net/wireless/b43/main.c -+++ b/drivers/net/wireless/b43/main.c -@@ -2158,19 +2158,8 @@ int b43_do_request_fw(struct b43_request +Index: linux-3.10-3.10.11/drivers/net/wireless/b43/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/b43/main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/b43/main.c 2014-05-05 12:41:42.000000000 +0000 +@@ -2158,19 +2158,8 @@ } err = request_firmware(&ctx->blob, ctx->fwname, ctx->dev->dev->dev); @@ -1530,9 +1694,11 @@ fw_ready: if (ctx->blob->size < sizeof(struct b43_fw_header)) goto err_format; ---- a/drivers/net/wireless/b43legacy/main.c -+++ b/drivers/net/wireless/b43legacy/main.c -@@ -1554,11 +1554,8 @@ static int do_request_fw(struct b43legac +Index: linux-3.10-3.10.11/drivers/net/wireless/b43legacy/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/b43legacy/main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/b43legacy/main.c 2014-05-05 12:41:43.000000000 +0000 +@@ -1554,11 +1554,8 @@ } else { err = request_firmware(fw, path, dev->dev->dev); } @@ -1545,9 +1711,11 @@ if ((*fw)->size < sizeof(struct b43legacy_fw_header)) goto err_format; hdr = (struct b43legacy_fw_header *)((*fw)->data); ---- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c -@@ -3037,10 +3037,8 @@ static int brcmf_sdbrcm_download_code_fi +Index: linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-05-05 12:41:43.000000000 +0000 +@@ -3037,10 +3037,8 @@ ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME, &bus->sdiodev->func[2]->dev); @@ -1559,7 +1727,7 @@ bus->fw_ptr = 0; memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC); -@@ -3159,10 +3157,8 @@ static int brcmf_sdbrcm_download_nvram(s +@@ -3159,10 +3157,8 @@ ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, &bus->sdiodev->func[2]->dev); @@ -1571,9 +1739,11 @@ ret = brcmf_process_nvram_vars(bus); ---- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c -+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c -@@ -379,19 +379,13 @@ static int brcms_request_fw(struct brcms +Index: linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-05-05 12:41:43.000000000 +0000 +@@ -379,19 +379,13 @@ sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); @@ -1595,9 +1765,11 @@ wl->fw.hdr_num_entries[i] = wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); } ---- a/drivers/net/wireless/ipw2x00/ipw2100.c -+++ b/drivers/net/wireless/ipw2x00/ipw2100.c -@@ -8428,12 +8428,8 @@ static int ipw2100_get_firmware(struct i +Index: linux-3.10-3.10.11/drivers/net/wireless/ipw2x00/ipw2100.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ipw2x00/ipw2100.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ipw2x00/ipw2100.c 2014-05-05 12:41:43.000000000 +0000 +@@ -8428,12 +8428,8 @@ rc = request_firmware(&fw->fw_entry, fw_name, &priv->pci_dev->dev); @@ -1611,9 +1783,11 @@ IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data, fw->fw_entry->size); ---- a/drivers/net/wireless/ipw2x00/ipw2200.c -+++ b/drivers/net/wireless/ipw2x00/ipw2200.c -@@ -3418,10 +3418,8 @@ static int ipw_get_fw(struct ipw_priv *p +Index: linux-3.10-3.10.11/drivers/net/wireless/ipw2x00/ipw2200.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ipw2x00/ipw2200.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ipw2x00/ipw2200.c 2014-05-05 12:41:43.000000000 +0000 +@@ -3418,10 +3418,8 @@ /* ask firmware_class module to get the boot firmware off disk */ rc = request_firmware(raw, name, &priv->pci_dev->dev); @@ -1625,9 +1799,11 @@ if ((*raw)->size < sizeof(*fw)) { IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size); ---- a/drivers/net/wireless/iwlegacy/3945-mac.c -+++ b/drivers/net/wireless/iwlegacy/3945-mac.c -@@ -1866,7 +1866,6 @@ il3945_read_ucode(struct il_priv *il) +Index: linux-3.10-3.10.11/drivers/net/wireless/iwlegacy/3945-mac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/iwlegacy/3945-mac.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/iwlegacy/3945-mac.c 2014-05-05 12:41:43.000000000 +0000 +@@ -1866,7 +1866,6 @@ sprintf(buf, "%s%u%s", name_pre, idx, ".ucode"); ret = request_firmware(&ucode_raw, buf, &il->pci_dev->dev); if (ret < 0) { @@ -1635,9 +1811,11 @@ if (ret == -ENOENT) continue; else ---- a/drivers/net/wireless/iwlwifi/iwl-drv.c -+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c -@@ -852,13 +852,8 @@ static void iwl_req_fw_callback(const st +Index: linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/iwlwifi/iwl-drv.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-drv.c 2014-05-05 12:41:43.000000000 +0000 +@@ -852,13 +852,8 @@ memset(&pieces, 0, sizeof(pieces)); @@ -1652,9 +1830,11 @@ IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", drv->firmware_name, ucode_raw->size); ---- a/drivers/net/wireless/libertas_tf/if_usb.c -+++ b/drivers/net/wireless/libertas_tf/if_usb.c -@@ -825,8 +825,6 @@ static int if_usb_prog_firmware(struct i +Index: linux-3.10-3.10.11/drivers/net/wireless/libertas_tf/if_usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/libertas_tf/if_usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/libertas_tf/if_usb.c 2014-05-05 12:41:43.000000000 +0000 +@@ -825,8 +825,6 @@ kparam_block_sysfs_write(fw_name); ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); if (ret < 0) { @@ -1663,9 +1843,11 @@ kparam_unblock_sysfs_write(fw_name); goto done; } ---- a/drivers/net/wireless/mwifiex/main.c -+++ b/drivers/net/wireless/mwifiex/main.c -@@ -316,11 +316,8 @@ static void mwifiex_fw_dpc(const struct +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c 2014-05-05 12:41:43.000000000 +0000 +@@ -316,11 +316,8 @@ struct mwifiex_adapter *adapter = context; struct mwifiex_fw_image fw; @@ -1678,9 +1860,11 @@ memset(&fw, 0, sizeof(struct mwifiex_fw_image)); adapter->firmware = firmware; ---- a/drivers/net/wireless/mwl8k.c -+++ b/drivers/net/wireless/mwl8k.c -@@ -5524,16 +5524,12 @@ static int mwl8k_firmware_load_success(s +Index: linux-3.10-3.10.11/drivers/net/wireless/mwl8k.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwl8k.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwl8k.c 2014-05-05 12:41:43.000000000 +0000 +@@ -5524,16 +5524,12 @@ static void mwl8k_fw_state_machine(const struct firmware *fw, void *context) { struct mwl8k_priv *priv = context; @@ -1698,7 +1882,7 @@ priv->fw_helper = fw; rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode, true); -@@ -5568,11 +5564,8 @@ static void mwl8k_fw_state_machine(const +@@ -5568,11 +5564,8 @@ break; case FW_STATE_LOADING_ALT: @@ -1711,7 +1895,7 @@ priv->fw_ucode = fw; rc = mwl8k_firmware_load_success(priv); if (rc) -@@ -5610,10 +5603,8 @@ retry: +@@ -5610,10 +5603,8 @@ /* Ask userland hotplug daemon for the device firmware */ rc = mwl8k_request_firmware(priv, fw_image, nowait); @@ -1723,9 +1907,11 @@ if (nowait) return rc; ---- a/drivers/net/wireless/orinoco/fw.c -+++ b/drivers/net/wireless/orinoco/fw.c -@@ -132,7 +132,6 @@ orinoco_dl_firmware(struct orinoco_priva +Index: linux-3.10-3.10.11/drivers/net/wireless/orinoco/fw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/orinoco/fw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/orinoco/fw.c 2014-05-05 12:41:44.000000000 +0000 +@@ -132,7 +132,6 @@ err = request_firmware(&fw_entry, firmware, priv->dev); if (err) { @@ -1733,7 +1919,7 @@ err = -ENOENT; goto free; } -@@ -292,10 +291,8 @@ symbol_dl_firmware(struct orinoco_privat +@@ -292,10 +291,8 @@ const struct firmware *fw_entry; if (!orinoco_cached_fw_get(priv, true)) { @@ -1745,7 +1931,7 @@ } else fw_entry = orinoco_cached_fw_get(priv, true); -@@ -311,10 +308,8 @@ symbol_dl_firmware(struct orinoco_privat +@@ -311,10 +308,8 @@ } if (!orinoco_cached_fw_get(priv, false)) { @@ -1757,9 +1943,11 @@ } else fw_entry = orinoco_cached_fw_get(priv, false); ---- a/drivers/net/wireless/orinoco/orinoco_usb.c -+++ b/drivers/net/wireless/orinoco/orinoco_usb.c -@@ -1690,7 +1690,6 @@ static int ezusb_probe(struct usb_interf +Index: linux-3.10-3.10.11/drivers/net/wireless/orinoco/orinoco_usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/orinoco/orinoco_usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/orinoco/orinoco_usb.c 2014-05-05 12:41:44.000000000 +0000 +@@ -1690,7 +1690,6 @@ if (ezusb_firmware_download(upriv, &firmware)) goto error; } else { @@ -1767,9 +1955,11 @@ goto error; } ---- a/drivers/net/wireless/p54/p54pci.c -+++ b/drivers/net/wireless/p54/p54pci.c -@@ -497,7 +497,6 @@ static void p54p_firmware_step2(const st +Index: linux-3.10-3.10.11/drivers/net/wireless/p54/p54pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/p54/p54pci.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/p54/p54pci.c 2014-05-05 12:41:44.000000000 +0000 +@@ -497,7 +497,6 @@ int err; if (!fw) { @@ -1777,9 +1967,11 @@ err = -ENOENT; goto out; } ---- a/drivers/net/wireless/p54/p54spi.c -+++ b/drivers/net/wireless/p54/p54spi.c -@@ -171,10 +171,8 @@ static int p54spi_request_firmware(struc +Index: linux-3.10-3.10.11/drivers/net/wireless/p54/p54spi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/p54/p54spi.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/p54/p54spi.c 2014-05-05 12:41:44.000000000 +0000 +@@ -171,10 +171,8 @@ /* FIXME: should driver use it's own struct device? */ ret = request_firmware(&priv->firmware, "3826.arm", &priv->spi->dev); @@ -1791,9 +1983,11 @@ ret = p54_parse_firmware(dev, priv->firmware); if (ret) { ---- a/drivers/net/wireless/p54/p54usb.c -+++ b/drivers/net/wireless/p54/p54usb.c -@@ -929,7 +929,6 @@ static void p54u_load_firmware_cb(const +Index: linux-3.10-3.10.11/drivers/net/wireless/p54/p54usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/p54/p54usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/p54/p54usb.c 2014-05-05 12:41:44.000000000 +0000 +@@ -929,7 +929,6 @@ err = p54u_start_ops(priv); } else { err = -ENOENT; @@ -1801,9 +1995,11 @@ } if (err) { ---- a/drivers/net/wireless/prism54/islpci_dev.c -+++ b/drivers/net/wireless/prism54/islpci_dev.c -@@ -93,12 +93,9 @@ isl_upload_firmware(islpci_private *priv +Index: linux-3.10-3.10.11/drivers/net/wireless/prism54/islpci_dev.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/prism54/islpci_dev.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/prism54/islpci_dev.c 2014-05-05 12:41:44.000000000 +0000 +@@ -93,12 +93,9 @@ const u32 *fw_ptr; rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV); @@ -1818,9 +2014,11 @@ /* prepare the Direct Memory Base register */ reg = ISL38XX_DEV_FIRMWARE_ADDRES; ---- a/drivers/net/wireless/rt2x00/rt2x00firmware.c -+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c -@@ -51,10 +51,8 @@ static int rt2x00lib_request_firmware(st +Index: linux-3.10-3.10.11/drivers/net/wireless/rt2x00/rt2x00firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/rt2x00/rt2x00firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/rt2x00/rt2x00firmware.c 2014-05-05 12:41:44.000000000 +0000 +@@ -51,10 +51,8 @@ rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name); retval = request_firmware(&fw, fw_name, device); @@ -1832,29 +2030,11 @@ if (!fw || !fw->size || !fw->data) { rt2x00_err(rt2x00dev, "Failed to read Firmware\n"); ---- a/drivers/net/wireless/rtlwifi/core.c -+++ b/drivers/net/wireless/rtlwifi/core.c -@@ -46,7 +46,6 @@ void rtl_fw_cb(const struct firmware *fi - "Firmware callback routine entered!\n"); - complete(&rtlpriv->firmware_loading_complete); - if (!firmware) { -- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); - rtlpriv->max_fw_size = 0; - return; - } ---- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c -+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c -@@ -97,7 +97,6 @@ static void rtl92se_fw_cb(const struct f - "Firmware callback routine entered!\n"); - complete(&rtlpriv->firmware_loading_complete); - if (!firmware) { -- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); - rtlpriv->max_fw_size = 0; - return; - } ---- a/drivers/net/wireless/ti/wl1251/main.c -+++ b/drivers/net/wireless/ti/wl1251/main.c -@@ -70,10 +70,8 @@ static int wl1251_fetch_firmware(struct +Index: linux-3.10-3.10.11/drivers/net/wireless/ti/wl1251/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ti/wl1251/main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ti/wl1251/main.c 2014-05-05 12:41:44.000000000 +0000 +@@ -70,10 +70,8 @@ ret = request_firmware(&fw, WL1251_FW_NAME, dev); @@ -1866,7 +2046,7 @@ if (fw->size % 4) { wl1251_error("firmware size is not multiple of 32 bits: %zu", -@@ -109,10 +107,8 @@ static int wl1251_fetch_nvs(struct wl125 +@@ -109,10 +107,8 @@ ret = request_firmware(&fw, WL1251_NVS_NAME, dev); @@ -1878,9 +2058,11 @@ if (fw->size % 4) { wl1251_error("nvs size is not multiple of 32 bits: %zu", ---- a/drivers/net/wireless/ti/wlcore/main.c -+++ b/drivers/net/wireless/ti/wlcore/main.c -@@ -753,10 +753,8 @@ static int wl12xx_fetch_firmware(struct +Index: linux-3.10-3.10.11/drivers/net/wireless/ti/wlcore/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ti/wlcore/main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ti/wlcore/main.c 2014-05-05 12:41:44.000000000 +0000 +@@ -753,10 +753,8 @@ ret = request_firmware(&fw, fw_name, wl->dev); @@ -1892,9 +2074,11 @@ if (fw->size % 4) { wl1271_error("firmware size is not multiple of 32 bits: %zu", ---- a/drivers/net/wireless/zd1201.c -+++ b/drivers/net/wireless/zd1201.c -@@ -65,8 +65,6 @@ static int zd1201_fw_upload(struct usb_d +Index: linux-3.10-3.10.11/drivers/net/wireless/zd1201.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/zd1201.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/zd1201.c 2014-05-05 12:41:44.000000000 +0000 +@@ -65,8 +65,6 @@ err = request_firmware(&fw_entry, fwfile, &dev->dev); if (err) { @@ -1903,9 +2087,11 @@ dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n"); return err; } ---- a/drivers/net/wireless/zd1211rw/zd_usb.c -+++ b/drivers/net/wireless/zd1211rw/zd_usb.c -@@ -121,16 +121,9 @@ static void int_urb_complete(struct urb +Index: linux-3.10-3.10.11/drivers/net/wireless/zd1211rw/zd_usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/zd1211rw/zd_usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/zd1211rw/zd_usb.c 2014-05-05 12:41:44.000000000 +0000 +@@ -121,16 +121,9 @@ static int request_fw_file( const struct firmware **fw, const char *name, struct device *device) { @@ -1923,9 +2109,11 @@ } static inline u16 get_bcdDevice(const struct usb_device *udev) ---- a/drivers/scsi/advansys.c -+++ b/drivers/scsi/advansys.c -@@ -4298,8 +4298,6 @@ static ushort AscInitAsc1000Driver(ASC_D +Index: linux-3.10-3.10.11/drivers/scsi/advansys.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/advansys.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/advansys.c 2014-05-05 12:41:44.000000000 +0000 +@@ -4298,8 +4298,6 @@ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); if (err) { @@ -1934,7 +2122,7 @@ asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; return err; } -@@ -4631,8 +4629,6 @@ static int AdvInitAsc3550Driver(ADV_DVC_ +@@ -4631,8 +4629,6 @@ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); if (err) { @@ -1943,7 +2131,7 @@ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return err; } -@@ -5147,8 +5143,6 @@ static int AdvInitAsc38C0800Driver(ADV_D +@@ -5147,8 +5143,6 @@ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); if (err) { @@ -1952,7 +2140,7 @@ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return err; } -@@ -5649,8 +5643,6 @@ static int AdvInitAsc38C1600Driver(ADV_D +@@ -5649,8 +5643,6 @@ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); if (err) { @@ -1961,9 +2149,11 @@ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return err; } ---- a/drivers/scsi/aic94xx/aic94xx_init.c -+++ b/drivers/scsi/aic94xx/aic94xx_init.c -@@ -397,8 +397,6 @@ static ssize_t asd_store_update_bios(str +Index: linux-3.10-3.10.11/drivers/scsi/aic94xx/aic94xx_init.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/aic94xx/aic94xx_init.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/aic94xx/aic94xx_init.c 2014-05-05 12:41:44.000000000 +0000 +@@ -397,8 +397,6 @@ filename_ptr, &asd_ha->pcidev->dev); if (err) { @@ -1972,9 +2162,11 @@ err = FAIL_OPEN_BIOS_FILE; goto out1; } ---- a/drivers/scsi/aic94xx/aic94xx_seq.c -+++ b/drivers/scsi/aic94xx/aic94xx_seq.c -@@ -1317,11 +1317,8 @@ int asd_init_seqs(struct asd_ha_struct * +Index: linux-3.10-3.10.11/drivers/scsi/aic94xx/aic94xx_seq.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/aic94xx/aic94xx_seq.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/aic94xx/aic94xx_seq.c 2014-05-05 12:41:44.000000000 +0000 +@@ -1317,11 +1317,8 @@ err = asd_request_firmware(asd_ha); @@ -1987,9 +2179,11 @@ err = asd_seq_download_seqs(asd_ha); if (err) { ---- a/drivers/scsi/bfa/bfad.c -+++ b/drivers/scsi/bfa/bfad.c -@@ -1803,7 +1803,6 @@ bfad_read_firmware(struct pci_dev *pdev, +Index: linux-3.10-3.10.11/drivers/scsi/bfa/bfad.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/bfa/bfad.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/bfa/bfad.c 2014-05-05 12:41:44.000000000 +0000 +@@ -1803,7 +1803,6 @@ const struct firmware *fw; if (request_firmware(&fw, fw_name, &pdev->dev)) { @@ -1997,9 +2191,11 @@ *bfi_image = NULL; goto out; } ---- a/drivers/scsi/ipr.c -+++ b/drivers/scsi/ipr.c -@@ -3907,10 +3907,8 @@ static ssize_t ipr_store_update_fw(struc +Index: linux-3.10-3.10.11/drivers/scsi/ipr.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/ipr.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/ipr.c 2014-05-05 12:41:44.000000000 +0000 +@@ -3907,10 +3907,8 @@ len = snprintf(fname, 99, "%s", buf); fname[len-1] = '\0'; @@ -2011,9 +2207,11 @@ image_hdr = (struct ipr_ucode_image_header *)fw_entry->data; ---- a/drivers/scsi/pm8001/pm8001_ctl.c -+++ b/drivers/scsi/pm8001/pm8001_ctl.c -@@ -542,9 +542,6 @@ static ssize_t pm8001_store_update_fw(st +Index: linux-3.10-3.10.11/drivers/scsi/pm8001/pm8001_ctl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/pm8001/pm8001_ctl.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/pm8001/pm8001_ctl.c 2014-05-05 12:41:44.000000000 +0000 +@@ -542,9 +542,6 @@ pm8001_ha->dev); if (err) { @@ -2023,9 +2221,11 @@ err = FAIL_OPEN_BIOS_FILE; goto out1; } ---- a/drivers/scsi/qla1280.c -+++ b/drivers/scsi/qla1280.c -@@ -1560,8 +1560,6 @@ qla1280_request_firmware(struct scsi_qla +Index: linux-3.10-3.10.11/drivers/scsi/qla1280.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/qla1280.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/qla1280.c 2014-05-05 12:41:44.000000000 +0000 +@@ -1560,8 +1560,6 @@ err = request_firmware(&fw, fwname, &ha->pdev->dev); if (err) { @@ -2034,9 +2234,11 @@ fw = ERR_PTR(err); goto unlock; } ---- a/drivers/scsi/qla2xxx/qla_init.c -+++ b/drivers/scsi/qla2xxx/qla_init.c -@@ -5134,8 +5134,6 @@ qla2x00_load_risc(scsi_qla_host_t *vha, +Index: linux-3.10-3.10.11/drivers/scsi/qla2xxx/qla_init.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/qla2xxx/qla_init.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/qla2xxx/qla_init.c 2014-05-05 12:41:44.000000000 +0000 +@@ -5134,8 +5134,6 @@ /* Load firmware blob. */ blob = qla2x00_request_firmware(vha); if (!blob) { @@ -2045,7 +2247,7 @@ ql_log(ql_log_info, vha, 0x0084, "Firmware images can be retrieved from: "QLA_FW_URL ".\n"); return QLA_FUNCTION_FAILED; -@@ -5236,8 +5234,6 @@ qla24xx_load_risc_blob(scsi_qla_host_t * +@@ -5236,8 +5234,6 @@ /* Load firmware blob. */ blob = qla2x00_request_firmware(vha); if (!blob) { @@ -2054,9 +2256,11 @@ ql_log(ql_log_warn, vha, 0x0091, "Firmware images can be retrieved from: " QLA_FW_URL ".\n"); ---- a/drivers/scsi/qla2xxx/qla_nx.c -+++ b/drivers/scsi/qla2xxx/qla_nx.c -@@ -2447,11 +2447,8 @@ try_blob_fw: +Index: linux-3.10-3.10.11/drivers/scsi/qla2xxx/qla_nx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/qla2xxx/qla_nx.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/qla2xxx/qla_nx.c 2014-05-05 12:41:44.000000000 +0000 +@@ -2441,11 +2441,8 @@ /* Load firmware blob. */ blob = ha->hablob = qla2x00_request_firmware(vha); @@ -2069,9 +2273,11 @@ /* Validating firmware blob */ if (qla82xx_validate_firmware_blob(vha, ---- a/drivers/scsi/qla2xxx/qla_os.c -+++ b/drivers/scsi/qla2xxx/qla_os.c -@@ -5204,8 +5204,6 @@ qla2x00_request_firmware(scsi_qla_host_t +Index: linux-3.10-3.10.11/drivers/scsi/qla2xxx/qla_os.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/qla2xxx/qla_os.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/qla2xxx/qla_os.c 2014-05-05 12:41:44.000000000 +0000 +@@ -5204,8 +5204,6 @@ goto out; if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) { @@ -2080,9 +2286,11 @@ blob->fw = NULL; blob = NULL; goto out; ---- a/drivers/scsi/qlogicpti.c -+++ b/drivers/scsi/qlogicpti.c -@@ -475,11 +475,8 @@ static int qlogicpti_load_firmware(struc +Index: linux-3.10-3.10.11/drivers/scsi/qlogicpti.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/qlogicpti.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/qlogicpti.c 2014-05-05 12:41:44.000000000 +0000 +@@ -475,11 +475,8 @@ int i, timeout; err = request_firmware(&fw, fwname, &qpti->op->dev); @@ -2095,9 +2303,11 @@ if (fw->size % 2) { printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", fw->size, fwname); ---- a/drivers/staging/comedi/drivers/usbdux.c -+++ b/drivers/staging/comedi/drivers/usbdux.c -@@ -2376,11 +2376,8 @@ static void usbdux_firmware_request_comp +Index: linux-3.10-3.10.11/drivers/staging/comedi/drivers/usbdux.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/comedi/drivers/usbdux.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/comedi/drivers/usbdux.c 2014-05-05 12:41:45.000000000 +0000 +@@ -2376,11 +2376,8 @@ struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; @@ -2110,9 +2320,11 @@ /* * we need to upload the firmware here because fw will be ---- a/drivers/staging/comedi/drivers/usbduxsigma.c -+++ b/drivers/staging/comedi/drivers/usbduxsigma.c -@@ -2358,11 +2358,8 @@ static void usbdux_firmware_request_comp +Index: linux-3.10-3.10.11/drivers/staging/comedi/drivers/usbduxsigma.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/comedi/drivers/usbduxsigma.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/comedi/drivers/usbduxsigma.c 2014-05-05 12:41:45.000000000 +0000 +@@ -2358,11 +2358,8 @@ struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; @@ -2125,9 +2337,11 @@ /* * we need to upload the firmware here because fw will be ---- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c -+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c -@@ -2203,16 +2203,12 @@ struct net_device *init_ft1000_card(stru +Index: linux-3.10-3.10.11/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c 2014-05-05 12:41:45.000000000 +0000 +@@ -2203,16 +2203,12 @@ info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (info->AsicID == ELECTRABUZZ_ID) { DEBUG(0, "ft1000_hw: ELECTRABUZZ ASIC\n"); @@ -2146,9 +2360,11 @@ } ft1000_enable_interrupts(dev); ---- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c -+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c -@@ -134,10 +134,8 @@ static int ft1000_probe(struct usb_inter +Index: linux-3.10-3.10.11/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c 2014-05-05 12:41:45.000000000 +0000 +@@ -134,10 +134,8 @@ ft1000dev->bulk_out_endpointAddr); ret = request_firmware(&dsp_fw, "ft3000.img", &dev->dev); @@ -2160,9 +2376,11 @@ size = max_t(uint, dsp_fw->size, 4096); pFileStart = kmalloc(size, GFP_KERNEL); ---- a/drivers/staging/media/as102/as102_fw.c -+++ b/drivers/staging/media/as102/as102_fw.c -@@ -190,11 +190,8 @@ int as102_fw_upload(struct as10x_bus_ada +Index: linux-3.10-3.10.11/drivers/staging/media/as102/as102_fw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/media/as102/as102_fw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/media/as102/as102_fw.c 2014-05-05 12:41:45.000000000 +0000 +@@ -190,11 +190,8 @@ /* request kernel to locate firmware file: part1 */ errno = request_firmware(&firmware, fw1, &dev->dev); @@ -2175,7 +2393,7 @@ /* initiate firmware upload */ errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); -@@ -213,11 +210,8 @@ int as102_fw_upload(struct as10x_bus_ada +@@ -213,11 +210,8 @@ /* request kernel to locate firmware file: part2 */ errno = request_firmware(&firmware, fw2, &dev->dev); @@ -2188,9 +2406,11 @@ /* initiate firmware upload */ errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); ---- a/drivers/staging/media/go7007/go7007-driver.c -+++ b/drivers/staging/media/go7007/go7007-driver.c -@@ -96,10 +96,8 @@ static int go7007_load_encoder(struct go +Index: linux-3.10-3.10.11/drivers/staging/media/go7007/go7007-driver.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/media/go7007/go7007-driver.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/media/go7007/go7007-driver.c 2014-05-05 12:41:45.000000000 +0000 +@@ -96,10 +96,8 @@ u16 intr_val, intr_data; if (go->boot_fw == NULL) { @@ -2202,9 +2422,11 @@ if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name); release_firmware(fw_entry); ---- a/drivers/staging/media/go7007/go7007-fw.c -+++ b/drivers/staging/media/go7007/go7007-fw.c -@@ -1570,12 +1570,8 @@ int go7007_construct_fw_image(struct go7 +Index: linux-3.10-3.10.11/drivers/staging/media/go7007/go7007-fw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/media/go7007/go7007-fw.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/media/go7007/go7007-fw.c 2014-05-05 12:41:45.000000000 +0000 +@@ -1570,12 +1570,8 @@ default: return -1; } @@ -2218,9 +2440,11 @@ code = kzalloc(codespace * 2, GFP_KERNEL); if (code == NULL) goto fw_failed; ---- a/drivers/staging/media/go7007/go7007-loader.c -+++ b/drivers/staging/media/go7007/go7007-loader.c -@@ -80,11 +80,8 @@ static int go7007_loader_probe(struct us +Index: linux-3.10-3.10.11/drivers/staging/media/go7007/go7007-loader.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/media/go7007/go7007-loader.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/media/go7007/go7007-loader.c 2014-05-05 12:41:45.000000000 +0000 +@@ -80,11 +80,8 @@ dev_info(&interface->dev, "loading firmware %s\n", fw1); @@ -2233,7 +2457,7 @@ ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); release_firmware(fw); if (0 != ret) { -@@ -95,11 +92,8 @@ static int go7007_loader_probe(struct us +@@ -95,11 +92,8 @@ if (fw2 == NULL) return 0; @@ -2246,9 +2470,11 @@ ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); release_firmware(fw); if (0 != ret) { ---- a/drivers/staging/media/lirc/lirc_zilog.c -+++ b/drivers/staging/media/lirc/lirc_zilog.c -@@ -764,8 +764,6 @@ static int fw_load(struct IR_tx *tx) +Index: linux-3.10-3.10.11/drivers/staging/media/lirc/lirc_zilog.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/media/lirc/lirc_zilog.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/media/lirc/lirc_zilog.c 2014-05-05 12:41:45.000000000 +0000 +@@ -764,8 +764,6 @@ /* Request codeset data file */ ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev); if (ret != 0) { @@ -2257,9 +2483,11 @@ ret = ret < 0 ? ret : -EFAULT; goto out; } ---- a/drivers/staging/rtl8192u/r819xU_firmware.c -+++ b/drivers/staging/rtl8192u/r819xU_firmware.c -@@ -284,10 +284,8 @@ bool init_firmware(struct net_device *de +Index: linux-3.10-3.10.11/drivers/staging/rtl8192u/r819xU_firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/rtl8192u/r819xU_firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/rtl8192u/r819xU_firmware.c 2014-05-05 12:41:45.000000000 +0000 +@@ -284,10 +284,8 @@ */ if(rst_opt == OPT_SYSTEM_RESET) { rc = request_firmware(&fw_entry, fw_name[init_step],&priv->udev->dev); @@ -2271,9 +2499,11 @@ if(fw_entry->size > sizeof(pfirmware->firmware_buf)) { RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); ---- a/drivers/staging/rtl8712/hal_init.c -+++ b/drivers/staging/rtl8712/hal_init.c -@@ -49,7 +49,6 @@ static void rtl871x_load_fw_cb(const str +Index: linux-3.10-3.10.11/drivers/staging/rtl8712/hal_init.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/rtl8712/hal_init.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/rtl8712/hal_init.c 2014-05-05 12:41:45.000000000 +0000 +@@ -49,7 +49,6 @@ if (!firmware) { struct usb_device *udev = padapter->dvobjpriv.pusbdev; struct usb_interface *pusb_intf = padapter->pusb_intf; @@ -2281,9 +2511,11 @@ padapter->fw_found = false; usb_put_dev(udev); usb_set_intfdata(pusb_intf, NULL); ---- a/drivers/staging/slicoss/slicoss.c -+++ b/drivers/staging/slicoss/slicoss.c -@@ -424,11 +424,8 @@ static int slic_card_download_gbrcv(stru +Index: linux-3.10-3.10.11/drivers/staging/slicoss/slicoss.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/slicoss/slicoss.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/slicoss/slicoss.c 2014-05-05 12:41:45.000000000 +0000 +@@ -424,11 +424,8 @@ } ret = request_firmware(&fw, file, &adapter->pcidev->dev); @@ -2296,7 +2528,7 @@ rcvucodelen = *(u32 *)(fw->data + index); index += 4; -@@ -502,11 +499,8 @@ static int slic_card_download(struct ada +@@ -502,11 +499,8 @@ return -ENOENT; } ret = request_firmware(&fw, file, &adapter->pcidev->dev); @@ -2309,9 +2541,11 @@ numsects = *(u32 *)(fw->data + index); index += 4; for (i = 0; i < numsects; i++) { ---- a/drivers/staging/vt6656/firmware.c -+++ b/drivers/staging/vt6656/firmware.c -@@ -57,11 +57,8 @@ int FIRMWAREbDownload(struct vnt_private +Index: linux-3.10-3.10.11/drivers/staging/vt6656/firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/vt6656/firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/vt6656/firmware.c 2014-05-05 12:41:45.000000000 +0000 +@@ -57,11 +57,8 @@ spin_unlock_irq(&pDevice->lock); rc = request_firmware(&fw, FIRMWARE_NAME, dev); @@ -2325,9 +2559,11 @@ pBuffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); if (!pBuffer) ---- a/drivers/tty/cyclades.c -+++ b/drivers/tty/cyclades.c -@@ -3520,10 +3520,8 @@ static int cyz_load_fw(struct pci_dev *p +Index: linux-3.10-3.10.11/drivers/tty/cyclades.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/cyclades.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/cyclades.c 2014-05-05 12:41:45.000000000 +0000 +@@ -3520,10 +3520,8 @@ int retval; retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev); @@ -2339,9 +2575,11 @@ /* Check whether the firmware is already loaded and running. If positive, skip this board */ ---- a/drivers/tty/moxa.c -+++ b/drivers/tty/moxa.c -@@ -867,13 +867,8 @@ static int moxa_init_board(struct moxa_b +Index: linux-3.10-3.10.11/drivers/tty/moxa.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/moxa.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/moxa.c 2014-05-05 12:41:45.000000000 +0000 +@@ -867,13 +867,8 @@ } ret = request_firmware(&fw, file, dev); @@ -2356,9 +2594,11 @@ ret = moxa_load_fw(brd, fw); ---- a/drivers/tty/serial/icom.c -+++ b/drivers/tty/serial/icom.c -@@ -373,7 +373,6 @@ static void load_code(struct icom_port * +Index: linux-3.10-3.10.11/drivers/tty/serial/icom.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/serial/icom.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/serial/icom.c 2014-05-05 12:41:45.000000000 +0000 +@@ -373,7 +373,6 @@ /* Load Call Setup into Adapter */ if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) { @@ -2366,7 +2606,7 @@ status = -1; goto load_code_exit; } -@@ -393,7 +392,6 @@ static void load_code(struct icom_port * +@@ -393,7 +392,6 @@ /* Load Resident DCE portion of Adapter */ if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) { @@ -2374,7 +2614,7 @@ status = -1; goto load_code_exit; } -@@ -438,7 +436,6 @@ static void load_code(struct icom_port * +@@ -438,7 +436,6 @@ } if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) { @@ -2382,9 +2622,11 @@ status = -1; goto load_code_exit; } ---- a/drivers/tty/serial/ucc_uart.c -+++ b/drivers/tty/serial/ucc_uart.c -@@ -1176,10 +1176,8 @@ static void uart_firmware_cont(const str +Index: linux-3.10-3.10.11/drivers/tty/serial/ucc_uart.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/serial/ucc_uart.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/serial/ucc_uart.c 2014-05-05 12:41:45.000000000 +0000 +@@ -1176,10 +1176,8 @@ struct device *dev = context; int ret; @@ -2396,9 +2638,11 @@ firmware = (struct qe_firmware *) fw->data; ---- a/drivers/usb/atm/cxacru.c -+++ b/drivers/usb/atm/cxacru.c -@@ -1082,8 +1082,6 @@ static int cxacru_find_firmware(struct c +Index: linux-3.10-3.10.11/drivers/usb/atm/cxacru.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/atm/cxacru.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/atm/cxacru.c 2014-05-05 12:41:45.000000000 +0000 +@@ -1082,8 +1082,6 @@ return -ENOENT; } @@ -2407,9 +2651,11 @@ return 0; } ---- a/drivers/usb/atm/ueagle-atm.c -+++ b/drivers/usb/atm/ueagle-atm.c -@@ -650,10 +650,8 @@ static void uea_upload_pre_firmware(cons +Index: linux-3.10-3.10.11/drivers/usb/atm/ueagle-atm.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/atm/ueagle-atm.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/atm/ueagle-atm.c 2014-05-05 12:41:45.000000000 +0000 +@@ -650,10 +650,8 @@ int ret, size; uea_enters(usb); @@ -2421,7 +2667,7 @@ pfw = fw_entry->data; size = fw_entry->size; -@@ -748,10 +746,6 @@ static int uea_load_firmware(struct usb_ +@@ -748,10 +746,6 @@ ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, GFP_KERNEL, usb, uea_upload_pre_firmware); @@ -2432,7 +2678,7 @@ uea_leaves(usb); return ret; -@@ -913,12 +907,8 @@ static int request_dsp(struct uea_softc +@@ -913,12 +907,8 @@ } ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev); @@ -2446,7 +2692,7 @@ if (UEA_CHIP_VERSION(sc) == EAGLE_IV) ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size); -@@ -1631,12 +1621,8 @@ static int request_cmvs_old(struct uea_s +@@ -1631,12 +1621,8 @@ cmvs_file_name(sc, cmv_name, 1); ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); @@ -2460,7 +2706,7 @@ data = (u8 *) (*fw)->data; size = (*fw)->size; -@@ -1673,9 +1659,6 @@ static int request_cmvs(struct uea_softc +@@ -1673,9 +1659,6 @@ "try to get older cmvs\n", cmv_name); return request_cmvs_old(sc, cmvs, fw); } @@ -2470,7 +2716,7 @@ return ret; } -@@ -1958,11 +1941,8 @@ static int load_XILINX_firmware(struct u +@@ -1958,11 +1941,8 @@ uea_enters(INS_TO_USBDEV(sc)); ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev); @@ -2483,9 +2729,11 @@ pfw = fw_entry->data; size = fw_entry->size; ---- a/drivers/usb/misc/emi26.c -+++ b/drivers/usb/misc/emi26.c -@@ -89,21 +89,17 @@ static int emi26_load_firmware (struct u +Index: linux-3.10-3.10.11/drivers/usb/misc/emi26.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/misc/emi26.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/misc/emi26.c 2014-05-05 12:41:45.000000000 +0000 +@@ -89,21 +89,17 @@ err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev); if (err) @@ -2510,9 +2758,11 @@ /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); ---- a/drivers/usb/misc/ezusb.c -+++ b/drivers/usb/misc/ezusb.c -@@ -80,12 +80,8 @@ static int ezusb_ihex_firmware_download( +Index: linux-3.10-3.10.11/drivers/usb/misc/ezusb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/misc/ezusb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/misc/ezusb.c 2014-05-05 12:41:45.000000000 +0000 +@@ -80,12 +80,8 @@ const struct ihex_binrec *record; if (request_ihex_firmware(&firmware, firmware_path, @@ -2526,9 +2776,11 @@ ret = ezusb_set_reset(dev, fx.cpucs_reg, 0); if (ret < 0) ---- a/drivers/usb/misc/isight_firmware.c -+++ b/drivers/usb/misc/isight_firmware.c -@@ -48,7 +48,6 @@ static int isight_firmware_load(struct u +Index: linux-3.10-3.10.11/drivers/usb/misc/isight_firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/misc/isight_firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/misc/isight_firmware.c 2014-05-05 12:41:45.000000000 +0000 +@@ -48,7 +48,6 @@ return -ENOMEM; if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { @@ -2536,9 +2788,11 @@ ret = -ENODEV; goto out; } ---- a/drivers/usb/serial/io_edgeport.c -+++ b/drivers/usb/serial/io_edgeport.c -@@ -302,11 +302,8 @@ static void update_edgeport_E2PROM(struc +Index: linux-3.10-3.10.11/drivers/usb/serial/io_edgeport.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/io_edgeport.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/io_edgeport.c 2014-05-05 12:41:45.000000000 +0000 +@@ -302,11 +302,8 @@ response = request_ihex_firmware(&fw, fw_name, &edge_serial->serial->dev->dev); @@ -2551,9 +2805,11 @@ rec = (const struct ihex_binrec *)fw->data; BootMajorVersion = rec->data[0]; ---- a/drivers/usb/serial/io_ti.c -+++ b/drivers/usb/serial/io_ti.c -@@ -782,8 +782,6 @@ static int build_i2c_fw_hdr(__u8 *header +Index: linux-3.10-3.10.11/drivers/usb/serial/io_ti.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/io_ti.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/io_ti.c 2014-05-05 12:41:45.000000000 +0000 +@@ -782,8 +782,6 @@ err = request_firmware(&fw, fw_name, dev); if (err) { @@ -2562,7 +2818,7 @@ kfree(buffer); return err; } -@@ -1341,8 +1339,6 @@ static int download_fw(struct edgeport_s +@@ -1341,8 +1339,6 @@ err = request_firmware(&fw, fw_name, dev); if (err) { @@ -2571,9 +2827,11 @@ kfree(buffer); return err; } ---- a/drivers/usb/serial/ti_usb_3410_5052.c -+++ b/drivers/usb/serial/ti_usb_3410_5052.c -@@ -1571,10 +1571,8 @@ static int ti_download_firmware(struct t +Index: linux-3.10-3.10.11/drivers/usb/serial/ti_usb_3410_5052.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/ti_usb_3410_5052.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/ti_usb_3410_5052.c 2014-05-05 12:41:45.000000000 +0000 +@@ -1572,10 +1572,8 @@ } status = request_firmware(&fw_p, buf, &dev->dev); } @@ -2585,9 +2843,11 @@ if (fw_p->size > TI_FIRMWARE_BUF_SIZE) { dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size); release_firmware(fw_p); ---- a/drivers/video/broadsheetfb.c -+++ b/drivers/video/broadsheetfb.c -@@ -741,10 +741,8 @@ static ssize_t broadsheet_loadstore_wave +Index: linux-3.10-3.10.11/drivers/video/broadsheetfb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/broadsheetfb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/broadsheetfb.c 2014-05-05 12:41:45.000000000 +0000 +@@ -741,10 +741,8 @@ return -EINVAL; err = request_firmware(&fw_entry, "broadsheet.wbf", dev); @@ -2599,9 +2859,11 @@ /* try to enforce reasonable min max on waveform */ if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) { ---- a/drivers/video/metronomefb.c -+++ b/drivers/video/metronomefb.c -@@ -677,10 +677,8 @@ static int metronomefb_probe(struct plat +Index: linux-3.10-3.10.11/drivers/video/metronomefb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/metronomefb.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/metronomefb.c 2014-05-05 12:41:45.000000000 +0000 +@@ -677,10 +677,8 @@ a) request the waveform file from userspace b) process waveform and decode into metromem */ retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev); @@ -2613,9 +2875,11 @@ retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31, par); ---- a/sound/drivers/vx/vx_hwdep.c -+++ b/sound/drivers/vx/vx_hwdep.c -@@ -71,10 +71,8 @@ int snd_vx_setup_firmware(struct vx_core +Index: linux-3.10-3.10.11/sound/drivers/vx/vx_hwdep.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/drivers/vx/vx_hwdep.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/drivers/vx/vx_hwdep.c 2014-05-05 12:41:45.000000000 +0000 +@@ -71,10 +71,8 @@ if (! fw_files[chip->type][i]) continue; sprintf(path, "vx/%s", fw_files[chip->type][i]); @@ -2627,9 +2891,11 @@ err = chip->ops->load_dsp(chip, i, fw); if (err < 0) { release_firmware(fw); ---- a/sound/isa/msnd/msnd_pinnacle.c -+++ b/sound/isa/msnd/msnd_pinnacle.c -@@ -387,15 +387,11 @@ static int upload_dsp_code(struct snd_ca +Index: linux-3.10-3.10.11/sound/isa/msnd/msnd_pinnacle.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/isa/msnd/msnd_pinnacle.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/isa/msnd/msnd_pinnacle.c 2014-05-05 12:41:45.000000000 +0000 +@@ -387,15 +387,11 @@ outb(HPBLKSEL_0, chip->io + HP_BLKS); err = request_firmware(&init_fw, INITCODEFILE, card->dev); @@ -2647,9 +2913,11 @@ memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size); if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) { ---- a/sound/isa/sscape.c -+++ b/sound/isa/sscape.c -@@ -543,10 +543,8 @@ static int sscape_upload_bootblock(struc +Index: linux-3.10-3.10.11/sound/isa/sscape.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/isa/sscape.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/isa/sscape.c 2014-05-05 12:41:45.000000000 +0000 +@@ -543,10 +543,8 @@ int ret; ret = request_firmware(&init_fw, "scope.cod", card->dev); @@ -2661,7 +2929,7 @@ ret = upload_dma_data(sscape, init_fw->data, init_fw->size); release_firmware(init_fw); -@@ -583,11 +581,8 @@ static int sscape_upload_microcode(struc +@@ -583,11 +581,8 @@ snprintf(name, sizeof(name), "sndscape.co%d", version); err = request_firmware(&init_fw, name, card->dev); @@ -2674,9 +2942,11 @@ err = upload_dma_data(sscape, init_fw->data, init_fw->size); if (err == 0) snd_printk(KERN_INFO "sscape: MIDI firmware loaded %d KBs\n", ---- a/sound/isa/wavefront/wavefront_synth.c -+++ b/sound/isa/wavefront/wavefront_synth.c -@@ -1947,10 +1947,8 @@ wavefront_download_firmware (snd_wavefro +Index: linux-3.10-3.10.11/sound/isa/wavefront/wavefront_synth.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/isa/wavefront/wavefront_synth.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/isa/wavefront/wavefront_synth.c 2014-05-05 12:41:46.000000000 +0000 +@@ -1947,10 +1947,8 @@ const struct firmware *firmware; err = request_firmware(&firmware, path, dev->card->dev); @@ -2688,9 +2958,11 @@ len = 0; buf = firmware->data; ---- a/sound/pci/asihpi/hpidspcd.c -+++ b/sound/pci/asihpi/hpidspcd.c -@@ -49,8 +49,6 @@ short hpi_dsp_code_open(u32 adapter, voi +Index: linux-3.10-3.10.11/sound/pci/asihpi/hpidspcd.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/asihpi/hpidspcd.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/asihpi/hpidspcd.c 2014-05-05 12:41:46.000000000 +0000 +@@ -49,8 +49,6 @@ err = request_firmware(&firmware, fw_name, &dev->dev); if (err || !firmware) { @@ -2699,9 +2971,11 @@ goto error1; } if (firmware->size < sizeof(header)) { ---- a/sound/pci/cs46xx/cs46xx_lib.c -+++ b/sound/pci/cs46xx/cs46xx_lib.c -@@ -411,10 +411,8 @@ static int snd_cs46xx_download_image(str +Index: linux-3.10-3.10.11/sound/pci/cs46xx/cs46xx_lib.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/cs46xx/cs46xx_lib.c 2014-05-05 12:41:35.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/cs46xx/cs46xx_lib.c 2014-05-05 12:41:46.000000000 +0000 +@@ -411,10 +411,8 @@ err = request_firmware(&firmware, "cs46xx/cs46xx-old.fw", &chip->pci->dev); @@ -2713,9 +2987,11 @@ err = snd_cs46xx_check_image_size(firmware); if (err < 0) ---- a/sound/pci/echoaudio/echoaudio.c -+++ b/sound/pci/echoaudio/echoaudio.c -@@ -57,10 +57,8 @@ static int get_firmware(const struct fir +Index: linux-3.10-3.10.11/sound/pci/echoaudio/echoaudio.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/echoaudio/echoaudio.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/echoaudio/echoaudio.c 2014-05-05 12:41:46.000000000 +0000 +@@ -57,10 +57,8 @@ DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); err = request_firmware(fw_entry, name, pci_device(chip)); @@ -2727,9 +3003,11 @@ chip->fw_cache[fw_index] = *fw_entry; #endif return err; ---- a/sound/pci/emu10k1/emu10k1_main.c -+++ b/sound/pci/emu10k1/emu10k1_main.c -@@ -879,10 +879,8 @@ static int snd_emu10k1_emu1010_init(stru +Index: linux-3.10-3.10.11/sound/pci/emu10k1/emu10k1_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/emu10k1/emu10k1_main.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/emu10k1/emu10k1_main.c 2014-05-05 12:41:46.000000000 +0000 +@@ -879,10 +879,8 @@ } err = request_firmware(&emu->firmware, filename, &emu->pci->dev); @@ -2741,9 +3019,11 @@ snd_printk(KERN_INFO "emu1010: firmware file = %s, size = 0x%zx\n", filename, emu->firmware->size); } ---- a/sound/pci/hda/hda_intel.c -+++ b/sound/pci/hda/hda_intel.c -@@ -3664,11 +3664,8 @@ static void azx_firmware_cb(const struct +Index: linux-3.10-3.10.11/sound/pci/hda/hda_intel.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/hda_intel.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/hda_intel.c 2014-05-05 12:41:46.000000000 +0000 +@@ -3664,11 +3664,8 @@ struct azx *chip = card->private_data; struct pci_dev *pci = chip->pci; @@ -2756,9 +3036,11 @@ chip->fw = fw; if (!chip->disabled) { ---- a/sound/pci/korg1212/korg1212.c -+++ b/sound/pci/korg1212/korg1212.c -@@ -2346,7 +2346,6 @@ static int snd_korg1212_create(struct sn +Index: linux-3.10-3.10.11/sound/pci/korg1212/korg1212.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/korg1212/korg1212.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/korg1212/korg1212.c 2014-05-05 12:41:46.000000000 +0000 +@@ -2346,7 +2346,6 @@ err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); if (err < 0) { release_firmware(dsp_code); @@ -2766,9 +3048,11 @@ snd_korg1212_free(korg1212); return err; } ---- a/sound/pci/mixart/mixart_hwdep.c -+++ b/sound/pci/mixart/mixart_hwdep.c -@@ -558,10 +558,8 @@ int snd_mixart_setup_firmware(struct mix +Index: linux-3.10-3.10.11/sound/pci/mixart/mixart_hwdep.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/mixart/mixart_hwdep.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/mixart/mixart_hwdep.c 2014-05-05 12:41:46.000000000 +0000 +@@ -558,10 +558,8 @@ for (i = 0; i < 3; i++) { sprintf(path, "mixart/%s", fw_files[i]); @@ -2780,9 +3064,11 @@ /* fake hwdep dsp record */ err = mixart_dsp_load(mgr, i, fw_entry); release_firmware(fw_entry); ---- a/sound/pci/pcxhr/pcxhr_hwdep.c -+++ b/sound/pci/pcxhr/pcxhr_hwdep.c -@@ -381,11 +381,8 @@ int pcxhr_setup_firmware(struct pcxhr_mg +Index: linux-3.10-3.10.11/sound/pci/pcxhr/pcxhr_hwdep.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/pcxhr/pcxhr_hwdep.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/pcxhr/pcxhr_hwdep.c 2014-05-05 12:41:46.000000000 +0000 +@@ -381,11 +381,8 @@ if (!fw_files[fw_set][i]) continue; sprintf(path, "pcxhr/%s", fw_files[fw_set][i]); @@ -2795,9 +3081,11 @@ /* fake hwdep dsp record */ err = pcxhr_dsp_load(mgr, i, fw_entry); release_firmware(fw_entry); ---- a/sound/pci/riptide/riptide.c -+++ b/sound/pci/riptide/riptide.c -@@ -1245,11 +1245,8 @@ static int try_to_load_firmware(struct c +Index: linux-3.10-3.10.11/sound/pci/riptide/riptide.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/riptide/riptide.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/riptide/riptide.c 2014-05-05 12:41:46.000000000 +0000 +@@ -1245,11 +1245,8 @@ if (!chip->fw_entry) { err = request_firmware(&chip->fw_entry, "riptide.hex", &chip->pci->dev); @@ -2810,9 +3098,11 @@ } err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size); if (err) { ---- a/sound/pci/rme9652/hdsp.c -+++ b/sound/pci/rme9652/hdsp.c -@@ -5150,10 +5150,8 @@ static int hdsp_request_fw_loader(struct +Index: linux-3.10-3.10.11/sound/pci/rme9652/hdsp.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/rme9652/hdsp.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/rme9652/hdsp.c 2014-05-05 12:41:46.000000000 +0000 +@@ -5150,10 +5150,8 @@ return -EINVAL; } @@ -2824,9 +3114,11 @@ if (fw->size < HDSP_FIRMWARE_SIZE) { snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n", (int)fw->size, HDSP_FIRMWARE_SIZE); ---- a/sound/soc/codecs/wm2000.c -+++ b/sound/soc/codecs/wm2000.c -@@ -888,10 +888,8 @@ static int wm2000_i2c_probe(struct i2c_c +Index: linux-3.10-3.10.11/sound/soc/codecs/wm2000.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/codecs/wm2000.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/codecs/wm2000.c 2014-05-05 12:41:46.000000000 +0000 +@@ -888,10 +888,8 @@ } ret = request_firmware(&fw, filename, &i2c->dev); @@ -2838,9 +3130,11 @@ /* Pre-cook the concatenation of the register address onto the image */ wm2000->anc_download_size = fw->size + 2; ---- a/sound/usb/6fire/firmware.c -+++ b/sound/usb/6fire/firmware.c -@@ -219,8 +219,6 @@ static int usb6fire_fw_ezusb_upload( +Index: linux-3.10-3.10.11/sound/usb/6fire/firmware.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/usb/6fire/firmware.c 2014-05-05 11:52:39.000000000 +0000 ++++ linux-3.10-3.10.11/sound/usb/6fire/firmware.c 2014-05-05 12:41:46.000000000 +0000 +@@ -219,8 +219,6 @@ ret = request_firmware(&fw, fwname, &device->dev); if (ret < 0) { kfree(rec); @@ -2849,7 +3143,7 @@ return ret; } ret = usb6fire_fw_ihex_init(fw, rec); -@@ -292,8 +290,6 @@ static int usb6fire_fw_fpga_upload( +@@ -292,8 +290,6 @@ ret = request_firmware(&fw, fwname, &device->dev); if (ret < 0) { diff -Nru linux-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers-rtlwifi.patch linux-3.10-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers-rtlwifi.patch --- linux-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers-rtlwifi.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers-rtlwifi.patch 2014-05-05 13:15:25.000000000 +0000 @@ -0,0 +1,24 @@ +Index: linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/rtlwifi/core.c 2014-05-05 13:06:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/core.c 2014-05-05 13:15:24.000000000 +0000 +@@ -55,7 +55,6 @@ + if (!err) + goto found_alt; + } +- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } +Index: linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/rtlwifi/rtl8192se/sw.c 2014-05-05 11:38:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/rtl8192se/sw.c 2014-05-05 13:15:24.000000000 +0000 +@@ -97,7 +97,6 @@ + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { +- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } diff -Nru linux-3.10.11/debian/patches/bugfix/all/HID-check-for-NULL-field-when-setting-values.patch linux-3.10-3.10.11/debian/patches/bugfix/all/HID-check-for-NULL-field-when-setting-values.patch --- linux-3.10.11/debian/patches/bugfix/all/HID-check-for-NULL-field-when-setting-values.patch 2013-09-10 03:48:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/HID-check-for-NULL-field-when-setting-values.patch 2013-12-23 04:40:19.000000000 +0000 @@ -12,9 +12,11 @@ drivers/hid/hid-core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -1156,7 +1156,12 @@ EXPORT_SYMBOL_GPL(hid_output_report); +Index: linux-3.10.11.rpi/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/hid/hid-core.c 2013-12-23 04:40:14.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/hid/hid-core.c 2013-12-23 04:40:18.000000000 +0000 +@@ -1156,7 +1156,12 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) { diff -Nru linux-3.10.11/debian/patches/bugfix/all/HID-ntrig-validate-feature-report-details.patch linux-3.10-3.10.11/debian/patches/bugfix/all/HID-ntrig-validate-feature-report-details.patch --- linux-3.10.11/debian/patches/bugfix/all/HID-ntrig-validate-feature-report-details.patch 2013-09-10 03:47:54.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/HID-ntrig-validate-feature-report-details.patch 2013-12-23 04:40:16.000000000 +0000 @@ -21,11 +21,11 @@ drivers/hid/hid-ntrig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c -index 98d1fdf..600f207 100644 ---- a/drivers/hid/hid-ntrig.c -+++ b/drivers/hid/hid-ntrig.c -@@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev) +Index: linux-3.10.11.rpi/drivers/hid/hid-ntrig.c +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/hid/hid-ntrig.c 2013-12-23 01:36:07.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/hid/hid-ntrig.c 2013-12-23 04:40:16.000000000 +0000 +@@ -115,7 +115,8 @@ struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. report_id_hash[0x0d]; diff -Nru linux-3.10.11/debian/patches/bugfix/all/HID-pantherlord-validate-output-report-details.patch linux-3.10-3.10.11/debian/patches/bugfix/all/HID-pantherlord-validate-output-report-details.patch --- linux-3.10.11/debian/patches/bugfix/all/HID-pantherlord-validate-output-report-details.patch 2013-09-10 03:47:54.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/HID-pantherlord-validate-output-report-details.patch 2013-12-23 04:40:16.000000000 +0000 @@ -20,11 +20,11 @@ drivers/hid/hid-pl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) -diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c -index d29112f..2dcd7d9 100644 ---- a/drivers/hid/hid-pl.c -+++ b/drivers/hid/hid-pl.c -@@ -132,8 +132,14 @@ static int plff_init(struct hid_device *hid) +Index: linux-3.10.11.rpi/drivers/hid/hid-pl.c +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/hid/hid-pl.c 2013-12-23 01:36:08.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/hid/hid-pl.c 2013-12-23 04:40:15.000000000 +0000 +@@ -132,8 +132,14 @@ strong = &report->field[0]->value[2]; weak = &report->field[0]->value[3]; debug("detected single-field device"); diff -Nru linux-3.10.11/debian/patches/bugfix/all/HID-picolcd_core-validate-output-report-details.patch linux-3.10-3.10.11/debian/patches/bugfix/all/HID-picolcd_core-validate-output-report-details.patch --- linux-3.10.11/debian/patches/bugfix/all/HID-picolcd_core-validate-output-report-details.patch 2013-09-10 03:47:54.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/HID-picolcd_core-validate-output-report-details.patch 2013-12-23 04:40:18.000000000 +0000 @@ -30,11 +30,11 @@ drivers/hid/hid-picolcd_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c -index b48092d..acbb0210 100644 ---- a/drivers/hid/hid-picolcd_core.c -+++ b/drivers/hid/hid-picolcd_core.c -@@ -290,7 +290,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, +Index: linux-3.10.11.rpi/drivers/hid/hid-picolcd_core.c +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/hid/hid-picolcd_core.c 2013-12-23 01:36:07.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/hid/hid-picolcd_core.c 2013-12-23 04:40:17.000000000 +0000 +@@ -290,7 +290,7 @@ buf += 10; cnt -= 10; } diff -Nru linux-3.10.11/debian/patches/bugfix/all/HID-sensor-hub-validate-feature-report-details.patch linux-3.10-3.10.11/debian/patches/bugfix/all/HID-sensor-hub-validate-feature-report-details.patch --- linux-3.10.11/debian/patches/bugfix/all/HID-sensor-hub-validate-feature-report-details.patch 2013-09-10 03:47:54.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/HID-sensor-hub-validate-feature-report-details.patch 2013-12-23 04:40:17.000000000 +0000 @@ -17,11 +17,11 @@ drivers/hid/hid-sensor-hub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c -index ffc80cf..6fca30e 100644 ---- a/drivers/hid/hid-sensor-hub.c -+++ b/drivers/hid/hid-sensor-hub.c -@@ -221,7 +221,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, +Index: linux-3.10.11.rpi/drivers/hid/hid-sensor-hub.c +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/hid/hid-sensor-hub.c 2013-12-23 02:26:47.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/hid/hid-sensor-hub.c 2013-12-23 04:40:17.000000000 +0000 +@@ -221,7 +221,8 @@ mutex_lock(&data->mutex); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); diff -Nru linux-3.10.11/debian/patches/bugfix/all/HID-validate-HID-report-id-size.patch linux-3.10-3.10.11/debian/patches/bugfix/all/HID-validate-HID-report-id-size.patch --- linux-3.10.11/debian/patches/bugfix/all/HID-validate-HID-report-id-size.patch 2013-09-10 04:22:37.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/HID-validate-HID-report-id-size.patch 2013-12-23 04:40:15.000000000 +0000 @@ -21,11 +21,11 @@ include/linux/hid.h | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) -diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 36668d1..5ea7d51 100644 ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -63,6 +63,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, +Index: linux-3.10.11.rpi/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/hid/hid-core.c 2013-12-23 02:26:50.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/hid/hid-core.c 2013-12-23 04:40:14.000000000 +0000 +@@ -63,6 +63,8 @@ struct hid_report_enum *report_enum = device->report_enum + type; struct hid_report *report; @@ -34,7 +34,7 @@ if (report_enum->report_id_hash[id]) return report_enum->report_id_hash[id]; -@@ -404,8 +406,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) +@@ -404,8 +406,10 @@ case HID_GLOBAL_ITEM_TAG_REPORT_ID: parser->global.report_id = item_udata(item); @@ -47,7 +47,7 @@ return -1; } return 0; -@@ -575,7 +579,7 @@ static void hid_close_report(struct hid_device *device) +@@ -575,7 +579,7 @@ for (i = 0; i < HID_REPORT_TYPES; i++) { struct hid_report_enum *report_enum = device->report_enum + i; @@ -56,11 +56,11 @@ struct hid_report *report = report_enum->report_id_hash[j]; if (report) hid_free_report(report); -diff --git a/include/linux/hid.h b/include/linux/hid.h -index 0c48991..ff545cc 100644 ---- a/include/linux/hid.h -+++ b/include/linux/hid.h -@@ -393,10 +393,12 @@ struct hid_report { +Index: linux-3.10.11.rpi/include/linux/hid.h +=================================================================== +--- linux-3.10.11.rpi.orig/include/linux/hid.h 2013-12-23 01:36:08.000000000 +0000 ++++ linux-3.10.11.rpi/include/linux/hid.h 2013-12-23 04:40:14.000000000 +0000 +@@ -393,10 +393,12 @@ struct hid_device *device; /* associated device */ }; diff -Nru linux-3.10.11/debian/patches/bugfix/all/ipv6-remove-max_addresses-check-from-ipv6_create_tem.patch linux-3.10-3.10.11/debian/patches/bugfix/all/ipv6-remove-max_addresses-check-from-ipv6_create_tem.patch --- linux-3.10.11/debian/patches/bugfix/all/ipv6-remove-max_addresses-check-from-ipv6_create_tem.patch 2013-09-10 03:40:31.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/ipv6-remove-max_addresses-check-from-ipv6_create_tem.patch 2013-12-23 04:40:14.000000000 +0000 @@ -39,9 +39,11 @@ net/ipv6/addrconf.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -1124,12 +1124,10 @@ retry: +Index: linux-3.10.11.rpi/net/ipv6/addrconf.c +=================================================================== +--- linux-3.10.11.rpi.orig/net/ipv6/addrconf.c 2013-12-23 01:36:08.000000000 +0000 ++++ linux-3.10.11.rpi/net/ipv6/addrconf.c 2013-12-23 04:40:14.000000000 +0000 +@@ -1124,12 +1124,10 @@ if (ifp->flags & IFA_F_OPTIMISTIC) addr_flags |= IFA_F_OPTIMISTIC; diff -Nru linux-3.10.11/debian/patches/bugfix/all/misc-bmp085-Enable-building-as-a-module.patch linux-3.10-3.10.11/debian/patches/bugfix/all/misc-bmp085-Enable-building-as-a-module.patch --- linux-3.10.11/debian/patches/bugfix/all/misc-bmp085-Enable-building-as-a-module.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/misc-bmp085-Enable-building-as-a-module.patch 2014-05-05 12:42:37.000000000 +0000 @@ -14,11 +14,11 @@ drivers/misc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index c002d86..7a68184 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -451,7 +451,7 @@ config ARM_CHARLCD +Index: linux-3.10-3.10.11/drivers/misc/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/Kconfig 2014-05-05 11:52:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/Kconfig 2014-05-05 12:42:36.000000000 +0000 +@@ -451,7 +451,7 @@ still useful. config BMP085 diff -Nru linux-3.10.11/debian/patches/bugfix/all/radeon-firmware-is-required-for-drm-and-kms-on-r600-onward.patch linux-3.10-3.10.11/debian/patches/bugfix/all/radeon-firmware-is-required-for-drm-and-kms-on-r600-onward.patch --- linux-3.10.11/debian/patches/bugfix/all/radeon-firmware-is-required-for-drm-and-kms-on-r600-onward.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/all/radeon-firmware-is-required-for-drm-and-kms-on-r600-onward.patch 2014-05-05 12:41:59.000000000 +0000 @@ -26,8 +26,10 @@ missing, except for the pre-R600 KMS case. --- ---- a/drivers/gpu/drm/radeon/radeon_drv.c -+++ b/drivers/gpu/drm/radeon/radeon_drv.c +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_drv.c 2014-05-05 11:52:28.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_drv.c 2014-05-05 12:41:59.000000000 +0000 @@ -36,6 +36,8 @@ #include #include @@ -37,7 +39,7 @@ /* -@@ -301,6 +303,37 @@ static struct drm_driver driver_old = { +@@ -308,6 +310,37 @@ static struct drm_driver kms_driver; @@ -75,7 +77,7 @@ static int radeon_kick_out_firmware_fb(struct pci_dev *pdev) { struct apertures_struct *ap; -@@ -327,6 +360,12 @@ static int radeon_pci_probe(struct pci_d +@@ -334,6 +367,12 @@ { int ret; @@ -88,7 +90,7 @@ /* Get rid of things like offb */ ret = radeon_kick_out_firmware_fb(pdev); if (ret) -@@ -435,6 +474,7 @@ static struct pci_driver *pdriver; +@@ -442,6 +481,7 @@ static struct pci_driver radeon_pci_driver = { .name = DRIVER_NAME, .id_table = pciidlist, diff -Nru linux-3.10.11/debian/patches/bugfix/arm/ARM-Fix-the-world-famous-typo-with-is_gate_vma.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/ARM-Fix-the-world-famous-typo-with-is_gate_vma.patch --- linux-3.10.11/debian/patches/bugfix/arm/ARM-Fix-the-world-famous-typo-with-is_gate_vma.patch 2013-08-15 19:09:24.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/ARM-Fix-the-world-famous-typo-with-is_gate_vma.patch 2013-12-23 04:40:12.000000000 +0000 @@ -8,11 +8,11 @@ arch/arm/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c -index d03b5bd..e28d43f 100644 ---- a/arch/arm/kernel/process.c -+++ b/arch/arm/kernel/process.c -@@ -459,7 +459,7 @@ int in_gate_area_no_mm(unsigned long addr) +Index: linux-3.10.11.rpi/arch/arm/kernel/process.c +=================================================================== +--- linux-3.10.11.rpi.orig/arch/arm/kernel/process.c 2013-12-23 01:36:09.000000000 +0000 ++++ linux-3.10.11.rpi/arch/arm/kernel/process.c 2013-12-23 04:40:12.000000000 +0000 +@@ -466,7 +466,7 @@ { return in_gate_area(NULL, addr); } diff -Nru linux-3.10.11/debian/patches/bugfix/arm/I2C-I2C-mv64xxx-remove-I2C_M_NOSTART-code.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/I2C-I2C-mv64xxx-remove-I2C_M_NOSTART-code.patch --- linux-3.10.11/debian/patches/bugfix/arm/I2C-I2C-mv64xxx-remove-I2C_M_NOSTART-code.patch 2013-08-13 18:27:21.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/I2C-I2C-mv64xxx-remove-I2C_M_NOSTART-code.patch 2014-05-05 12:42:59.000000000 +0000 @@ -17,11 +17,11 @@ drivers/i2c/busses/i2c-mv64xxx.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) -diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c -index 4b45c73..f11cb25 100644 ---- a/drivers/i2c/busses/i2c-mv64xxx.c -+++ b/drivers/i2c/busses/i2c-mv64xxx.c -@@ -419,28 +419,12 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, +Index: linux-3.10-3.10.11/drivers/i2c/busses/i2c-mv64xxx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/i2c/busses/i2c-mv64xxx.c 2014-05-05 11:52:06.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/i2c/busses/i2c-mv64xxx.c 2014-05-05 12:42:58.000000000 +0000 +@@ -421,28 +421,12 @@ spin_lock_irqsave(&drv_data->lock, flags); mv64xxx_i2c_prepare_for_io(drv_data, msg); diff -Nru linux-3.10.11/debian/patches/bugfix/arm/i2c-imx-add-module_device_table.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/i2c-imx-add-module_device_table.patch --- linux-3.10.11/debian/patches/bugfix/arm/i2c-imx-add-module_device_table.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/i2c-imx-add-module_device_table.patch 2014-05-05 12:42:29.000000000 +0000 @@ -11,11 +11,11 @@ drivers/i2c/busses/i2c-imx.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c -index 6406aa9..e242797 100644 ---- a/drivers/i2c/busses/i2c-imx.c -+++ b/drivers/i2c/busses/i2c-imx.c -@@ -147,6 +147,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = { +Index: linux-3.10-3.10.11/drivers/i2c/busses/i2c-imx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/i2c/busses/i2c-imx.c 2014-05-05 11:52:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/i2c/busses/i2c-imx.c 2014-05-05 12:42:29.000000000 +0000 +@@ -148,6 +148,7 @@ { .compatible = "fsl,imx21-i2c", .data = &imx_i2c_devtype[IMX21_I2C], }, { /* sentinel */ } }; diff -Nru linux-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-fix-race-between-FSM-interrupt-and-proce.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-fix-race-between-FSM-interrupt-and-proce.patch --- linux-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-fix-race-between-FSM-interrupt-and-proce.patch 2013-08-13 18:27:32.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-fix-race-between-FSM-interrupt-and-proce.patch 2014-05-05 12:43:00.000000000 +0000 @@ -35,11 +35,11 @@ drivers/i2c/busses/i2c-mv64xxx.c | 54 +++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 20 deletions(-) -diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c -index bb37e14..6356439 100644 ---- a/drivers/i2c/busses/i2c-mv64xxx.c -+++ b/drivers/i2c/busses/i2c-mv64xxx.c -@@ -86,6 +86,8 @@ enum { +Index: linux-3.10-3.10.11/drivers/i2c/busses/i2c-mv64xxx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/i2c/busses/i2c-mv64xxx.c 2014-05-05 12:42:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/i2c/busses/i2c-mv64xxx.c 2014-05-05 12:43:00.000000000 +0000 +@@ -86,6 +86,8 @@ }; struct mv64xxx_i2c_data { @@ -48,7 +48,7 @@ int irq; u32 state; u32 action; -@@ -194,7 +196,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) +@@ -196,7 +198,7 @@ if ((drv_data->bytes_left == 0) || (drv_data->aborting && (drv_data->byte_posn != 0))) { @@ -57,7 +57,7 @@ drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; drv_data->state = MV64XXX_I2C_STATE_IDLE; } else { -@@ -271,12 +273,25 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) +@@ -273,12 +275,25 @@ { switch(drv_data->action) { case MV64XXX_I2C_ACTION_SEND_RESTART: @@ -86,7 +86,7 @@ break; case MV64XXX_I2C_ACTION_CONTINUE: -@@ -412,20 +427,15 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) +@@ -414,20 +429,15 @@ static int mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, @@ -110,7 +110,7 @@ drv_data->send_stop = is_last; drv_data->block = 1; -@@ -453,16 +463,20 @@ static int +@@ -455,16 +465,20 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap); diff -Nru linux-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-move-mv64xxx_i2c_prepare_for_io.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-move-mv64xxx_i2c_prepare_for_io.patch --- linux-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-move-mv64xxx_i2c_prepare_for_io.patch 2013-08-13 18:27:26.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/I2C-mv64xxx-move-mv64xxx_i2c_prepare_for_io.patch 2014-05-05 12:43:00.000000000 +0000 @@ -14,11 +14,11 @@ drivers/i2c/busses/i2c-mv64xxx.c | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) -diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c -index f11cb25..bb37e14 100644 ---- a/drivers/i2c/busses/i2c-mv64xxx.c -+++ b/drivers/i2c/busses/i2c-mv64xxx.c -@@ -110,6 +110,32 @@ struct mv64xxx_i2c_data { +Index: linux-3.10-3.10.11/drivers/i2c/busses/i2c-mv64xxx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/i2c/busses/i2c-mv64xxx.c 2014-05-05 12:42:58.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/i2c/busses/i2c-mv64xxx.c 2014-05-05 12:42:59.000000000 +0000 +@@ -112,6 +112,32 @@ struct i2c_adapter adapter; }; @@ -51,7 +51,7 @@ /* ***************************************************************************** * -@@ -347,32 +373,6 @@ mv64xxx_i2c_intr(int irq, void *dev_id) +@@ -349,32 +375,6 @@ ***************************************************************************** */ static void diff -Nru linux-3.10.11/debian/patches/bugfix/arm/imx-sgtl5000-probe-defer.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/imx-sgtl5000-probe-defer.patch --- linux-3.10.11/debian/patches/bugfix/arm/imx-sgtl5000-probe-defer.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/imx-sgtl5000-probe-defer.patch 2014-05-05 12:42:30.000000000 +0000 @@ -10,11 +10,11 @@ [ not sure if upstream will like that ] Signed-off-by: Arnaud Patard -Index: linux/sound/soc/fsl/imx-sgtl5000.c +Index: linux-3.10-3.10.11/sound/soc/fsl/imx-sgtl5000.c =================================================================== ---- linux.orig/sound/soc/fsl/imx-sgtl5000.c 2013-05-16 09:33:01.000000000 +0200 -+++ linux/sound/soc/fsl/imx-sgtl5000.c 2013-05-16 09:35:14.000000000 +0200 -@@ -113,13 +113,13 @@ static int imx_sgtl5000_probe(struct pla +--- linux-3.10-3.10.11.orig/sound/soc/fsl/imx-sgtl5000.c 2014-05-05 11:52:17.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/fsl/imx-sgtl5000.c 2014-05-05 12:42:30.000000000 +0000 +@@ -113,13 +113,13 @@ ssi_pdev = of_find_device_by_node(ssi_np); if (!ssi_pdev) { dev_err(&pdev->dev, "failed to find SSI platform device\n"); diff -Nru linux-3.10.11/debian/patches/bugfix/arm/ixp4xx_iobe.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/ixp4xx_iobe.patch --- linux-3.10.11/debian/patches/bugfix/arm/ixp4xx_iobe.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/ixp4xx_iobe.patch 2014-05-05 12:42:33.000000000 +0000 @@ -15,11 +15,11 @@ Signed-off-by: Arnaud Patard -Index: linux-3.1/arch/arm/mach-ixp4xx/include/mach/io.h +Index: linux-3.10-3.10.11/arch/arm/mach-ixp4xx/include/mach/io.h =================================================================== ---- linux-3.1.orig/arch/arm/mach-ixp4xx/include/mach/io.h 2011-11-13 14:14:50.662853902 +0100 -+++ linux-3.1/arch/arm/mach-ixp4xx/include/mach/io.h 2011-11-13 14:19:38.522841236 +0100 -@@ -387,6 +387,20 @@ static inline unsigned int ioread16(cons +--- linux-3.10-3.10.11.orig/arch/arm/mach-ixp4xx/include/mach/io.h 2014-05-05 11:52:16.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-ixp4xx/include/mach/io.h 2014-05-05 12:42:33.000000000 +0000 +@@ -363,6 +363,20 @@ #endif } @@ -40,7 +40,7 @@ #define ioread16_rep(p, v, c) ioread16_rep(p, v, c) static inline void ioread16_rep(const void __iomem *addr, void *vaddr, u32 count) -@@ -417,6 +431,21 @@ static inline unsigned int ioread32(cons +@@ -393,6 +407,21 @@ } } @@ -62,7 +62,7 @@ #define ioread32_rep(p, v, c) ioread32_rep(p, v, c) static inline void ioread32_rep(const void __iomem *addr, void *vaddr, u32 count) -@@ -475,6 +504,20 @@ static inline void iowrite16(u16 value, +@@ -451,6 +480,20 @@ #endif } @@ -83,7 +83,7 @@ #define iowrite16_rep(p, v, c) iowrite16_rep(p, v, c) static inline void iowrite16_rep(void __iomem *addr, const void *vaddr, u32 count) -@@ -504,6 +547,20 @@ static inline void iowrite32(u32 value, +@@ -480,6 +523,20 @@ #endif } diff -Nru linux-3.10.11/debian/patches/bugfix/arm/mvneta-module-fix.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/mvneta-module-fix.patch --- linux-3.10.11/debian/patches/bugfix/arm/mvneta-module-fix.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/mvneta-module-fix.patch 2014-05-05 12:42:28.000000000 +0000 @@ -10,9 +10,11 @@ Signed-off-by: Arnaud Patard ---- a/drivers/net/ethernet/marvell/mvneta.c 2013-04-14 22:17:41.073749379 +0200 -+++ b/drivers/net/ethernet/marvell/mvneta.c 2013-04-14 23:22:16.033578898 +0200 -@@ -89,6 +89,8 @@ +Index: linux-3.10-3.10.11/drivers/net/ethernet/marvell/mvneta.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/marvell/mvneta.c 2014-05-05 11:52:19.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/marvell/mvneta.c 2014-05-05 12:42:28.000000000 +0000 +@@ -88,6 +88,8 @@ #define MVNETA_TX_IN_PRGRS BIT(1) #define MVNETA_TX_FIFO_EMPTY BIT(8) #define MVNETA_RX_MIN_FRAME_SIZE 0x247c @@ -21,7 +23,7 @@ #define MVNETA_TYPE_PRIO 0x24bc #define MVNETA_FORCE_UNI BIT(21) #define MVNETA_TXQ_CMD_1 0x24e4 -@@ -657,6 +659,9 @@ static void mvneta_port_sgmii_config(str +@@ -655,6 +657,9 @@ val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); val |= MVNETA_GMAC2_PSC_ENABLE; mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); @@ -31,7 +33,7 @@ } /* Start the Ethernet port RX and TX activity */ -@@ -2729,20 +2734,10 @@ static int mvneta_probe(struct platform_ +@@ -2718,20 +2723,10 @@ pp = netdev_priv(dev); @@ -52,7 +54,7 @@ pp->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(pp->clk)) { err = PTR_ERR(pp->clk); -@@ -2751,7 +2746,16 @@ static int mvneta_probe(struct platform_ +@@ -2740,7 +2735,16 @@ clk_prepare_enable(pp->clk); diff -Nru linux-3.10.11/debian/patches/bugfix/arm/omap-musb-choice.patch linux-3.10-3.10.11/debian/patches/bugfix/arm/omap-musb-choice.patch --- linux-3.10.11/debian/patches/bugfix/arm/omap-musb-choice.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/arm/omap-musb-choice.patch 2014-05-05 12:42:28.000000000 +0000 @@ -10,9 +10,11 @@ Removing the choice entry make things work. Signed-off-by: Arnaud Patard ---- a/drivers/usb/musb/Kconfig -+++ b/drivers/usb/musb/Kconfig -@@ -27,9 +27,6 @@ config USB_MUSB_HDRC +Index: linux-3.10-3.10.11/drivers/usb/musb/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/musb/Kconfig 2014-05-05 11:52:19.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/musb/Kconfig 2014-05-05 12:42:27.000000000 +0000 +@@ -27,9 +27,6 @@ if USB_MUSB_HDRC @@ -22,7 +24,7 @@ config USB_MUSB_DAVINCI tristate "DaVinci" depends on ARCH_DAVINCI_DMx -@@ -62,8 +59,6 @@ config USB_MUSB_BLACKFIN +@@ -62,8 +59,6 @@ config USB_MUSB_UX500 tristate "U8500 and U5500" diff -Nru linux-3.10.11/debian/patches/bugfix/m68k/atari-irqs.patch linux-3.10-3.10.11/debian/patches/bugfix/m68k/atari-irqs.patch --- linux-3.10.11/debian/patches/bugfix/m68k/atari-irqs.patch 2013-08-13 18:12:42.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/m68k/atari-irqs.patch 2013-12-23 04:40:10.000000000 +0000 @@ -3,9 +3,11 @@ Origin: http://thread.gmane.org/gmane.linux.debian.devel.kernel/91476/focus=5003 Forwarded: http://thread.gmane.org/gmane.linux.ports.m68k/5009 ---- a/arch/m68k/include/asm/irqflags.h -+++ b/arch/m68k/include/asm/irqflags.h -@@ -67,6 +67,10 @@ static inline void arch_local_irq_restor +Index: linux-3.10.11.rpi/arch/m68k/include/asm/irqflags.h +=================================================================== +--- linux-3.10.11.rpi.orig/arch/m68k/include/asm/irqflags.h 2013-12-23 01:36:10.000000000 +0000 ++++ linux-3.10.11.rpi/arch/m68k/include/asm/irqflags.h 2013-12-23 04:40:09.000000000 +0000 +@@ -67,6 +67,10 @@ static inline bool arch_irqs_disabled_flags(unsigned long flags) { diff -Nru linux-3.10.11/debian/patches/bugfix/m68k/ethernat-kconfig.patch linux-3.10-3.10.11/debian/patches/bugfix/m68k/ethernat-kconfig.patch --- linux-3.10.11/debian/patches/bugfix/m68k/ethernat-kconfig.patch 2013-08-13 18:12:42.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/m68k/ethernat-kconfig.patch 2013-12-23 04:40:09.000000000 +0000 @@ -2,9 +2,11 @@ Description: Make SMC91X driver selectable for ATARI_ETHERNAT boards Origin: http://git.kernel.org/cgit/linux/kernel/git/geert/linux-m68k.git/commit/?id=edee09224891c259071238d5a8d2be5e3ca7f09c ---- a/drivers/net/ethernet/smsc/Kconfig -+++ b/drivers/net/ethernet/smsc/Kconfig -@@ -6,7 +6,8 @@ config NET_VENDOR_SMSC +Index: linux-3.10.11.rpi/drivers/net/ethernet/smsc/Kconfig +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/net/ethernet/smsc/Kconfig 2013-12-23 01:36:10.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/net/ethernet/smsc/Kconfig 2013-12-23 04:40:08.000000000 +0000 +@@ -6,7 +6,8 @@ bool "SMC (SMSC)/Western Digital devices" default y depends on ARM || ISA || MAC || ARM64 || MIPS || M32R || SUPERH || \ @@ -14,7 +16,7 @@ ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from -@@ -40,7 +41,7 @@ config SMC91X +@@ -40,7 +41,7 @@ select NET_CORE select MII depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \ diff -Nru linux-3.10.11/debian/patches/bugfix/mips/disable-advansys.patch linux-3.10-3.10.11/debian/patches/bugfix/mips/disable-advansys.patch --- linux-3.10.11/debian/patches/bugfix/mips/disable-advansys.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/mips/disable-advansys.patch 2014-05-05 12:42:31.000000000 +0000 @@ -12,9 +12,11 @@ But report: http://www.mail-archive.com/linux-scsi@vger.kernel.org/msg12773.html ---- a/drivers/scsi/Kconfig 2007-12-27 19:16:18.000000000 +0000 -+++ b/drivers/scsi/Kconfig 2007-12-27 19:16:58.000000000 +0000 -@@ -523,6 +523,7 @@ +Index: linux-3.10-3.10.11/drivers/scsi/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/Kconfig 2014-05-05 11:52:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/Kconfig 2014-05-05 12:42:30.000000000 +0000 +@@ -568,6 +568,7 @@ tristate "AdvanSys SCSI support" depends on SCSI && VIRT_TO_BUS depends on ISA || EISA || PCI diff -Nru linux-3.10.11/debian/patches/bugfix/powerpc/lpar-console.patch linux-3.10-3.10.11/debian/patches/bugfix/powerpc/lpar-console.patch --- linux-3.10.11/debian/patches/bugfix/powerpc/lpar-console.patch 2013-07-14 23:47:08.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/powerpc/lpar-console.patch 2014-05-05 12:42:32.000000000 +0000 @@ -8,8 +8,10 @@ Original version by Bastian Blank . ---- a/drivers/tty/hvc/hvc_vio.c -+++ b/drivers/tty/hvc/hvc_vio.c +Index: linux-3.10-3.10.11/drivers/tty/hvc/hvc_vio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/hvc/hvc_vio.c 2014-05-05 11:52:16.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/hvc/hvc_vio.c 2014-05-05 12:42:31.000000000 +0000 @@ -48,6 +48,7 @@ #include #include @@ -18,7 +20,7 @@ #include "hvc_console.h" -@@ -440,7 +441,9 @@ +@@ -457,7 +458,9 @@ if (hvterm_priv0.proto == HV_PROTOCOL_HVSI) goto out; #endif diff -Nru linux-3.10.11/debian/patches/bugfix/x86/amd64_edac-Fix-single-channel-setups.patch linux-3.10-3.10.11/debian/patches/bugfix/x86/amd64_edac-Fix-single-channel-setups.patch --- linux-3.10.11/debian/patches/bugfix/x86/amd64_edac-Fix-single-channel-setups.patch 2013-09-08 00:58:32.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/x86/amd64_edac-Fix-single-channel-setups.patch 2013-12-23 04:40:13.000000000 +0000 @@ -23,11 +23,11 @@ drivers/edac/amd64_edac.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) -diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c -index 8b6a034..8b3d901 100644 ---- a/drivers/edac/amd64_edac.c -+++ b/drivers/edac/amd64_edac.c -@@ -2470,8 +2470,15 @@ static int amd64_init_one_instance(struct pci_dev *F2) +Index: linux-3.10.11.rpi/drivers/edac/amd64_edac.c +=================================================================== +--- linux-3.10.11.rpi.orig/drivers/edac/amd64_edac.c 2013-12-23 01:36:08.000000000 +0000 ++++ linux-3.10.11.rpi/drivers/edac/amd64_edac.c 2013-12-23 04:40:13.000000000 +0000 +@@ -2470,8 +2470,15 @@ layers[0].size = pvt->csels[0].b_cnt; layers[0].is_virt_csrow = true; layers[1].type = EDAC_MC_LAYER_CHANNEL; diff -Nru linux-3.10.11/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch linux-3.10-3.10.11/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch --- linux-3.10.11/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch 2014-05-05 12:42:36.000000000 +0000 @@ -14,9 +14,11 @@ un-blacklist it in udev. --- ---- a/drivers/video/via/via-core.c -+++ b/drivers/video/via/via-core.c -@@ -753,7 +753,14 @@ static struct pci_device_id via_pci_tabl +Index: linux-3.10-3.10.11/drivers/video/via/via-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/via/via-core.c 2014-05-05 11:52:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/via/via-core.c 2014-05-05 12:42:35.000000000 +0000 +@@ -753,7 +753,14 @@ .driver_data = UNICHROME_VX900 }, { } }; diff -Nru linux-3.10.11/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch linux-3.10-3.10.11/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch --- linux-3.10.11/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch 2013-05-04 20:38:33.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch 2014-05-05 12:42:15.000000000 +0000 @@ -19,16 +19,13 @@ net/ieee802154/af_ieee802154.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) -diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c -index cd949d5..8f49dd5 100644 ---- a/net/ieee802154/af_ieee802154.c -+++ b/net/ieee802154/af_ieee802154.c -@@ -363,4 +363,4 @@ module_init(af_ieee802154_init); +Index: linux-3.10-3.10.11/net/ieee802154/af_ieee802154.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ieee802154/af_ieee802154.c 2014-05-05 11:52:23.000000000 +0000 ++++ linux-3.10-3.10.11/net/ieee802154/af_ieee802154.c 2014-05-05 12:42:14.000000000 +0000 +@@ -370,4 +370,4 @@ module_exit(af_ieee802154_remove); MODULE_LICENSE("GPL"); -MODULE_ALIAS_NETPROTO(PF_IEEE802154); +/* MODULE_ALIAS_NETPROTO(PF_IEEE802154); */ --- -1.7.2.3 - diff -Nru linux-3.10.11/debian/patches/debian/arch-sh4-fix-uimage-build.patch linux-3.10-3.10.11/debian/patches/debian/arch-sh4-fix-uimage-build.patch --- linux-3.10.11/debian/patches/debian/arch-sh4-fix-uimage-build.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/arch-sh4-fix-uimage-build.patch 2014-05-05 12:41:32.000000000 +0000 @@ -6,9 +6,11 @@ [bwh: This was added without a description, but I think it is dealing with a similar issue to powerpcspe-omit-uimage.patch] ---- a/arch/sh/Makefile -+++ b/arch/sh/Makefile -@@ -75,7 +75,6 @@ +Index: linux-3.10-3.10.11/arch/sh/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sh/Makefile 2014-05-05 11:52:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sh/Makefile 2014-05-05 12:41:32.000000000 +0000 +@@ -81,7 +81,6 @@ # Give the various platforms the opportunity to set default image types defaultimage-$(CONFIG_SUPERH32) := zImage diff -Nru linux-3.10.11/debian/patches/debian/ast-disable-autoload.patch linux-3.10-3.10.11/debian/patches/debian/ast-disable-autoload.patch --- linux-3.10.11/debian/patches/debian/ast-disable-autoload.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/ast-disable-autoload.patch 2014-05-05 12:42:22.000000000 +0000 @@ -8,9 +8,11 @@ have to be loaded either by local configuration or as part of a package of a compatible X driver. ---- a/drivers/gpu/drm/ast/ast_drv.c -+++ b/drivers/gpu/drm/ast/ast_drv.c -@@ -58,7 +58,7 @@ static DEFINE_PCI_DEVICE_TABLE(pciidlist +Index: linux-3.10-3.10.11/drivers/gpu/drm/ast/ast_drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/ast/ast_drv.c 2014-05-05 11:52:21.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/ast/ast_drv.c 2014-05-05 12:42:21.000000000 +0000 +@@ -58,7 +58,7 @@ {0, 0, 0}, }; diff -Nru linux-3.10.11/debian/patches/debian/aufs3-mark-as-staging.patch linux-3.10-3.10.11/debian/patches/debian/aufs3-mark-as-staging.patch --- linux-3.10.11/debian/patches/debian/aufs3-mark-as-staging.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/aufs3-mark-as-staging.patch 2014-05-05 12:42:12.000000000 +0000 @@ -4,9 +4,11 @@ I really don't want to support this. ---- a/fs/aufs/module.c -+++ b/fs/aufs/module.c -@@ -104,6 +104,7 @@ MODULE_DESCRIPTION(AUFS_NAME +Index: linux-3.10-3.10.11/fs/aufs/module.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/aufs/module.c 2014-05-05 12:42:05.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/module.c 2014-05-05 12:42:11.000000000 +0000 +@@ -104,6 +104,7 @@ " -- Advanced multi layered unification filesystem"); MODULE_VERSION(AUFS_VERSION); MODULE_ALIAS_FS(AUFS_NAME); diff -Nru linux-3.10.11/debian/patches/debian/AUFS_PROC_MAP-is-BROKEN.patch linux-3.10-3.10.11/debian/patches/debian/AUFS_PROC_MAP-is-BROKEN.patch --- linux-3.10.11/debian/patches/debian/AUFS_PROC_MAP-is-BROKEN.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/AUFS_PROC_MAP-is-BROKEN.patch 2014-05-05 12:42:13.000000000 +0000 @@ -6,9 +6,11 @@ This config option depends on aufs3-proc_map.patch, which we don't apply. ---- a/fs/aufs/Kconfig -+++ b/fs/aufs/Kconfig -@@ -102,6 +102,7 @@ config AUFS_RDU +Index: linux-3.10-3.10.11/fs/aufs/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/fs/aufs/Kconfig 2014-05-05 12:42:05.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/Kconfig 2014-05-05 12:42:12.000000000 +0000 +@@ -101,6 +101,7 @@ config AUFS_PROC_MAP bool "support for /proc/maps and lsof(1)" diff -Nru linux-3.10.11/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch linux-3.10-3.10.11/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch --- linux-3.10.11/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch 2014-05-05 12:42:23.000000000 +0000 @@ -11,8 +11,10 @@ once it's ready to speak MBIM. --- ---- a/drivers/net/usb/cdc_ncm.c -+++ b/drivers/net/usb/cdc_ncm.c +Index: linux-3.10-3.10.11/drivers/net/usb/cdc_ncm.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/usb/cdc_ncm.c 2014-05-05 11:52:21.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/usb/cdc_ncm.c 2014-05-05 12:42:23.000000000 +0000 @@ -55,11 +55,7 @@ #define DRIVER_VERSION "14-Mar-2012" diff -Nru linux-3.10.11/debian/patches/debian/cgroups-Document-the-Debian-memory-resource-controll.patch linux-3.10-3.10.11/debian/patches/debian/cgroups-Document-the-Debian-memory-resource-controll.patch --- linux-3.10.11/debian/patches/debian/cgroups-Document-the-Debian-memory-resource-controll.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/cgroups-Document-the-Debian-memory-resource-controll.patch 2014-05-05 12:42:19.000000000 +0000 @@ -3,9 +3,11 @@ Forwarded: not-needed --- ---- a/Documentation/cgroups/memory.txt -+++ b/Documentation/cgroups/memory.txt -@@ -46,6 +46,10 @@ Features: +Index: linux-3.10-3.10.11/Documentation/cgroups/memory.txt +=================================================================== +--- linux-3.10-3.10.11.orig/Documentation/cgroups/memory.txt 2014-05-05 11:52:22.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/cgroups/memory.txt 2014-05-05 12:42:18.000000000 +0000 +@@ -47,6 +47,10 @@ Kernel memory support is a work in progress, and the current version provides basically functionality. (See Section 2.7) diff -Nru linux-3.10.11/debian/patches/debian/cirrus-disable-modeset-by-default.patch linux-3.10-3.10.11/debian/patches/debian/cirrus-disable-modeset-by-default.patch --- linux-3.10.11/debian/patches/debian/cirrus-disable-modeset-by-default.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/cirrus-disable-modeset-by-default.patch 2014-05-05 12:42:20.000000000 +0000 @@ -7,9 +7,11 @@ xserver-xorg-video-cirrus will need to override this once it is compatible, by installing a modprobe config file. ---- a/drivers/gpu/drm/cirrus/cirrus_drv.c -+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c -@@ -15,7 +15,7 @@ +Index: linux-3.10-3.10.11/drivers/gpu/drm/cirrus/cirrus_drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/cirrus/cirrus_drv.c 2014-05-05 11:52:22.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/cirrus/cirrus_drv.c 2014-05-05 12:42:20.000000000 +0000 +@@ -14,7 +14,7 @@ #include "cirrus_drv.h" diff -Nru linux-3.10.11/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch linux-3.10-3.10.11/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch --- linux-3.10.11/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch 2013-05-04 20:38:34.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch 2014-05-05 12:42:16.000000000 +0000 @@ -19,11 +19,11 @@ net/decnet/af_decnet.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) -diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c -index 7a58c87..ed9e2b0 100644 ---- a/net/decnet/af_decnet.c -+++ b/net/decnet/af_decnet.c -@@ -2358,7 +2358,7 @@ void dn_unregister_sysctl(void); +Index: linux-3.10-3.10.11/net/decnet/af_decnet.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/decnet/af_decnet.c 2014-05-05 11:52:23.000000000 +0000 ++++ linux-3.10-3.10.11/net/decnet/af_decnet.c 2014-05-05 12:42:16.000000000 +0000 +@@ -2358,7 +2358,7 @@ MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); MODULE_AUTHOR("Linux DECnet Project Team"); MODULE_LICENSE("GPL"); @@ -32,6 +32,3 @@ static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n"; --- -1.7.2.3 - diff -Nru linux-3.10.11/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch linux-3.10-3.10.11/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch --- linux-3.10.11/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch 2014-05-05 12:42:17.000000000 +0000 @@ -7,9 +7,11 @@ This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415 ('VFS: don't do protected {sym,hard}links by default'). ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -651,8 +651,8 @@ static inline void put_link(struct namei +Index: linux-3.10-3.10.11/fs/namei.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/namei.c 2014-05-05 11:52:23.000000000 +0000 ++++ linux-3.10-3.10.11/fs/namei.c 2014-05-05 12:42:17.000000000 +0000 +@@ -699,8 +699,8 @@ path_put(link); } diff -Nru linux-3.10.11/debian/patches/debian/gitignore.patch linux-3.10-3.10.11/debian/patches/debian/gitignore.patch --- linux-3.10.11/debian/patches/debian/gitignore.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/gitignore.patch 2014-05-05 12:41:30.000000000 +0000 @@ -3,8 +3,10 @@ Subject: Tweak gitignore for Debian pkg-kernel using git svn. Forwarded: not-needed ---- a/.gitignore -+++ b/.gitignore +Index: linux-3.10-3.10.11/.gitignore +=================================================================== +--- linux-3.10-3.10.11.orig/.gitignore 2014-05-05 11:52:41.000000000 +0000 ++++ linux-3.10-3.10.11/.gitignore 2014-05-05 12:41:29.000000000 +0000 @@ -46,11 +46,6 @@ /Module.symvers diff -Nru linux-3.10.11/debian/patches/debian/ia64-hardcode-arch-script-output.patch linux-3.10-3.10.11/debian/patches/debian/ia64-hardcode-arch-script-output.patch --- linux-3.10.11/debian/patches/debian/ia64-hardcode-arch-script-output.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/ia64-hardcode-arch-script-output.patch 2014-05-05 12:41:30.000000000 +0000 @@ -21,11 +21,11 @@ altogether, and allow for the possibility of other archs to provide their own scripts in the future. -diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile -index e7cbaa0..c8af869 100644 ---- a/arch/ia64/Makefile -+++ b/arch/ia64/Makefile -@@ -30,16 +30,7 @@ cflags-y := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \ +Index: linux-3.10-3.10.11/arch/ia64/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/arch/ia64/Makefile 2014-05-05 11:52:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/ia64/Makefile 2014-05-05 12:41:30.000000000 +0000 +@@ -30,16 +30,7 @@ -falign-functions=32 -frename-registers -fno-optimize-sibling-calls KBUILD_CFLAGS_KERNEL := -mconstant-gp @@ -43,7 +43,7 @@ KBUILD_CFLAGS += $(cflags-y) head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o -@@ -69,7 +60,7 @@ boot := arch/ia64/hp/sim/boot +@@ -68,7 +59,7 @@ PHONY += boot compressed check @@ -52,7 +52,7 @@ compressed: vmlinux.gz -@@ -78,9 +69,6 @@ vmlinuz: vmlinux.gz +@@ -77,9 +68,6 @@ vmlinux.gz: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ @@ -62,7 +62,7 @@ archclean: $(Q)$(MAKE) $(clean)=$(boot) -@@ -96,7 +84,6 @@ define archhelp +@@ -95,7 +83,6 @@ echo '* compressed - Build compressed kernel image' echo ' install - Install compressed kernel image' echo ' boot - Build vmlinux and bootloader for Ski simulator' diff -Nru linux-3.10.11/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch linux-3.10-3.10.11/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch --- linux-3.10.11/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch 2014-05-05 12:41:36.000000000 +0000 @@ -13,8 +13,10 @@ not easy to detect that this particular failure is harmless. So stop requesting the unreleased firmware. ---- a/drivers/net/wireless/iwlwifi/iwl-6000.c -+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c +Index: linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-6000.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/iwlwifi/iwl-6000.c 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-6000.c 2014-05-05 12:41:36.000000000 +0000 @@ -31,7 +31,7 @@ #include "dvm/commands.h" /* needed for BT for now */ diff -Nru linux-3.10.11/debian/patches/debian/kernelvariables.patch linux-3.10-3.10.11/debian/patches/debian/kernelvariables.patch --- linux-3.10.11/debian/patches/debian/kernelvariables.patch 2013-05-04 20:38:34.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/kernelvariables.patch 2014-05-05 12:41:28.000000000 +0000 @@ -12,9 +12,11 @@ This file can only be read after we establish the build tree, and all use of $(ARCH) needs to be moved after this. ---- a/Makefile -+++ b/Makefile -@@ -195,42 +195,6 @@ export KBUILD_BUILDHOST := $(SUBARCH) +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:41:26.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:41:27.000000000 +0000 +@@ -195,42 +195,6 @@ ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) @@ -57,7 +59,7 @@ KCONFIG_CONFIG ?= .config export KCONFIG_CONFIG -@@ -349,6 +313,44 @@ CFLAGS_KERNEL = +@@ -349,6 +313,44 @@ AFLAGS_KERNEL = CFLAGS_GCOV = -fprofile-arcs -ftest-coverage diff -Nru linux-3.10.11/debian/patches/debian/mgag200-disable-autoload.patch linux-3.10-3.10.11/debian/patches/debian/mgag200-disable-autoload.patch --- linux-3.10.11/debian/patches/debian/mgag200-disable-autoload.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/mgag200-disable-autoload.patch 2014-05-05 12:42:23.000000000 +0000 @@ -8,9 +8,11 @@ loaded either by local configuration or as part of a package of a compatible X driver. ---- a/drivers/gpu/drm/mgag200/mgag200_drv.c -+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c -@@ -38,7 +38,7 @@ static DEFINE_PCI_DEVICE_TABLE(pciidlist +Index: linux-3.10-3.10.11/drivers/gpu/drm/mgag200/mgag200_drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/mgag200/mgag200_drv.c 2014-05-05 11:52:21.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/mgag200/mgag200_drv.c 2014-05-05 12:42:22.000000000 +0000 +@@ -38,7 +38,7 @@ {0,} }; diff -Nru linux-3.10.11/debian/patches/debian/mips-disable-werror.patch linux-3.10-3.10.11/debian/patches/debian/mips-disable-werror.patch --- linux-3.10.11/debian/patches/debian/mips-disable-werror.patch 2013-05-04 20:38:33.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/mips-disable-werror.patch 2014-05-05 12:41:31.000000000 +0000 @@ -10,10 +10,10 @@ arch/mips/Kbuild | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) -diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild -index e322d65..2e6b28f 100644 ---- a/arch/mips/Kbuild -+++ b/arch/mips/Kbuild +Index: linux-3.10-3.10.11/arch/mips/Kbuild +=================================================================== +--- linux-3.10-3.10.11.orig/arch/mips/Kbuild 2014-05-05 11:52:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/mips/Kbuild 2014-05-05 12:41:31.000000000 +0000 @@ -1,8 +1,3 @@ -# Fail on warnings - also for files referenced in subdirs -# -Werror can be disabled for specific files using: @@ -23,6 +23,3 @@ # platform specific definitions include arch/mips/Kbuild.platforms obj-y := $(platform-y) --- -1.7.1 - diff -Nru linux-3.10.11/debian/patches/debian/powerpcspe-omit-uimage.patch linux-3.10-3.10.11/debian/patches/debian/powerpcspe-omit-uimage.patch --- linux-3.10.11/debian/patches/debian/powerpcspe-omit-uimage.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/powerpcspe-omit-uimage.patch 2014-05-05 12:41:33.000000000 +0000 @@ -7,10 +7,10 @@ Bug-Debian: http://bugs.debian.org/708094 Forwarded: not-needed -Index: linux-3.8.12/arch/powerpc/boot/Makefile +Index: linux-3.10-3.10.11/arch/powerpc/boot/Makefile =================================================================== ---- linux-3.8.12.orig/arch/powerpc/boot/Makefile 2013-05-13 21:05:41.000000000 +0200 -+++ linux-3.8.12/arch/powerpc/boot/Makefile 2013-05-14 07:48:26.434286772 +0200 +--- linux-3.10-3.10.11.orig/arch/powerpc/boot/Makefile 2014-05-05 11:52:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/boot/Makefile 2014-05-05 12:41:32.000000000 +0000 @@ -204,7 +204,6 @@ image-$(CONFIG_PPC_PMAC) += zImage.pmac image-$(CONFIG_PPC_HOLLY) += dtbImage.holly diff -Nru linux-3.10.11/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch linux-3.10-3.10.11/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch --- linux-3.10.11/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch 2013-05-04 20:38:33.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch 2014-05-05 12:42:16.000000000 +0000 @@ -19,16 +19,13 @@ net/rds/af_rds.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) -diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c -index 98e0538..d8d4525 100644 ---- a/net/rds/af_rds.c -+++ b/net/rds/af_rds.c -@@ -574,4 +574,4 @@ MODULE_DESCRIPTION("RDS: Reliable Datagram Sockets" +Index: linux-3.10-3.10.11/net/rds/af_rds.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/rds/af_rds.c 2014-05-05 11:52:23.000000000 +0000 ++++ linux-3.10-3.10.11/net/rds/af_rds.c 2014-05-05 12:42:15.000000000 +0000 +@@ -596,4 +596,4 @@ " v" DRV_VERSION " (" DRV_RELDATE ")"); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_ALIAS_NETPROTO(PF_RDS); +/* MODULE_ALIAS_NETPROTO(PF_RDS); */ --- -1.7.2.3 - diff -Nru linux-3.10.11/debian/patches/debian/sched-autogroup-disabled.patch linux-3.10-3.10.11/debian/patches/debian/sched-autogroup-disabled.patch --- linux-3.10.11/debian/patches/debian/sched-autogroup-disabled.patch 2013-05-04 20:38:34.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/sched-autogroup-disabled.patch 2014-05-05 12:42:18.000000000 +0000 @@ -6,8 +6,10 @@ We want to provide the option of autogrouping but without enabling it by default yet. ---- a/kernel/sched/auto_group.c -+++ b/kernel/sched/auto_group.c +Index: linux-3.10-3.10.11/kernel/sched/auto_group.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/sched/auto_group.c 2014-05-05 11:52:22.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/sched/auto_group.c 2014-05-05 12:42:17.000000000 +0000 @@ -9,7 +9,7 @@ #include #include diff -Nru linux-3.10.11/debian/patches/debian/udl-disable-autoload.patch linux-3.10-3.10.11/debian/patches/debian/udl-disable-autoload.patch --- linux-3.10.11/debian/patches/debian/udl-disable-autoload.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/udl-disable-autoload.patch 2014-05-05 12:42:21.000000000 +0000 @@ -8,9 +8,11 @@ have to be loaded either by local configuration or as part of a package of a compatible X driver. ---- a/drivers/gpu/drm/udl/udl_drv.c -+++ b/drivers/gpu/drm/udl/udl_drv.c -@@ -30,7 +30,7 @@ static struct usb_device_id id_table[] = +Index: linux-3.10-3.10.11/drivers/gpu/drm/udl/udl_drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/udl/udl_drv.c 2014-05-05 11:52:21.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/udl/udl_drv.c 2014-05-05 12:42:21.000000000 +0000 +@@ -30,7 +30,7 @@ USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, {}, }; diff -Nru linux-3.10.11/debian/patches/debian/version.patch linux-3.10-3.10.11/debian/patches/debian/version.patch --- linux-3.10.11/debian/patches/debian/version.patch 2013-07-14 23:47:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/version.patch 2014-05-05 12:41:27.000000000 +0000 @@ -7,9 +7,11 @@ $DISTRIBUTION_OFFICIAL_BUILD, $DISTRIBUTOR and $DISTRIBUTION_VERSION are set. ---- a/Makefile -+++ b/Makefile -@@ -826,7 +826,7 @@ endif +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 11:52:43.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:41:26.000000000 +0000 +@@ -826,7 +826,7 @@ prepare2: prepare3 outputmakefile asm-generic prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ @@ -18,7 +20,7 @@ $(cmd_crmodverdir) archprepare: archheaders archscripts prepare1 scripts_basic -@@ -858,12 +858,25 @@ define filechk_version.h +@@ -858,12 +858,25 @@ echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';) endef @@ -44,8 +46,10 @@ PHONY += headerdep headerdep: $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \ ---- a/arch/x86/um/sysrq_64.c -+++ b/arch/x86/um/sysrq_64.c +Index: linux-3.10-3.10.11/arch/x86/um/sysrq_64.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/um/sysrq_64.c 2014-05-05 11:52:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/um/sysrq_64.c 2014-05-05 12:41:26.000000000 +0000 @@ -8,6 +8,7 @@ #include #include @@ -54,7 +58,7 @@ #include #include #include -@@ -16,8 +17,9 @@ void __show_regs(struct pt_regs *regs) +@@ -16,8 +17,9 @@ { printk("\n"); print_modules(); @@ -66,8 +70,10 @@ printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, PT_REGS_IP(regs)); printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs), ---- a/arch/ia64/kernel/process.c -+++ b/arch/ia64/kernel/process.c +Index: linux-3.10-3.10.11/arch/ia64/kernel/process.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/ia64/kernel/process.c 2014-05-05 11:52:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/ia64/kernel/process.c 2014-05-05 12:41:26.000000000 +0000 @@ -30,6 +30,7 @@ #include #include @@ -76,7 +82,7 @@ #include #include -@@ -103,9 +104,9 @@ show_regs (struct pt_regs *regs) +@@ -103,9 +104,9 @@ print_modules(); printk("\n"); show_regs_print_info(KERN_DEFAULT); @@ -88,8 +94,10 @@ print_symbol("ip is at %s\n", ip); printk("unat: %016lx pfs : %016lx rsc : %016lx\n", regs->ar_unat, regs->ar_pfs, regs->ar_rsc); ---- a/arch/powerpc/kernel/process.c -+++ b/arch/powerpc/kernel/process.c +Index: linux-3.10-3.10.11/arch/powerpc/kernel/process.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kernel/process.c 2014-05-05 11:52:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kernel/process.c 2014-05-05 12:41:26.000000000 +0000 @@ -38,6 +38,7 @@ #include #include @@ -98,7 +106,7 @@ #include #include -@@ -842,8 +843,9 @@ void show_regs(struct pt_regs * regs) +@@ -853,8 +854,9 @@ printk("NIP: "REG" LR: "REG" CTR: "REG"\n", regs->nip, regs->link, regs->ctr); @@ -110,8 +118,10 @@ printk("MSR: "REG" ", regs->msr); printbits(regs->msr, msr_bits); printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); ---- a/kernel/printk.c -+++ b/kernel/printk.c +Index: linux-3.10-3.10.11/kernel/printk.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/printk.c 2014-05-05 11:52:43.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/printk.c 2014-05-05 12:41:26.000000000 +0000 @@ -45,6 +45,7 @@ #include #include @@ -120,7 +130,7 @@ #include -@@ -2883,11 +2884,12 @@ void __init dump_stack_set_arch_desc(con +@@ -2892,11 +2893,12 @@ */ void dump_stack_print_info(const char *log_lvl) { diff -Nru linux-3.10.11/debian/patches/debian/yama-disable-by-default.patch linux-3.10-3.10.11/debian/patches/debian/yama-disable-by-default.patch --- linux-3.10.11/debian/patches/debian/yama-disable-by-default.patch 2013-06-19 03:36:07.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/debian/yama-disable-by-default.patch 2014-05-05 12:42:19.000000000 +0000 @@ -4,8 +4,10 @@ Bug-Debian: http://bugs.debian.org/712740 Forwarded: not-needed ---- a/security/yama/yama_lsm.c -+++ b/security/yama/yama_lsm.c +Index: linux-3.10-3.10.11/security/yama/yama_lsm.c +=================================================================== +--- linux-3.10-3.10.11.orig/security/yama/yama_lsm.c 2014-05-05 11:52:22.000000000 +0000 ++++ linux-3.10-3.10.11/security/yama/yama_lsm.c 2014-05-05 12:42:19.000000000 +0000 @@ -24,7 +24,7 @@ #define YAMA_SCOPE_CAPABILITY 2 #define YAMA_SCOPE_NO_ATTACH 3 @@ -15,7 +17,7 @@ /* describe a ptrace relationship for potential exception */ struct ptrace_relation { -@@ -425,7 +425,7 @@ static __init int yama_init(void) +@@ -425,7 +425,7 @@ return 0; #endif diff -Nru linux-3.10.11/debian/patches/dummytemplate.diff linux-3.10-3.10.11/debian/patches/dummytemplate.diff --- linux-3.10.11/debian/patches/dummytemplate.diff 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/dummytemplate.diff 2013-12-23 04:08:57.000000000 +0000 @@ -0,0 +1,5 @@ +diff -uN a/1.txt b/1.txt +--- a/dummy/PATCHNAME.txt 1970-01-01 00:00:00.000000000 +0000 ++++ b/dummy/PATCHNAME.txt 2013-12-23 04:07:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/features/all/aufs3/aufs3-add.patch linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-add.patch --- linux-3.10.11/debian/patches/features/all/aufs3/aufs3-add.patch 2013-08-31 17:37:57.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-add.patch 2014-05-05 12:42:11.000000000 +0000 @@ -6,8 +6,10 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch ---- a/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/ABI/testing/debugfs-aufs 2013-06-02 18:23:34.749538984 +0100 +Index: linux-3.10-3.10.11/Documentation/ABI/testing/debugfs-aufs +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/ABI/testing/debugfs-aufs 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,50 @@ +What: /debug/aufs/si_/ +Date: March 2009 @@ -59,8 +61,10 @@ + be created. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. ---- a/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/ABI/testing/sysfs-aufs 2012-01-10 02:15:56.000000000 +0000 +Index: linux-3.10-3.10.11/Documentation/ABI/testing/sysfs-aufs +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/ABI/testing/sysfs-aufs 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,24 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 @@ -86,8 +90,10 @@ + even if it is the default path. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. ---- a/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/README 2013-08-07 14:04:57.879008639 +0100 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/README +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/README 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,346 @@ + +Aufs3 -- advanced multi layered unification filesystem version 3.x @@ -435,8 +441,10 @@ +# Local variables: ; +# mode: text; +# End: ; ---- a/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/01intro.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/01intro.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/01intro.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,162 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -600,8 +608,10 @@ +Some people may think it is better to pass such work to user space +helper, instead of doing in kernel space. Actually I am still thinking +about it. But currently I have implemented it in kernel space. ---- a/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/02struct.txt 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/02struct.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/02struct.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,243 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -846,8 +856,10 @@ +- etc. + +For this purpose, use "aumvdown" command in aufs-util.git. ---- a/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/03lookup.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/03lookup.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/03lookup.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,106 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -955,8 +967,10 @@ + test, and skip therevalidatin in step 4. It is useful and improves + aufs performance when system surely hide the aufs branches from user, + by over-mounting something (or another method). ---- a/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/04branch.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/04branch.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/04branch.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,76 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1034,8 +1048,10 @@ + - a file on the branch is mmap-ed. + - a regular file on the branch is opened for write and there is no + same named entry on the upper branch. ---- a/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/05wbr_policy.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/05wbr_policy.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,65 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1102,8 +1118,10 @@ + where the source and the target exists and selects the higher + one. If the selected branch is readonly, then aufs follows the + copyup policy. ---- a/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/06mmap.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/06mmap.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/06mmap.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,47 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1152,8 +1170,10 @@ +generic_file_mmap() and handles struct vm_operations_struct. In this +approach, aufs met a hard problem and I could not solve it without +switching the approach. ---- a/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/07export.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/07export.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/07export.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,59 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1214,8 +1234,10 @@ + convert it into ESTALE for NFSD. +- readdir(): call lockdep_on/off() because filldir in NFSD calls + lookup_one_len(), vfs_getattr(), encode_fh() and others. ---- a/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/08shwh.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/08shwh.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/08shwh.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,53 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1270,8 +1292,10 @@ + +This new squashfs archive can be stored on the boot device and the +initramfs will use it to replace the old one at the next boot. ---- a/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/10dynop.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/10dynop.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/10dynop.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,47 @@ + +# Copyright (C) 2010-2013 Junjiro R. Okajima @@ -1320,8 +1344,10 @@ +XIP mainly. +Currently this approach is applied to file_operations and +vm_operations_struct for regular files only. ---- a/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/99plan.txt 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/Documentation/filesystems/aufs/design/99plan.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/filesystems/aufs/design/99plan.txt 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,96 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1419,8 +1445,10 @@ +Opened File) is specified (by default), aufs returns the filedata from +/new. +Otherwise from /new. ---- a/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/Kconfig 2013-08-31 18:32:36.447371122 +0100 +Index: linux-3.10-3.10.11/fs/aufs/Kconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/Kconfig 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,202 @@ +config AUFS_FS + tristate "Aufs (Advanced multi layered unification filesystem) support" @@ -1624,8 +1652,10 @@ + Automatic configuration for internal use. + When aufs supports Magic SysRq, enabled automatically. +endif ---- a/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/Makefile 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/Makefile 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,42 @@ + +include ${src}/magic.mk @@ -1669,8 +1699,10 @@ +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o +aufs-$(CONFIG_AUFS_DEBUG) += debug.o +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o ---- a/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/aufs.h 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/aufs.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/aufs.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1732,8 +1764,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_H__ */ ---- a/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/branch.c 2013-08-31 18:37:41.071378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/branch.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/branch.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1213 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -2948,8 +2982,10 @@ + AuTraceErr(err); + return err; +} ---- a/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/branch.h 2013-08-07 14:04:57.883008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/branch.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/branch.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -3206,8 +3242,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_BRANCH_H__ */ ---- a/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/conf.mk 2012-01-10 02:15:56.000000000 +0000 +Index: linux-3.10-3.10.11/fs/aufs/conf.mk +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/conf.mk 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,38 @@ + +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} @@ -3247,8 +3285,10 @@ +${obj}/sysfs.o: ${AuConfName} + +-include ${srctree}/${src}/conf_priv.mk ---- a/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/cpup.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/cpup.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/cpup.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1266 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -4516,8 +4556,10 @@ + dput(parent); + return err; +} ---- a/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/cpup.h 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/cpup.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/cpup.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -4612,8 +4654,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_CPUP_H__ */ ---- a/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dbgaufs.c 2013-08-07 14:04:57.883008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dbgaufs.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dbgaufs.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5048,8 +5092,10 @@ + err = 0; + return err; +} ---- a/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dbgaufs.h 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/dbgaufs.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dbgaufs.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5100,8 +5146,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __DBGAUFS_H__ */ ---- a/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dcsub.c 2013-08-31 18:37:41.071378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dcsub.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dcsub.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5346,8 +5394,10 @@ + + return path_is_under(path + 0, path + 1); +} ---- a/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dcsub.h 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/dcsub.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dcsub.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5443,8 +5493,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DCSUB_H__ */ ---- a/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/debug.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/debug.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/debug.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,491 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5937,8 +5989,10 @@ + + return 0; +} ---- a/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/debug.h 2013-08-07 14:04:57.883008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/debug.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/debug.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -6182,8 +6236,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DEBUG_H__ */ ---- a/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dentry.c 2013-08-07 14:04:57.883008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dentry.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dentry.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1065 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -7250,8 +7306,10 @@ + .d_weak_revalidate = aufs_d_revalidate, + .d_release = aufs_d_release +}; ---- a/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dentry.h 2013-08-07 14:04:57.883008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dentry.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dentry.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -7487,8 +7545,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DENTRY_H__ */ ---- a/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dinfo.c 2013-08-31 18:37:41.071378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dinfo.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dinfo.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,543 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -8033,8 +8093,10 @@ + return bindex; + return -1; +} ---- a/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dir.c 2013-08-31 18:37:41.071378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dir.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dir.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,632 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -8668,8 +8730,10 @@ + .flush = aufs_flush_dir, + .fsync = aufs_fsync_dir +}; ---- a/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dir.h 2013-08-31 18:37:41.071378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dir.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dir.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -8808,8 +8872,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DIR_H__ */ ---- a/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dynop.c 2013-08-31 18:37:41.071378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/dynop.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dynop.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -9190,8 +9256,10 @@ + for (i = 0; i < AuDyLast; i++) + WARN_ON(!list_empty(&dynop[i].head)); +} ---- a/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dynop.h 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/dynop.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/dynop.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -9269,8 +9337,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DYNOP_H__ */ ---- a/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/export.c 2013-08-31 18:37:41.071378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/export.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/export.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,826 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -10098,8 +10168,10 @@ + BUILD_BUG_ON(sizeof(u) != sizeof(int)); + atomic_set(&sbinfo->si_xigen_next, u); +} ---- a/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/f_op.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/f_op.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/f_op.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,721 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -10822,8 +10894,10 @@ + .aio_splice_read = aufs_aio_splice_read +#endif +}; ---- a/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/f_op_sp.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/f_op_sp.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/f_op_sp.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -11208,8 +11282,10 @@ + + return ret; +} ---- a/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/file.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/file.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/file.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,708 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -11919,8 +11995,10 @@ + .swap_deactivate = aufs_swap_deactivate +#endif /* CONFIG_AUFS_DEBUG */ +}; ---- a/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/file.h 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/file.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/file.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -12232,8 +12310,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FILE_H__ */ ---- a/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/finfo.c 2013-03-10 01:48:58.459093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/finfo.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/finfo.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -12392,8 +12472,10 @@ +out: + return err; +} ---- a/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/fstype.h 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/fstype.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/fstype.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -12865,8 +12947,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FSTYPE_H__ */ ---- a/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hfsnotify.c 2013-08-07 14:04:57.887008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/hfsnotify.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/hfsnotify.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -13164,8 +13248,10 @@ + .fin_br = au_hfsn_fin_br, + .init_br = au_hfsn_init_br +}; ---- a/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hfsplus.c 2013-06-02 18:23:34.753538984 +0100 +Index: linux-3.10-3.10.11/fs/aufs/hfsplus.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/hfsplus.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -13223,8 +13309,10 @@ + au_sbr_put(dentry->d_sb, bindex); + } +} ---- a/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hnotify.c 2013-08-31 18:37:41.075378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/hnotify.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/hnotify.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,712 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -13938,8 +14026,10 @@ + if (au_cachep[AuCache_HNOTIFY]) + au_hn_destroy_cache(); +} ---- a/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/i_op.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/i_op.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1115 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -15056,8 +15146,10 @@ + + .update_time = aufs_update_time +}; ---- a/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_add.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/i_op_add.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/i_op_add.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,739 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -15798,8 +15890,10 @@ +out: + return err; +} ---- a/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_del.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/i_op_del.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/i_op_del.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,502 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -16303,8 +16397,10 @@ + AuTraceErr(err); + return err; +} ---- a/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_ren.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/i_op_ren.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/i_op_ren.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1009 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -17315,8 +17411,10 @@ + AuTraceErr(err); + return err; +} ---- a/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/iinfo.c 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/iinfo.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/iinfo.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -17594,8 +17692,10 @@ + iinfo->ii_hinode = NULL; + AuRwDestroy(&iinfo->ii_rwsem); +} ---- a/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/inode.c 2013-08-07 14:04:57.887008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/inode.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/inode.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,492 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -18089,8 +18189,10 @@ + mask |= MAY_READ; /* force permission check */ + return au_test_h_perm(h_inode, mask); +} ---- a/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/inode.h 2013-08-07 14:04:57.887008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/inode.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/inode.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,600 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -18692,8 +18794,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_INODE_H__ */ ---- a/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/ioctl.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/ioctl.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/ioctl.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -18897,8 +19001,10 @@ + return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif ---- a/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/loop.c 2013-08-31 18:37:41.079378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/loop.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/loop.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -19035,8 +19141,10 @@ +{ + kfree(au_warn_loopback_array); +} ---- a/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/loop.h 2013-08-31 18:37:41.079378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/loop.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/loop.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -19088,8 +19196,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_LOOP_H__ */ ---- a/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/magic.mk 2012-01-10 02:15:56.000000000 +0000 +Index: linux-3.10-3.10.11/fs/aufs/magic.mk +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/magic.mk 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,54 @@ + +# defined in ${srctree}/fs/fuse/inode.c @@ -19145,8 +19255,10 @@ +ifdef CONFIG_HFSPLUS_FS +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b +endif ---- a/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/module.c 2013-08-07 14:04:57.887008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/module.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/module.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -19351,8 +19463,10 @@ + +module_init(aufs_init); +module_exit(aufs_exit); ---- a/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/module.h 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/module.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/module.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -19459,8 +19573,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ ---- a/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/mvdown.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/mvdown.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/mvdown.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,562 @@ +/* + * Copyright (C) 2011-2013 Junjiro R. Okajima @@ -20024,8 +20140,10 @@ + AuTraceErr(err); + return err; +} ---- a/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/opts.c 2013-06-02 18:23:34.753538984 +0100 +Index: linux-3.10-3.10.11/fs/aufs/opts.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/opts.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1697 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -21724,8 +21842,10 @@ +{ + return au_mntflags(sb) & AuOptMask_UDBA; +} ---- a/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/opts.h 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/opts.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/opts.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -21936,8 +22056,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_OPTS_H__ */ ---- a/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/plink.c 2013-08-07 14:04:57.887008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/plink.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/plink.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -22459,8 +22581,10 @@ + } + } +} ---- a/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/poll.c 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/poll.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/poll.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -22518,8 +22642,10 @@ + AuTraceErr((int)mask); + return mask; +} ---- a/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/procfs.c 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/procfs.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/procfs.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -22691,8 +22817,10 @@ +out: + return err; +} ---- a/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/rdu.c 2013-08-31 18:37:41.079378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/rdu.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/rdu.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,384 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -23078,8 +23206,10 @@ + return err; +} +#endif ---- a/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/rwsem.h 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/rwsem.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/rwsem.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -23269,8 +23399,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_RWSEM_H__ */ ---- a/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sbinfo.c 2013-06-02 18:23:34.753538984 +0100 +Index: linux-3.10-3.10.11/fs/aufs/sbinfo.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/sbinfo.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -23618,8 +23750,10 @@ + p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid); + spin_unlock(&sbinfo->au_si_pid.tree_lock); +} ---- a/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/spl.h 2013-06-02 18:23:34.753538984 +0100 +Index: linux-3.10-3.10.11/fs/aufs/spl.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/spl.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -23733,8 +23867,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_SPL_H__ */ ---- a/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/super.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/super.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/super.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,992 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -24728,8 +24864,10 @@ + /* no need to __module_get() and module_put(). */ + .owner = THIS_MODULE, +}; ---- a/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/super.h 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/super.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/super.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,559 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -25290,8 +25428,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_SUPER_H__ */ ---- a/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysaufs.c 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/sysaufs.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/sysaufs.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -25398,8 +25538,10 @@ +out: + return err; +} ---- a/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysaufs.h 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/sysaufs.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/sysaufs.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -25505,8 +25647,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __SYSAUFS_H__ */ ---- a/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysfs.c 2013-06-02 18:23:34.753538984 +0100 +Index: linux-3.10-3.10.11/fs/aufs/sysfs.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/sysfs.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -25765,8 +25909,10 @@ + br->br_name, err); + } +} ---- a/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysrq.c 2013-08-07 14:04:57.887008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/sysrq.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/sysrq.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -25919,8 +26065,10 @@ + if (unlikely(err)) + pr_err("err %d (ignored)\n", err); +} ---- a/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vdir.c 2013-08-31 18:37:41.079378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/vdir.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/vdir.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,878 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -26800,8 +26948,10 @@ + /* smp_mb(); */ + return 0; +} ---- a/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vfsub.c 2013-08-31 18:37:41.079378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/vfsub.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/vfsub.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,769 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -27572,8 +27722,10 @@ + + return err; +} ---- a/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vfsub.h 2013-08-31 18:37:41.083378381 +0100 +Index: linux-3.10-3.10.11/fs/aufs/vfsub.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/vfsub.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -27869,8 +28021,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_VFSUB_H__ */ ---- a/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wbr_policy.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/wbr_policy.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/wbr_policy.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,693 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -28565,8 +28719,10 @@ + .fin = au_wbr_create_fin_mfs + } +}; ---- a/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/whout.c 2013-08-07 14:04:57.891008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/whout.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/whout.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1022 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -29590,8 +29746,10 @@ + au_whtmp_rmdir_free(args); + } +} ---- a/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/whout.h 2013-06-02 18:23:34.753538984 +0100 +Index: linux-3.10-3.10.11/fs/aufs/whout.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/whout.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -29680,8 +29838,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WHOUT_H__ */ ---- a/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wkq.c 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/fs/aufs/wkq.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/wkq.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -29896,8 +30056,10 @@ + + return err; +} ---- a/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wkq.h 2013-03-10 01:48:58.463093058 +0000 +Index: linux-3.10-3.10.11/fs/aufs/wkq.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/wkq.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -29991,8 +30153,10 @@ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WKQ_H__ */ ---- a/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/xino.c 2013-08-07 14:04:57.891008639 +0100 +Index: linux-3.10-3.10.11/fs/aufs/xino.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/xino.c 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,1264 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -31258,8 +31422,10 @@ +out: + return err; +} ---- a/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/linux/aufs_type.h 2013-08-07 14:04:57.891008639 +0100 +Index: linux-3.10-3.10.11/include/linux/aufs_type.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/aufs_type.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2012-2013 Junjiro R. Okajima @@ -31280,8 +31446,10 @@ + */ + +#include ---- a/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/uapi/linux/aufs_type.h 2013-08-31 18:37:45.995378498 +0100 +Index: linux-3.10-3.10.11/include/uapi/linux/aufs_type.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/include/uapi/linux/aufs_type.h 2014-05-05 12:42:05.000000000 +0000 @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima diff -Nru linux-3.10.11/debian/patches/features/all/aufs3/aufs3-base.patch linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-base.patch --- linux-3.10.11/debian/patches/features/all/aufs3/aufs3-base.patch 2013-08-31 17:37:57.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-base.patch 2014-05-05 12:42:01.000000000 +0000 @@ -8,11 +8,11 @@ aufs3.10 base patch -diff --git a/fs/file_table.c b/fs/file_table.c -index 485dc0e..8db8096 100644 ---- a/fs/file_table.c -+++ b/fs/file_table.c -@@ -36,7 +36,7 @@ struct files_stat_struct files_stat = { +Index: linux-3.10-3.10.11/fs/file_table.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/file_table.c 2014-05-05 11:52:28.000000000 +0000 ++++ linux-3.10-3.10.11/fs/file_table.c 2014-05-05 12:42:00.000000000 +0000 +@@ -36,7 +36,7 @@ .max_files = NR_FILE }; @@ -21,11 +21,11 @@ /* SLAB cache for file structures */ static struct kmem_cache *filp_cachep __read_mostly; -diff --git a/fs/inode.c b/fs/inode.c -index 00d5fc3..f324521 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -1498,7 +1498,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode, +Index: linux-3.10-3.10.11/fs/inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/inode.c 2014-05-05 11:52:28.000000000 +0000 ++++ linux-3.10-3.10.11/fs/inode.c 2014-05-05 12:42:00.000000000 +0000 +@@ -1498,7 +1498,7 @@ * This does the actual work of updating an inodes time or version. Must have * had called mnt_want_write() before calling this. */ @@ -34,11 +34,11 @@ { if (inode->i_op->update_time) return inode->i_op->update_time(inode, time, flags); -diff --git a/fs/splice.c b/fs/splice.c -index d37431d..987346f 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); +Index: linux-3.10-3.10.11/fs/splice.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/splice.c 2014-05-05 11:52:28.000000000 +0000 ++++ linux-3.10-3.10.11/fs/splice.c 2014-05-05 12:42:00.000000000 +0000 +@@ -1093,8 +1093,8 @@ /* * Attempt to initiate a splice from pipe to file. */ @@ -49,7 +49,7 @@ { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -@@ -1124,9 +1124,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1124,9 +1124,9 @@ /* * Attempt to initiate a splice from a file to a pipe. */ @@ -62,11 +62,11 @@ { ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 65c2be2..0148214 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -2574,6 +2574,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *); +Index: linux-3.10-3.10.11/include/linux/fs.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/fs.h 2014-05-05 11:52:28.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/fs.h 2014-05-05 12:42:00.000000000 +0000 +@@ -2574,6 +2574,7 @@ extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); @@ -74,11 +74,11 @@ extern int file_update_time(struct file *file); extern int generic_show_options(struct seq_file *m, struct dentry *root); -diff --git a/include/linux/splice.h b/include/linux/splice.h -index 74575cb..bfc6fb6 100644 ---- a/include/linux/splice.h -+++ b/include/linux/splice.h -@@ -92,4 +92,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); +Index: linux-3.10-3.10.11/include/linux/splice.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/splice.h 2014-05-05 11:52:28.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/splice.h 2014-05-05 12:42:00.000000000 +0000 +@@ -92,4 +92,10 @@ extern void spd_release_page(struct splice_pipe_desc *, unsigned int); extern const struct pipe_buf_operations page_cache_pipe_buf_ops; diff -Nru linux-3.10.11/debian/patches/features/all/aufs3/aufs3-kbuild.patch linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-kbuild.patch --- linux-3.10.11/debian/patches/features/all/aufs3/aufs3-kbuild.patch 2013-08-31 17:37:57.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-kbuild.patch 2014-05-05 12:42:05.000000000 +0000 @@ -8,11 +8,11 @@ aufs3.10 kbuild patch -diff --git a/fs/Kconfig b/fs/Kconfig -index c229f82..397b473 100644 ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -212,6 +212,7 @@ source "fs/ufs/Kconfig" +Index: linux-3.10-3.10.11/fs/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/fs/Kconfig 2014-05-05 11:52:26.000000000 +0000 ++++ linux-3.10-3.10.11/fs/Kconfig 2014-05-05 12:42:04.000000000 +0000 +@@ -212,6 +212,7 @@ source "fs/exofs/Kconfig" source "fs/f2fs/Kconfig" source "fs/efivarfs/Kconfig" @@ -20,20 +20,20 @@ endif # MISC_FILESYSTEMS -diff --git a/fs/Makefile b/fs/Makefile -index 4fe6df3..4a57676 100644 ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules +Index: linux-3.10-3.10.11/fs/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/fs/Makefile 2014-05-05 11:52:26.000000000 +0000 ++++ linux-3.10-3.10.11/fs/Makefile 2014-05-05 12:42:04.000000000 +0000 +@@ -126,3 +126,4 @@ obj-$(CONFIG_CEPH_FS) += ceph/ obj-$(CONFIG_PSTORE) += pstore/ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ +obj-$(CONFIG_AUFS_FS) += aufs/ -diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild -index bdc6e87..349600c 100644 ---- a/include/uapi/linux/Kbuild -+++ b/include/uapi/linux/Kbuild -@@ -56,6 +56,7 @@ header-y += atmppp.h +Index: linux-3.10-3.10.11/include/uapi/linux/Kbuild +=================================================================== +--- linux-3.10-3.10.11.orig/include/uapi/linux/Kbuild 2014-05-05 11:52:26.000000000 +0000 ++++ linux-3.10-3.10.11/include/uapi/linux/Kbuild 2014-05-05 12:42:04.000000000 +0000 +@@ -56,6 +56,7 @@ header-y += atmsap.h header-y += atmsvc.h header-y += audit.h diff -Nru linux-3.10.11/debian/patches/features/all/aufs3/aufs3-standalone.patch linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-standalone.patch --- linux-3.10.11/debian/patches/features/all/aufs3/aufs3-standalone.patch 2013-08-31 17:37:57.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs3-standalone.patch 2014-05-05 12:42:02.000000000 +0000 @@ -8,11 +8,11 @@ aufs3.10 standalone patch -diff --git a/fs/file_table.c b/fs/file_table.c -index 8db8096..e271e28 100644 ---- a/fs/file_table.c -+++ b/fs/file_table.c -@@ -37,6 +37,7 @@ struct files_stat_struct files_stat = { +Index: linux-3.10-3.10.11/fs/file_table.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/file_table.c 2014-05-05 12:42:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/file_table.c 2014-05-05 12:42:01.000000000 +0000 +@@ -37,6 +37,7 @@ }; DEFINE_LGLOCK(files_lglock); @@ -20,7 +20,7 @@ /* SLAB cache for file structures */ static struct kmem_cache *filp_cachep __read_mostly; -@@ -405,6 +406,8 @@ void file_sb_list_del(struct file *file) +@@ -405,6 +406,8 @@ } } @@ -29,11 +29,11 @@ #ifdef CONFIG_SMP /* -diff --git a/fs/inode.c b/fs/inode.c -index f324521..bff7670 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -56,6 +56,7 @@ static struct hlist_head *inode_hashtable __read_mostly; +Index: linux-3.10-3.10.11/fs/inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/inode.c 2014-05-05 12:42:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/inode.c 2014-05-05 12:42:01.000000000 +0000 +@@ -56,6 +56,7 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock); @@ -41,7 +41,7 @@ /* * Empty aops. Can be used for the cases where the user does not -@@ -1514,6 +1515,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags) +@@ -1514,6 +1515,7 @@ mark_inode_dirty_sync(inode); return 0; } @@ -49,11 +49,11 @@ /** * touch_atime - update the access time -diff --git a/fs/namespace.c b/fs/namespace.c -index 7b1ca9b..51db6ad 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -54,6 +54,7 @@ EXPORT_SYMBOL_GPL(fs_kobj); +Index: linux-3.10-3.10.11/fs/namespace.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/namespace.c 2014-05-05 11:52:27.000000000 +0000 ++++ linux-3.10-3.10.11/fs/namespace.c 2014-05-05 12:42:01.000000000 +0000 +@@ -54,6 +54,7 @@ * tree or hash is modified or when a vfsmount structure is modified. */ DEFINE_BRLOCK(vfsmount_lock); @@ -61,7 +61,7 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) { -@@ -427,6 +428,7 @@ void __mnt_drop_write(struct vfsmount *mnt) +@@ -427,6 +428,7 @@ mnt_dec_writers(real_mount(mnt)); preempt_enable(); } @@ -69,7 +69,7 @@ /** * mnt_drop_write - give up write access to a mount -@@ -1456,6 +1458,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, +@@ -1456,6 +1458,7 @@ } return 0; } @@ -77,10 +77,10 @@ static void cleanup_group_ids(struct mount *mnt, struct mount *end) { -diff --git a/fs/notify/group.c b/fs/notify/group.c -index bd2625b..2ff2a0f 100644 ---- a/fs/notify/group.c -+++ b/fs/notify/group.c +Index: linux-3.10-3.10.11/fs/notify/group.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/notify/group.c 2014-05-05 11:52:27.000000000 +0000 ++++ linux-3.10-3.10.11/fs/notify/group.c 2014-05-05 12:42:01.000000000 +0000 @@ -22,6 +22,7 @@ #include #include @@ -89,7 +89,7 @@ #include #include "fsnotify.h" -@@ -65,6 +66,7 @@ void fsnotify_get_group(struct fsnotify_group *group) +@@ -65,6 +66,7 @@ { atomic_inc(&group->refcnt); } @@ -97,7 +97,7 @@ /* * Drop a reference to a group. Free it if it's through. -@@ -74,6 +76,7 @@ void fsnotify_put_group(struct fsnotify_group *group) +@@ -74,6 +76,7 @@ if (atomic_dec_and_test(&group->refcnt)) fsnotify_final_destroy_group(group); } @@ -105,7 +105,7 @@ /* * Create a new fsnotify_group and hold a reference for the group returned. -@@ -102,6 +105,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) +@@ -102,6 +105,7 @@ return group; } @@ -113,11 +113,11 @@ int fsnotify_fasync(int fd, struct file *file, int on) { -diff --git a/fs/notify/mark.c b/fs/notify/mark.c -index fc6b49b..a6bb87d 100644 ---- a/fs/notify/mark.c -+++ b/fs/notify/mark.c -@@ -115,6 +115,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) +Index: linux-3.10-3.10.11/fs/notify/mark.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/notify/mark.c 2014-05-05 11:52:27.000000000 +0000 ++++ linux-3.10-3.10.11/fs/notify/mark.c 2014-05-05 12:42:01.000000000 +0000 +@@ -115,6 +115,7 @@ mark->free_mark(mark); } } @@ -125,7 +125,7 @@ /* * Any time a mark is getting freed we end up here. -@@ -197,6 +198,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, +@@ -197,6 +198,7 @@ fsnotify_destroy_mark_locked(mark, group); mutex_unlock(&group->mark_mutex); } @@ -133,7 +133,7 @@ void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) { -@@ -281,6 +283,7 @@ err: +@@ -281,6 +283,7 @@ return ret; } @@ -141,7 +141,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, struct inode *inode, struct vfsmount *mnt, int allow_dups) -@@ -342,6 +345,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, +@@ -342,6 +345,7 @@ atomic_set(&mark->refcnt, 1); mark->free_mark = free_mark; } @@ -149,11 +149,11 @@ static int fsnotify_mark_destroy(void *ignored) { -diff --git a/fs/open.c b/fs/open.c -index 8c74100..be563cd 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -61,6 +61,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, +Index: linux-3.10-3.10.11/fs/open.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/open.c 2014-05-05 11:52:27.000000000 +0000 ++++ linux-3.10-3.10.11/fs/open.c 2014-05-05 12:42:01.000000000 +0000 +@@ -61,6 +61,7 @@ mutex_unlock(&dentry->d_inode->i_mutex); return ret; } @@ -161,11 +161,11 @@ long vfs_truncate(struct path *path, loff_t length) { -diff --git a/fs/splice.c b/fs/splice.c -index 987346f..8d6a045 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -1120,6 +1120,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +Index: linux-3.10-3.10.11/fs/splice.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/splice.c 2014-05-05 12:42:00.000000000 +0000 ++++ linux-3.10-3.10.11/fs/splice.c 2014-05-05 12:42:01.000000000 +0000 +@@ -1120,6 +1120,7 @@ file_end_write(out); return ret; } @@ -173,7 +173,7 @@ /* * Attempt to initiate a splice from a file to a pipe. -@@ -1146,6 +1147,7 @@ long do_splice_to(struct file *in, loff_t *ppos, +@@ -1146,6 +1147,7 @@ return splice_read(in, ppos, pipe, len, flags); } @@ -181,11 +181,11 @@ /** * splice_direct_to_actor - splices data directly between two non-pipes -diff --git a/security/commoncap.c b/security/commoncap.c -index c44b6fe..d78b003 100644 ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr) +Index: linux-3.10-3.10.11/security/commoncap.c +=================================================================== +--- linux-3.10-3.10.11.orig/security/commoncap.c 2014-05-05 11:52:27.000000000 +0000 ++++ linux-3.10-3.10.11/security/commoncap.c 2014-05-05 12:42:01.000000000 +0000 +@@ -988,9 +988,11 @@ } return ret; } @@ -197,10 +197,10 @@ return 0; } +EXPORT_SYMBOL_GPL(cap_mmap_file); -diff --git a/security/device_cgroup.c b/security/device_cgroup.c -index dd0dc57..9760ecb6 100644 ---- a/security/device_cgroup.c -+++ b/security/device_cgroup.c +Index: linux-3.10-3.10.11/security/device_cgroup.c +=================================================================== +--- linux-3.10-3.10.11.orig/security/device_cgroup.c 2014-05-05 11:52:27.000000000 +0000 ++++ linux-3.10-3.10.11/security/device_cgroup.c 2014-05-05 12:42:01.000000000 +0000 @@ -7,6 +7,7 @@ #include #include @@ -209,7 +209,7 @@ #include #include #include -@@ -789,6 +790,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask) +@@ -789,6 +790,7 @@ return __devcgroup_check_permission(type, imajor(inode), iminor(inode), access); } @@ -217,11 +217,11 @@ int devcgroup_inode_mknod(int mode, dev_t dev) { -diff --git a/security/security.c b/security/security.c -index a3dce87..06a6ea6 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -396,6 +396,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry) +Index: linux-3.10-3.10.11/security/security.c +=================================================================== +--- linux-3.10-3.10.11.orig/security/security.c 2014-05-05 11:52:27.000000000 +0000 ++++ linux-3.10-3.10.11/security/security.c 2014-05-05 12:42:01.000000000 +0000 +@@ -396,6 +396,7 @@ return 0; return security_ops->path_rmdir(dir, dentry); } @@ -229,7 +229,7 @@ int security_path_unlink(struct path *dir, struct dentry *dentry) { -@@ -412,6 +413,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry, +@@ -412,6 +413,7 @@ return 0; return security_ops->path_symlink(dir, dentry, old_name); } @@ -237,7 +237,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) -@@ -420,6 +422,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, +@@ -420,6 +422,7 @@ return 0; return security_ops->path_link(old_dentry, new_dir, new_dentry); } @@ -245,7 +245,7 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) -@@ -438,6 +441,7 @@ int security_path_truncate(struct path *path) +@@ -438,6 +441,7 @@ return 0; return security_ops->path_truncate(path); } @@ -253,7 +253,7 @@ int security_path_chmod(struct path *path, umode_t mode) { -@@ -445,6 +449,7 @@ int security_path_chmod(struct path *path, umode_t mode) +@@ -445,6 +449,7 @@ return 0; return security_ops->path_chmod(path, mode); } @@ -261,7 +261,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { -@@ -452,6 +457,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) +@@ -452,6 +457,7 @@ return 0; return security_ops->path_chown(path, uid, gid); } @@ -269,7 +269,7 @@ int security_path_chroot(struct path *path) { -@@ -528,6 +534,7 @@ int security_inode_readlink(struct dentry *dentry) +@@ -528,6 +534,7 @@ return 0; return security_ops->inode_readlink(dentry); } @@ -277,7 +277,7 @@ int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) { -@@ -542,6 +549,7 @@ int security_inode_permission(struct inode *inode, int mask) +@@ -542,6 +549,7 @@ return 0; return security_ops->inode_permission(inode, mask); } @@ -285,7 +285,7 @@ int security_inode_setattr(struct dentry *dentry, struct iattr *attr) { -@@ -663,6 +671,7 @@ int security_file_permission(struct file *file, int mask) +@@ -663,6 +671,7 @@ return fsnotify_perm(file, mask); } @@ -293,7 +293,7 @@ int security_file_alloc(struct file *file) { -@@ -723,6 +732,7 @@ int security_mmap_file(struct file *file, unsigned long prot, +@@ -723,6 +732,7 @@ return ret; return ima_file_mmap(file, prot); } diff -Nru linux-3.10.11/debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch --- linux-3.10.11/debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch 2013-08-31 17:41:24.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch 2014-05-05 12:42:13.000000000 +0000 @@ -11,11 +11,11 @@ fs/aufs/mvdown.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) -diff --git a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c -index 628d627..1ac7688 100644 ---- a/fs/aufs/ioctl.c -+++ b/fs/aufs/ioctl.c -@@ -152,7 +152,6 @@ long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) +Index: linux-3.10-3.10.11/fs/aufs/ioctl.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/aufs/ioctl.c 2014-05-05 12:42:05.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/ioctl.c 2014-05-05 12:42:13.000000000 +0000 +@@ -152,7 +152,6 @@ switch (cmd) { case AUFS_CTL_MVDOWN: @@ -23,11 +23,11 @@ err = au_mvdown(file->f_dentry, (void __user *)arg); break; -diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c -index e68002e..5f56645 100644 ---- a/fs/aufs/mvdown.c -+++ b/fs/aufs/mvdown.c -@@ -489,6 +489,8 @@ int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) +Index: linux-3.10-3.10.11/fs/aufs/mvdown.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/aufs/mvdown.c 2014-05-05 12:42:05.000000000 +0000 ++++ linux-3.10-3.10.11/fs/aufs/mvdown.c 2014-05-05 12:42:13.000000000 +0000 +@@ -489,6 +489,8 @@ if (unlikely(!capable(CAP_SYS_ADMIN))) goto out; diff -Nru linux-3.10.11/debian/patches/features/all/cgroups-Allow-memory-cgroup-support-to-be-included-b.patch linux-3.10-3.10.11/debian/patches/features/all/cgroups-Allow-memory-cgroup-support-to-be-included-b.patch --- linux-3.10.11/debian/patches/features/all/cgroups-Allow-memory-cgroup-support-to-be-included-b.patch 2013-07-14 23:47:06.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/cgroups-Allow-memory-cgroup-support-to-be-included-b.patch 2013-12-23 10:41:51.000000000 +0000 @@ -17,9 +17,11 @@ mm/memcontrol.c | 3 +++ 4 files changed, 29 insertions(+), 6 deletions(-) ---- a/Documentation/kernel-parameters.txt -+++ b/Documentation/kernel-parameters.txt -@@ -449,8 +449,8 @@ bytes respectively. Such letter suffixes +Index: linux-3.10.11.rpi/Documentation/kernel-parameters.txt +=================================================================== +--- linux-3.10.11.rpi.orig/Documentation/kernel-parameters.txt 2013-12-23 10:39:19.000000000 +0000 ++++ linux-3.10.11.rpi/Documentation/kernel-parameters.txt 2013-12-23 10:41:50.000000000 +0000 +@@ -458,8 +458,8 @@ ccw_timeout_log [S390] See Documentation/s390/CommonIO for details. @@ -30,9 +32,11 @@ {Currently supported controllers - "memory"} checkreqprot [SELINUX] Set initial checkreqprot flag value. ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -845,6 +845,14 @@ config MEMCG +Index: linux-3.10.11.rpi/init/Kconfig +=================================================================== +--- linux-3.10.11.rpi.orig/init/Kconfig 2013-12-23 10:39:19.000000000 +0000 ++++ linux-3.10.11.rpi/init/Kconfig 2013-12-23 10:41:50.000000000 +0000 +@@ -890,6 +890,14 @@ This config option also selects MM_OWNER config option, which could in turn add some fork/exit overhead. @@ -47,9 +51,11 @@ config MEMCG_SWAP bool "Memory Resource Controller Swap Extension" depends on MEMCG && SWAP ---- a/kernel/cgroup.c -+++ b/kernel/cgroup.c -@@ -5193,7 +5193,7 @@ static void cgroup_release_agent(struct +Index: linux-3.10.11.rpi/kernel/cgroup.c +=================================================================== +--- linux-3.10.11.rpi.orig/kernel/cgroup.c 2013-12-23 10:39:19.000000000 +0000 ++++ linux-3.10.11.rpi/kernel/cgroup.c 2013-12-23 10:41:50.000000000 +0000 +@@ -5072,7 +5072,7 @@ mutex_unlock(&cgroup_mutex); } @@ -58,7 +64,7 @@ { int i; char *token; -@@ -5213,17 +5213,29 @@ static int __init cgroup_disable(char *s +@@ -5092,17 +5092,29 @@ continue; if (!strcmp(token, ss->name)) { @@ -91,9 +97,11 @@ /* * Functons for CSS ID. */ ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -6789,6 +6789,9 @@ static void mem_cgroup_move_task(struct +Index: linux-3.10.11.rpi/mm/memcontrol.c +=================================================================== +--- linux-3.10.11.rpi.orig/mm/memcontrol.c 2013-12-23 10:39:19.000000000 +0000 ++++ linux-3.10.11.rpi/mm/memcontrol.c 2013-12-23 10:41:50.000000000 +0000 +@@ -6938,6 +6938,9 @@ struct cgroup_subsys mem_cgroup_subsys = { .name = "memory", diff -Nru linux-3.10.11/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch linux-3.10-3.10.11/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch --- linux-3.10.11/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/cpu-devices/Partially-revert-cpufreq-Add-support-for-x86-cpuinfo.patch 2014-05-05 12:42:35.000000000 +0000 @@ -13,10 +13,10 @@ drivers/cpufreq/e_powersaver.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) -diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c -index 3fffbe6..4bd6815 100644 ---- a/drivers/cpufreq/e_powersaver.c -+++ b/drivers/cpufreq/e_powersaver.c +Index: linux-3.10-3.10.11/drivers/cpufreq/e_powersaver.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/cpufreq/e_powersaver.c 2014-05-05 11:52:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/cpufreq/e_powersaver.c 2014-05-05 12:42:34.000000000 +0000 @@ -16,7 +16,6 @@ #include #include @@ -25,7 +25,7 @@ #include #include -@@ -438,19 +437,18 @@ static struct cpufreq_driver eps_driver = { +@@ -437,19 +436,18 @@ .attr = eps_attr, }; diff -Nru linux-3.10.11/debian/patches/features/all/doc-build-parallel.patch linux-3.10-3.10.11/debian/patches/features/all/doc-build-parallel.patch --- linux-3.10.11/debian/patches/features/all/doc-build-parallel.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/doc-build-parallel.patch 2014-05-05 12:41:29.000000000 +0000 @@ -10,11 +10,11 @@ Since dh_compress will compress manual pages later, we don't need to run gzip here at all. -diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile -index 5a2882d..71c7077 100644 ---- a/Documentation/DocBook/Makefile -+++ b/Documentation/DocBook/Makefile -@@ -146,7 +146,7 @@ quiet_cmd_db2html = HTML $@ +Index: linux-3.10-3.10.11/Documentation/DocBook/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Documentation/DocBook/Makefile 2014-05-05 11:52:42.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/DocBook/Makefile 2014-05-05 12:41:28.000000000 +0000 +@@ -159,7 +159,7 @@ cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi quiet_cmd_db2man = MAN $@ diff -Nru linux-3.10.11/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch linux-3.10-3.10.11/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch --- linux-3.10.11/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch 2014-05-05 12:41:35.000000000 +0000 @@ -11,9 +11,11 @@ drivers/media/dvb/dvb-usb/af9005-fe.c | 66 ++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 14 deletions(-) ---- a/drivers/media/usb/dvb-usb/Kconfig -+++ b/drivers/media/usb/dvb-usb/Kconfig -@@ -227,10 +227,10 @@ config DVB_USB_OPERA1 +Index: linux-3.10-3.10.11/drivers/media/usb/dvb-usb/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/dvb-usb/Kconfig 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/dvb-usb/Kconfig 2014-05-05 12:41:34.000000000 +0000 +@@ -231,10 +231,10 @@ config DVB_USB_AF9005 tristate "Afatech AF9005 DVB-T USB1.1 support" @@ -25,8 +27,10 @@ help Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver and the TerraTec Cinergy T USB XE (Rev.1) ---- a/drivers/media/usb/dvb-usb/af9005-fe.c -+++ b/drivers/media/usb/dvb-usb/af9005-fe.c +Index: linux-3.10-3.10.11/drivers/media/usb/dvb-usb/af9005-fe.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/dvb-usb/af9005-fe.c 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/dvb-usb/af9005-fe.c 2014-05-05 12:41:34.000000000 +0000 @@ -22,10 +22,26 @@ * see Documentation/dvb/README.dvb-usb for more information */ @@ -55,7 +59,7 @@ struct af9005_fe_state { struct dvb_usb_device *d; -@@ -816,6 +832,8 @@ static int af9005_fe_init(struct dvb_fro +@@ -816,6 +832,8 @@ { struct af9005_fe_state *state = fe->demodulator_priv; struct dvb_usb_adapter *adap = fe->dvb->priv; @@ -64,7 +68,7 @@ int ret, i, scriptlen; u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; u8 buf[2]; -@@ -968,37 +986,55 @@ static int af9005_fe_init(struct dvb_fro +@@ -968,37 +986,55 @@ if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01))) return ret; @@ -132,7 +136,7 @@ /* save original TOPs */ deb_info("save original TOPs\n"); -@@ -1078,6 +1114,10 @@ static int af9005_fe_init(struct dvb_fro +@@ -1078,6 +1114,10 @@ deb_info("profit!\n"); return 0; diff -Nru linux-3.10.11/debian/patches/features/all/efi-autoload-efivars.patch linux-3.10-3.10.11/debian/patches/features/all/efi-autoload-efivars.patch --- linux-3.10.11/debian/patches/features/all/efi-autoload-efivars.patch 2013-09-08 16:10:43.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/efi-autoload-efivars.patch 2014-05-05 12:42:51.000000000 +0000 @@ -15,8 +15,10 @@ are available. This should trigger udev to load them. --- ---- a/arch/x86/platform/efi/efi.c -+++ b/arch/x86/platform/efi/efi.c +Index: linux-3.10-3.10.11/arch/x86/platform/efi/efi.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/platform/efi/efi.c 2014-05-05 11:52:09.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/platform/efi/efi.c 2014-05-05 12:42:51.000000000 +0000 @@ -42,6 +42,7 @@ #include #include @@ -25,7 +27,7 @@ #include #include -@@ -783,6 +784,20 @@ void __init efi_late_init(void) +@@ -783,6 +784,20 @@ efi_bgrt_init(); } @@ -46,9 +48,11 @@ void __init efi_set_executable(efi_memory_desc_t *md, bool executable) { u64 addr, npages; ---- a/drivers/firmware/efi/efivars.c -+++ b/drivers/firmware/efi/efivars.c -@@ -77,6 +77,7 @@ MODULE_AUTHOR("Matt Domsch vif_data_size = sizeof(struct iwl_mvm_vif); hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt); @@ -73,11 +73,3 @@ hw->wiphy->max_remain_on_channel_duration = 10000; hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; --- -1.7.10.4 - --- -To unsubscribe from this list: send the line "unsubscribe stable" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - diff -Nru linux-3.10.11/debian/patches/features/all/Kbuild-kconfig-Verbose-version-of-listnewconfig.patch linux-3.10-3.10.11/debian/patches/features/all/Kbuild-kconfig-Verbose-version-of-listnewconfig.patch --- linux-3.10.11/debian/patches/features/all/Kbuild-kconfig-Verbose-version-of-listnewconfig.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/Kbuild-kconfig-Verbose-version-of-listnewconfig.patch 2014-05-05 12:41:34.000000000 +0000 @@ -18,9 +18,11 @@ scripts/kconfig/lkc_proto.h | 1 + 4 files changed, 44 insertions(+), 10 deletions(-) ---- a/scripts/kconfig/conf.c -+++ b/scripts/kconfig/conf.c -@@ -368,7 +368,6 @@ static void conf(struct menu *menu) +Index: linux-3.10-3.10.11/scripts/kconfig/conf.c +=================================================================== +--- linux-3.10-3.10.11.orig/scripts/kconfig/conf.c 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/scripts/kconfig/conf.c 2014-05-05 12:41:33.000000000 +0000 +@@ -368,7 +368,6 @@ switch (prop->type) { case P_MENU: if ((input_mode == silentoldconfig || @@ -28,7 +30,7 @@ input_mode == olddefconfig) && rootEntry != menu) { check_conf(menu); -@@ -429,11 +428,7 @@ static void check_conf(struct menu *menu +@@ -429,11 +428,7 @@ if (sym && !sym_has_value(sym)) { if (sym_is_changable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { @@ -41,7 +43,7 @@ if (!conf_cnt++) printf(_("*\n* Restart config...\n*\n")); rootEntry = menu_get_parent_menu(menu); -@@ -446,6 +441,30 @@ static void check_conf(struct menu *menu +@@ -446,6 +441,30 @@ check_conf(child); } @@ -72,7 +74,7 @@ static struct option long_opts[] = { {"oldaskconfig", no_argument, NULL, oldaskconfig}, {"oldconfig", no_argument, NULL, oldconfig}, -@@ -493,6 +512,7 @@ int main(int ac, char **av) +@@ -493,6 +512,7 @@ const char *progname = av[0]; int opt; const char *name, *defconfig_file = NULL /* gcc uninit */; @@ -80,7 +82,7 @@ struct stat tmpstat; setlocale(LC_ALL, ""); -@@ -666,16 +686,18 @@ int main(int ac, char **av) +@@ -666,16 +686,18 @@ input_mode = silentoldconfig; /* fall through */ case oldconfig: @@ -103,9 +105,11 @@ break; } ---- a/scripts/kconfig/confdata.c -+++ b/scripts/kconfig/confdata.c -@@ -727,6 +727,14 @@ next_menu: +Index: linux-3.10-3.10.11/scripts/kconfig/confdata.c +=================================================================== +--- linux-3.10-3.10.11.orig/scripts/kconfig/confdata.c 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/scripts/kconfig/confdata.c 2014-05-05 12:41:33.000000000 +0000 +@@ -727,6 +727,14 @@ return 0; } @@ -120,7 +124,7 @@ int conf_write(const char *name) { FILE *out; -@@ -1153,7 +1161,10 @@ void conf_set_all_new_symbols(enum conf_ +@@ -1153,7 +1161,10 @@ } for_all_symbols(i, sym) { @@ -132,9 +136,11 @@ continue; switch (sym_get_type(sym)) { case S_BOOLEAN: ---- a/scripts/kconfig/expr.h -+++ b/scripts/kconfig/expr.h -@@ -106,6 +106,8 @@ struct symbol { +Index: linux-3.10-3.10.11/scripts/kconfig/expr.h +=================================================================== +--- linux-3.10-3.10.11.orig/scripts/kconfig/expr.h 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/scripts/kconfig/expr.h 2014-05-05 12:41:33.000000000 +0000 +@@ -106,6 +106,8 @@ #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ @@ -143,9 +149,11 @@ #define SYMBOL_MAXLENGTH 256 #define SYMBOL_HASHSIZE 9973 ---- a/scripts/kconfig/lkc_proto.h -+++ b/scripts/kconfig/lkc_proto.h -@@ -7,6 +7,7 @@ P(conf_read_simple,int,(const char *name +Index: linux-3.10-3.10.11/scripts/kconfig/lkc_proto.h +=================================================================== +--- linux-3.10-3.10.11.orig/scripts/kconfig/lkc_proto.h 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/scripts/kconfig/lkc_proto.h 2014-05-05 12:41:33.000000000 +0000 +@@ -7,6 +7,7 @@ P(conf_write_defconfig,int,(const char *name)); P(conf_write,int,(const char *name)); P(conf_write_autoconf,int,(void)); diff -Nru linux-3.10.11/debian/patches/features/all/sound-pci-cs46xx-request_firmware.patch linux-3.10-3.10.11/debian/patches/features/all/sound-pci-cs46xx-request_firmware.patch --- linux-3.10.11/debian/patches/features/all/sound-pci-cs46xx-request_firmware.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/sound-pci-cs46xx-request_firmware.patch 2014-05-05 12:41:36.000000000 +0000 @@ -7,11 +7,11 @@ Tested by Antonio Ospite . Unfortunately we cannot currently distribute the firmware. -diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig -index 17e03b9..124b3a0 100644 ---- a/sound/pci/Kconfig -+++ b/sound/pci/Kconfig -@@ -229,7 +229,7 @@ config SND_CS4281 +Index: linux-3.10-3.10.11/sound/pci/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/Kconfig 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/Kconfig 2014-05-05 12:41:35.000000000 +0000 +@@ -257,7 +257,7 @@ config SND_CS46XX tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x" @@ -20,7 +20,7 @@ select SND_RAWMIDI select SND_AC97_CODEC help -@@ -241,6 +241,7 @@ config SND_CS46XX +@@ -269,6 +269,7 @@ config SND_CS46XX_NEW_DSP bool "Cirrus Logic (Sound Fusion) New DSP support" @@ -28,10 +28,10 @@ depends on SND_CS46XX default y help -diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c -index 1be96ea..b12b930 100644 ---- a/sound/pci/cs46xx/cs46xx_lib.c -+++ b/sound/pci/cs46xx/cs46xx_lib.c +Index: linux-3.10-3.10.11/sound/pci/cs46xx/cs46xx_lib.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/cs46xx/cs46xx_lib.c 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/cs46xx/cs46xx_lib.c 2014-05-05 12:41:35.000000000 +0000 @@ -54,6 +54,8 @@ #include #include @@ -41,7 +41,7 @@ #include -@@ -308,7 +309,7 @@ static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97, +@@ -309,7 +311,7 @@ */ int snd_cs46xx_download(struct snd_cs46xx *chip, @@ -50,7 +50,7 @@ unsigned long offset, unsigned long len) { -@@ -321,9 +322,9 @@ int snd_cs46xx_download(struct snd_cs46xx *chip, +@@ -322,9 +324,9 @@ dst = chip->region.idx[bank+1].remap_addr + offset; len /= sizeof(u32); @@ -62,7 +62,7 @@ dst += sizeof(u32); } return 0; -@@ -360,23 +361,77 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, +@@ -361,23 +363,77 @@ #else /* old DSP image */ @@ -151,17 +151,17 @@ #endif /* CONFIG_SND_CS46XX_NEW_DSP */ /* -@@ -3874,3 +3929,5 @@ int __devinit snd_cs46xx_create(struct snd_card *card, +@@ -3887,3 +3943,5 @@ *rchip = chip; return 0; } + +MODULE_FIRMWARE("cs46xx/cs46xx-old.fw"); -diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h -index 4eb55aa..85babb5 100644 ---- a/sound/pci/cs46xx/cs46xx_lib.h -+++ b/sound/pci/cs46xx/cs46xx_lib.h -@@ -103,8 +103,8 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip); +Index: linux-3.10-3.10.11/sound/pci/cs46xx/cs46xx_lib.h +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/cs46xx/cs46xx_lib.h 2014-05-05 11:52:40.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/cs46xx/cs46xx_lib.h 2014-05-05 12:41:35.000000000 +0000 +@@ -103,8 +103,8 @@ #define cs46xx_dsp_proc_done(chip) #endif int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip); diff -Nru linux-3.10.11/debian/patches/features/all/sysrq-mask.patch linux-3.10-3.10.11/debian/patches/features/all/sysrq-mask.patch --- linux-3.10.11/debian/patches/features/all/sysrq-mask.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/sysrq-mask.patch 2014-05-05 12:42:14.000000000 +0000 @@ -6,8 +6,10 @@ Add a Kconfig variable to set the initial value of the Magic SysRq mask (sysctl: kernel.sysrq). ---- a/include/linux/sysrq.h -+++ b/include/linux/sysrq.h +Index: linux-3.10-3.10.11/include/linux/sysrq.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/sysrq.h 2014-05-05 11:52:24.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/sysrq.h 2014-05-05 12:42:13.000000000 +0000 @@ -18,7 +18,7 @@ #include @@ -17,11 +19,11 @@ /* Possible values of bitmask for enabling sysrq functions */ /* 0x0001 is reserved for enable everything */ -diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug -index 234ceb1..415a834 100644 ---- a/lib/Kconfig.debug -+++ b/lib/Kconfig.debug -@@ -50,6 +50,14 @@ config MAGIC_SYSRQ +Index: linux-3.10-3.10.11/lib/Kconfig.debug +=================================================================== +--- linux-3.10-3.10.11.orig/lib/Kconfig.debug 2014-05-05 11:52:24.000000000 +0000 ++++ linux-3.10-3.10.11/lib/Kconfig.debug 2014-05-05 12:42:14.000000000 +0000 +@@ -66,6 +66,14 @@ keys are documented in . Don't say Y unless you really know what this hack does. diff -Nru linux-3.10.11/debian/patches/features/all/x86-memtest-WARN-if-bad-RAM-found.patch linux-3.10-3.10.11/debian/patches/features/all/x86-memtest-WARN-if-bad-RAM-found.patch --- linux-3.10.11/debian/patches/features/all/x86-memtest-WARN-if-bad-RAM-found.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/x86-memtest-WARN-if-bad-RAM-found.patch 2014-05-05 12:42:50.000000000 +0000 @@ -13,11 +13,11 @@ arch/x86/mm/memtest.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) -diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c -index 92faf3a..ac6bdaa 100644 ---- a/arch/x86/mm/memtest.c -+++ b/arch/x86/mm/memtest.c -@@ -30,6 +30,8 @@ static u64 patterns[] __initdata = { +Index: linux-3.10-3.10.11/arch/x86/mm/memtest.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/mm/memtest.c 2014-05-05 11:52:10.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/mm/memtest.c 2014-05-05 12:42:50.000000000 +0000 +@@ -31,6 +31,8 @@ static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad) { diff -Nru linux-3.10.11/debian/patches/features/all/xen/microcode-amd-fam15plus.patch linux-3.10-3.10.11/debian/patches/features/all/xen/microcode-amd-fam15plus.patch --- linux-3.10.11/debian/patches/features/all/xen/microcode-amd-fam15plus.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/xen/microcode-amd-fam15plus.patch 2014-05-05 12:42:25.000000000 +0000 @@ -9,11 +9,11 @@ arch/x86/kernel/microcode_xen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) -diff --git a/arch/x86/kernel/microcode_xen.c b/arch/x86/kernel/microcode_xen.c -index 6a73957..9e50566 100644 ---- a/arch/x86/kernel/microcode_xen.c -+++ b/arch/x86/kernel/microcode_xen.c -@@ -58,7 +58,7 @@ static int xen_microcode_update(int cpu) +Index: linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/microcode_xen.c 2014-05-05 12:42:24.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c 2014-05-05 12:42:25.000000000 +0000 +@@ -58,7 +58,7 @@ static enum ucode_state xen_request_microcode_fw(int cpu, struct device *device) { @@ -22,7 +22,7 @@ struct cpuinfo_x86 *c = &cpu_data(cpu); const struct firmware *firmware; struct ucode_cpu_info *uci = ucode_cpu_info + cpu; -@@ -74,7 +74,11 @@ static enum ucode_state xen_request_microcode_fw(int cpu, struct device *device) +@@ -74,7 +74,11 @@ break; case X86_VENDOR_AMD: diff -Nru linux-3.10.11/debian/patches/features/all/xen/microcode-api-update.patch linux-3.10-3.10.11/debian/patches/features/all/xen/microcode-api-update.patch --- linux-3.10.11/debian/patches/features/all/xen/microcode-api-update.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/xen/microcode-api-update.patch 2014-05-05 12:42:27.000000000 +0000 @@ -8,11 +8,11 @@ arch/x86/kernel/microcode_xen.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) -diff --git a/arch/x86/kernel/microcode_xen.c b/arch/x86/kernel/microcode_xen.c -index 9e50566..6b7aa48 100644 ---- a/arch/x86/kernel/microcode_xen.c -+++ b/arch/x86/kernel/microcode_xen.c -@@ -56,7 +56,8 @@ static int xen_microcode_update(int cpu) +Index: linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/microcode_xen.c 2014-05-05 12:42:26.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c 2014-05-05 12:42:26.000000000 +0000 +@@ -56,7 +56,8 @@ return err; } @@ -22,6 +22,3 @@ { char name[36]; struct cpuinfo_x86 *c = &cpu_data(cpu); --- -1.7.2.5 - diff -Nru linux-3.10.11/debian/patches/features/all/xen/microcode.patch linux-3.10-3.10.11/debian/patches/features/all/xen/microcode.patch --- linux-3.10.11/debian/patches/features/all/xen/microcode.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/xen/microcode.patch 2014-05-05 12:42:25.000000000 +0000 @@ -23,9 +23,11 @@ 5 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/microcode_xen.c ---- a/arch/x86/include/asm/microcode.h -+++ b/arch/x86/include/asm/microcode.h -@@ -71,4 +71,13 @@ static inline int __init save_microcode_ +Index: linux-3.10-3.10.11/arch/x86/include/asm/microcode.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/microcode.h 2014-05-05 11:52:20.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/microcode.h 2014-05-05 12:42:24.000000000 +0000 +@@ -71,4 +71,13 @@ } #endif @@ -39,9 +41,11 @@ +#endif + #endif /* _ASM_X86_MICROCODE_H */ ---- a/arch/x86/kernel/Makefile -+++ b/arch/x86/kernel/Makefile -@@ -93,6 +93,7 @@ obj-$(CONFIG_MICROCODE_INTEL_LIB) += mic +Index: linux-3.10-3.10.11/arch/x86/kernel/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/Makefile 2014-05-05 11:52:20.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/Makefile 2014-05-05 12:42:24.000000000 +0000 +@@ -93,6 +93,7 @@ microcode-y := microcode_core.o microcode-$(CONFIG_MICROCODE_INTEL) += microcode_intel.o microcode-$(CONFIG_MICROCODE_AMD) += microcode_amd.o @@ -49,8 +53,10 @@ obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o ---- a/arch/x86/kernel/microcode_core.c -+++ b/arch/x86/kernel/microcode_core.c +Index: linux-3.10-3.10.11/arch/x86/kernel/microcode_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/microcode_core.c 2014-05-05 11:52:20.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/microcode_core.c 2014-05-05 12:42:24.000000000 +0000 @@ -84,6 +84,7 @@ #include #include @@ -59,7 +65,7 @@ #include #include #include -@@ -546,7 +547,9 @@ static int __init microcode_init(void) +@@ -546,7 +547,9 @@ struct cpuinfo_x86 *c = &cpu_data(0); int error; @@ -70,8 +76,10 @@ microcode_ops = init_intel_microcode(); else if (c->x86_vendor == X86_VENDOR_AMD) microcode_ops = init_amd_microcode(); ---- /dev/null -+++ b/arch/x86/kernel/microcode_xen.c +Index: linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c 2014-05-05 12:42:24.000000000 +0000 @@ -0,0 +1,198 @@ +/* + * Xen microcode update driver @@ -271,9 +279,11 @@ + return NULL; + return µcode_xen_ops; +} ---- a/arch/x86/xen/Kconfig -+++ b/arch/x86/xen/Kconfig -@@ -51,3 +51,6 @@ config XEN_DEBUG_FS +Index: linux-3.10-3.10.11/arch/x86/xen/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/xen/Kconfig 2014-05-05 11:52:20.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/xen/Kconfig 2014-05-05 12:42:24.000000000 +0000 +@@ -51,3 +51,6 @@ Enable statistics output and various tuning options in debugfs. Enabling this option may incur a significant performance overhead. diff -Nru linux-3.10.11/debian/patches/features/all/xen/microcode-typo.patch linux-3.10-3.10.11/debian/patches/features/all/xen/microcode-typo.patch --- linux-3.10.11/debian/patches/features/all/xen/microcode-typo.patch 2013-07-14 23:47:05.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/all/xen/microcode-typo.patch 2014-05-05 12:42:26.000000000 +0000 @@ -11,11 +11,11 @@ arch/x86/kernel/microcode_xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/x86/kernel/microcode_xen.c b/arch/x86/kernel/microcode_xen.c -index 9d2a06b..6a73957 100644 ---- a/arch/x86/kernel/microcode_xen.c -+++ b/arch/x86/kernel/microcode_xen.c -@@ -157,7 +157,7 @@ static enum ucode_state xen_request_microcode_user(int cpu, +Index: linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/microcode_xen.c 2014-05-05 12:42:25.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/microcode_xen.c 2014-05-05 12:42:26.000000000 +0000 +@@ -161,7 +161,7 @@ ret = UCODE_OK; out: diff -Nru linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usb-clock-DT-lookups.patch linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usb-clock-DT-lookups.patch --- linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usb-clock-DT-lookups.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usb-clock-DT-lookups.patch 2014-05-05 12:42:38.000000000 +0000 @@ -8,10 +8,10 @@ --- (limited to 'arch/arm/boot/dts') -diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi -index 761ae1c..b118e01 100644 ---- a/arch/arm/boot/dts/imx51.dtsi -+++ b/arch/arm/boot/dts/imx51.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx51.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx51.dtsi 2014-05-05 12:42:37.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx51.dtsi 2014-05-05 12:42:38.000000000 +0000 @@ -179,6 +179,7 @@ compatible = "fsl,imx51-usb", "fsl,imx27-usb"; reg = <0x73f80000 0x0200>; @@ -52,10 +52,10 @@ }; gpio1: gpio@73f84000 { -diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi -index 6c8fa7d..faea9fa 100644 ---- a/arch/arm/boot/dts/imx53.dtsi -+++ b/arch/arm/boot/dts/imx53.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx53.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx53.dtsi 2014-05-05 12:42:37.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx53.dtsi 2014-05-05 12:42:38.000000000 +0000 @@ -167,6 +167,7 @@ compatible = "fsl,imx53-usb", "fsl,imx27-usb"; reg = <0x53f80000 0x0200>; @@ -96,5 +96,3 @@ }; gpio1: gpio@53f84000 { --- -cgit v0.9.1 diff -Nru linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usbmisc-entries.patch linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usbmisc-entries.patch --- linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usbmisc-entries.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-add-imx5x-usbmisc-entries.patch 2014-05-05 12:42:38.000000000 +0000 @@ -8,10 +8,10 @@ --- (limited to 'arch/arm/boot/dts') -diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi -index 21bb786..761ae1c 100644 ---- a/arch/arm/boot/dts/imx51.dtsi -+++ b/arch/arm/boot/dts/imx51.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx51.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx51.dtsi 2014-05-05 11:52:15.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx51.dtsi 2014-05-05 12:42:37.000000000 +0000 @@ -179,6 +179,7 @@ compatible = "fsl,imx51-usb", "fsl,imx27-usb"; reg = <0x73f80000 0x0200>; @@ -53,10 +53,10 @@ gpio1: gpio@73f84000 { compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; reg = <0x73f84000 0x4000>; -diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi -index 845982e..6c8fa7d 100644 ---- a/arch/arm/boot/dts/imx53.dtsi -+++ b/arch/arm/boot/dts/imx53.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx53.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx53.dtsi 2014-05-05 11:52:15.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx53.dtsi 2014-05-05 12:42:37.000000000 +0000 @@ -167,6 +167,7 @@ compatible = "fsl,imx53-usb", "fsl,imx27-usb"; reg = <0x53f80000 0x0200>; @@ -98,5 +98,3 @@ gpio1: gpio@53f84000 { compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; reg = <0x53f84000 0x4000>; --- -cgit v0.9.1 diff -Nru linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-imx53-qsb.dts-enable-usbotg-and-usbh1.patch linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-imx53-qsb.dts-enable-usbotg-and-usbh1.patch --- linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-imx53-qsb.dts-enable-usbotg-and-usbh1.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-imx53-qsb.dts-enable-usbotg-and-usbh1.patch 2014-05-05 12:42:40.000000000 +0000 @@ -8,10 +8,10 @@ --- (limited to 'arch/arm/boot/dts') -diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts -index 8f0e9ae..160d1bc 100644 ---- a/arch/arm/boot/dts/imx53-qsb.dts -+++ b/arch/arm/boot/dts/imx53-qsb.dts +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx53-qsb.dts +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx53-qsb.dts 2014-05-05 11:52:14.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx53-qsb.dts 2014-05-05 12:42:40.000000000 +0000 @@ -268,3 +268,11 @@ phy-reset-gpios = <&gpio7 6 0>; status = "okay"; @@ -24,5 +24,3 @@ +&usbotg { + status = "okay"; +}; --- -cgit v0.9.1 diff -Nru linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-use-usb-nop-xceiv-usbphy-entries-for-imx5x.patch linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-use-usb-nop-xceiv-usbphy-entries-for-imx5x.patch --- linux-3.10.11/debian/patches/features/arm/ARM-dts-imx-use-usb-nop-xceiv-usbphy-entries-for-imx5x.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/ARM-dts-imx-use-usb-nop-xceiv-usbphy-entries-for-imx5x.patch 2014-05-05 12:42:39.000000000 +0000 @@ -8,10 +8,10 @@ --- (limited to 'arch/arm/boot/dts') -diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi -index b118e01..f23636f 100644 ---- a/arch/arm/boot/dts/imx51.dtsi -+++ b/arch/arm/boot/dts/imx51.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx51.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx51.dtsi 2014-05-05 12:42:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx51.dtsi 2014-05-05 12:42:39.000000000 +0000 @@ -175,12 +175,20 @@ }; }; @@ -33,10 +33,10 @@ status = "disabled"; }; -diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi -index faea9fa..c4ddf51 100644 ---- a/arch/arm/boot/dts/imx53.dtsi -+++ b/arch/arm/boot/dts/imx53.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx53.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx53.dtsi 2014-05-05 12:42:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx53.dtsi 2014-05-05 12:42:39.000000000 +0000 @@ -163,12 +163,27 @@ }; }; @@ -73,5 +73,3 @@ status = "disabled"; }; --- -cgit v0.9.1 diff -Nru linux-3.10.11/debian/patches/features/arm/imx53-qsb-usb-power.patch linux-3.10-3.10.11/debian/patches/features/arm/imx53-qsb-usb-power.patch --- linux-3.10.11/debian/patches/features/arm/imx53-qsb-usb-power.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/imx53-qsb-usb-power.patch 2014-05-05 12:42:41.000000000 +0000 @@ -7,10 +7,10 @@ Signed-off-by: Arnaud Patard [bwh: For 3.10, use macro for PIN_FUNC_ID in GPIO list] -Index: linux/arch/arm/boot/dts/imx53-qsb.dts +Index: linux-3.10-3.10.11/arch/arm/boot/dts/imx53-qsb.dts =================================================================== ---- linux.orig/arch/arm/boot/dts/imx53-qsb.dts 2013-05-20 00:46:34.000000000 +0200 -+++ linux/arch/arm/boot/dts/imx53-qsb.dts 2013-05-20 01:06:31.000000000 +0200 +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/imx53-qsb.dts 2014-05-05 12:42:40.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/imx53-qsb.dts 2014-05-05 12:42:41.000000000 +0000 @@ -66,6 +66,15 @@ regulator-max-microvolt = <3200000>; regulator-always-on; diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0001-net-Add-EMAC-ethernet-driver-found-on-Allwinner-A10-.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0001-net-Add-EMAC-ethernet-driver-found-on-Allwinner-A10-.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0001-net-Add-EMAC-ethernet-driver-found-on-Allwinner-A10-.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0001-net-Add-EMAC-ethernet-driver-found-on-Allwinner-A10-.patch 2014-05-05 12:42:43.000000000 +0000 @@ -31,11 +31,10 @@ create mode 100644 drivers/net/ethernet/allwinner/sun4i-emac.c create mode 100644 drivers/net/ethernet/allwinner/sun4i-emac.h -diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt -new file mode 100644 -index 0000000..b90bfcd ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt +Index: linux-3.10-3.10.11/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt 2014-05-05 12:42:42.000000000 +0000 @@ -0,0 +1,22 @@ +* Allwinner EMAC ethernet controller + @@ -59,11 +58,11 @@ + clocks = <&ahb_gates 17>; + phy = <&phy0>; +}; -diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig -index ed956e0..18fd6fb 100644 ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -20,6 +20,7 @@ config SUNGEM_PHY +Index: linux-3.10-3.10.11/drivers/net/ethernet/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/Kconfig 2014-05-05 11:52:13.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/Kconfig 2014-05-05 12:42:42.000000000 +0000 +@@ -20,6 +20,7 @@ source "drivers/net/ethernet/3com/Kconfig" source "drivers/net/ethernet/adaptec/Kconfig" source "drivers/net/ethernet/aeroflex/Kconfig" @@ -71,11 +70,11 @@ source "drivers/net/ethernet/alteon/Kconfig" source "drivers/net/ethernet/amd/Kconfig" source "drivers/net/ethernet/apple/Kconfig" -diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile -index 8268d85..009da27 100644 ---- a/drivers/net/ethernet/Makefile -+++ b/drivers/net/ethernet/Makefile -@@ -6,6 +6,7 @@ obj-$(CONFIG_NET_VENDOR_3COM) += 3com/ +Index: linux-3.10-3.10.11/drivers/net/ethernet/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/Makefile 2014-05-05 11:52:13.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/Makefile 2014-05-05 12:42:42.000000000 +0000 +@@ -6,6 +6,7 @@ obj-$(CONFIG_NET_VENDOR_8390) += 8390/ obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/ obj-$(CONFIG_GRETH) += aeroflex/ @@ -83,11 +82,10 @@ obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ obj-$(CONFIG_NET_VENDOR_AMD) += amd/ obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ -diff --git a/drivers/net/ethernet/allwinner/Kconfig b/drivers/net/ethernet/allwinner/Kconfig -new file mode 100644 -index 0000000..66d3532 ---- /dev/null -+++ b/drivers/net/ethernet/allwinner/Kconfig +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/Kconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/Kconfig 2014-05-05 12:42:42.000000000 +0000 @@ -0,0 +1,36 @@ +# +# Allwinner device configuration @@ -125,22 +123,20 @@ + will be called sun4i-emac. + +endif # NET_VENDOR_ALLWINNER -diff --git a/drivers/net/ethernet/allwinner/Makefile b/drivers/net/ethernet/allwinner/Makefile -new file mode 100644 -index 0000000..03129f7 ---- /dev/null -+++ b/drivers/net/ethernet/allwinner/Makefile +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/Makefile 2014-05-05 12:42:42.000000000 +0000 @@ -0,0 +1,5 @@ +# +# Makefile for the Allwinner device drivers. +# + +obj-$(CONFIG_SUN4I_EMAC) += sun4i-emac.o -diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c -new file mode 100644 -index 0000000..b411344 ---- /dev/null -+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:42.000000000 +0000 @@ -0,0 +1,960 @@ +/* + * Allwinner EMAC Fast Ethernet driver for Linux. @@ -1102,11 +1098,10 @@ +MODULE_AUTHOR("Maxime Ripard "); +MODULE_DESCRIPTION("Allwinner A10 emac network driver"); +MODULE_LICENSE("GPL"); -diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h -new file mode 100644 -index 0000000..38c72d9 ---- /dev/null -+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.h 2014-05-05 12:42:42.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * Allwinner EMAC Fast Ethernet driver for Linux. @@ -1216,6 +1211,3 @@ +#define EMAC_EEPROM_MAGIC (0x444d394b) +#define EMAC_UNDOCUMENTED_MAGIC (0x0143414d) +#endif /* _SUN4I_EMAC_H_ */ --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0002-net-Add-MDIO-bus-driver-for-the-Allwinner-EMAC.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0002-net-Add-MDIO-bus-driver-for-the-Allwinner-EMAC.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0002-net-Add-MDIO-bus-driver-for-the-Allwinner-EMAC.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0002-net-Add-MDIO-bus-driver-for-the-Allwinner-EMAC.patch 2014-05-05 12:42:44.000000000 +0000 @@ -19,11 +19,10 @@ create mode 100644 Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt create mode 100644 drivers/net/phy/mdio-sun4i.c -diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt b/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt -new file mode 100644 -index 0000000..00b9f9a ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt +Index: linux-3.10-3.10.11/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt 2014-05-05 12:42:43.000000000 +0000 @@ -0,0 +1,26 @@ +* Allwinner A10 MDIO Ethernet Controller interface + @@ -51,11 +50,11 @@ + reg = <0>; + }; +}; -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 1e11f2b..3a316b3 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -144,6 +144,16 @@ config MDIO_OCTEON +Index: linux-3.10-3.10.11/drivers/net/phy/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/phy/Kconfig 2014-05-05 11:52:12.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/phy/Kconfig 2014-05-05 12:42:43.000000000 +0000 +@@ -144,6 +144,16 @@ If in doubt, say Y. @@ -72,20 +71,19 @@ config MDIO_BUS_MUX tristate depends on OF_MDIO -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index 9645e38..23a2ab2 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -30,3 +30,4 @@ obj-$(CONFIG_AMD_PHY) += amd.o +Index: linux-3.10-3.10.11/drivers/net/phy/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/phy/Makefile 2014-05-05 11:52:12.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/phy/Makefile 2014-05-05 12:42:43.000000000 +0000 +@@ -30,3 +30,4 @@ obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o +obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o -diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c -new file mode 100644 -index 0000000..61d3f4e ---- /dev/null -+++ b/drivers/net/phy/mdio-sun4i.c +Index: linux-3.10-3.10.11/drivers/net/phy/mdio-sun4i.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/phy/mdio-sun4i.c 2014-05-05 12:42:43.000000000 +0000 @@ -0,0 +1,194 @@ +/* + * Allwinner EMAC MDIO interface driver @@ -281,6 +279,3 @@ +MODULE_DESCRIPTION("Allwinner EMAC MDIO interface driver"); +MODULE_AUTHOR("Maxime Ripard "); +MODULE_LICENSE("GPL"); --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0003-ARM-sun4i-Add-muxing-options-for-the-ethernet-contro.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0003-ARM-sun4i-Add-muxing-options-for-the-ethernet-contro.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0003-ARM-sun4i-Add-muxing-options-for-the-ethernet-contro.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0003-ARM-sun4i-Add-muxing-options-for-the-ethernet-contro.patch 2014-05-05 12:42:44.000000000 +0000 @@ -15,10 +15,10 @@ arch/arm/boot/dts/sun4i-a10.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) -diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi -index e7ef619..ff1f41f 100644 ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 11:52:12.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 12:42:44.000000000 +0000 @@ -199,6 +199,17 @@ allwinner,drive = <0>; allwinner,pull = <0>; @@ -37,6 +37,3 @@ }; timer@01c20c00 { --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0004-ARM-sunxi-Add-EMAC-controller-node-to-sun4i-DTSI.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0004-ARM-sunxi-Add-EMAC-controller-node-to-sun4i-DTSI.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0004-ARM-sunxi-Add-EMAC-controller-node-to-sun4i-DTSI.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0004-ARM-sunxi-Add-EMAC-controller-node-to-sun4i-DTSI.patch 2014-05-05 12:42:45.000000000 +0000 @@ -11,10 +11,10 @@ arch/arm/boot/dts/sun4i-a10.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) -diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi -index ff1f41f..983da33 100644 ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 12:42:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 12:42:45.000000000 +0000 @@ -163,6 +163,22 @@ reg = <0x01c20000 0x300000>; ranges; @@ -38,6 +38,3 @@ intc: interrupt-controller@01c20400 { compatible = "allwinner,sun4i-ic"; reg = <0x01c20400 0x400>; --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0005-ARM-cubieboard-Enable-ethernet-EMAC-support-in-dts.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0005-ARM-cubieboard-Enable-ethernet-EMAC-support-in-dts.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0005-ARM-cubieboard-Enable-ethernet-EMAC-support-in-dts.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0005-ARM-cubieboard-Enable-ethernet-EMAC-support-in-dts.patch 2014-05-05 12:42:46.000000000 +0000 @@ -12,10 +12,10 @@ arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) -diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -index b70fe0d..e752b57 100644 ---- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10-cubieboard.dts +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun4i-a10-cubieboard.dts 2014-05-05 11:52:11.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10-cubieboard.dts 2014-05-05 12:42:45.000000000 +0000 @@ -27,6 +27,21 @@ }; @@ -38,6 +38,3 @@ pinctrl@01c20800 { led_pins_cubieboard: led_pins@0 { allwinner,pins = "PH20", "PH21"; --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0006-ARM-sunxi-Add-EMAC-Controller-to-Hackberry-dt.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0006-ARM-sunxi-Add-EMAC-Controller-to-Hackberry-dt.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0006-ARM-sunxi-Add-EMAC-Controller-to-Hackberry-dt.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0006-ARM-sunxi-Add-EMAC-Controller-to-Hackberry-dt.patch 2014-05-05 12:42:47.000000000 +0000 @@ -14,10 +14,10 @@ arch/arm/boot/dts/sun4i-a10-hackberry.dts | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) -diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts -index b9efac1..3514b37 100644 ---- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts -+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10-hackberry.dts +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun4i-a10-hackberry.dts 2014-05-05 11:52:11.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10-hackberry.dts 2014-05-05 12:42:46.000000000 +0000 @@ -23,10 +23,51 @@ }; @@ -70,6 +70,3 @@ + }; + }; }; --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0007-net-sun4i-emac-fix-a-typo-in-emac_probe.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0007-net-sun4i-emac-fix-a-typo-in-emac_probe.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0007-net-sun4i-emac-fix-a-typo-in-emac_probe.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0007-net-sun4i-emac-fix-a-typo-in-emac_probe.patch 2014-05-05 12:42:47.000000000 +0000 @@ -13,11 +13,11 @@ drivers/net/ethernet/allwinner/sun4i-emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c -index b411344..26083cd 100644 ---- a/drivers/net/ethernet/allwinner/sun4i-emac.c -+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c -@@ -821,7 +821,7 @@ static int emac_probe(struct platform_device *pdev) +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:42.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:47.000000000 +0000 +@@ -821,7 +821,7 @@ db->membase = of_iomap(np, 0); if (!db->membase) { dev_err(&pdev->dev, "failed to remap registers\n"); @@ -26,6 +26,3 @@ goto out; } --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0008-net-sun4i-emac-remove-erroneous-assignment.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0008-net-sun4i-emac-remove-erroneous-assignment.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0008-net-sun4i-emac-remove-erroneous-assignment.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0008-net-sun4i-emac-remove-erroneous-assignment.patch 2014-05-05 12:42:48.000000000 +0000 @@ -23,11 +23,11 @@ drivers/net/ethernet/allwinner/sun4i-emac.c | 4 ---- 1 file changed, 4 deletions(-) -diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c -index 26083cd..0bb2f4a 100644 ---- a/drivers/net/ethernet/allwinner/sun4i-emac.c -+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c -@@ -869,10 +869,6 @@ static int emac_probe(struct platform_device *pdev) +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:47.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:47.000000000 +0000 +@@ -869,10 +869,6 @@ ndev->watchdog_timeo = msecs_to_jiffies(watchdog); ndev->ethtool_ops = &emac_ethtool_ops; @@ -38,6 +38,3 @@ platform_set_drvdata(pdev, ndev); /* Carrier starts down, phylib will bring it up */ --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0009-net-sun4i-emac-Remove-redundant-platform_set_drvdata.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0009-net-sun4i-emac-Remove-redundant-platform_set_drvdata.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0009-net-sun4i-emac-Remove-redundant-platform_set_drvdata.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0009-net-sun4i-emac-Remove-redundant-platform_set_drvdata.patch 2014-05-05 12:42:49.000000000 +0000 @@ -17,11 +17,11 @@ drivers/net/ethernet/allwinner/sun4i-emac.c | 2 -- 1 file changed, 2 deletions(-) -diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c -index 0bb2f4a..e9c8dbe 100644 ---- a/drivers/net/ethernet/allwinner/sun4i-emac.c -+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c -@@ -898,8 +898,6 @@ static int emac_remove(struct platform_device *pdev) +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:47.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:48.000000000 +0000 +@@ -898,8 +898,6 @@ { struct net_device *ndev = platform_get_drvdata(pdev); @@ -30,6 +30,3 @@ unregister_netdev(ndev); free_netdev(ndev); --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/sunxi-emac/0010-net-sun4i-emac-Staticize-local-symbols.patch linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0010-net-sun4i-emac-Staticize-local-symbols.patch --- linux-3.10.11/debian/patches/features/arm/sunxi-emac/0010-net-sun4i-emac-Staticize-local-symbols.patch 2013-07-14 23:46:35.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/sunxi-emac/0010-net-sun4i-emac-Staticize-local-symbols.patch 2014-05-05 12:42:50.000000000 +0000 @@ -14,11 +14,11 @@ drivers/net/ethernet/allwinner/sun4i-emac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c -index e9c8dbe..50b853a 100644 ---- a/drivers/net/ethernet/allwinner/sun4i-emac.c -+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c -@@ -258,7 +258,7 @@ static const struct ethtool_ops emac_ethtool_ops = { +Index: linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/allwinner/sun4i-emac.c 2014-05-05 12:42:49.000000000 +0000 +@@ -258,7 +258,7 @@ .get_link = ethtool_op_get_link, }; @@ -27,7 +27,7 @@ { struct emac_board_info *db = netdev_priv(ndev); unsigned int reg_val; -@@ -310,7 +310,7 @@ unsigned int emac_setup(struct net_device *ndev) +@@ -310,7 +310,7 @@ return 0; } @@ -36,6 +36,3 @@ { struct emac_board_info *db = netdev_priv(ndev); unsigned int reg_val; --- -1.7.10.4 - diff -Nru linux-3.10.11/debian/patches/features/arm/usbmisc-imx-add-module_device_table.patch linux-3.10-3.10.11/debian/patches/features/arm/usbmisc-imx-add-module_device_table.patch --- linux-3.10.11/debian/patches/features/arm/usbmisc-imx-add-module_device_table.patch 2013-07-15 00:08:01.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/features/arm/usbmisc-imx-add-module_device_table.patch 2014-05-05 12:42:41.000000000 +0000 @@ -11,11 +11,11 @@ drivers/usb/chipidea/usbmisc_imx.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c -index 588bae8..c912e7b 100644 ---- a/drivers/usb/chipidea/usbmisc_imx.c -+++ b/drivers/usb/chipidea/usbmisc_imx.c -@@ -175,6 +175,7 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { +Index: linux-3.10-3.10.11/drivers/usb/chipidea/usbmisc_imx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/chipidea/usbmisc_imx.c 2014-05-05 11:52:13.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/chipidea/usbmisc_imx.c 2014-05-05 12:42:40.000000000 +0000 +@@ -175,6 +175,7 @@ }, { /* sentinel */ } }; diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1000_f4cc06ac2d9fc7a483eb778abec66f60487687f4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1000_f4cc06ac2d9fc7a483eb778abec66f60487687f4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1000_f4cc06ac2d9fc7a483eb778abec66f60487687f4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1000_f4cc06ac2d9fc7a483eb778abec66f60487687f4.patch 2014-05-05 12:43:01.000000000 +0000 @@ -0,0 +1,43 @@ +commit f4cc06ac2d9fc7a483eb778abec66f60487687f4 +Author: stephen hemminger +Date: Thu Aug 1 22:32:07 2013 -0700 + + htb: fix sign extension bug + + [ Upstream commit cbd375567f7e4811b1c721f75ec519828ac6583f ] + + When userspace passes a large priority value + the assignment of the unsigned value hopt->prio + to signed int cl->prio causes cl->prio to become negative and the + comparison is with TC_HTB_NUMPRIO is always false. + + The result is that HTB crashes by referencing outside + the array when processing packets. With this patch the large value + wraps around like other values outside the normal range. + + See: https://bugzilla.kernel.org/show_bug.cgi?id=60669 + + Signed-off-by: Stephen Hemminger + Acked-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sched/sch_htb.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sched/sch_htb.c 2014-05-05 11:52:05.000000000 +0000 ++++ linux-3.10-3.10.11/net/sched/sch_htb.c 2014-05-05 12:43:01.000000000 +0000 +@@ -87,7 +87,7 @@ + unsigned int children; + struct htb_class *parent; /* parent class */ + +- int prio; /* these two are used only by leaves... */ ++ u32 prio; /* these two are used only by leaves... */ + int quantum; /* but stored for parent-to-leaf return */ + + union { +Index: linux-3.10-3.10.11/dummy/rpi_1000_f4cc06ac2d9fc7a483eb778abec66f60487687f4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1000_f4cc06ac2d9fc7a483eb778abec66f60487687f4.txt 2014-05-05 12:43:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1001_b4f55925ace5646d72df5af6fdab74fdbb288229.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1001_b4f55925ace5646d72df5af6fdab74fdbb288229.patch --- linux-3.10.11/debian/patches/rpi/rpi_1001_b4f55925ace5646d72df5af6fdab74fdbb288229.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1001_b4f55925ace5646d72df5af6fdab74fdbb288229.patch 2014-05-05 12:43:02.000000000 +0000 @@ -0,0 +1,45 @@ +commit b4f55925ace5646d72df5af6fdab74fdbb288229 +Author: Daniel Borkmann +Date: Fri Aug 2 11:32:43 2013 +0200 + + net: rtm_to_ifaddr: free ifa if ifa_cacheinfo processing fails + + [ Upstream commit 446266b0c742a2c9ee8f0dce759a0117bce58a86 ] + + Commit 5c766d642 ("ipv4: introduce address lifetime") leaves the ifa + resource that was allocated via inet_alloc_ifa() unfreed when returning + the function with -EINVAL. Thus, free it first via inet_free_ifa(). + + Signed-off-by: Daniel Borkmann + Reviewed-by: Jiri Pirko + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/devinet.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/devinet.c 2014-05-05 11:52:04.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/devinet.c 2014-05-05 12:43:02.000000000 +0000 +@@ -771,7 +771,7 @@ + ci = nla_data(tb[IFA_CACHEINFO]); + if (!ci->ifa_valid || ci->ifa_prefered > ci->ifa_valid) { + err = -EINVAL; +- goto errout; ++ goto errout_free; + } + *pvalid_lft = ci->ifa_valid; + *pprefered_lft = ci->ifa_prefered; +@@ -779,6 +779,8 @@ + + return ifa; + ++errout_free: ++ inet_free_ifa(ifa); + errout: + return ERR_PTR(err); + } +Index: linux-3.10-3.10.11/dummy/rpi_1001_b4f55925ace5646d72df5af6fdab74fdbb288229.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1001_b4f55925ace5646d72df5af6fdab74fdbb288229.txt 2014-05-05 12:43:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1002_4691236cedfb12e2644f4c84b4b14a6882e1fd7b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1002_4691236cedfb12e2644f4c84b4b14a6882e1fd7b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1002_4691236cedfb12e2644f4c84b4b14a6882e1fd7b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1002_4691236cedfb12e2644f4c84b4b14a6882e1fd7b.patch 2014-05-05 12:43:03.000000000 +0000 @@ -0,0 +1,74 @@ +commit 4691236cedfb12e2644f4c84b4b14a6882e1fd7b +Author: Roman Gushchin +Date: Fri Aug 2 18:36:40 2013 +0400 + + net: check net.core.somaxconn sysctl values + + [ Upstream commit 5f671d6b4ec3e6d66c2a868738af2cdea09e7509 ] + + It's possible to assign an invalid value to the net.core.somaxconn + sysctl variable, because there is no checks at all. + + The sk_max_ack_backlog field of the sock structure is defined as + unsigned short. Therefore, the backlog argument in inet_listen() + shouldn't exceed USHRT_MAX. The backlog argument in the listen() syscall + is truncated to the somaxconn value. So, the somaxconn value shouldn't + exceed 65535 (USHRT_MAX). + Also, negative values of somaxconn are meaningless. + + before: + $ sysctl -w net.core.somaxconn=256 + net.core.somaxconn = 256 + $ sysctl -w net.core.somaxconn=65536 + net.core.somaxconn = 65536 + $ sysctl -w net.core.somaxconn=-100 + net.core.somaxconn = -100 + + after: + $ sysctl -w net.core.somaxconn=256 + net.core.somaxconn = 256 + $ sysctl -w net.core.somaxconn=65536 + error: "Invalid argument" setting key "net.core.somaxconn" + $ sysctl -w net.core.somaxconn=-100 + error: "Invalid argument" setting key "net.core.somaxconn" + + Based on a prior patch from Changli Gao. + + Signed-off-by: Roman Gushchin + Reported-by: Changli Gao + Suggested-by: Eric Dumazet + Acked-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/sysctl_net_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/sysctl_net_core.c 2014-05-05 11:52:04.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/sysctl_net_core.c 2014-05-05 12:43:02.000000000 +0000 +@@ -20,7 +20,9 @@ + #include + #include + ++static int zero = 0; + static int one = 1; ++static int ushort_max = USHRT_MAX; + + #ifdef CONFIG_RPS + static int rps_sock_flow_sysctl(ctl_table *table, int write, +@@ -204,7 +206,9 @@ + .data = &init_net.core.sysctl_somaxconn, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec ++ .extra1 = &zero, ++ .extra2 = &ushort_max, ++ .proc_handler = proc_dointvec_minmax + }, + { } + }; +Index: linux-3.10-3.10.11/dummy/rpi_1002_4691236cedfb12e2644f4c84b4b14a6882e1fd7b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1002_4691236cedfb12e2644f4c84b4b14a6882e1fd7b.txt 2014-05-05 12:43:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1003_3b8dd03efa3008933d14e7203b7b29200330f039.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1003_3b8dd03efa3008933d14e7203b7b29200330f039.patch --- linux-3.10.11/debian/patches/rpi/rpi_1003_3b8dd03efa3008933d14e7203b7b29200330f039.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1003_3b8dd03efa3008933d14e7203b7b29200330f039.patch 2014-05-05 12:43:04.000000000 +0000 @@ -0,0 +1,45 @@ +commit 3b8dd03efa3008933d14e7203b7b29200330f039 +Author: Michael S. Tsirkin +Date: Mon Aug 5 18:25:54 2013 +0300 + + macvlan: validate flags + + [ Upstream commit 1512747820367c8b3b8b72035f0f78c62f2bf1e9 ] + + commit df8ef8f3aaa6692970a436204c4429210addb23a + macvlan: add FDB bridge ops and macvlan flags + added a flags field to macvlan, which can be + controlled from userspace. + The idea is to make the interface future-proof + so we can add flags and not new fields. + + However, flags value isn't validated, as a result, + userspace can't detect which flags are supported. + + Signed-off-by: Michael S. Tsirkin + Cc: "David S. Miller" + Cc: John Fastabend + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/macvlan.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/macvlan.c 2014-05-05 11:52:04.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/macvlan.c 2014-05-05 12:43:03.000000000 +0000 +@@ -727,6 +727,10 @@ + return -EADDRNOTAVAIL; + } + ++ if (data && data[IFLA_MACVLAN_FLAGS] && ++ nla_get_u16(data[IFLA_MACVLAN_FLAGS]) & ~MACVLAN_FLAG_NOPROMISC) ++ return -EINVAL; ++ + if (data && data[IFLA_MACVLAN_MODE]) { + switch (nla_get_u32(data[IFLA_MACVLAN_MODE])) { + case MACVLAN_MODE_PRIVATE: +Index: linux-3.10-3.10.11/dummy/rpi_1003_3b8dd03efa3008933d14e7203b7b29200330f039.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1003_3b8dd03efa3008933d14e7203b7b29200330f039.txt 2014-05-05 12:43:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1004_5cf1ad6c6a29186821843e5d6f70ebbbce587f4f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1004_5cf1ad6c6a29186821843e5d6f70ebbbce587f4f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1004_5cf1ad6c6a29186821843e5d6f70ebbbce587f4f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1004_5cf1ad6c6a29186821843e5d6f70ebbbce587f4f.patch 2014-05-05 12:43:05.000000000 +0000 @@ -0,0 +1,48 @@ +commit 5cf1ad6c6a29186821843e5d6f70ebbbce587f4f +Author: Veaceslav Falico +Date: Fri Aug 2 19:07:38 2013 +0200 + + neighbour: populate neigh_parms on alloc before calling ndo_neigh_setup + + [ Upstream commit 63134803a6369dcf7dddf7f0d5e37b9566b308d2 ] + + dev->ndo_neigh_setup() might need some of the values of neigh_parms, so + populate them before calling it. + + Signed-off-by: Veaceslav Falico + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/neighbour.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/neighbour.c 2014-05-05 11:52:04.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/neighbour.c 2014-05-05 12:43:04.000000000 +0000 +@@ -1445,16 +1445,18 @@ + atomic_set(&p->refcnt, 1); + p->reachable_time = + neigh_rand_reach_time(p->base_reachable_time); ++ dev_hold(dev); ++ p->dev = dev; ++ write_pnet(&p->net, hold_net(net)); ++ p->sysctl_table = NULL; + + if (ops->ndo_neigh_setup && ops->ndo_neigh_setup(dev, p)) { ++ release_net(net); ++ dev_put(dev); + kfree(p); + return NULL; + } + +- dev_hold(dev); +- p->dev = dev; +- write_pnet(&p->net, hold_net(net)); +- p->sysctl_table = NULL; + write_lock_bh(&tbl->lock); + p->next = tbl->parms.next; + tbl->parms.next = p; +Index: linux-3.10-3.10.11/dummy/rpi_1004_5cf1ad6c6a29186821843e5d6f70ebbbce587f4f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1004_5cf1ad6c6a29186821843e5d6f70ebbbce587f4f.txt 2014-05-05 12:43:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1005_92986ce4e59db8c4c44caf9633095ab07f1d79f5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1005_92986ce4e59db8c4c44caf9633095ab07f1d79f5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1005_92986ce4e59db8c4c44caf9633095ab07f1d79f5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1005_92986ce4e59db8c4c44caf9633095ab07f1d79f5.patch 2014-05-05 12:43:05.000000000 +0000 @@ -0,0 +1,44 @@ +commit 92986ce4e59db8c4c44caf9633095ab07f1d79f5 +Author: Veaceslav Falico +Date: Fri Aug 2 19:07:39 2013 +0200 + + bonding: modify only neigh_parms owned by us + + [ Upstream commit 9918d5bf329d0dc5bb2d9d293bcb772bdb626e65 ] + + Otherwise, on neighbour creation, bond_neigh_init() will be called with a + foreign netdev. + + Signed-off-by: Veaceslav Falico + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/bonding/bond_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/bonding/bond_main.c 2014-05-05 11:52:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/bonding/bond_main.c 2014-05-05 12:43:05.000000000 +0000 +@@ -3770,11 +3770,17 @@ + * The bonding ndo_neigh_setup is called at init time beofre any + * slave exists. So we must declare proxy setup function which will + * be used at run time to resolve the actual slave neigh param setup. ++ * ++ * It's also called by master devices (such as vlans) to setup their ++ * underlying devices. In that case - do nothing, we're already set up from ++ * our init. + */ + static int bond_neigh_setup(struct net_device *dev, + struct neigh_parms *parms) + { +- parms->neigh_setup = bond_neigh_init; ++ /* modify only our neigh_parms */ ++ if (parms->dev == dev) ++ parms->neigh_setup = bond_neigh_init; + + return 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1005_92986ce4e59db8c4c44caf9633095ab07f1d79f5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1005_92986ce4e59db8c4c44caf9633095ab07f1d79f5.txt 2014-05-05 12:43:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1006_8b2b5e27cae0bd2572687869111e516ab445be34.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1006_8b2b5e27cae0bd2572687869111e516ab445be34.patch --- linux-3.10.11/debian/patches/rpi/rpi_1006_8b2b5e27cae0bd2572687869111e516ab445be34.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1006_8b2b5e27cae0bd2572687869111e516ab445be34.patch 2014-05-05 12:43:06.000000000 +0000 @@ -0,0 +1,55 @@ +commit 8b2b5e27cae0bd2572687869111e516ab445be34 +Author: Eric Dumazet +Date: Mon Aug 5 11:18:49 2013 -0700 + + fib_trie: remove potential out of bound access + + [ Upstream commit aab515d7c32a34300312416c50314e755ea6f765 ] + + AddressSanitizer [1] dynamic checker pointed a potential + out of bound access in leaf_walk_rcu() + + We could allocate one more slot in tnode_new() to leave the prefetch() + in-place but it looks not worth the pain. + + Bug added in commit 82cfbb008572b ("[IPV4] fib_trie: iterator recode") + + [1] : + https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel + + Reported-by: Andrey Konovalov + Signed-off-by: Eric Dumazet + Cc: Dmitry Vyukov + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/fib_trie.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/fib_trie.c 2014-05-05 11:52:03.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/fib_trie.c 2014-05-05 12:43:06.000000000 +0000 +@@ -71,7 +71,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1761,10 +1760,8 @@ + if (!c) + continue; + +- if (IS_LEAF(c)) { +- prefetch(rcu_dereference_rtnl(p->child[idx])); ++ if (IS_LEAF(c)) + return (struct leaf *) c; +- } + + /* Rescan start scanning in new node */ + p = (struct tnode *) c; +Index: linux-3.10-3.10.11/dummy/rpi_1006_8b2b5e27cae0bd2572687869111e516ab445be34.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1006_8b2b5e27cae0bd2572687869111e516ab445be34.txt 2014-05-05 12:43:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1007_5ddf771720b5761435133058842f274072afa8ed.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1007_5ddf771720b5761435133058842f274072afa8ed.patch --- linux-3.10.11/debian/patches/rpi/rpi_1007_5ddf771720b5761435133058842f274072afa8ed.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1007_5ddf771720b5761435133058842f274072afa8ed.patch 2014-05-05 12:43:07.000000000 +0000 @@ -0,0 +1,42 @@ +commit 5ddf771720b5761435133058842f274072afa8ed +Author: Linus Lüssing +Date: Tue Aug 6 00:32:05 2013 +0200 + + bridge: don't try to update timers in case of broken MLD queries + + [ Upstream commit 248ba8ec05a2c3b118c2224e57eb10c128176ab1 ] + + Currently we are reading an uninitialized value for the max_delay + variable when snooping an MLD query message of invalid length and would + update our timers with that. + + Fixing this by simply ignoring such broken MLD queries (just like we do + for IGMP already). + + This is a regression introduced by: + "bridge: disable snooping if there is no querier" (b00589af3b04) + + Reported-by: Paul Bolle + Signed-off-by: Linus Lüssing + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_multicast.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_multicast.c 2014-05-05 11:52:03.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_multicast.c 2014-05-05 12:43:07.000000000 +0000 +@@ -1185,7 +1185,7 @@ + max_delay = msecs_to_jiffies(ntohs(mld->mld_maxdelay)); + if (max_delay) + group = &mld->mld_mca; +- } else if (skb->len >= sizeof(*mld2q)) { ++ } else { + if (!pskb_may_pull(skb, sizeof(*mld2q))) { + err = -EINVAL; + goto out; +Index: linux-3.10-3.10.11/dummy/rpi_1007_5ddf771720b5761435133058842f274072afa8ed.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1007_5ddf771720b5761435133058842f274072afa8ed.txt 2014-05-05 12:43:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1008_16f033319c6805588375afbda88ea5a513393dd3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1008_16f033319c6805588375afbda88ea5a513393dd3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1008_16f033319c6805588375afbda88ea5a513393dd3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1008_16f033319c6805588375afbda88ea5a513393dd3.patch 2014-05-05 12:43:08.000000000 +0000 @@ -0,0 +1,72 @@ +commit 16f033319c6805588375afbda88ea5a513393dd3 +Author: Eric Dumazet +Date: Mon Aug 5 17:10:15 2013 -0700 + + tcp: cubic: fix overflow error in bictcp_update() + + [ Upstream commit 2ed0edf9090bf4afa2c6fc4f38575a85a80d4b20 ] + + commit 17a6e9f1aa9 ("tcp_cubic: fix clock dependency") added an + overflow error in bictcp_update() in following code : + + /* change the unit from HZ to bictcp_HZ */ + t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3) - + ca->epoch_start) << BICTCP_HZ) / HZ; + + Because msecs_to_jiffies() being unsigned long, compiler does + implicit type promotion. + + We really want to constrain (tcp_time_stamp - ca->epoch_start) + to a signed 32bit value, or else 't' has unexpected high values. + + This bugs triggers an increase of retransmit rates ~24 days after + boot [1], as the high order bit of tcp_time_stamp flips. + + [1] for hosts with HZ=1000 + + Big thanks to Van Jacobson for spotting this problem. + + Diagnosed-by: Van Jacobson + Signed-off-by: Eric Dumazet + Cc: Neal Cardwell + Cc: Yuchung Cheng + Cc: Stephen Hemminger + Acked-by: Neal Cardwell + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_cubic.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_cubic.c 2014-05-05 11:52:02.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_cubic.c 2014-05-05 12:43:07.000000000 +0000 +@@ -206,8 +206,8 @@ + */ + static inline void bictcp_update(struct bictcp *ca, u32 cwnd) + { +- u64 offs; +- u32 delta, t, bic_target, max_cnt; ++ u32 delta, bic_target, max_cnt; ++ u64 offs, t; + + ca->ack_cnt++; /* count the number of ACKs */ + +@@ -250,9 +250,11 @@ + * if the cwnd < 1 million packets !!! + */ + ++ t = (s32)(tcp_time_stamp - ca->epoch_start); ++ t += msecs_to_jiffies(ca->delay_min >> 3); + /* change the unit from HZ to bictcp_HZ */ +- t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3) +- - ca->epoch_start) << BICTCP_HZ) / HZ; ++ t <<= BICTCP_HZ; ++ do_div(t, HZ); + + if (t < ca->bic_K) /* t - K */ + offs = ca->bic_K - t; +Index: linux-3.10-3.10.11/dummy/rpi_1008_16f033319c6805588375afbda88ea5a513393dd3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1008_16f033319c6805588375afbda88ea5a513393dd3.txt 2014-05-05 12:43:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1009_ca02d414915693909f9d7f455c4598d3f8b514b3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1009_ca02d414915693909f9d7f455c4598d3f8b514b3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1009_ca02d414915693909f9d7f455c4598d3f8b514b3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1009_ca02d414915693909f9d7f455c4598d3f8b514b3.patch 2014-05-05 12:43:09.000000000 +0000 @@ -0,0 +1,50 @@ +commit ca02d414915693909f9d7f455c4598d3f8b514b3 +Author: Eric Dumazet +Date: Mon Aug 5 20:05:12 2013 -0700 + + tcp: cubic: fix bug in bictcp_acked() + + [ Upstream commit cd6b423afd3c08b27e1fed52db828ade0addbc6b ] + + While investigating about strange increase of retransmit rates + on hosts ~24 days after boot, Van found hystart was disabled + if ca->epoch_start was 0, as following condition is true + when tcp_time_stamp high order bit is set. + + (s32)(tcp_time_stamp - ca->epoch_start) < HZ + + Quoting Van : + + At initialization & after every loss ca->epoch_start is set to zero so + I believe that the above line will turn off hystart as soon as the 2^31 + bit is set in tcp_time_stamp & hystart will stay off for 24 days. + I think we've observed that cubic's restart is too aggressive without + hystart so this might account for the higher drop rate we observe. + + Diagnosed-by: Van Jacobson + Signed-off-by: Eric Dumazet + Cc: Neal Cardwell + Cc: Yuchung Cheng + Acked-by: Neal Cardwell + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_cubic.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_cubic.c 2014-05-05 12:43:07.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_cubic.c 2014-05-05 12:43:08.000000000 +0000 +@@ -416,7 +416,7 @@ + return; + + /* Discard delay samples right after fast recovery */ +- if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ) ++ if (ca->epoch_start && (s32)(tcp_time_stamp - ca->epoch_start) < HZ) + return; + + delay = (rtt_us << 3) / USEC_PER_MSEC; +Index: linux-3.10-3.10.11/dummy/rpi_1009_ca02d414915693909f9d7f455c4598d3f8b514b3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1009_ca02d414915693909f9d7f455c4598d3f8b514b3.txt 2014-05-05 12:43:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1010_24e8ac721e0e13cab478bd190977daac48b6146c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1010_24e8ac721e0e13cab478bd190977daac48b6146c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1010_24e8ac721e0e13cab478bd190977daac48b6146c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1010_24e8ac721e0e13cab478bd190977daac48b6146c.patch 2014-05-05 12:43:10.000000000 +0000 @@ -0,0 +1,62 @@ +commit 24e8ac721e0e13cab478bd190977daac48b6146c +Author: Hannes Frederic Sowa +Date: Wed Aug 7 02:34:31 2013 +0200 + + ipv6: don't stop backtracking in fib6_lookup_1 if subtree does not match + + [ Upstream commit 3e3be275851bc6fc90bfdcd732cd95563acd982b ] + + In case a subtree did not match we currently stop backtracking and return + NULL (root table from fib_lookup). This could yield in invalid routing + table lookups when using subtrees. + + Instead continue to backtrack until a valid subtree or node is found + and return this match. + + Also remove unneeded NULL check. + + Reported-by: Teco Boot + Cc: YOSHIFUJI Hideaki + Cc: David Lamparter + Cc: + Signed-off-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/ip6_fib.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_fib.c 2014-05-05 11:52:01.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_fib.c 2014-05-05 12:43:09.000000000 +0000 +@@ -993,14 +993,22 @@ + + if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) { + #ifdef CONFIG_IPV6_SUBTREES +- if (fn->subtree) +- fn = fib6_lookup_1(fn->subtree, args + 1); ++ if (fn->subtree) { ++ struct fib6_node *sfn; ++ sfn = fib6_lookup_1(fn->subtree, ++ args + 1); ++ if (!sfn) ++ goto backtrack; ++ fn = sfn; ++ } + #endif +- if (!fn || fn->fn_flags & RTN_RTINFO) ++ if (fn->fn_flags & RTN_RTINFO) + return fn; + } + } +- ++#ifdef CONFIG_IPV6_SUBTREES ++backtrack: ++#endif + if (fn->fn_flags & RTN_ROOT) + break; + +Index: linux-3.10-3.10.11/dummy/rpi_1010_24e8ac721e0e13cab478bd190977daac48b6146c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1010_24e8ac721e0e13cab478bd190977daac48b6146c.txt 2014-05-05 12:43:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1011_27c1c98bd3b44b7c5f5c0ecfe1a1ec1240b73829.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1011_27c1c98bd3b44b7c5f5c0ecfe1a1ec1240b73829.patch --- linux-3.10.11/debian/patches/rpi/rpi_1011_27c1c98bd3b44b7c5f5c0ecfe1a1ec1240b73829.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1011_27c1c98bd3b44b7c5f5c0ecfe1a1ec1240b73829.patch 2014-05-05 12:43:11.000000000 +0000 @@ -0,0 +1,42 @@ +commit 27c1c98bd3b44b7c5f5c0ecfe1a1ec1240b73829 +Author: Timo Teräs +Date: Tue Aug 6 13:45:43 2013 +0300 + + ip_gre: fix ipgre_header to return correct offset MIME-Version: 1.0 + + [ Upstream commit 77a482bdb2e68d13fae87541b341905ba70d572b ] + + Fix ipgre_header() (header_ops->create) to return the correct + amount of bytes pushed. Most callers of dev_hard_header() seem + to care only if it was success, but af_packet.c uses it as + offset to the skb to copy from userspace only once. In practice + this fixes packet socket sendto()/sendmsg() to gre tunnels. + + Regression introduced in c54419321455631079c7d6e60bc732dd0c5914c5 + ("GRE: Refactor GRE tunneling code.") + + Cc: Pravin B Shelar + Signed-off-by: Timo Teräs + Acked-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/ip_gre.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ip_gre.c 2014-05-05 11:52:01.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ip_gre.c 2014-05-05 12:43:10.000000000 +0000 +@@ -572,7 +572,7 @@ + if (daddr) + memcpy(&iph->daddr, daddr, 4); + if (iph->daddr) +- return t->hlen; ++ return t->hlen + sizeof(*iph); + + return -(t->hlen + sizeof(*iph)); + } +Index: linux-3.10-3.10.11/dummy/rpi_1011_27c1c98bd3b44b7c5f5c0ecfe1a1ec1240b73829.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1011_27c1c98bd3b44b7c5f5c0ecfe1a1ec1240b73829.txt 2014-05-05 12:43:10.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1012_6c1a4bb872100c852b07480396744608278dd9ee.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1012_6c1a4bb872100c852b07480396744608278dd9ee.patch --- linux-3.10.11/debian/patches/rpi/rpi_1012_6c1a4bb872100c852b07480396744608278dd9ee.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1012_6c1a4bb872100c852b07480396744608278dd9ee.patch 2014-05-05 12:43:11.000000000 +0000 @@ -0,0 +1,33 @@ +commit 6c1a4bb872100c852b07480396744608278dd9ee +Author: Dave Jones +Date: Fri Aug 9 11:16:34 2013 -0700 + + 8139cp: Fix skb leak in rx_status_loop failure path. + + [ Upstream commit d06f5187469eee1b2932c02fd093d113cfc60d5e ] + + Introduced in cf3c4c03060b688cbc389ebc5065ebcce5653e96 + ("8139cp: Add dma_mapping_error checking") + + Signed-off-by: Dave Jones + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/realtek/8139cp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/realtek/8139cp.c 2014-05-05 11:52:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/realtek/8139cp.c 2014-05-05 12:43:11.000000000 +0000 +@@ -524,6 +524,7 @@ + PCI_DMA_FROMDEVICE); + if (dma_mapping_error(&cp->pdev->dev, new_mapping)) { + dev->stats.rx_dropped++; ++ kfree_skb(new_skb); + goto rx_next; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1012_6c1a4bb872100c852b07480396744608278dd9ee.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1012_6c1a4bb872100c852b07480396744608278dd9ee.txt 2014-05-05 12:43:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1013_21db4be1321b1fe80a28eb122e459c8ab3c2bd1f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1013_21db4be1321b1fe80a28eb122e459c8ab3c2bd1f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1013_21db4be1321b1fe80a28eb122e459c8ab3c2bd1f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1013_21db4be1321b1fe80a28eb122e459c8ab3c2bd1f.patch 2014-05-05 12:43:12.000000000 +0000 @@ -0,0 +1,33 @@ +commit 21db4be1321b1fe80a28eb122e459c8ab3c2bd1f +Author: Sridhar Samudrala +Date: Thu Aug 8 15:19:48 2013 -0700 + + rtnetlink: Fix inverted check in ndo_dflt_fdb_del() + + [ Upstream commit 645359930231d5e78fd3296a38b98c1a658a7ade ] + + Fix inverted check when deleting an fdb entry. + + Signed-off-by: Sridhar Samudrala + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/rtnetlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/rtnetlink.c 2014-05-05 11:52:00.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/rtnetlink.c 2014-05-05 12:43:12.000000000 +0000 +@@ -2142,7 +2142,7 @@ + /* If aging addresses are supported device will need to + * implement its own handler for this. + */ +- if (ndm->ndm_state & NUD_PERMANENT) { ++ if (!(ndm->ndm_state & NUD_PERMANENT)) { + pr_info("%s: FDB only supports static addresses\n", dev->name); + return -EINVAL; + } +Index: linux-3.10-3.10.11/dummy/rpi_1013_21db4be1321b1fe80a28eb122e459c8ab3c2bd1f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1013_21db4be1321b1fe80a28eb122e459c8ab3c2bd1f.txt 2014-05-05 12:43:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1014_e307a8acf8c075261f8110b7088f20d2f7206f56.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1014_e307a8acf8c075261f8110b7088f20d2f7206f56.patch --- linux-3.10.11/debian/patches/rpi/rpi_1014_e307a8acf8c075261f8110b7088f20d2f7206f56.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1014_e307a8acf8c075261f8110b7088f20d2f7206f56.patch 2014-05-05 12:43:13.000000000 +0000 @@ -0,0 +1,101 @@ +commit e307a8acf8c075261f8110b7088f20d2f7206f56 +Author: Pravin B Shelar +Date: Fri Aug 23 12:44:55 2013 -0700 + + genl: Fix genl dumpit() locking. + + [ Upstream commit 9b96309c5b0b9e466773c07a5bc8b7b68fcf010a ] + + In case of genl-family with parallel ops off, dumpif() callback + is expected to run under genl_lock, But commit def3117493eafd9df + (genl: Allow concurrent genl callbacks.) changed this behaviour + where only first dumpit() op was called under genl-lock. + For subsequent dump, only nlk->cb_lock was taken. + Following patch fixes it by defining locked dumpit() and done() + callback which takes care of genl-locking. + + Signed-off-by: Pravin B Shelar + CC: Jesse Gross + CC: Johannes Berg + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/netlink/genetlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/netlink/genetlink.c 2014-05-05 11:52:00.000000000 +0000 ++++ linux-3.10-3.10.11/net/netlink/genetlink.c 2014-05-05 12:43:12.000000000 +0000 +@@ -544,6 +544,30 @@ + } + EXPORT_SYMBOL(genlmsg_put); + ++static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) ++{ ++ struct genl_ops *ops = cb->data; ++ int rc; ++ ++ genl_lock(); ++ rc = ops->dumpit(skb, cb); ++ genl_unlock(); ++ return rc; ++} ++ ++static int genl_lock_done(struct netlink_callback *cb) ++{ ++ struct genl_ops *ops = cb->data; ++ int rc = 0; ++ ++ if (ops->done) { ++ genl_lock(); ++ rc = ops->done(cb); ++ genl_unlock(); ++ } ++ return rc; ++} ++ + static int genl_family_rcv_msg(struct genl_family *family, + struct sk_buff *skb, + struct nlmsghdr *nlh) +@@ -572,15 +596,32 @@ + return -EPERM; + + if (nlh->nlmsg_flags & NLM_F_DUMP) { +- struct netlink_dump_control c = { +- .dump = ops->dumpit, +- .done = ops->done, +- }; ++ int rc; + + if (ops->dumpit == NULL) + return -EOPNOTSUPP; + +- return netlink_dump_start(net->genl_sock, skb, nlh, &c); ++ if (!family->parallel_ops) { ++ struct netlink_dump_control c = { ++ .data = ops, ++ .dump = genl_lock_dumpit, ++ .done = genl_lock_done, ++ }; ++ ++ genl_unlock(); ++ rc = netlink_dump_start(net->genl_sock, skb, nlh, &c); ++ genl_lock(); ++ ++ } else { ++ struct netlink_dump_control c = { ++ .dump = ops->dumpit, ++ .done = ops->done, ++ }; ++ ++ rc = netlink_dump_start(net->genl_sock, skb, nlh, &c); ++ } ++ ++ return rc; + } + + if (ops->doit == NULL) +Index: linux-3.10-3.10.11/dummy/rpi_1014_e307a8acf8c075261f8110b7088f20d2f7206f56.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1014_e307a8acf8c075261f8110b7088f20d2f7206f56.txt 2014-05-05 12:43:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1015_a8077ef001460c41bc0509b096d3d342002c4d9b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1015_a8077ef001460c41bc0509b096d3d342002c4d9b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1015_a8077ef001460c41bc0509b096d3d342002c4d9b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1015_a8077ef001460c41bc0509b096d3d342002c4d9b.patch 2014-05-05 12:43:14.000000000 +0000 @@ -0,0 +1,152 @@ +commit a8077ef001460c41bc0509b096d3d342002c4d9b +Author: Pravin B Shelar +Date: Fri Aug 23 12:45:04 2013 -0700 + + genl: Hold reference on correct module while netlink-dump. + + [ Upstream commit 33c6b1f6b154894321f5734e50c66621e9134e7e ] + + netlink dump operations take module as parameter to hold + reference for entire netlink dump duration. + Currently it holds ref only on genl module which is not correct + when we use ops registered to genl from another module. + Following patch adds module pointer to genl_ops so that netlink + can hold ref count on it. + + Signed-off-by: Pravin B Shelar + CC: Jesse Gross + CC: Johannes Berg + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/genetlink.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/genetlink.h 2014-05-05 11:51:59.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/genetlink.h 2014-05-05 12:43:14.000000000 +0000 +@@ -61,6 +61,7 @@ + struct list_head ops_list; /* private */ + struct list_head family_list; /* private */ + struct list_head mcast_groups; /* private */ ++ struct module *module; + }; + + /** +@@ -121,9 +122,24 @@ + struct list_head ops_list; + }; + +-extern int genl_register_family(struct genl_family *family); +-extern int genl_register_family_with_ops(struct genl_family *family, ++extern int __genl_register_family(struct genl_family *family); ++ ++static inline int genl_register_family(struct genl_family *family) ++{ ++ family->module = THIS_MODULE; ++ return __genl_register_family(family); ++} ++ ++extern int __genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops); ++ ++static inline int genl_register_family_with_ops(struct genl_family *family, ++ struct genl_ops *ops, size_t n_ops) ++{ ++ family->module = THIS_MODULE; ++ return __genl_register_family_with_ops(family, ops, n_ops); ++} ++ + extern int genl_unregister_family(struct genl_family *family); + extern int genl_register_ops(struct genl_family *, struct genl_ops *ops); + extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops); +Index: linux-3.10-3.10.11/net/netlink/genetlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/netlink/genetlink.c 2014-05-05 12:43:12.000000000 +0000 ++++ linux-3.10-3.10.11/net/netlink/genetlink.c 2014-05-05 12:43:14.000000000 +0000 +@@ -364,7 +364,7 @@ + EXPORT_SYMBOL(genl_unregister_ops); + + /** +- * genl_register_family - register a generic netlink family ++ * __genl_register_family - register a generic netlink family + * @family: generic netlink family + * + * Registers the specified family after validating it first. Only one +@@ -374,7 +374,7 @@ + * + * Return 0 on success or a negative error code. + */ +-int genl_register_family(struct genl_family *family) ++int __genl_register_family(struct genl_family *family) + { + int err = -EINVAL; + +@@ -430,10 +430,10 @@ + errout: + return err; + } +-EXPORT_SYMBOL(genl_register_family); ++EXPORT_SYMBOL(__genl_register_family); + + /** +- * genl_register_family_with_ops - register a generic netlink family ++ * __genl_register_family_with_ops - register a generic netlink family + * @family: generic netlink family + * @ops: operations to be registered + * @n_ops: number of elements to register +@@ -457,12 +457,12 @@ + * + * Return 0 on success or a negative error code. + */ +-int genl_register_family_with_ops(struct genl_family *family, ++int __genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops) + { + int err, i; + +- err = genl_register_family(family); ++ err = __genl_register_family(family); + if (err) + return err; + +@@ -476,7 +476,7 @@ + genl_unregister_family(family); + return err; + } +-EXPORT_SYMBOL(genl_register_family_with_ops); ++EXPORT_SYMBOL(__genl_register_family_with_ops); + + /** + * genl_unregister_family - unregister generic netlink family +@@ -603,22 +603,24 @@ + + if (!family->parallel_ops) { + struct netlink_dump_control c = { ++ .module = family->module, + .data = ops, + .dump = genl_lock_dumpit, + .done = genl_lock_done, + }; + + genl_unlock(); +- rc = netlink_dump_start(net->genl_sock, skb, nlh, &c); ++ rc = __netlink_dump_start(net->genl_sock, skb, nlh, &c); + genl_lock(); + + } else { + struct netlink_dump_control c = { ++ .module = family->module, + .dump = ops->dumpit, + .done = ops->done, + }; + +- rc = netlink_dump_start(net->genl_sock, skb, nlh, &c); ++ rc = __netlink_dump_start(net->genl_sock, skb, nlh, &c); + } + + return rc; +Index: linux-3.10-3.10.11/dummy/rpi_1015_a8077ef001460c41bc0509b096d3d342002c4d9b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1015_a8077ef001460c41bc0509b096d3d342002c4d9b.txt 2014-05-05 12:43:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1016_e8d11678770b9bbdcc5c2a9b3a041d136575f322.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1016_e8d11678770b9bbdcc5c2a9b3a041d136575f322.patch --- linux-3.10.11/debian/patches/rpi/rpi_1016_e8d11678770b9bbdcc5c2a9b3a041d136575f322.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1016_e8d11678770b9bbdcc5c2a9b3a041d136575f322.patch 2014-05-05 12:43:16.000000000 +0000 @@ -0,0 +1,81 @@ +commit e8d11678770b9bbdcc5c2a9b3a041d136575f322 +Author: Pravin B Shelar +Date: Tue Aug 13 01:41:06 2013 -0700 + + ip_tunnel: Do not use inner ip-header-id for tunnel ip-header-id. + + [ Upstream commit 4221f40513233fa8edeef7fc82e44163fde03b9b ] + + Using inner-id for tunnel id is not safe in some rare cases. + E.g. packets coming from multiple sources entering same tunnel + can have same id. Therefore on tunnel packet receive we + could have packets from two different stream but with same + source and dst IP with same ip-id which could confuse ip packet + reassembly. + + Following patch reverts optimization from commit + 490ab08127 (IP_GRE: Fix IP-Identification.) + + Signed-off-by: Pravin B Shelar + CC: Jarno Rajahalme + CC: Ansis Atteka + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/vxlan.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/vxlan.c 2014-05-05 11:51:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/vxlan.c 2014-05-05 12:43:15.000000000 +0000 +@@ -1090,7 +1090,7 @@ + iph->daddr = dst; + iph->saddr = fl4.saddr; + iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); +- tunnel_ip_select_ident(skb, old_iph, &rt->dst); ++ __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); + + nf_reset(skb); + +Index: linux-3.10-3.10.11/include/net/ip_tunnels.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/ip_tunnels.h 2014-05-05 11:51:59.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/ip_tunnels.h 2014-05-05 12:43:15.000000000 +0000 +@@ -141,20 +141,6 @@ + return INET_ECN_encapsulate(tos, inner); + } + +-static inline void tunnel_ip_select_ident(struct sk_buff *skb, +- const struct iphdr *old_iph, +- struct dst_entry *dst) +-{ +- struct iphdr *iph = ip_hdr(skb); +- +- /* Use inner packet iph-id if possible. */ +- if (skb->protocol == htons(ETH_P_IP) && old_iph->id) +- iph->id = old_iph->id; +- else +- __ip_select_ident(iph, dst, +- (skb_shinfo(skb)->gso_segs ?: 1) - 1); +-} +- + static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev) + { + int err; +Index: linux-3.10-3.10.11/net/ipv4/ip_tunnel.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ip_tunnel.c 2014-05-05 11:51:59.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ip_tunnel.c 2014-05-05 12:43:15.000000000 +0000 +@@ -686,7 +686,7 @@ + iph->daddr = fl4.daddr; + iph->saddr = fl4.saddr; + iph->ttl = ttl; +- tunnel_ip_select_ident(skb, inner_iph, &rt->dst); ++ __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); + + iptunnel_xmit(skb, dev); + return; +Index: linux-3.10-3.10.11/dummy/rpi_1016_e8d11678770b9bbdcc5c2a9b3a041d136575f322.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1016_e8d11678770b9bbdcc5c2a9b3a041d136575f322.txt 2014-05-05 12:43:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1017_f784dbb9b9b868185b78295b120dbc1f79513e55.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1017_f784dbb9b9b868185b78295b120dbc1f79513e55.patch --- linux-3.10.11/debian/patches/rpi/rpi_1017_f784dbb9b9b868185b78295b120dbc1f79513e55.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1017_f784dbb9b9b868185b78295b120dbc1f79513e55.patch 2014-05-05 12:43:16.000000000 +0000 @@ -0,0 +1,74 @@ +commit f784dbb9b9b868185b78295b120dbc1f79513e55 +Author: Asbjoern Sloth Toennesen +Date: Mon Aug 12 16:30:09 2013 +0000 + + rtnetlink: rtnl_bridge_getlink: Call nlmsg_find_attr() with ifinfomsg header + + [ Upstream commit 3e805ad288c524bb65aad3f1e004402223d3d504 ] + + Fix the iproute2 command `bridge vlan show`, after switching from + rtgenmsg to ifinfomsg. + + Let's start with a little history: + + Feb 20: Vlad Yasevich got his VLAN-aware bridge patchset included in + the 3.9 merge window. + In the kernel commit 6cbdceeb, he added attribute support to + bridge GETLINK requests sent with rtgenmsg. + + Mar 6th: Vlad got this iproute2 reference implementation of the bridge + vlan netlink interface accepted (iproute2 9eff0e5c) + + Apr 25th: iproute2 switched from using rtgenmsg to ifinfomsg (63338dca) + http://patchwork.ozlabs.org/patch/239602/ + http://marc.info/?t=136680900700007 + + Apr 28th: Linus released 3.9 + + Apr 30th: Stephen released iproute2 3.9.0 + + The `bridge vlan show` command haven't been working since the switch to + ifinfomsg, or in a released version of iproute2. Since the kernel side + only supports rtgenmsg, which iproute2 switched away from just prior to + the iproute2 3.9.0 release. + + I haven't been able to find any documentation, about neither rtgenmsg + nor ifinfomsg, and in which situation to use which, but kernel commit + 88c5b5ce seams to suggest that ifinfomsg should be used. + + Fixing this in kernel will break compatibility, but I doubt that anybody + have been using it due to this bug in the user space reference + implementation, at least not without noticing this bug. That said the + functionality is still fully functional in 3.9, when reversing iproute2 + commit 63338dca. + + This could also be fixed in iproute2, but thats an ugly patch that would + reintroduce rtgenmsg in iproute2, and from searching in netdev it seams + like rtgenmsg usage is discouraged. I'm assuming that the only reason + that Vlad implemented the kernel side to use rtgenmsg, was because + iproute2 was using it at the time. + + Signed-off-by: Asbjoern Sloth Toennesen + Reviewed-by: Vlad Yasevich + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/rtnetlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/rtnetlink.c 2014-05-05 12:43:12.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/rtnetlink.c 2014-05-05 12:43:16.000000000 +0000 +@@ -2374,7 +2374,7 @@ + struct nlattr *extfilt; + u32 filter_mask = 0; + +- extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct rtgenmsg), ++ extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), + IFLA_EXT_MASK); + if (extfilt) + filter_mask = nla_get_u32(extfilt); +Index: linux-3.10-3.10.11/dummy/rpi_1017_f784dbb9b9b868185b78295b120dbc1f79513e55.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1017_f784dbb9b9b868185b78295b120dbc1f79513e55.txt 2014-05-05 12:43:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1018_b59bde78dbf049a2671603034562940ac6eb1181.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1018_b59bde78dbf049a2671603034562940ac6eb1181.patch --- linux-3.10.11/debian/patches/rpi/rpi_1018_b59bde78dbf049a2671603034562940ac6eb1181.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1018_b59bde78dbf049a2671603034562940ac6eb1181.patch 2014-05-05 12:43:17.000000000 +0000 @@ -0,0 +1,50 @@ +commit b59bde78dbf049a2671603034562940ac6eb1181 +Author: Dan Carpenter +Date: Thu Aug 15 15:52:57 2013 +0300 + + tun: signedness bug in tun_get_user() + + [ Upstream commit 15718ea0d844e4816dbd95d57a8a0e3e264ba90e ] + + The recent fix d9bf5f1309 "tun: compare with 0 instead of total_len" is + not totally correct. Because "len" and "sizeof()" are size_t type, that + means they are never less than zero. + + Signed-off-by: Dan Carpenter + Acked-by: Michael S. Tsirkin + Acked-by: Neil Horman + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/tun.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/tun.c 2014-05-05 11:51:58.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/tun.c 2014-05-05 12:43:17.000000000 +0000 +@@ -1076,8 +1076,9 @@ + u32 rxhash; + + if (!(tun->flags & TUN_NO_PI)) { +- if ((len -= sizeof(pi)) > total_len) ++ if (len < sizeof(pi)) + return -EINVAL; ++ len -= sizeof(pi); + + if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) + return -EFAULT; +@@ -1085,8 +1086,9 @@ + } + + if (tun->flags & TUN_VNET_HDR) { +- if ((len -= tun->vnet_hdr_sz) > total_len) ++ if (len < tun->vnet_hdr_sz) + return -EINVAL; ++ len -= tun->vnet_hdr_sz; + + if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) + return -EFAULT; +Index: linux-3.10-3.10.11/dummy/rpi_1018_b59bde78dbf049a2671603034562940ac6eb1181.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1018_b59bde78dbf049a2671603034562940ac6eb1181.txt 2014-05-05 12:43:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1019_ad558a2970f60e8a52f048c96f0f6ea7dc691fb7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1019_ad558a2970f60e8a52f048c96f0f6ea7dc691fb7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1019_ad558a2970f60e8a52f048c96f0f6ea7dc691fb7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1019_ad558a2970f60e8a52f048c96f0f6ea7dc691fb7.patch 2014-05-05 12:43:18.000000000 +0000 @@ -0,0 +1,68 @@ +commit ad558a2970f60e8a52f048c96f0f6ea7dc691fb7 +Author: Hannes Frederic Sowa +Date: Fri Aug 16 13:02:27 2013 +0200 + + ipv6: remove max_addresses check from ipv6_create_tempaddr + + [ Upstream commit 4b08a8f1bd8cb4541c93ec170027b4d0782dab52 ] + + Because of the max_addresses check attackers were able to disable privacy + extensions on an interface by creating enough autoconfigured addresses: + + + + But the check is not actually needed: max_addresses protects the + kernel to install too many ipv6 addresses on an interface and guards + addrconf_prefix_rcv to install further addresses as soon as this limit + is reached. We only generate temporary addresses in direct response of + a new address showing up. As soon as we filled up the maximum number of + addresses of an interface, we stop installing more addresses and thus + also stop generating more temp addresses. + + Even if the attacker tries to generate a lot of temporary addresses + by announcing a prefix and removing it again (lifetime == 0) we won't + install more temp addresses, because the temporary addresses do count + to the maximum number of addresses, thus we would stop installing new + autoconfigured addresses when the limit is reached. + + This patch fixes CVE-2013-0343 (but other layer-2 attacks are still + possible). + + Thanks to Ding Tianhong to bring this topic up again. + + Signed-off-by: Hannes Frederic Sowa + Cc: Ding Tianhong + Cc: George Kargiotakis + Cc: P J P + Cc: YOSHIFUJI Hideaki + Acked-by: Ding Tianhong + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/addrconf.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/addrconf.c 2014-05-05 11:51:58.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/addrconf.c 2014-05-05 12:43:18.000000000 +0000 +@@ -1124,12 +1124,10 @@ + if (ifp->flags & IFA_F_OPTIMISTIC) + addr_flags |= IFA_F_OPTIMISTIC; + +- ift = !max_addresses || +- ipv6_count_addresses(idev) < max_addresses ? +- ipv6_add_addr(idev, &addr, tmp_plen, +- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, +- addr_flags) : NULL; +- if (IS_ERR_OR_NULL(ift)) { ++ ift = ipv6_add_addr(idev, &addr, tmp_plen, ++ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, ++ addr_flags); ++ if (IS_ERR(ift)) { + in6_ifa_put(ifp); + in6_dev_put(idev); + pr_info("%s: retry temporary address regeneration\n", __func__); +Index: linux-3.10-3.10.11/dummy/rpi_1019_ad558a2970f60e8a52f048c96f0f6ea7dc691fb7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1019_ad558a2970f60e8a52f048c96f0f6ea7dc691fb7.txt 2014-05-05 12:43:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1020_a829a28873ec2f5daedd77ef91e430b260af1521.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1020_a829a28873ec2f5daedd77ef91e430b260af1521.patch --- linux-3.10.11/debian/patches/rpi/rpi_1020_a829a28873ec2f5daedd77ef91e430b260af1521.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1020_a829a28873ec2f5daedd77ef91e430b260af1521.patch 2014-05-05 12:43:19.000000000 +0000 @@ -0,0 +1,68 @@ +commit a829a28873ec2f5daedd77ef91e430b260af1521 +Author: Hannes Frederic Sowa +Date: Fri Aug 16 13:30:07 2013 +0200 + + ipv6: drop packets with multiple fragmentation headers + + [ Upstream commit f46078cfcd77fa5165bf849f5e568a7ac5fa569c ] + + It is not allowed for an ipv6 packet to contain multiple fragmentation + headers. So discard packets which were already reassembled by + fragmentation logic and send back a parameter problem icmp. + + The updates for RFC 6980 will come in later, I have to do a bit more + research here. + + Cc: YOSHIFUJI Hideaki + Signed-off-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/ipv6.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/ipv6.h 2014-05-05 11:51:57.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/ipv6.h 2014-05-05 12:43:18.000000000 +0000 +@@ -101,6 +101,7 @@ + #define IP6SKB_FORWARDED 2 + #define IP6SKB_REROUTED 4 + #define IP6SKB_ROUTERALERT 8 ++#define IP6SKB_FRAGMENTED 16 + }; + + #define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) +Index: linux-3.10-3.10.11/net/ipv6/reassembly.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/reassembly.c 2014-05-05 11:51:57.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/reassembly.c 2014-05-05 12:43:18.000000000 +0000 +@@ -490,6 +490,7 @@ + ipv6_hdr(head)->payload_len = htons(payload_len); + ipv6_change_dsfield(ipv6_hdr(head), 0xff, ecn); + IP6CB(head)->nhoff = nhoff; ++ IP6CB(head)->flags |= IP6SKB_FRAGMENTED; + + /* Yes, and fold redundant checksum back. 8) */ + if (head->ip_summed == CHECKSUM_COMPLETE) +@@ -524,6 +525,9 @@ + struct net *net = dev_net(skb_dst(skb)->dev); + int evicted; + ++ if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED) ++ goto fail_hdr; ++ + IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS); + + /* Jumbo payload inhibits frag. header */ +@@ -544,6 +548,7 @@ + ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMOKS); + + IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb); ++ IP6CB(skb)->flags |= IP6SKB_FRAGMENTED; + return 1; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1020_a829a28873ec2f5daedd77ef91e430b260af1521.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1020_a829a28873ec2f5daedd77ef91e430b260af1521.txt 2014-05-05 12:43:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1021_f3f905389f1aaae9e091a28d018c66e08c85eddd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1021_f3f905389f1aaae9e091a28d018c66e08c85eddd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1021_f3f905389f1aaae9e091a28d018c66e08c85eddd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1021_f3f905389f1aaae9e091a28d018c66e08c85eddd.patch 2014-05-05 12:43:20.000000000 +0000 @@ -0,0 +1,50 @@ +commit f3f905389f1aaae9e091a28d018c66e08c85eddd +Author: Andrey Vagin +Date: Fri Aug 16 19:04:36 2013 +0400 + + tcp: set timestamps for restored skb-s + + [ Upstream commit 7ed5c5ae96d23da22de95e1c7a239537acd378b1 ] + + When the repair mode is turned off, the write queue seqs are + updated so that the whole queue is considered to be 'already sent. + + The "when" field must be set for such skb. It's used in tcp_rearm_rto + for example. If the "when" field isn't set, the retransmit timeout can + be calculated incorrectly and a tcp connected can stop for two minutes + (TCP_RTO_MAX). + + Acked-by: Pavel Emelyanov + Cc: "David S. Miller" + Cc: Alexey Kuznetsov + Cc: James Morris + Cc: Hideaki YOSHIFUJI + Cc: Patrick McHardy + Signed-off-by: Andrey Vagin + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp.c 2014-05-05 11:51:57.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp.c 2014-05-05 12:43:19.000000000 +0000 +@@ -1118,6 +1118,13 @@ + goto wait_for_memory; + + /* ++ * All packets are restored as if they have ++ * already been sent. ++ */ ++ if (tp->repair) ++ TCP_SKB_CB(skb)->when = tcp_time_stamp; ++ ++ /* + * Check whether we can use HW checksum. + */ + if (sk->sk_route_caps & NETIF_F_ALL_CSUM) +Index: linux-3.10-3.10.11/dummy/rpi_1021_f3f905389f1aaae9e091a28d018c66e08c85eddd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1021_f3f905389f1aaae9e091a28d018c66e08c85eddd.txt 2014-05-05 12:43:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1022_fc26e4cf6f6be400ea7b5442982c58e76b6beda4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1022_fc26e4cf6f6be400ea7b5442982c58e76b6beda4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1022_fc26e4cf6f6be400ea7b5442982c58e76b6beda4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1022_fc26e4cf6f6be400ea7b5442982c58e76b6beda4.patch 2014-05-05 12:43:21.000000000 +0000 @@ -0,0 +1,44 @@ +commit fc26e4cf6f6be400ea7b5442982c58e76b6beda4 +Author: Willem de Bruijn +Date: Mon Aug 19 16:40:22 2013 -0400 + + packet: restore packet statistics tp_packets to include drops + + [ Upstream commit 8bcdeaff5ed544704a9a691d4aef0adb3f9c5b8f ] + + getsockopt PACKET_STATISTICS returns tp_packets + tp_drops. Commit + ee80fbf301 ("packet: account statistics only in tpacket_stats_u") + cleaned up the getsockopt PACKET_STATISTICS code. + This also changed semantics. Historically, tp_packets included + tp_drops on return. The commit removed the line that adds tp_drops + into tp_packets. + + This patch reinstates the old semantics. + + Signed-off-by: Willem de Bruijn + Acked-by: Daniel Borkmann + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/packet/af_packet.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/packet/af_packet.c 2014-05-05 11:51:57.000000000 +0000 ++++ linux-3.10-3.10.11/net/packet/af_packet.c 2014-05-05 12:43:20.000000000 +0000 +@@ -3259,9 +3259,11 @@ + + if (po->tp_version == TPACKET_V3) { + lv = sizeof(struct tpacket_stats_v3); ++ st.stats3.tp_packets += st.stats3.tp_drops; + data = &st.stats3; + } else { + lv = sizeof(struct tpacket_stats); ++ st.stats1.tp_packets += st.stats1.tp_drops; + data = &st.stats1; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1022_fc26e4cf6f6be400ea7b5442982c58e76b6beda4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1022_fc26e4cf6f6be400ea7b5442982c58e76b6beda4.txt 2014-05-05 12:43:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1023_9f0bd377e1210501cd11eef80159e5d7f6160fef.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1023_9f0bd377e1210501cd11eef80159e5d7f6160fef.patch --- linux-3.10.11/debian/patches/rpi/rpi_1023_9f0bd377e1210501cd11eef80159e5d7f6160fef.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1023_9f0bd377e1210501cd11eef80159e5d7f6160fef.patch 2014-05-05 12:43:22.000000000 +0000 @@ -0,0 +1,119 @@ +commit 9f0bd377e1210501cd11eef80159e5d7f6160fef +Author: Toshiaki Makita +Date: Tue Aug 20 17:10:18 2013 +0900 + + bridge: Use the correct bit length for bitmap functions in the VLAN code + + [ Upstream commit ef40b7ef181b7b1a24df2ef2d1ef84956bffa635 ] + + The VLAN code needs to know the length of the per-port VLAN bitmap to + perform its most basic operations (retrieving VLAN informations, removing + VLANs, forwarding database manipulation, etc). Unfortunately, in the + current implementation we are using a macro that indicates the bitmap + size in longs in places where the size in bits is expected, which in + some cases can cause what appear to be random failures. + Use the correct macro. + + Signed-off-by: Toshiaki Makita + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_fdb.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_fdb.c 2014-05-05 11:51:56.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_fdb.c 2014-05-05 12:43:21.000000000 +0000 +@@ -161,7 +161,7 @@ + if (!pv) + return; + +- for_each_set_bit_from(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) { ++ for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) { + f = __br_fdb_get(br, br->dev->dev_addr, vid); + if (f && f->is_local && !f->dst) + fdb_delete(br, f); +@@ -725,7 +725,7 @@ + /* VID was specified, so use it. */ + err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); + } else { +- if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN)) { ++ if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) { + err = __br_fdb_add(ndm, p, addr, nlh_flags, 0); + goto out; + } +@@ -734,7 +734,7 @@ + * specify a VLAN. To be nice, add/update entry for every + * vlan on this port. + */ +- for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) { ++ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { + err = __br_fdb_add(ndm, p, addr, nlh_flags, vid); + if (err) + goto out; +@@ -812,7 +812,7 @@ + + err = __br_fdb_delete(p, addr, vid); + } else { +- if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN)) { ++ if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) { + err = __br_fdb_delete(p, addr, 0); + goto out; + } +@@ -822,7 +822,7 @@ + * vlan on this port. + */ + err = -ENOENT; +- for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) { ++ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { + err &= __br_fdb_delete(p, addr, vid); + } + } +Index: linux-3.10-3.10.11/net/bridge/br_netlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_netlink.c 2014-05-05 11:51:56.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_netlink.c 2014-05-05 12:43:21.000000000 +0000 +@@ -128,7 +128,7 @@ + else + pv = br_get_vlan_info(br); + +- if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN)) ++ if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) + goto done; + + af = nla_nest_start(skb, IFLA_AF_SPEC); +@@ -136,7 +136,7 @@ + goto nla_put_failure; + + pvid = br_get_pvid(pv); +- for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) { ++ for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { + vinfo.vid = vid; + vinfo.flags = 0; + if (vid == pvid) +Index: linux-3.10-3.10.11/net/bridge/br_vlan.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_vlan.c 2014-05-05 11:51:56.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_vlan.c 2014-05-05 12:43:21.000000000 +0000 +@@ -108,7 +108,7 @@ + + clear_bit(vid, v->vlan_bitmap); + v->num_vlans--; +- if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN)) { ++ if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) { + if (v->port_idx) + rcu_assign_pointer(v->parent.port->vlan_info, NULL); + else +@@ -122,7 +122,7 @@ + { + smp_wmb(); + v->pvid = 0; +- bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN); ++ bitmap_zero(v->vlan_bitmap, VLAN_N_VID); + if (v->port_idx) + rcu_assign_pointer(v->parent.port->vlan_info, NULL); + else +Index: linux-3.10-3.10.11/dummy/rpi_1023_9f0bd377e1210501cd11eef80159e5d7f6160fef.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1023_9f0bd377e1210501cd11eef80159e5d7f6160fef.txt 2014-05-05 12:43:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1024_c06ab09127706af38e9e2869afef82a0f63e5fd7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1024_c06ab09127706af38e9e2869afef82a0f63e5fd7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1024_c06ab09127706af38e9e2869afef82a0f63e5fd7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1024_c06ab09127706af38e9e2869afef82a0f63e5fd7.patch 2014-05-05 12:43:23.000000000 +0000 @@ -0,0 +1,202 @@ +commit c06ab09127706af38e9e2869afef82a0f63e5fd7 +Author: Jesper Dangaard Brouer +Date: Wed Aug 14 23:47:11 2013 +0200 + + net_sched: restore "linklayer atm" handling + + [ Upstream commit 8a8e3d84b1719a56f9151909e80ea6ebc5b8e318 ] + + commit 56b765b79 ("htb: improved accuracy at high rates") + broke the "linklayer atm" handling. + + tc class add ... htb rate X ceil Y linklayer atm + + The linklayer setting is implemented by modifying the rate table + which is send to the kernel. No direct parameter were + transferred to the kernel indicating the linklayer setting. + + The commit 56b765b79 ("htb: improved accuracy at high rates") + removed the use of the rate table system. + + To keep compatible with older iproute2 utils, this patch detects + the linklayer by parsing the rate table. It also supports future + versions of iproute2 to send this linklayer parameter to the + kernel directly. This is done by using the __reserved field in + struct tc_ratespec, to convey the choosen linklayer option, but + only using the lower 4 bits of this field. + + Linklayer detection is limited to speeds below 100Mbit/s, because + at high rates the rtab is gets too inaccurate, so bad that + several fields contain the same values, this resembling the ATM + detect. Fields even start to contain "0" time to send, e.g. at + 1000Mbit/s sending a 96 bytes packet cost "0", thus the rtab have + been more broken than we first realized. + + Signed-off-by: Jesper Dangaard Brouer + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/sch_generic.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/sch_generic.h 2014-05-05 11:51:56.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/sch_generic.h 2014-05-05 12:43:22.000000000 +0000 +@@ -682,13 +682,19 @@ + u64 rate_bps; + u32 mult; + u16 overhead; ++ u8 linklayer; + u8 shift; + }; + + static inline u64 psched_l2t_ns(const struct psched_ratecfg *r, + unsigned int len) + { +- return ((u64)(len + r->overhead) * r->mult) >> r->shift; ++ len += r->overhead; ++ ++ if (unlikely(r->linklayer == TC_LINKLAYER_ATM)) ++ return ((u64)(DIV_ROUND_UP(len,48)*53) * r->mult) >> r->shift; ++ ++ return ((u64)len * r->mult) >> r->shift; + } + + extern void psched_ratecfg_precompute(struct psched_ratecfg *r, const struct tc_ratespec *conf); +@@ -699,6 +705,7 @@ + memset(res, 0, sizeof(*res)); + res->rate = r->rate_bps >> 3; + res->overhead = r->overhead; ++ res->linklayer = (r->linklayer & TC_LINKLAYER_MASK); + } + + #endif +Index: linux-3.10-3.10.11/include/uapi/linux/pkt_sched.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/uapi/linux/pkt_sched.h 2014-05-05 11:51:56.000000000 +0000 ++++ linux-3.10-3.10.11/include/uapi/linux/pkt_sched.h 2014-05-05 12:43:22.000000000 +0000 +@@ -73,9 +73,17 @@ + #define TC_H_ROOT (0xFFFFFFFFU) + #define TC_H_INGRESS (0xFFFFFFF1U) + ++/* Need to corrospond to iproute2 tc/tc_core.h "enum link_layer" */ ++enum tc_link_layer { ++ TC_LINKLAYER_UNAWARE, /* Indicate unaware old iproute2 util */ ++ TC_LINKLAYER_ETHERNET, ++ TC_LINKLAYER_ATM, ++}; ++#define TC_LINKLAYER_MASK 0x0F /* limit use to lower 4 bits */ ++ + struct tc_ratespec { + unsigned char cell_log; +- unsigned char __reserved; ++ __u8 linklayer; /* lower 4 bits */ + unsigned short overhead; + short cell_align; + unsigned short mpu; +Index: linux-3.10-3.10.11/net/sched/sch_api.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sched/sch_api.c 2014-05-05 11:51:56.000000000 +0000 ++++ linux-3.10-3.10.11/net/sched/sch_api.c 2014-05-05 12:43:22.000000000 +0000 +@@ -285,6 +285,45 @@ + return q; + } + ++/* The linklayer setting were not transferred from iproute2, in older ++ * versions, and the rate tables lookup systems have been dropped in ++ * the kernel. To keep backward compatible with older iproute2 tc ++ * utils, we detect the linklayer setting by detecting if the rate ++ * table were modified. ++ * ++ * For linklayer ATM table entries, the rate table will be aligned to ++ * 48 bytes, thus some table entries will contain the same value. The ++ * mpu (min packet unit) is also encoded into the old rate table, thus ++ * starting from the mpu, we find low and high table entries for ++ * mapping this cell. If these entries contain the same value, when ++ * the rate tables have been modified for linklayer ATM. ++ * ++ * This is done by rounding mpu to the nearest 48 bytes cell/entry, ++ * and then roundup to the next cell, calc the table entry one below, ++ * and compare. ++ */ ++static __u8 __detect_linklayer(struct tc_ratespec *r, __u32 *rtab) ++{ ++ int low = roundup(r->mpu, 48); ++ int high = roundup(low+1, 48); ++ int cell_low = low >> r->cell_log; ++ int cell_high = (high >> r->cell_log) - 1; ++ ++ /* rtab is too inaccurate at rates > 100Mbit/s */ ++ if ((r->rate > (100000000/8)) || (rtab[0] == 0)) { ++ pr_debug("TC linklayer: Giving up ATM detection\n"); ++ return TC_LINKLAYER_ETHERNET; ++ } ++ ++ if ((cell_high > cell_low) && (cell_high < 256) ++ && (rtab[cell_low] == rtab[cell_high])) { ++ pr_debug("TC linklayer: Detected ATM, low(%d)=high(%d)=%u\n", ++ cell_low, cell_high, rtab[cell_high]); ++ return TC_LINKLAYER_ATM; ++ } ++ return TC_LINKLAYER_ETHERNET; ++} ++ + static struct qdisc_rate_table *qdisc_rtab_list; + + struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *tab) +@@ -308,6 +347,8 @@ + rtab->rate = *r; + rtab->refcnt = 1; + memcpy(rtab->data, nla_data(tab), 1024); ++ if (r->linklayer == TC_LINKLAYER_UNAWARE) ++ r->linklayer = __detect_linklayer(r, rtab->data); + rtab->next = qdisc_rtab_list; + qdisc_rtab_list = rtab; + } +Index: linux-3.10-3.10.11/net/sched/sch_generic.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sched/sch_generic.c 2014-05-05 11:51:56.000000000 +0000 ++++ linux-3.10-3.10.11/net/sched/sch_generic.c 2014-05-05 12:43:22.000000000 +0000 +@@ -908,6 +908,7 @@ + memset(r, 0, sizeof(*r)); + r->overhead = conf->overhead; + r->rate_bps = (u64)conf->rate << 3; ++ r->linklayer = (conf->linklayer & TC_LINKLAYER_MASK); + r->mult = 1; + /* + * Calibrate mult, shift so that token counting is accurate +Index: linux-3.10-3.10.11/net/sched/sch_htb.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sched/sch_htb.c 2014-05-05 12:43:01.000000000 +0000 ++++ linux-3.10-3.10.11/net/sched/sch_htb.c 2014-05-05 12:43:22.000000000 +0000 +@@ -1312,6 +1312,7 @@ + struct htb_sched *q = qdisc_priv(sch); + struct htb_class *cl = (struct htb_class *)*arg, *parent; + struct nlattr *opt = tca[TCA_OPTIONS]; ++ struct qdisc_rate_table *rtab = NULL, *ctab = NULL; + struct nlattr *tb[TCA_HTB_MAX + 1]; + struct tc_htb_opt *hopt; + +@@ -1333,6 +1334,18 @@ + if (!hopt->rate.rate || !hopt->ceil.rate) + goto failure; + ++ /* Keeping backward compatible with rate_table based iproute2 tc */ ++ if (hopt->rate.linklayer == TC_LINKLAYER_UNAWARE) { ++ rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB]); ++ if (rtab) ++ qdisc_put_rtab(rtab); ++ } ++ if (hopt->ceil.linklayer == TC_LINKLAYER_UNAWARE) { ++ ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB]); ++ if (ctab) ++ qdisc_put_rtab(ctab); ++ } ++ + if (!cl) { /* new class */ + struct Qdisc *new_q; + int prio; +Index: linux-3.10-3.10.11/dummy/rpi_1024_c06ab09127706af38e9e2869afef82a0f63e5fd7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1024_c06ab09127706af38e9e2869afef82a0f63e5fd7.txt 2014-05-05 12:43:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1025_40361e8fcc76eb603970d4da02592d4dc4a6f631.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1025_40361e8fcc76eb603970d4da02592d4dc4a6f631.patch --- linux-3.10.11/debian/patches/rpi/rpi_1025_40361e8fcc76eb603970d4da02592d4dc4a6f631.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1025_40361e8fcc76eb603970d4da02592d4dc4a6f631.patch 2014-05-05 12:43:24.000000000 +0000 @@ -0,0 +1,36 @@ +commit 40361e8fcc76eb603970d4da02592d4dc4a6f631 +Author: Ben Hutchings +Date: Tue Jul 9 17:12:49 2013 +0100 + + sfc: Fix lookup of default RX MAC filters when steered using ethtool + + [ Upstream commit f3851b0acc5a75bd33c6d344a2e4f920e1622ff0 ] + + commit 385904f819e3 ('sfc: Don't use + efx_filter_{build,hash,increment}() for default MAC filters') used the + wrong name to find the index of default RX MAC filters at insertion/ + update time. This could result in memory corruption and would in any + case silently fail to update the filter. + + Signed-off-by: Ben Hutchings + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/sfc/filter.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/sfc/filter.c 2014-05-05 11:51:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/sfc/filter.c 2014-05-05 12:43:23.000000000 +0000 +@@ -675,7 +675,7 @@ + BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0); + BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF != + EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF); +- rep_index = spec->type - EFX_FILTER_INDEX_UC_DEF; ++ rep_index = spec->type - EFX_FILTER_UC_DEF; + ins_index = rep_index; + + spin_lock_bh(&state->lock); +Index: linux-3.10-3.10.11/dummy/rpi_1025_40361e8fcc76eb603970d4da02592d4dc4a6f631.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1025_40361e8fcc76eb603970d4da02592d4dc4a6f631.txt 2014-05-05 12:43:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1026_3d740e64f6e333efb2c539d5ea7ed56a5ba2757d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1026_3d740e64f6e333efb2c539d5ea7ed56a5ba2757d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1026_3d740e64f6e333efb2c539d5ea7ed56a5ba2757d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1026_3d740e64f6e333efb2c539d5ea7ed56a5ba2757d.patch 2014-05-05 12:43:25.000000000 +0000 @@ -0,0 +1,38 @@ +commit 3d740e64f6e333efb2c539d5ea7ed56a5ba2757d +Author: Sathya Perla +Date: Thu Aug 22 12:23:41 2013 +0530 + + be2net: fix disabling TX in be_close() + + [ Upstream commit 6e1f99757a2b24b7255263b2240a0eb04215174d ] + + commit fba875591 ("disable TX in be_close()") disabled TX in be_close() + to protect be_xmit() from touching freed up queues in the AER recovery + flow. But, TX must be disabled *before* cleaning up TX completions in + the close() path, not after. This allows be_tx_compl_clean() to free up + all TX-req skbs that were notified to the HW. + + Signed-off-by: Sathya Perla + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/emulex/benet/be_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/emulex/benet/be_main.c 2014-05-05 11:51:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/emulex/benet/be_main.c 2014-05-05 12:43:24.000000000 +0000 +@@ -2561,8 +2561,8 @@ + /* Wait for all pending tx completions to arrive so that + * all tx skbs are freed. + */ +- be_tx_compl_clean(adapter); + netif_tx_disable(netdev); ++ be_tx_compl_clean(adapter); + + be_rx_qs_destroy(adapter); + +Index: linux-3.10-3.10.11/dummy/rpi_1026_3d740e64f6e333efb2c539d5ea7ed56a5ba2757d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1026_3d740e64f6e333efb2c539d5ea7ed56a5ba2757d.txt 2014-05-05 12:43:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1027_f2e39b5ea18377e079ab44323d9c8653a15fc5d6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1027_f2e39b5ea18377e079ab44323d9c8653a15fc5d6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1027_f2e39b5ea18377e079ab44323d9c8653a15fc5d6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1027_f2e39b5ea18377e079ab44323d9c8653a15fc5d6.patch 2014-05-05 12:43:26.000000000 +0000 @@ -0,0 +1,45 @@ +commit f2e39b5ea18377e079ab44323d9c8653a15fc5d6 +Author: Rob Gardner +Date: Sun Aug 25 16:02:23 2013 -0600 + + net: usb: Add HP hs2434 device to ZLP exception table + + [ Upstream commit 03803a59e32453ee5737c6096a295f748f03cc49 ] + + This patch adds another entry (HP hs2434 Mobile Broadband) to the list + of exceptional devices that require a zero length packet in order to + function properly. This list was added in commit 844e88f0. The hs2434 + is manufactured by Sierra Wireless, who also produces the MC7710, + which the ZLP exception list was created for in the first place. So + hopefully it is just this one producer's devices that will need this + workaround. + + Tested on a DM1-4310NR HP notebook, which does not function without this + change. + + Signed-off-by: Rob Gardner + Acked-by: Bjørn Mork + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/usb/cdc_mbim.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/usb/cdc_mbim.c 2014-05-05 11:51:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/usb/cdc_mbim.c 2014-05-05 12:43:25.000000000 +0000 +@@ -400,6 +400,10 @@ + { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68a2, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_mbim_info_zlp, + }, ++ /* HP hs2434 Mobile Broadband Module needs ZLPs */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3f0, 0x4b1d, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long)&cdc_mbim_info_zlp, ++ }, + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_mbim_info, + }, +Index: linux-3.10-3.10.11/dummy/rpi_1027_f2e39b5ea18377e079ab44323d9c8653a15fc5d6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1027_f2e39b5ea18377e079ab44323d9c8653a15fc5d6.txt 2014-05-05 12:43:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1028_6f198dcab737db9335f1f4c7d97f801e0d5de186.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1028_6f198dcab737db9335f1f4c7d97f801e0d5de186.patch --- linux-3.10.11/debian/patches/rpi/rpi_1028_6f198dcab737db9335f1f4c7d97f801e0d5de186.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1028_6f198dcab737db9335f1f4c7d97f801e0d5de186.patch 2014-05-05 12:43:26.000000000 +0000 @@ -0,0 +1,50 @@ +commit 6f198dcab737db9335f1f4c7d97f801e0d5de186 +Author: Andrew Vagin +Date: Tue Aug 27 12:20:40 2013 +0400 + + tcp: initialize rcv_tstamp for restored sockets + + [ Upstream commit c7781a6e3c4a9a17e144ec2db00ebfea327bd627 ] + + u32 rcv_tstamp; /* timestamp of last received ACK */ + + Its value used in tcp_retransmit_timer, which closes socket + if the last ack was received more then TCP_RTO_MAX ago. + + Currently rcv_tstamp is initialized to zero and if tcp_retransmit_timer + is called before receiving a first ack, the connection is closed. + + This patch initializes rcv_tstamp to a timestamp, when a socket was + restored. + + Reported-by: Cyrill Gorcunov + Cc: Pavel Emelyanov + Cc: Eric Dumazet + Cc: "David S. Miller" + Cc: Alexey Kuznetsov + Cc: James Morris + Cc: Hideaki YOSHIFUJI + Cc: Patrick McHardy + Signed-off-by: Andrey Vagin + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_output.c 2014-05-05 11:51:54.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_output.c 2014-05-05 12:43:26.000000000 +0000 +@@ -2808,6 +2808,8 @@ + + if (likely(!tp->repair)) + tp->rcv_nxt = 0; ++ else ++ tp->rcv_tstamp = tcp_time_stamp; + tp->rcv_wup = tp->rcv_nxt; + tp->copied_seq = tp->rcv_nxt; + +Index: linux-3.10-3.10.11/dummy/rpi_1028_6f198dcab737db9335f1f4c7d97f801e0d5de186.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1028_6f198dcab737db9335f1f4c7d97f801e0d5de186.txt 2014-05-05 12:43:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1029_6fe6efd941d49f7169e78b2e60ca2dc6a56ca8b4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1029_6fe6efd941d49f7169e78b2e60ca2dc6a56ca8b4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1029_6fe6efd941d49f7169e78b2e60ca2dc6a56ca8b4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1029_6fe6efd941d49f7169e78b2e60ca2dc6a56ca8b4.patch 2014-05-05 12:43:27.000000000 +0000 @@ -0,0 +1,70 @@ +commit 6fe6efd941d49f7169e78b2e60ca2dc6a56ca8b4 +Author: Andrew Vagin +Date: Tue Aug 27 12:21:55 2013 +0400 + + tcp: don't apply tsoffset if rcv_tsecr is zero + + [ Upstream commit e3e12028315749b7fa2edbc37328e5847be9ede9 ] + + The zero value means that tsecr is not valid, so it's a special case. + + tsoffset is used to customize tcp_time_stamp for one socket. + tsoffset is usually zero, it's used when a socket was moved from one + host to another host. + + Currently this issue affects logic of tcp_rcv_rtt_measure_ts. Due to + incorrect value of rcv_tsecr, tcp_rcv_rtt_measure_ts sets rto to + TCP_RTO_MAX. + + Reported-by: Cyrill Gorcunov + Cc: Pavel Emelyanov + Cc: Eric Dumazet + Cc: "David S. Miller" + Cc: Alexey Kuznetsov + Cc: James Morris + Cc: Hideaki YOSHIFUJI + Cc: Patrick McHardy + Signed-off-by: Andrey Vagin + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_input.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_input.c 2014-05-05 11:51:54.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_input.c 2014-05-05 12:43:27.000000000 +0000 +@@ -3598,7 +3598,10 @@ + ++ptr; + tp->rx_opt.rcv_tsval = ntohl(*ptr); + ++ptr; +- tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset; ++ if (*ptr) ++ tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset; ++ else ++ tp->rx_opt.rcv_tsecr = 0; + return true; + } + return false; +@@ -3623,7 +3626,7 @@ + } + + tcp_parse_options(skb, &tp->rx_opt, 1, NULL); +- if (tp->rx_opt.saw_tstamp) ++ if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) + tp->rx_opt.rcv_tsecr -= tp->tsoffset; + + return true; +@@ -5376,7 +5379,7 @@ + int saved_clamp = tp->rx_opt.mss_clamp; + + tcp_parse_options(skb, &tp->rx_opt, 0, &foc); +- if (tp->rx_opt.saw_tstamp) ++ if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) + tp->rx_opt.rcv_tsecr -= tp->tsoffset; + + if (th->ack) { +Index: linux-3.10-3.10.11/dummy/rpi_1029_6fe6efd941d49f7169e78b2e60ca2dc6a56ca8b4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1029_6fe6efd941d49f7169e78b2e60ca2dc6a56ca8b4.txt 2014-05-05 12:43:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1030_5612d36ca1438c23280b962a80943d14b2e9f778.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1030_5612d36ca1438c23280b962a80943d14b2e9f778.patch --- linux-3.10.11/debian/patches/rpi/rpi_1030_5612d36ca1438c23280b962a80943d14b2e9f778.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1030_5612d36ca1438c23280b962a80943d14b2e9f778.patch 2014-05-05 12:43:28.000000000 +0000 @@ -0,0 +1,48 @@ +commit 5612d36ca1438c23280b962a80943d14b2e9f778 +Author: Chris Clark +Date: Tue Aug 27 12:02:15 2013 -0600 + + ipv4: sendto/hdrincl: don't use destination address found in header + + [ Upstream commit c27c9322d015dc1d9dfdf31724fca71c0476c4d1 ] + + ipv4: raw_sendmsg: don't use header's destination address + + A sendto() regression was bisected and found to start with commit + f8126f1d5136be1 (ipv4: Adjust semantics of rt->rt_gateway.) + + The problem is that it tries to ARP-lookup the constructed packet's + destination address rather than the explicitly provided address. + + Fix this using FLOWI_FLAG_KNOWN_NH so that given nexthop is used. + + cf. commit 2ad5b9e4bd314fc685086b99e90e5de3bc59e26b + + Reported-by: Chris Clark + Bisected-by: Chris Clark + Tested-by: Chris Clark + Suggested-by: Julian Anastasov + Signed-off-by: Chris Clark + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/raw.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/raw.c 2014-05-05 11:51:53.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/raw.c 2014-05-05 12:43:27.000000000 +0000 +@@ -571,7 +571,8 @@ + flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, + RT_SCOPE_UNIVERSE, + inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, +- inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP, ++ inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP | ++ (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), + daddr, saddr, 0, 0); + + if (!inet->hdrincl) { +Index: linux-3.10-3.10.11/dummy/rpi_1030_5612d36ca1438c23280b962a80943d14b2e9f778.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1030_5612d36ca1438c23280b962a80943d14b2e9f778.txt 2014-05-05 12:43:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1031_4b7ead801d3e174ae14ccaed02773041419ae278.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1031_4b7ead801d3e174ae14ccaed02773041419ae278.patch --- linux-3.10.11/debian/patches/rpi/rpi_1031_4b7ead801d3e174ae14ccaed02773041419ae278.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1031_4b7ead801d3e174ae14ccaed02773041419ae278.patch 2014-05-05 12:43:29.000000000 +0000 @@ -0,0 +1,76 @@ +commit 4b7ead801d3e174ae14ccaed02773041419ae278 +Author: Thomas Graf +Date: Tue Sep 3 13:37:01 2013 +0200 + + ipv6: Don't depend on per socket memory for neighbour discovery messages + + [ Upstream commit 25a6e6b84fba601eff7c28d30da8ad7cfbef0d43 ] + + Allocating skbs when sending out neighbour discovery messages + currently uses sock_alloc_send_skb() based on a per net namespace + socket and thus share a socket wmem buffer space. + + If a netdevice is temporarily unable to transmit due to carrier + loss or for other reasons, the queued up ndisc messages will cosnume + all of the wmem space and will thus prevent from any more skbs to + be allocated even for netdevices that are able to transmit packets. + + The number of neighbour discovery messages sent is very limited, + use of alloc_skb() bypasses the socket wmem buffer size enforcement + while the manual call to skb_set_owner_w() maintains the socket + reference needed for the IPv6 output path. + + This patch has orginally been posted by Eric Dumazet in a modified + form. + + Signed-off-by: Thomas Graf + Cc: Eric Dumazet + Cc: Hannes Frederic Sowa + Cc: Stephen Warren + Cc: Fabio Estevam + Tested-by: Fabio Estevam + Tested-by: Stephen Warren + Acked-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/ndisc.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ndisc.c 2014-05-05 11:51:53.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ndisc.c 2014-05-05 12:43:28.000000000 +0000 +@@ -372,14 +372,11 @@ + int tlen = dev->needed_tailroom; + struct sock *sk = dev_net(dev)->ipv6.ndisc_sk; + struct sk_buff *skb; +- int err; + +- skb = sock_alloc_send_skb(sk, +- hlen + sizeof(struct ipv6hdr) + len + tlen, +- 1, &err); ++ skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC); + if (!skb) { +- ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb, err=%d\n", +- __func__, err); ++ ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n", ++ __func__); + return NULL; + } + +@@ -389,6 +386,11 @@ + skb_reserve(skb, hlen + sizeof(struct ipv6hdr)); + skb_reset_transport_header(skb); + ++ /* Manually assign socket ownership as we avoid calling ++ * sock_alloc_send_pskb() to bypass wmem buffer limits ++ */ ++ skb_set_owner_w(skb, sk); ++ + return skb; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1031_4b7ead801d3e174ae14ccaed02773041419ae278.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1031_4b7ead801d3e174ae14ccaed02773041419ae278.txt 2014-05-05 12:43:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1032_b70a23ab4ab5a95ab9be1bf77b73c1ad9f4e15a4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1032_b70a23ab4ab5a95ab9be1bf77b73c1ad9f4e15a4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1032_b70a23ab4ab5a95ab9be1bf77b73c1ad9f4e15a4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1032_b70a23ab4ab5a95ab9be1bf77b73c1ad9f4e15a4.patch 2014-05-05 12:43:30.000000000 +0000 @@ -0,0 +1,39 @@ +commit b70a23ab4ab5a95ab9be1bf77b73c1ad9f4e15a4 +Author: Phil Oester +Date: Tue Aug 27 16:41:40 2013 -0700 + + tcp: tcp_make_synack() should use sock_wmalloc + + [ Upstream commit eb8895debe1baba41fcb62c78a16f0c63c21662a ] + + In commit 90ba9b19 (tcp: tcp_make_synack() can use alloc_skb()), Eric changed + the call to sock_wmalloc in tcp_make_synack to alloc_skb. In doing so, + the netfilter owner match lost its ability to block the SYNACK packet on + outbound listening sockets. Revert the change, restoring the owner match + functionality. + + This closes netfilter bugzilla #847. + + Signed-off-by: Phil Oester + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_output.c 2014-05-05 12:43:26.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_output.c 2014-05-05 12:43:29.000000000 +0000 +@@ -2664,7 +2664,7 @@ + int tcp_header_size; + int mss; + +- skb = alloc_skb(MAX_TCP_HEADER + 15, sk_gfp_atomic(sk, GFP_ATOMIC)); ++ skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); + if (unlikely(!skb)) { + dst_release(dst); + return NULL; +Index: linux-3.10-3.10.11/dummy/rpi_1032_b70a23ab4ab5a95ab9be1bf77b73c1ad9f4e15a4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1032_b70a23ab4ab5a95ab9be1bf77b73c1ad9f4e15a4.txt 2014-05-05 12:43:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1033_8db07b82b70897d868d864402b43a68da5e0cd59.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1033_8db07b82b70897d868d864402b43a68da5e0cd59.patch --- linux-3.10.11/debian/patches/rpi/rpi_1033_8db07b82b70897d868d864402b43a68da5e0cd59.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1033_8db07b82b70897d868d864402b43a68da5e0cd59.patch 2014-05-05 12:43:30.000000000 +0000 @@ -0,0 +1,54 @@ +commit 8db07b82b70897d868d864402b43a68da5e0cd59 +Author: Erik Hugne +Date: Wed Aug 28 09:29:58 2013 +0200 + + tipc: set sk_err correctly when connection fails + + [ Upstream commit 2c8d85182348021fc0a1bed193a4be4161dc8364 ] + + Should a connect fail, if the publication/server is unavailable or + due to some other error, a positive value will be returned and errno + is never set. If the application code checks for an explicit zero + return from connect (success) or a negative return (failure), it + will not catch the error and subsequent send() calls will fail as + shown from the strace snippet below. + + socket(0x1e /* PF_??? */, SOCK_SEQPACKET, 0) = 3 + connect(3, {sa_family=0x1e /* AF_??? */, sa_data="\2\1\322\4\0\0\322\4\0\0\0\0\0\0"}, 16) = 111 + sendto(3, "test", 4, 0, NULL, 0) = -1 EPIPE (Broken pipe) + + The reason for this behaviour is that TIPC wrongly inverts error + codes set in sk_err. + + Signed-off-by: Erik Hugne + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/tipc/socket.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/tipc/socket.c 2014-05-05 11:51:52.000000000 +0000 ++++ linux-3.10-3.10.11/net/tipc/socket.c 2014-05-05 12:43:30.000000000 +0000 +@@ -1179,7 +1179,7 @@ + /* Accept only ACK or NACK message */ + if (unlikely(msg_errcode(msg))) { + sock->state = SS_DISCONNECTING; +- sk->sk_err = -ECONNREFUSED; ++ sk->sk_err = ECONNREFUSED; + retval = TIPC_OK; + break; + } +@@ -1190,7 +1190,7 @@ + res = auto_connect(sock, msg); + if (res) { + sock->state = SS_DISCONNECTING; +- sk->sk_err = res; ++ sk->sk_err = -res; + retval = TIPC_OK; + break; + } +Index: linux-3.10-3.10.11/dummy/rpi_1033_8db07b82b70897d868d864402b43a68da5e0cd59.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1033_8db07b82b70897d868d864402b43a68da5e0cd59.txt 2014-05-05 12:43:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1034_56a12acebcbd08342f7287a5870fe7ec2c0de91a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1034_56a12acebcbd08342f7287a5870fe7ec2c0de91a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1034_56a12acebcbd08342f7287a5870fe7ec2c0de91a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1034_56a12acebcbd08342f7287a5870fe7ec2c0de91a.patch 2014-05-05 12:43:31.000000000 +0000 @@ -0,0 +1,60 @@ +commit 56a12acebcbd08342f7287a5870fe7ec2c0de91a +Author: Eric Dumazet +Date: Wed Aug 28 18:10:43 2013 -0700 + + net: revert 8728c544a9c ("net: dev_pick_tx() fix") + + [ Upstream commit 702821f4ea6f68db18aa1de7d8ed62c6ba586a64 ] + + commit 8728c544a9cbdc ("net: dev_pick_tx() fix") and commit + b6fe83e9525a ("bonding: refine IFF_XMIT_DST_RELEASE capability") + are quite incompatible : Queue selection is disabled because skb + dst was dropped before entering bonding device. + + This causes major performance regression, mainly because TCP packets + for a given flow can be sent to multiple queues. + + This is particularly visible when using the new FQ packet scheduler + with MQ + FQ setup on the slaves. + + We can safely revert the first commit now that 416186fbf8c5b + ("net: Split core bits of netdev_pick_tx into __netdev_pick_tx") + properly caps the queue_index. + + Reported-by: Xi Wang + Diagnosed-by: Xi Wang + Signed-off-by: Eric Dumazet + Cc: Tom Herbert + Cc: Alexander Duyck + Cc: Denys Fedorysychenko + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/flow_dissector.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/flow_dissector.c 2014-05-05 11:51:52.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/flow_dissector.c 2014-05-05 12:43:31.000000000 +0000 +@@ -345,14 +345,9 @@ + if (new_index < 0) + new_index = skb_tx_hash(dev, skb); + +- if (queue_index != new_index && sk) { +- struct dst_entry *dst = +- rcu_dereference_check(sk->sk_dst_cache, 1); +- +- if (dst && skb_dst(skb) == dst) +- sk_tx_queue_set(sk, queue_index); +- +- } ++ if (queue_index != new_index && sk && ++ rcu_access_pointer(sk->sk_dst_cache)) ++ sk_tx_queue_set(sk, queue_index); + + queue_index = new_index; + } +Index: linux-3.10-3.10.11/dummy/rpi_1034_56a12acebcbd08342f7287a5870fe7ec2c0de91a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1034_56a12acebcbd08342f7287a5870fe7ec2c0de91a.txt 2014-05-05 12:43:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1035_00897febb83864e2dd388d719b256cb362198e27.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1035_00897febb83864e2dd388d719b256cb362198e27.patch --- linux-3.10.11/debian/patches/rpi/rpi_1035_00897febb83864e2dd388d719b256cb362198e27.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1035_00897febb83864e2dd388d719b256cb362198e27.patch 2014-05-05 12:43:32.000000000 +0000 @@ -0,0 +1,47 @@ +commit 00897febb83864e2dd388d719b256cb362198e27 +Author: Daniel Borkmann +Date: Thu Aug 29 23:55:05 2013 +0200 + + net: bridge: convert MLDv2 Query MRC into msecs_to_jiffies for max_delay + + [ Upstream commit 2d98c29b6fb3de44d9eaa73c09f9cf7209346383 ] + + While looking into MLDv1/v2 code, I noticed that bridging code does + not convert it's max delay into jiffies for MLDv2 messages as we do + in core IPv6' multicast code. + + RFC3810, 5.1.3. Maximum Response Code says: + + The Maximum Response Code field specifies the maximum time allowed + before sending a responding Report. The actual time allowed, called + the Maximum Response Delay, is represented in units of milliseconds, + and is derived from the Maximum Response Code as follows: [...] + + As we update timers that work with jiffies, we need to convert it. + + Signed-off-by: Daniel Borkmann + Cc: Linus Lüssing + Cc: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_multicast.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_multicast.c 2014-05-05 12:43:07.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_multicast.c 2014-05-05 12:43:31.000000000 +0000 +@@ -1193,7 +1193,8 @@ + mld2q = (struct mld2_query *)icmp6_hdr(skb); + if (!mld2q->mld2q_nsrcs) + group = &mld2q->mld2q_mca; +- max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(ntohs(mld2q->mld2q_mrc)) : 1; ++ ++ max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL); + } + + if (!group) +Index: linux-3.10-3.10.11/dummy/rpi_1035_00897febb83864e2dd388d719b256cb362198e27.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1035_00897febb83864e2dd388d719b256cb362198e27.txt 2014-05-05 12:43:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1036_2aae409672a9ec6078702b2fe92bd41ecf05d826.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1036_2aae409672a9ec6078702b2fe92bd41ecf05d826.patch --- linux-3.10.11/debian/patches/rpi/rpi_1036_2aae409672a9ec6078702b2fe92bd41ecf05d826.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1036_2aae409672a9ec6078702b2fe92bd41ecf05d826.patch 2014-05-05 12:43:33.000000000 +0000 @@ -0,0 +1,77 @@ +commit 2aae409672a9ec6078702b2fe92bd41ecf05d826 +Author: Jiri Bohac +Date: Fri Aug 30 11:18:45 2013 +0200 + + ICMPv6: treat dest unreachable codes 5 and 6 as EACCES, not EPROTO + + [ Upstream commit 61e76b178dbe7145e8d6afa84bb4ccea71918994 ] + + RFC 4443 has defined two additional codes for ICMPv6 type 1 (destination + unreachable) messages: + 5 - Source address failed ingress/egress policy + 6 - Reject route to destination + + Now they are treated as protocol error and icmpv6_err_convert() converts them + to EPROTO. + + RFC 4443 says: + "Codes 5 and 6 are more informative subsets of code 1." + + Treat codes 5 and 6 as code 1 (EACCES) + + Btw, connect() returning -EPROTO confuses firefox, so that fallback to + other/IPv4 addresses does not work: + https://bugzilla.mozilla.org/show_bug.cgi?id=910773 + + Signed-off-by: Jiri Bohac + Acked-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/uapi/linux/icmpv6.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/uapi/linux/icmpv6.h 2014-05-05 11:51:51.000000000 +0000 ++++ linux-3.10-3.10.11/include/uapi/linux/icmpv6.h 2014-05-05 12:43:32.000000000 +0000 +@@ -115,6 +115,8 @@ + #define ICMPV6_NOT_NEIGHBOUR 2 + #define ICMPV6_ADDR_UNREACH 3 + #define ICMPV6_PORT_UNREACH 4 ++#define ICMPV6_POLICY_FAIL 5 ++#define ICMPV6_REJECT_ROUTE 6 + + /* + * Codes for Time Exceeded +Index: linux-3.10-3.10.11/net/ipv6/icmp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/icmp.c 2014-05-05 11:51:51.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/icmp.c 2014-05-05 12:43:32.000000000 +0000 +@@ -931,6 +931,14 @@ + .err = ECONNREFUSED, + .fatal = 1, + }, ++ { /* POLICY_FAIL */ ++ .err = EACCES, ++ .fatal = 1, ++ }, ++ { /* REJECT_ROUTE */ ++ .err = EACCES, ++ .fatal = 1, ++ }, + }; + + int icmpv6_err_convert(u8 type, u8 code, int *err) +@@ -942,7 +950,7 @@ + switch (type) { + case ICMPV6_DEST_UNREACH: + fatal = 1; +- if (code <= ICMPV6_PORT_UNREACH) { ++ if (code < ARRAY_SIZE(tab_unreach)) { + *err = tab_unreach[code].err; + fatal = tab_unreach[code].fatal; + } +Index: linux-3.10-3.10.11/dummy/rpi_1036_2aae409672a9ec6078702b2fe92bd41ecf05d826.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1036_2aae409672a9ec6078702b2fe92bd41ecf05d826.txt 2014-05-05 12:43:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1037_84a38c47c2bbcb361caa1631c92eaf5916e178d6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1037_84a38c47c2bbcb361caa1631c92eaf5916e178d6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1037_84a38c47c2bbcb361caa1631c92eaf5916e178d6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1037_84a38c47c2bbcb361caa1631c92eaf5916e178d6.patch 2014-05-05 12:43:34.000000000 +0000 @@ -0,0 +1,60 @@ +commit 84a38c47c2bbcb361caa1631c92eaf5916e178d6 +Author: Nithin Sujir +Date: Fri Aug 30 17:01:36 2013 -0700 + + tg3: Don't turn off led on 5719 serdes port 0 + + [ Upstream commit 989038e217e94161862a959e82f9a1ecf8dda152 ] + + Turning off led on port 0 of the 5719 serdes causes all other ports to + lose power and stop functioning. Add tg3_phy_led_bug() function to check + for this condition. We use a switch() in tg3_phy_led_bug() for + consistency with the tg3_phy_power_bug() function. + + Signed-off-by: Nithin Nayak Sujir + Signed-off-by: Michael Chan + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/broadcom/tg3.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/broadcom/tg3.c 2014-05-05 12:41:42.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/broadcom/tg3.c 2014-05-05 12:43:33.000000000 +0000 +@@ -3003,6 +3003,19 @@ + return false; + } + ++static bool tg3_phy_led_bug(struct tg3 *tp) ++{ ++ switch (tg3_asic_rev(tp)) { ++ case ASIC_REV_5719: ++ if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && ++ !tp->pci_fn) ++ return true; ++ return false; ++ } ++ ++ return false; ++} ++ + static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) + { + u32 val; +@@ -3050,8 +3063,9 @@ + } + return; + } else if (do_low_power) { +- tg3_writephy(tp, MII_TG3_EXT_CTRL, +- MII_TG3_EXT_CTRL_FORCE_LED_OFF); ++ if (!tg3_phy_led_bug(tp)) ++ tg3_writephy(tp, MII_TG3_EXT_CTRL, ++ MII_TG3_EXT_CTRL_FORCE_LED_OFF); + + val = MII_TG3_AUXCTL_PCTL_100TX_LPWR | + MII_TG3_AUXCTL_PCTL_SPR_ISOLATE | +Index: linux-3.10-3.10.11/dummy/rpi_1037_84a38c47c2bbcb361caa1631c92eaf5916e178d6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1037_84a38c47c2bbcb361caa1631c92eaf5916e178d6.txt 2014-05-05 12:43:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1038_bd35c1a7f659dfa01179e456881285a9f057d30c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1038_bd35c1a7f659dfa01179e456881285a9f057d30c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1038_bd35c1a7f659dfa01179e456881285a9f057d30c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1038_bd35c1a7f659dfa01179e456881285a9f057d30c.patch 2014-05-05 12:43:34.000000000 +0000 @@ -0,0 +1,49 @@ +commit bd35c1a7f659dfa01179e456881285a9f057d30c +Author: Jason Wang +Date: Mon Sep 2 16:41:00 2013 +0800 + + vhost_net: poll vhost queue after marking DMA is done + + [ Upstream commit 19c73b3e08d16ee923f3962df4abf6205127896a ] + + We used to poll vhost queue before making DMA is done, this is racy if vhost + thread were waked up before marking DMA is done which can result the signal to + be missed. Fix this by always polling the vhost thread before DMA is done. + + Signed-off-by: Jason Wang + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/vhost/net.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/vhost/net.c 2014-05-05 11:51:50.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/vhost/net.c 2014-05-05 12:43:34.000000000 +0000 +@@ -307,6 +307,11 @@ + struct vhost_virtqueue *vq = ubufs->vq; + int cnt = atomic_read(&ubufs->kref.refcount); + ++ /* set len to mark this desc buffers done DMA */ ++ vq->heads[ubuf->desc].len = success ? ++ VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; ++ vhost_net_ubuf_put(ubufs); ++ + /* + * Trigger polling thread if guest stopped submitting new buffers: + * in this case, the refcount after decrement will eventually reach 1 +@@ -317,10 +322,6 @@ + */ + if (cnt <= 2 || !(cnt % 16)) + vhost_poll_queue(&vq->poll); +- /* set len to mark this desc buffers done DMA */ +- vq->heads[ubuf->desc].len = success ? +- VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; +- vhost_net_ubuf_put(ubufs); + } + + /* Expects to be always run from workqueue - which acts as +Index: linux-3.10-3.10.11/dummy/rpi_1038_bd35c1a7f659dfa01179e456881285a9f057d30c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1038_bd35c1a7f659dfa01179e456881285a9f057d30c.txt 2014-05-05 12:43:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1039_ef1f8bcdc2febd53978905b5b0a5201104cce653.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1039_ef1f8bcdc2febd53978905b5b0a5201104cce653.patch --- linux-3.10.11/debian/patches/rpi/rpi_1039_ef1f8bcdc2febd53978905b5b0a5201104cce653.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1039_ef1f8bcdc2febd53978905b5b0a5201104cce653.patch 2014-05-05 12:43:35.000000000 +0000 @@ -0,0 +1,94 @@ +commit ef1f8bcdc2febd53978905b5b0a5201104cce653 +Author: Hannes Frederic Sowa +Date: Tue Sep 3 02:13:31 2013 +0200 + + ipv6: fix null pointer dereference in __ip6addrlbl_add + + [ Upstream commit 639739b5e609a5074839bb22fc061b37baa06269 ] + + Commit b67bfe0d42cac56c512dd5da4b1b347a23f4b70a ("hlist: drop + the node parameter from iterators") changed the behavior of + hlist_for_each_entry_safe to leave the p argument NULL. + + Fix this up by tracking the last argument. + + Reported-by: Michele Baldessari + Cc: Hideaki YOSHIFUJI + Cc: Sasha Levin + Signed-off-by: Hannes Frederic Sowa + Tested-by: Michele Baldessari + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/addrlabel.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/addrlabel.c 2014-05-05 11:51:50.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/addrlabel.c 2014-05-05 12:43:35.000000000 +0000 +@@ -251,38 +251,36 @@ + /* add a label */ + static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace) + { ++ struct hlist_node *n; ++ struct ip6addrlbl_entry *last = NULL, *p = NULL; + int ret = 0; + +- ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n", +- __func__, +- newp, replace); ++ ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n", __func__, newp, ++ replace); + +- if (hlist_empty(&ip6addrlbl_table.head)) { +- hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head); +- } else { +- struct hlist_node *n; +- struct ip6addrlbl_entry *p = NULL; +- hlist_for_each_entry_safe(p, n, +- &ip6addrlbl_table.head, list) { +- if (p->prefixlen == newp->prefixlen && +- net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) && +- p->ifindex == newp->ifindex && +- ipv6_addr_equal(&p->prefix, &newp->prefix)) { +- if (!replace) { +- ret = -EEXIST; +- goto out; +- } +- hlist_replace_rcu(&p->list, &newp->list); +- ip6addrlbl_put(p); +- goto out; +- } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) || +- (p->prefixlen < newp->prefixlen)) { +- hlist_add_before_rcu(&newp->list, &p->list); ++ hlist_for_each_entry_safe(p, n, &ip6addrlbl_table.head, list) { ++ if (p->prefixlen == newp->prefixlen && ++ net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) && ++ p->ifindex == newp->ifindex && ++ ipv6_addr_equal(&p->prefix, &newp->prefix)) { ++ if (!replace) { ++ ret = -EEXIST; + goto out; + } ++ hlist_replace_rcu(&p->list, &newp->list); ++ ip6addrlbl_put(p); ++ goto out; ++ } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) || ++ (p->prefixlen < newp->prefixlen)) { ++ hlist_add_before_rcu(&newp->list, &p->list); ++ goto out; + } +- hlist_add_after_rcu(&p->list, &newp->list); ++ last = p; + } ++ if (last) ++ hlist_add_after_rcu(&last->list, &newp->list); ++ else ++ hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head); + out: + if (!ret) + ip6addrlbl_table.seq++; +Index: linux-3.10-3.10.11/dummy/rpi_1039_ef1f8bcdc2febd53978905b5b0a5201104cce653.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1039_ef1f8bcdc2febd53978905b5b0a5201104cce653.txt 2014-05-05 12:43:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1040_a22eb149b18ed385c72d527c42dc398c97b6387f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1040_a22eb149b18ed385c72d527c42dc398c97b6387f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1040_a22eb149b18ed385c72d527c42dc398c97b6387f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1040_a22eb149b18ed385c72d527c42dc398c97b6387f.patch 2014-05-05 12:43:36.000000000 +0000 @@ -0,0 +1,49 @@ +commit a22eb149b18ed385c72d527c42dc398c97b6387f +Author: Daniel Borkmann +Date: Tue Sep 3 19:29:12 2013 +0200 + + net: ipv6: tcp: fix potential use after free in tcp_v6_do_rcv + + [ Upstream commit 3a1c756590633c0e86df606e5c618c190926a0df ] + + In tcp_v6_do_rcv() code, when processing pkt options, we soley work + on our skb clone opt_skb that we've created earlier before entering + tcp_rcv_established() on our way. However, only in condition ... + + if (np->rxopt.bits.rxtclass) + np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb)); + + ... we work on skb itself. As we extract every other information out + of opt_skb in ipv6_pktoptions path, this seems wrong, since skb can + already be released by tcp_rcv_established() earlier on. When we try + to access it in ipv6_hdr(), we will dereference freed skb. + + [ Bug added by commit 4c507d2897bd9b ("net: implement IP_RECVTOS for + IP_PKTOPTIONS") ] + + Signed-off-by: Daniel Borkmann + Cc: Eric Dumazet + Acked-by: Eric Dumazet + Acked-by: Jiri Benc + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/tcp_ipv6.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/tcp_ipv6.c 2014-05-05 11:51:49.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/tcp_ipv6.c 2014-05-05 12:43:35.000000000 +0000 +@@ -1426,7 +1426,7 @@ + if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) + np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; + if (np->rxopt.bits.rxtclass) +- np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb)); ++ np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(opt_skb)); + if (ipv6_opt_accepted(sk, opt_skb)) { + skb_set_owner_r(opt_skb, sk); + opt_skb = xchg(&np->pktoptions, opt_skb); +Index: linux-3.10-3.10.11/dummy/rpi_1040_a22eb149b18ed385c72d527c42dc398c97b6387f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1040_a22eb149b18ed385c72d527c42dc398c97b6387f.txt 2014-05-05 12:43:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1041_4c54b9db01842eb0f4eb54af6949b7606ea39e7a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1041_4c54b9db01842eb0f4eb54af6949b7606ea39e7a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1041_4c54b9db01842eb0f4eb54af6949b7606ea39e7a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1041_4c54b9db01842eb0f4eb54af6949b7606ea39e7a.patch 2014-05-05 12:43:37.000000000 +0000 @@ -0,0 +1,121 @@ +commit 4c54b9db01842eb0f4eb54af6949b7606ea39e7a +Author: Thomas Petazzoni +Date: Wed Sep 4 16:21:18 2013 +0200 + + net: mvneta: properly disable HW PHY polling and ensure adjust_link() works + + [ Upstream commit 714086029116b6b0a34e67ba1dd2f0d1cf26770c ] + + This commit fixes a long-standing bug that has been reported by many + users: on some Armada 370 platforms, only the network interface that + has been used in U-Boot to tftp the kernel works properly in + Linux. The other network interfaces can see a 'link up', but are + unable to transmit data. The reports were generally made on the Armada + 370-based Mirabox, but have also been given on the Armada 370-RD + board. + + The network MAC in the Armada 370/XP (supported by the mvneta driver + in Linux) has a functionality that allows it to continuously poll the + PHY and directly update the MAC configuration accordingly (speed, + duplex, etc.). The very first versions of the driver submitted for + review were using this hardware mechanism, but due to this, the driver + was not integrated with the kernel phylib. Following reviews, the + driver was changed to use the phylib, and therefore a software based + polling. In software based polling, Linux regularly talks to the PHY + over the MDIO bus, and sees if the link status has changed. If it's + the case then the adjust_link() callback of the driver is called to + update the MAC configuration accordingly. + + However, it turns out that the adjust_link() callback was not + configuring the hardware in a completely correct way: while it was + setting the speed and duplex bits correctly, it wasn't telling the + hardware to actually take into account those bits rather than what the + hardware-based PHY polling mechanism has concluded. So, in fact the + adjust_link() callback was basically a no-op. + + However, the network happened to be working because on the network + interfaces used by U-Boot for tftp on Armada 370 platforms because the + hardware PHY polling was enabled by the bootloader, and left enabled + by Linux. However, the second network interface not used for tftp (or + both network interfaces if the kernel is loaded from USB, NAND or SD + card) didn't had the hardware PHY polling enabled. + + This patch fixes this situation by: + + (1) Making sure that the hardware PHY polling is disabled by clearing + the MVNETA_PHY_POLLING_ENABLE bit in the MVNETA_UNIT_CONTROL + register in the driver ->probe() function. + + (2) Making sure that the duplex and speed selections made by the + adjust_link() callback are taken into account by clearing the + MVNETA_GMAC_AN_SPEED_EN and MVNETA_GMAC_AN_DUPLEX_EN bits in the + MVNETA_GMAC_AUTONEG_CONFIG register. + + This patch has been tested on Armada 370 Mirabox, and now both network + interfaces are usable after boot. + + [ Problem introduced by commit c5aff18 ("net: mvneta: driver for + Marvell Armada 370/XP network unit") ] + + Signed-off-by: Thomas Petazzoni + Cc: Willy Tarreau + Cc: Jochen De Smet + Cc: Peter Sanford + Cc: Ethan Tuttle + Cc: Chény Yves-Gael + Cc: Ryan Press + Cc: Simon Guinot + Cc: vdonnefort@lacie.com + Cc: stable@vger.kernel.org + Acked-by: Jason Cooper + Tested-by: Vincent Donnefort + Tested-by: Yves-Gael Cheny + Tested-by: Gregory CLEMENT + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/marvell/mvneta.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/marvell/mvneta.c 2014-05-05 12:42:28.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/marvell/mvneta.c 2014-05-05 12:43:36.000000000 +0000 +@@ -138,7 +138,9 @@ + #define MVNETA_GMAC_FORCE_LINK_PASS BIT(1) + #define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5) + #define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6) ++#define MVNETA_GMAC_AN_SPEED_EN BIT(7) + #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) ++#define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) + #define MVNETA_MIB_COUNTERS_BASE 0x3080 + #define MVNETA_MIB_LATE_COLLISION 0x7c + #define MVNETA_DA_FILT_SPEC_MCAST 0x3400 +@@ -916,6 +918,13 @@ + /* Assign port SDMA configuration */ + mvreg_write(pp, MVNETA_SDMA_CONFIG, val); + ++ /* Disable PHY polling in hardware, since we're using the ++ * kernel phylib to do this. ++ */ ++ val = mvreg_read(pp, MVNETA_UNIT_CONTROL); ++ val &= ~MVNETA_PHY_POLLING_ENABLE; ++ mvreg_write(pp, MVNETA_UNIT_CONTROL, val); ++ + mvneta_set_ucast_table(pp, -1); + mvneta_set_special_mcast_table(pp, -1); + mvneta_set_other_mcast_table(pp, -1); +@@ -2293,7 +2302,9 @@ + val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); + val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED | + MVNETA_GMAC_CONFIG_GMII_SPEED | +- MVNETA_GMAC_CONFIG_FULL_DUPLEX); ++ MVNETA_GMAC_CONFIG_FULL_DUPLEX | ++ MVNETA_GMAC_AN_SPEED_EN | ++ MVNETA_GMAC_AN_DUPLEX_EN); + + if (phydev->duplex) + val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; +Index: linux-3.10-3.10.11/dummy/rpi_1041_4c54b9db01842eb0f4eb54af6949b7606ea39e7a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1041_4c54b9db01842eb0f4eb54af6949b7606ea39e7a.txt 2014-05-05 12:43:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1042_751190a69d7c885b98716e2aca339f6c4b988704.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1042_751190a69d7c885b98716e2aca339f6c4b988704.patch --- linux-3.10.11/debian/patches/rpi/rpi_1042_751190a69d7c885b98716e2aca339f6c4b988704.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1042_751190a69d7c885b98716e2aca339f6c4b988704.patch 2014-05-05 12:43:38.000000000 +0000 @@ -0,0 +1,42 @@ +commit 751190a69d7c885b98716e2aca339f6c4b988704 +Author: John Haxby +Date: Wed Aug 14 16:23:18 2013 +0100 + + crypto: xor - Check for osxsave as well as avx in crypto/xor + + commit edb6f29464afc65fc73767540b854abf63ae7144 upstream. + + This affects xen pv guests with sufficiently old versions of xen and + sufficiently new hardware. On such a system, a guest with a btrfs + root won't even boot. + + Signed-off-by: John Haxby + Signed-off-by: Herbert Xu + Reported-by: Michael Marineau + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/include/asm/xor_avx.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/xor_avx.h 2014-05-05 11:51:49.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/xor_avx.h 2014-05-05 12:43:37.000000000 +0000 +@@ -167,12 +167,12 @@ + + #define AVX_XOR_SPEED \ + do { \ +- if (cpu_has_avx) \ ++ if (cpu_has_avx && cpu_has_osxsave) \ + xor_speed(&xor_block_avx); \ + } while (0) + + #define AVX_SELECT(FASTEST) \ +- (cpu_has_avx ? &xor_block_avx : FASTEST) ++ (cpu_has_avx && cpu_has_osxsave ? &xor_block_avx : FASTEST) + + #else + +Index: linux-3.10-3.10.11/dummy/rpi_1042_751190a69d7c885b98716e2aca339f6c4b988704.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1042_751190a69d7c885b98716e2aca339f6c4b988704.txt 2014-05-05 12:43:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1043_70aa7b8f105b0b5bb82d2082a230efb7f34645a0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1043_70aa7b8f105b0b5bb82d2082a230efb7f34645a0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1043_70aa7b8f105b0b5bb82d2082a230efb7f34645a0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1043_70aa7b8f105b0b5bb82d2082a230efb7f34645a0.patch 2014-05-05 12:43:38.000000000 +0000 @@ -0,0 +1,41 @@ +commit 70aa7b8f105b0b5bb82d2082a230efb7f34645a0 +Author: Sangjung Woo +Date: Wed Sep 11 14:24:21 2013 -0700 + + drivers/rtc/rtc-max77686.c: Fix wrong register + + commit 1748cbf7f7c464593232cde914f5a103181a83b5 upstream. + + Fix a read of the wrong register when checking whether the RTC timer has + reached the alarm time. + + Signed-off-by: Sangjung Woo + Signed-off-by: Myugnjoo Ham + Reviewed-by: Jonghwa Lee + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/rtc/rtc-max77686.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/rtc/rtc-max77686.c 2014-05-05 11:51:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/rtc/rtc-max77686.c 2014-05-05 12:43:38.000000000 +0000 +@@ -240,9 +240,9 @@ + } + + alrm->pending = 0; +- ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS1, &val); ++ ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS2, &val); + if (ret < 0) { +- dev_err(info->dev, "%s:%d fail to read status1 reg(%d)\n", ++ dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n", + __func__, __LINE__, ret); + goto out; + } +Index: linux-3.10-3.10.11/dummy/rpi_1043_70aa7b8f105b0b5bb82d2082a230efb7f34645a0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1043_70aa7b8f105b0b5bb82d2082a230efb7f34645a0.txt 2014-05-05 12:43:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1044_7bf0f5bd9213cd0d75383ec36d3aae5f08e185c4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1044_7bf0f5bd9213cd0d75383ec36d3aae5f08e185c4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1044_7bf0f5bd9213cd0d75383ec36d3aae5f08e185c4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1044_7bf0f5bd9213cd0d75383ec36d3aae5f08e185c4.patch 2014-05-05 12:43:39.000000000 +0000 @@ -0,0 +1,68 @@ +commit 7bf0f5bd9213cd0d75383ec36d3aae5f08e185c4 +Author: Bing Zhao +Date: Mon Aug 19 16:10:21 2013 -0700 + + mwifiex: do not create AP and P2P interfaces upon driver loading + + commit 1211c961170cedb21c30d5bb7e2033c8720b38db upstream. + + Bug 60747 - 1286:2044 [Microsoft Surface Pro] + Marvell 88W8797 wifi show 3 interface under network + https://bugzilla.kernel.org/show_bug.cgi?id=60747 + + This issue was also reported previously by OLPC and some folks from + the community. + + There are 3 network interfaces with different types being created + when mwifiex driver is loaded: + + 1. mlan0 (infra. STA) + 2. uap0 (AP) + 3. p2p0 (P2P_CLIENT) + + The Network Manager attempts to use all 3 interfaces above without + filtering the managed interface type. As the result, 3 identical + interfaces are displayed under network manager. If user happens to + click on an entry under which its interface is uap0 or p2p0, the + association will fail. + + Work around it by removing the creation of AP and P2P interfaces + at driver loading time. These interfaces can be added with 'iw' or + other applications manually when they are needed. + + Signed-off-by: Bing Zhao + Signed-off-by: Avinash Patil + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/main.c 2014-05-05 12:41:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c 2014-05-05 12:43:39.000000000 +0000 +@@ -360,20 +360,6 @@ + dev_err(adapter->dev, "cannot create default STA interface\n"); + goto err_add_intf; + } +- +- /* Create AP interface by default */ +- if (!mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", +- NL80211_IFTYPE_AP, NULL, NULL)) { +- dev_err(adapter->dev, "cannot create default AP interface\n"); +- goto err_add_intf; +- } +- +- /* Create P2P interface by default */ +- if (!mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", +- NL80211_IFTYPE_P2P_CLIENT, NULL, NULL)) { +- dev_err(adapter->dev, "cannot create default P2P interface\n"); +- goto err_add_intf; +- } + rtnl_unlock(); + + mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); +Index: linux-3.10-3.10.11/dummy/rpi_1044_7bf0f5bd9213cd0d75383ec36d3aae5f08e185c4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1044_7bf0f5bd9213cd0d75383ec36d3aae5f08e185c4.txt 2014-05-05 12:43:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1045_9cfceacb4983272c1f0a6926aec2b127143df692.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1045_9cfceacb4983272c1f0a6926aec2b127143df692.patch --- linux-3.10.11/debian/patches/rpi/rpi_1045_9cfceacb4983272c1f0a6926aec2b127143df692.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1045_9cfceacb4983272c1f0a6926aec2b127143df692.patch 2014-05-05 12:43:40.000000000 +0000 @@ -0,0 +1,47 @@ +commit 9cfceacb4983272c1f0a6926aec2b127143df692 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sun May 26 16:55:59 2013 +0800 + + ARM: at91: dt: sam9260: add i2c gpio pinctrl + + commit f89ae61bd74ae195c464bdd97a134e30908884d5 upstream. + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nicolas Ferre + Cc: Boris BREZILLON + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9260.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/at91sam9260.dtsi 2014-05-05 11:51:47.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9260.dtsi 2014-05-05 12:43:39.000000000 +0000 +@@ -340,6 +340,14 @@ + }; + }; + ++ i2c_gpio0 { ++ pinctrl_i2c_gpio0: i2c_gpio0-0 { ++ atmel,pins = ++ <0 23 0x0 0x3 /* PA23 gpio I2C_SDA pin */ ++ 0 24 0x0 0x3>; /* PA24 gpio I2C_SCL pin */ ++ }; ++ }; ++ + pioA: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; +@@ -592,6 +600,8 @@ + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c_gpio0>; + status = "disabled"; + }; + }; +Index: linux-3.10-3.10.11/dummy/rpi_1045_9cfceacb4983272c1f0a6926aec2b127143df692.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1045_9cfceacb4983272c1f0a6926aec2b127143df692.txt 2014-05-05 12:43:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1046_410dbb746130bc052bb3c7a337a86252874adbdf.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1046_410dbb746130bc052bb3c7a337a86252874adbdf.patch --- linux-3.10.11/debian/patches/rpi/rpi_1046_410dbb746130bc052bb3c7a337a86252874adbdf.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1046_410dbb746130bc052bb3c7a337a86252874adbdf.patch 2014-05-05 12:43:41.000000000 +0000 @@ -0,0 +1,24 @@ +commit 410dbb746130bc052bb3c7a337a86252874adbdf +Author: Greg Kroah-Hartman +Date: Sat Sep 14 06:55:12 2013 -0700 + + Linux 3.10.12 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:41:27.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:43:40.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 11 ++SUBLEVEL = 12 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1046_410dbb746130bc052bb3c7a337a86252874adbdf.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1046_410dbb746130bc052bb3c7a337a86252874adbdf.txt 2014-05-05 12:43:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1047_e62b0f0196a7ea462d04e320cdd727aed51dd60f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1047_e62b0f0196a7ea462d04e320cdd727aed51dd60f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1047_e62b0f0196a7ea462d04e320cdd727aed51dd60f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1047_e62b0f0196a7ea462d04e320cdd727aed51dd60f.patch 2014-05-05 12:43:42.000000000 +0000 @@ -0,0 +1,33 @@ +commit e62b0f0196a7ea462d04e320cdd727aed51dd60f +Author: Greg Kroah-Hartman +Date: Tue Sep 3 15:00:11 2013 -0700 + + SCSI: Allow MPT Fusion SAS 3.0 driver to be built into the kernel + + commit 9807b4d94911be4e4efb9a08481b24292a9edf8a upstream. + + Right now the Makefile for the mpt3sas driver does not even allow the + driver to be built into the kernel. So fix that up, as there doesn't + seem to be any obvious reason why this shouldn't be done. + + Signed-off-by: Greg Kroah-Hartman + Acked-by: Sreekanth Reddy + Signed-off-by: James Bottomley + +Index: linux-3.10-3.10.11/drivers/scsi/mpt3sas/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/mpt3sas/Makefile 2014-05-05 11:51:47.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/mpt3sas/Makefile 2014-05-05 12:43:41.000000000 +0000 +@@ -1,5 +1,5 @@ + # mpt3sas makefile +-obj-m += mpt3sas.o ++obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o + mpt3sas-y += mpt3sas_base.o \ + mpt3sas_config.o \ + mpt3sas_scsih.o \ +Index: linux-3.10-3.10.11/dummy/rpi_1047_e62b0f0196a7ea462d04e320cdd727aed51dd60f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1047_e62b0f0196a7ea462d04e320cdd727aed51dd60f.txt 2014-05-05 12:43:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1048_e7d63334e76b3cbb0ef599fef1643701fdb28aad.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1048_e7d63334e76b3cbb0ef599fef1643701fdb28aad.patch --- linux-3.10.11/debian/patches/rpi/rpi_1048_e7d63334e76b3cbb0ef599fef1643701fdb28aad.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1048_e7d63334e76b3cbb0ef599fef1643701fdb28aad.patch 2014-05-05 12:43:43.000000000 +0000 @@ -0,0 +1,40 @@ +commit e7d63334e76b3cbb0ef599fef1643701fdb28aad +Author: Richard Weinberger +Date: Mon Aug 19 08:48:12 2013 +0200 + + UBI: Fix PEB leak in wear_leveling_worker() + + commit 5ef4414f4bc26a19cfd5cd11aee9697a863e4d51 upstream. + + get_peb_for_wl() removes the PEB from the free list. + If the WL subsystem detects that no wear leveling is needed + it cancels the operation and drops the gained PEB. + In this case we have to put the PEB back into the free list. + + This issue was introduced with commit ed4b7021c + (UBI: remove PEB from free tree in get_peb_for_wl()). + + Signed-off-by: Richard Weinberger + Signed-off-by: Artem Bityutskiy + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/mtd/ubi/wl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/mtd/ubi/wl.c 2014-05-05 11:51:46.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mtd/ubi/wl.c 2014-05-05 12:43:42.000000000 +0000 +@@ -1069,6 +1069,9 @@ + if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { + dbg_wl("no WL needed: min used EC %d, max free EC %d", + e1->ec, e2->ec); ++ ++ /* Give the unused PEB back */ ++ wl_tree_add(e2, &ubi->free); + goto out_cancel; + } + self_check_in_wl_tree(ubi, e1, &ubi->used); +Index: linux-3.10-3.10.11/dummy/rpi_1048_e7d63334e76b3cbb0ef599fef1643701fdb28aad.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1048_e7d63334e76b3cbb0ef599fef1643701fdb28aad.txt 2014-05-05 12:43:42.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1049_13915e203f991e77eb5a52bcd4c61e5f155e3bbc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1049_13915e203f991e77eb5a52bcd4c61e5f155e3bbc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1049_13915e203f991e77eb5a52bcd4c61e5f155e3bbc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1049_13915e203f991e77eb5a52bcd4c61e5f155e3bbc.patch 2014-05-05 12:43:44.000000000 +0000 @@ -0,0 +1,47 @@ +commit 13915e203f991e77eb5a52bcd4c61e5f155e3bbc +Author: Alan Stern +Date: Fri Sep 6 11:49:51 2013 -0400 + + SCSI: sd: Fix potential out-of-bounds access + + commit 984f1733fcee3fbc78d47e26c5096921c5d9946a upstream. + + This patch fixes an out-of-bounds error in sd_read_cache_type(), found + by Google's AddressSanitizer tool. When the loop ends, we know that + "offset" lies beyond the end of the data in the buffer, so no Caching + mode page was found. In theory it may be present, but the buffer size + is limited to 512 bytes. + + Signed-off-by: Alan Stern + Reported-by: Dmitry Vyukov + Signed-off-by: James Bottomley + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/scsi/sd.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/sd.c 2014-05-05 11:51:46.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/sd.c 2014-05-05 12:43:43.000000000 +0000 +@@ -2409,14 +2409,9 @@ + } + } + +- if (modepage == 0x3F) { +- sd_printk(KERN_ERR, sdkp, "No Caching mode page " +- "present\n"); +- goto defaults; +- } else if ((buffer[offset] & 0x3f) != modepage) { +- sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); +- goto defaults; +- } ++ sd_printk(KERN_ERR, sdkp, "No Caching mode page found\n"); ++ goto defaults; ++ + Page_found: + if (modepage == 8) { + sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); +Index: linux-3.10-3.10.11/dummy/rpi_1049_13915e203f991e77eb5a52bcd4c61e5f155e3bbc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1049_13915e203f991e77eb5a52bcd4c61e5f155e3bbc.txt 2014-05-05 12:43:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1050_139653e11c9eec4d5eff614e688d6bec99b78d7f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1050_139653e11c9eec4d5eff614e688d6bec99b78d7f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1050_139653e11c9eec4d5eff614e688d6bec99b78d7f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1050_139653e11c9eec4d5eff614e688d6bec99b78d7f.patch 2014-05-05 12:43:44.000000000 +0000 @@ -0,0 +1,52 @@ +commit 139653e11c9eec4d5eff614e688d6bec99b78d7f +Author: Herbert Xu +Date: Sun Sep 8 14:33:50 2013 +1000 + + crypto: api - Fix race condition in larval lookup + + commit 77dbd7a95e4a4f15264c333a9e9ab97ee27dc2aa upstream. + + crypto_larval_lookup should only return a larval if it created one. + Any larval created by another entity must be processed through + crypto_larval_wait before being returned. + + Otherwise this will lead to a larval being killed twice, which + will most likely lead to a crash. + + Reported-by: Kees Cook + Tested-by: Kees Cook + Signed-off-by: Herbert Xu + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/crypto/api.c +=================================================================== +--- linux-3.10-3.10.11.orig/crypto/api.c 2014-05-05 11:51:46.000000000 +0000 ++++ linux-3.10-3.10.11/crypto/api.c 2014-05-05 12:43:44.000000000 +0000 +@@ -34,6 +34,8 @@ + BLOCKING_NOTIFIER_HEAD(crypto_chain); + EXPORT_SYMBOL_GPL(crypto_chain); + ++static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); ++ + struct crypto_alg *crypto_mod_get(struct crypto_alg *alg) + { + return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL; +@@ -144,8 +146,11 @@ + } + up_write(&crypto_alg_sem); + +- if (alg != &larval->alg) ++ if (alg != &larval->alg) { + kfree(larval); ++ if (crypto_is_larval(alg)) ++ alg = crypto_larval_wait(alg); ++ } + + return alg; + } +Index: linux-3.10-3.10.11/dummy/rpi_1050_139653e11c9eec4d5eff614e688d6bec99b78d7f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1050_139653e11c9eec4d5eff614e688d6bec99b78d7f.txt 2014-05-05 12:43:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1051_d8ba750f9a2feb07bb6f0448807907b674ca4525.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1051_d8ba750f9a2feb07bb6f0448807907b674ca4525.patch --- linux-3.10.11/debian/patches/rpi/rpi_1051_d8ba750f9a2feb07bb6f0448807907b674ca4525.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1051_d8ba750f9a2feb07bb6f0448807907b674ca4525.patch 2014-05-05 12:43:45.000000000 +0000 @@ -0,0 +1,54 @@ +commit d8ba750f9a2feb07bb6f0448807907b674ca4525 +Author: Anton Blanchard +Date: Wed Aug 7 02:01:19 2013 +1000 + + powerpc: Handle unaligned ldbrx/stdbrx + + commit 230aef7a6a23b6166bd4003bfff5af23c9bd381f upstream. + + Normally when we haven't implemented an alignment handler for + a load or store instruction the process will be terminated. + + The alignment handler uses the DSISR (or a pseudo one) to locate + the right handler. Unfortunately ldbrx and stdbrx overlap lfs and + stfs so we incorrectly think ldbrx is an lfs and stdbrx is an + stfs. + + This bug is particularly nasty - instead of terminating the + process we apply an incorrect fixup and continue on. + + With more and more overlapping instructions we should stop + creating a pseudo DSISR and index using the instruction directly, + but for now add a special case to catch ldbrx/stdbrx. + + Signed-off-by: Anton Blanchard + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/kernel/align.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kernel/align.c 2014-05-05 11:51:45.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kernel/align.c 2014-05-05 12:43:45.000000000 +0000 +@@ -764,6 +764,16 @@ + nb = aligninfo[instr].len; + flags = aligninfo[instr].flags; + ++ /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ ++ if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { ++ nb = 8; ++ flags = LD+SW; ++ } else if (IS_XFORM(instruction) && ++ ((instruction >> 1) & 0x3ff) == 660) { ++ nb = 8; ++ flags = ST+SW; ++ } ++ + /* Byteswap little endian loads and stores */ + swiz = 0; + if (regs->msr & MSR_LE) { +Index: linux-3.10-3.10.11/dummy/rpi_1051_d8ba750f9a2feb07bb6f0448807907b674ca4525.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1051_d8ba750f9a2feb07bb6f0448807907b674ca4525.txt 2014-05-05 12:43:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1052_d08bfff9ef39c029befa68b2641ad2f7a2c894b6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1052_d08bfff9ef39c029befa68b2641ad2f7a2c894b6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1052_d08bfff9ef39c029befa68b2641ad2f7a2c894b6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1052_d08bfff9ef39c029befa68b2641ad2f7a2c894b6.patch 2014-05-05 12:43:46.000000000 +0000 @@ -0,0 +1,97 @@ +commit d08bfff9ef39c029befa68b2641ad2f7a2c894b6 +Author: Vaidyanathan Srinivasan +Date: Fri Sep 6 00:25:06 2013 +0530 + + powerpc: Default arch idle could cede processor on pseries + + commit 363edbe2614aa90df706c0f19ccfa2a6c06af0be upstream. + + When adding cpuidle support to pSeries, we introduced two + regressions: + + - The new cpuidle backend driver only works under hypervisors + supporting the "SLPLAR" option, which isn't the case of the + old POWER4 hypervisor and the HV "light" used on js2x blades + + - The cpuidle driver registers fairly late, meaning that for + a significant portion of the boot process, we end up having + all threads spinning. This slows down the boot process and + increases the overall resource usage if the hypervisor has + shared processors. + + This fixes both by implementing a "default" idle that will cede + to the hypervisor when possible, in a very simple way without + all the bells and whisles of cpuidle. + + Reported-by: Paul Mackerras + Signed-off-by: Vaidyanathan Srinivasan + Acked-by: Deepthi Dharwar + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/platforms/pseries/setup.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/platforms/pseries/setup.c 2014-05-05 11:51:45.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/platforms/pseries/setup.c 2014-05-05 12:43:46.000000000 +0000 +@@ -354,7 +354,7 @@ + } + early_initcall(alloc_dispatch_log_kmem_cache); + +-static void pSeries_idle(void) ++static void pseries_lpar_idle(void) + { + /* This would call on the cpuidle framework, and the back-end pseries + * driver to go to idle states +@@ -362,10 +362,22 @@ + if (cpuidle_idle_call()) { + /* On error, execute default handler + * to go into low thread priority and possibly +- * low power mode. ++ * low power mode by cedeing processor to hypervisor + */ +- HMT_low(); +- HMT_very_low(); ++ ++ /* Indicate to hypervisor that we are idle. */ ++ get_lppaca()->idle = 1; ++ ++ /* ++ * Yield the processor to the hypervisor. We return if ++ * an external interrupt occurs (which are driven prior ++ * to returning here) or if a prod occurs from another ++ * processor. When returning here, external interrupts ++ * are enabled. ++ */ ++ cede_processor(); ++ ++ get_lppaca()->idle = 0; + } + } + +@@ -456,15 +468,14 @@ + + pSeries_nvram_init(); + +- if (firmware_has_feature(FW_FEATURE_SPLPAR)) { ++ if (firmware_has_feature(FW_FEATURE_LPAR)) { + vpa_init(boot_cpuid); +- ppc_md.power_save = pSeries_idle; +- } +- +- if (firmware_has_feature(FW_FEATURE_LPAR)) ++ ppc_md.power_save = pseries_lpar_idle; + ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; +- else ++ } else { ++ /* No special idle routine */ + ppc_md.enable_pmcs = power4_enable_pmcs; ++ } + + ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; + +Index: linux-3.10-3.10.11/dummy/rpi_1052_d08bfff9ef39c029befa68b2641ad2f7a2c894b6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1052_d08bfff9ef39c029befa68b2641ad2f7a2c894b6.txt 2014-05-05 12:43:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1053_93326685f124a1b2a71843b1c41328be13f97bbb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1053_93326685f124a1b2a71843b1c41328be13f97bbb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1053_93326685f124a1b2a71843b1c41328be13f97bbb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1053_93326685f124a1b2a71843b1c41328be13f97bbb.patch 2014-05-05 12:43:47.000000000 +0000 @@ -0,0 +1,56 @@ +commit 93326685f124a1b2a71843b1c41328be13f97bbb +Author: Roger Pau Monne +Date: Wed Jul 31 17:00:42 2013 +0200 + + xen-gnt: prevent adding duplicate gnt callbacks + + commit 5f338d9001094a56cf87bd8a280b4e7ff953bb59 upstream. + + With the current implementation, the callback in the tail of the list + can be added twice, because the check done in + gnttab_request_free_callback is bogus, callback->next can be NULL if + it is the last callback in the list. If we add the same callback twice + we end up with an infinite loop, were callback == callback->next. + + Replace this check with a proper one that iterates over the list to + see if the callback has already been added. + + Signed-off-by: Roger Pau Monné + Cc: Konrad Rzeszutek Wilk + Cc: David Vrabel + Signed-off-by: Konrad Rzeszutek Wilk + Acked-by: Matt Wilson + Reviewed-by: David Vrabel + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/xen/grant-table.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/xen/grant-table.c 2014-05-05 11:51:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/xen/grant-table.c 2014-05-05 12:43:47.000000000 +0000 +@@ -729,9 +729,18 @@ + void (*fn)(void *), void *arg, u16 count) + { + unsigned long flags; ++ struct gnttab_free_callback *cb; ++ + spin_lock_irqsave(&gnttab_list_lock, flags); +- if (callback->next) +- goto out; ++ ++ /* Check if the callback is already on the list */ ++ cb = gnttab_free_callback_list; ++ while (cb) { ++ if (cb == callback) ++ goto out; ++ cb = cb->next; ++ } ++ + callback->fn = fn; + callback->arg = arg; + callback->count = count; +Index: linux-3.10-3.10.11/dummy/rpi_1053_93326685f124a1b2a71843b1c41328be13f97bbb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1053_93326685f124a1b2a71843b1c41328be13f97bbb.txt 2014-05-05 12:43:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1054_863008a9b50259d3a4b1c9a387804f9509413de4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1054_863008a9b50259d3a4b1c9a387804f9509413de4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1054_863008a9b50259d3a4b1c9a387804f9509413de4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1054_863008a9b50259d3a4b1c9a387804f9509413de4.patch 2014-05-05 12:43:48.000000000 +0000 @@ -0,0 +1,44 @@ +commit 863008a9b50259d3a4b1c9a387804f9509413de4 +Author: Rob Herring +Date: Thu Aug 29 07:43:52 2013 -0500 + + ARM: xen: only set pm function ptrs for Xen guests + + commit 9dd4b2944c46e1fdbd0a516c221c8a2670cbf005 upstream. + + xen_pm_init was unconditionally setting pm_power_off and arm_pm_restart + function pointers. This breaks multi-platform kernels. Make this + conditional on running as a Xen guest and make it a late_initcall to + ensure it is setup after platform code for Dom0. + + Signed-off-by: Rob Herring + Signed-off-by: Stefano Stabellini + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/xen/enlighten.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/xen/enlighten.c 2014-05-05 11:51:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/xen/enlighten.c 2014-05-05 12:43:47.000000000 +0000 +@@ -273,12 +273,15 @@ + + static int __init xen_pm_init(void) + { ++ if (!xen_domain()) ++ return -ENODEV; ++ + pm_power_off = xen_power_off; + arm_pm_restart = xen_restart; + + return 0; + } +-subsys_initcall(xen_pm_init); ++late_initcall(xen_pm_init); + + static irqreturn_t xen_arm_callback(int irq, void *arg) + { +Index: linux-3.10-3.10.11/dummy/rpi_1054_863008a9b50259d3a4b1c9a387804f9509413de4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1054_863008a9b50259d3a4b1c9a387804f9509413de4.txt 2014-05-05 12:43:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1055_61704f036693ca93a7d916899288eba9a98b006f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1055_61704f036693ca93a7d916899288eba9a98b006f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1055_61704f036693ca93a7d916899288eba9a98b006f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1055_61704f036693ca93a7d916899288eba9a98b006f.patch 2014-05-05 12:43:50.000000000 +0000 @@ -0,0 +1,249 @@ +commit 61704f036693ca93a7d916899288eba9a98b006f +Author: Colin Cross +Date: Wed Aug 28 18:41:47 2013 -0700 + + cpuidle: coupled: abort idle if pokes are pending + + commit f983827bcb9d2c34c4d8935861a1e9128aec2baf upstream. + + Joseph Lo reported a lockup on Tegra20 caused + by a race condition in coupled cpuidle. When two or more cpus + enter idle at the same time, the first cpus to arrive may go to the + ready loop without processing pending pokes from the last cpu to + arrive. + + This patch adds a check for pending pokes once all cpus have been + synchronized in the ready loop and resets the coupled state and + retries if any cpus failed to handle their pending poke. + + Retrying on all cpus may trigger the same issue again, so this patch + also adds a check to ensure that each cpu has received at least one + poke between when it enters the waiting loop and when it moves on to + the ready loop. + + Reported-and-tested-by: Joseph Lo + Tested-by: Stephen Warren + Signed-off-by: Colin Cross + Signed-off-by: Rafael J. Wysocki + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/cpuidle/coupled.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/cpuidle/coupled.c 2014-05-05 11:51:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/cpuidle/coupled.c 2014-05-05 12:43:49.000000000 +0000 +@@ -106,6 +106,7 @@ + cpumask_t coupled_cpus; + int requested_state[NR_CPUS]; + atomic_t ready_waiting_counts; ++ atomic_t abort_barrier; + int online_count; + int refcnt; + int prevent; +@@ -122,12 +123,19 @@ + static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb); + + /* +- * The cpuidle_coupled_poked_mask mask is used to avoid calling ++ * The cpuidle_coupled_poke_pending mask is used to avoid calling + * __smp_call_function_single with the per cpu call_single_data struct already + * in use. This prevents a deadlock where two cpus are waiting for each others + * call_single_data struct to be available + */ +-static cpumask_t cpuidle_coupled_poked_mask; ++static cpumask_t cpuidle_coupled_poke_pending; ++ ++/* ++ * The cpuidle_coupled_poked mask is used to ensure that each cpu has been poked ++ * once to minimize entering the ready loop with a poke pending, which would ++ * require aborting and retrying. ++ */ ++static cpumask_t cpuidle_coupled_poked; + + /** + * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus +@@ -291,10 +299,11 @@ + return state; + } + +-static void cpuidle_coupled_poked(void *info) ++static void cpuidle_coupled_handle_poke(void *info) + { + int cpu = (unsigned long)info; +- cpumask_clear_cpu(cpu, &cpuidle_coupled_poked_mask); ++ cpumask_set_cpu(cpu, &cpuidle_coupled_poked); ++ cpumask_clear_cpu(cpu, &cpuidle_coupled_poke_pending); + } + + /** +@@ -313,7 +322,7 @@ + { + struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu); + +- if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poked_mask)) ++ if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poke_pending)) + __smp_call_function_single(cpu, csd, 0); + } + +@@ -340,30 +349,19 @@ + * @coupled: the struct coupled that contains the current cpu + * @next_state: the index in drv->states of the requested state for this cpu + * +- * Updates the requested idle state for the specified cpuidle device, +- * poking all coupled cpus out of idle if necessary to let them see the new +- * state. ++ * Updates the requested idle state for the specified cpuidle device. ++ * Returns the number of waiting cpus. + */ +-static void cpuidle_coupled_set_waiting(int cpu, ++static int cpuidle_coupled_set_waiting(int cpu, + struct cpuidle_coupled *coupled, int next_state) + { +- int w; +- + coupled->requested_state[cpu] = next_state; + + /* +- * If this is the last cpu to enter the waiting state, poke +- * all the other cpus out of their waiting state so they can +- * enter a deeper state. This can race with one of the cpus +- * exiting the waiting state due to an interrupt and +- * decrementing waiting_count, see comment below. +- * + * The atomic_inc_return provides a write barrier to order the write + * to requested_state with the later write that increments ready_count. + */ +- w = atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK; +- if (w == coupled->online_count) +- cpuidle_coupled_poke_others(cpu, coupled); ++ return atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK; + } + + /** +@@ -418,13 +416,24 @@ + static int cpuidle_coupled_clear_pokes(int cpu) + { + local_irq_enable(); +- while (cpumask_test_cpu(cpu, &cpuidle_coupled_poked_mask)) ++ while (cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending)) + cpu_relax(); + local_irq_disable(); + + return need_resched() ? -EINTR : 0; + } + ++static bool cpuidle_coupled_any_pokes_pending(struct cpuidle_coupled *coupled) ++{ ++ cpumask_t cpus; ++ int ret; ++ ++ cpumask_and(&cpus, cpu_online_mask, &coupled->coupled_cpus); ++ ret = cpumask_and(&cpus, &cpuidle_coupled_poke_pending, &cpus); ++ ++ return ret; ++} ++ + /** + * cpuidle_enter_state_coupled - attempt to enter a state with coupled cpus + * @dev: struct cpuidle_device for the current cpu +@@ -449,6 +458,7 @@ + { + int entered_state = -1; + struct cpuidle_coupled *coupled = dev->coupled; ++ int w; + + if (!coupled) + return -EINVAL; +@@ -465,14 +475,33 @@ + /* Read barrier ensures online_count is read after prevent is cleared */ + smp_rmb(); + +- cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state); ++reset: ++ cpumask_clear_cpu(dev->cpu, &cpuidle_coupled_poked); ++ ++ w = cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state); ++ /* ++ * If this is the last cpu to enter the waiting state, poke ++ * all the other cpus out of their waiting state so they can ++ * enter a deeper state. This can race with one of the cpus ++ * exiting the waiting state due to an interrupt and ++ * decrementing waiting_count, see comment below. ++ */ ++ if (w == coupled->online_count) { ++ cpumask_set_cpu(dev->cpu, &cpuidle_coupled_poked); ++ cpuidle_coupled_poke_others(dev->cpu, coupled); ++ } + + retry: + /* + * Wait for all coupled cpus to be idle, using the deepest state +- * allowed for a single cpu. ++ * allowed for a single cpu. If this was not the poking cpu, wait ++ * for at least one poke before leaving to avoid a race where ++ * two cpus could arrive at the waiting loop at the same time, ++ * but the first of the two to arrive could skip the loop without ++ * processing the pokes from the last to arrive. + */ +- while (!cpuidle_coupled_cpus_waiting(coupled)) { ++ while (!cpuidle_coupled_cpus_waiting(coupled) || ++ !cpumask_test_cpu(dev->cpu, &cpuidle_coupled_poked)) { + if (cpuidle_coupled_clear_pokes(dev->cpu)) { + cpuidle_coupled_set_not_waiting(dev->cpu, coupled); + goto out; +@@ -493,6 +522,12 @@ + } + + /* ++ * Make sure final poke status for this cpu is visible before setting ++ * cpu as ready. ++ */ ++ smp_wmb(); ++ ++ /* + * All coupled cpus are probably idle. There is a small chance that + * one of the other cpus just became active. Increment the ready count, + * and spin until all coupled cpus have incremented the counter. Once a +@@ -511,6 +546,28 @@ + cpu_relax(); + } + ++ /* ++ * Make sure read of all cpus ready is done before reading pending pokes ++ */ ++ smp_rmb(); ++ ++ /* ++ * There is a small chance that a cpu left and reentered idle after this ++ * cpu saw that all cpus were waiting. The cpu that reentered idle will ++ * have sent this cpu a poke, which will still be pending after the ++ * ready loop. The pending interrupt may be lost by the interrupt ++ * controller when entering the deep idle state. It's not possible to ++ * clear a pending interrupt without turning interrupts on and handling ++ * it, and it's too late to turn on interrupts here, so reset the ++ * coupled idle state of all cpus and retry. ++ */ ++ if (cpuidle_coupled_any_pokes_pending(coupled)) { ++ cpuidle_coupled_set_done(dev->cpu, coupled); ++ /* Wait for all cpus to see the pending pokes */ ++ cpuidle_coupled_parallel_barrier(dev, &coupled->abort_barrier); ++ goto reset; ++ } ++ + /* all cpus have acked the coupled state */ + next_state = cpuidle_coupled_get_state(dev, coupled); + +@@ -596,7 +653,7 @@ + coupled->refcnt++; + + csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu); +- csd->func = cpuidle_coupled_poked; ++ csd->func = cpuidle_coupled_handle_poke; + csd->info = (void *)(unsigned long)dev->cpu; + + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1055_61704f036693ca93a7d916899288eba9a98b006f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1055_61704f036693ca93a7d916899288eba9a98b006f.txt 2014-05-05 12:43:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1056_736899ab702dc85345217e124686b661a56ecb6a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1056_736899ab702dc85345217e124686b661a56ecb6a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1056_736899ab702dc85345217e124686b661a56ecb6a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1056_736899ab702dc85345217e124686b661a56ecb6a.patch 2014-05-05 12:43:51.000000000 +0000 @@ -0,0 +1,96 @@ +commit 736899ab702dc85345217e124686b661a56ecb6a +Author: Colin Cross +Date: Fri Aug 23 12:45:12 2013 -0700 + + cpuidle: coupled: fix race condition between pokes and safe state + + commit 9e19b73c30a5fa42a53583a1f7817dd857126156 upstream. + + The coupled cpuidle waiting loop clears pending pokes before + entering the safe state. If a poke arrives just before the + pokes are cleared, but after the while loop condition checks, + the poke will be lost and the cpu will stay in the safe state + until another interrupt arrives. This may cause the cpu that + sent the poke to spin in the ready loop with interrupts off + until another cpu receives an interrupt, and if no other cpus + have interrupts routed to them it can spin forever. + + Change the return value of cpuidle_coupled_clear_pokes to + return if a poke was cleared, and move the need_resched() + checks into the callers. In the waiting loop, if + a poke was cleared restart the loop to repeat the while + condition checks. + + Reported-by: Neil Zhang + Signed-off-by: Colin Cross + Signed-off-by: Rafael J. Wysocki + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/cpuidle/coupled.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/cpuidle/coupled.c 2014-05-05 12:43:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/cpuidle/coupled.c 2014-05-05 12:43:50.000000000 +0000 +@@ -408,19 +408,22 @@ + * been processed and the poke bit has been cleared. + * + * Other interrupts may also be processed while interrupts are enabled, so +- * need_resched() must be tested after turning interrupts off again to make sure ++ * need_resched() must be tested after this function returns to make sure + * the interrupt didn't schedule work that should take the cpu out of idle. + * +- * Returns 0 if need_resched was false, -EINTR if need_resched was true. ++ * Returns 0 if no poke was pending, 1 if a poke was cleared. + */ + static int cpuidle_coupled_clear_pokes(int cpu) + { ++ if (!cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending)) ++ return 0; ++ + local_irq_enable(); + while (cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending)) + cpu_relax(); + local_irq_disable(); + +- return need_resched() ? -EINTR : 0; ++ return 1; + } + + static bool cpuidle_coupled_any_pokes_pending(struct cpuidle_coupled *coupled) +@@ -464,7 +467,8 @@ + return -EINVAL; + + while (coupled->prevent) { +- if (cpuidle_coupled_clear_pokes(dev->cpu)) { ++ cpuidle_coupled_clear_pokes(dev->cpu); ++ if (need_resched()) { + local_irq_enable(); + return entered_state; + } +@@ -502,7 +506,10 @@ + */ + while (!cpuidle_coupled_cpus_waiting(coupled) || + !cpumask_test_cpu(dev->cpu, &cpuidle_coupled_poked)) { +- if (cpuidle_coupled_clear_pokes(dev->cpu)) { ++ if (cpuidle_coupled_clear_pokes(dev->cpu)) ++ continue; ++ ++ if (need_resched()) { + cpuidle_coupled_set_not_waiting(dev->cpu, coupled); + goto out; + } +@@ -516,7 +523,8 @@ + dev->safe_state_index); + } + +- if (cpuidle_coupled_clear_pokes(dev->cpu)) { ++ cpuidle_coupled_clear_pokes(dev->cpu); ++ if (need_resched()) { + cpuidle_coupled_set_not_waiting(dev->cpu, coupled); + goto out; + } +Index: linux-3.10-3.10.11/dummy/rpi_1056_736899ab702dc85345217e124686b661a56ecb6a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1056_736899ab702dc85345217e124686b661a56ecb6a.txt 2014-05-05 12:43:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1057_0fc9593a11f12e1c8cbe28cecf7a0ef3b2797822.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1057_0fc9593a11f12e1c8cbe28cecf7a0ef3b2797822.patch --- linux-3.10.11/debian/patches/rpi/rpi_1057_0fc9593a11f12e1c8cbe28cecf7a0ef3b2797822.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1057_0fc9593a11f12e1c8cbe28cecf7a0ef3b2797822.patch 2014-05-05 12:43:52.000000000 +0000 @@ -0,0 +1,148 @@ +commit 0fc9593a11f12e1c8cbe28cecf7a0ef3b2797822 +Author: Lorenzo Pieralisi +Date: Thu Apr 18 18:31:35 2013 +0100 + + ARM: dts: at91: cpus/cpu node dts updates + + commit e757a6ee3e6fc1583b12b156588e8583f798d35c upstream. + + This patch updates the in-kernel dts files according to the latest cpus + and cpu bindings updates for ARM. + + Signed-off-by: Lorenzo Pieralisi + Acked-by: Nicolas Ferre + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/at91rm9200.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/at91rm9200.dtsi 2014-05-05 11:51:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/at91rm9200.dtsi 2014-05-05 12:43:51.000000000 +0000 +@@ -35,8 +35,12 @@ + ssc2 = &ssc2; + }; + cpus { +- cpu@0 { ++ #address-cells = <0>; ++ #size-cells = <0>; ++ ++ cpu { + compatible = "arm,arm920t"; ++ device_type = "cpu"; + }; + }; + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9260.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/at91sam9260.dtsi 2014-05-05 12:43:39.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9260.dtsi 2014-05-05 12:43:51.000000000 +0000 +@@ -32,8 +32,12 @@ + ssc0 = &ssc0; + }; + cpus { +- cpu@0 { +- compatible = "arm,arm926ejs"; ++ #address-cells = <0>; ++ #size-cells = <0>; ++ ++ cpu { ++ compatible = "arm,arm926ej-s"; ++ device_type = "cpu"; + }; + }; + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9263.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/at91sam9263.dtsi 2014-05-05 11:51:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9263.dtsi 2014-05-05 12:43:51.000000000 +0000 +@@ -29,8 +29,12 @@ + ssc1 = &ssc1; + }; + cpus { +- cpu@0 { +- compatible = "arm,arm926ejs"; ++ #address-cells = <0>; ++ #size-cells = <0>; ++ ++ cpu { ++ compatible = "arm,arm926ej-s"; ++ device_type = "cpu"; + }; + }; + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9g45.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/at91sam9g45.dtsi 2014-05-05 11:51:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9g45.dtsi 2014-05-05 12:43:51.000000000 +0000 +@@ -35,8 +35,12 @@ + ssc1 = &ssc1; + }; + cpus { +- cpu@0 { +- compatible = "arm,arm926ejs"; ++ #address-cells = <0>; ++ #size-cells = <0>; ++ ++ cpu { ++ compatible = "arm,arm926ej-s"; ++ device_type = "cpu"; + }; + }; + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9n12.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/at91sam9n12.dtsi 2014-05-05 11:51:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9n12.dtsi 2014-05-05 12:43:51.000000000 +0000 +@@ -31,8 +31,12 @@ + ssc0 = &ssc0; + }; + cpus { +- cpu@0 { +- compatible = "arm,arm926ejs"; ++ #address-cells = <0>; ++ #size-cells = <0>; ++ ++ cpu { ++ compatible = "arm,arm926ej-s"; ++ device_type = "cpu"; + }; + }; + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9x5.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/at91sam9x5.dtsi 2014-05-05 11:51:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/at91sam9x5.dtsi 2014-05-05 12:43:51.000000000 +0000 +@@ -33,8 +33,12 @@ + ssc0 = &ssc0; + }; + cpus { +- cpu@0 { +- compatible = "arm,arm926ejs"; ++ #address-cells = <0>; ++ #size-cells = <0>; ++ ++ cpu { ++ compatible = "arm,arm926ej-s"; ++ device_type = "cpu"; + }; + }; + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sama5d3.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sama5d3.dtsi 2014-05-05 11:51:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sama5d3.dtsi 2014-05-05 12:43:51.000000000 +0000 +@@ -36,7 +36,9 @@ + }; + cpus { + cpu@0 { ++ device_type = "cpu"; + compatible = "arm,cortex-a5"; ++ reg = <0x0>; + }; + }; + +Index: linux-3.10-3.10.11/dummy/rpi_1057_0fc9593a11f12e1c8cbe28cecf7a0ef3b2797822.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1057_0fc9593a11f12e1c8cbe28cecf7a0ef3b2797822.txt 2014-05-05 12:43:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1058_ed58fb796257c770cd9f1de07b49ed9a054f93eb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1058_ed58fb796257c770cd9f1de07b49ed9a054f93eb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1058_ed58fb796257c770cd9f1de07b49ed9a054f93eb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1058_ed58fb796257c770cd9f1de07b49ed9a054f93eb.patch 2014-05-05 12:43:53.000000000 +0000 @@ -0,0 +1,49 @@ +commit ed58fb796257c770cd9f1de07b49ed9a054f93eb +Author: Lorenzo Pieralisi +Date: Thu Apr 18 18:41:57 2013 +0100 + + ARM: dts: sunxi: cpus/cpu nodes dts updates + + commit 14c44aa541744d4cf06db89c27a1e6df293c64d5 upstream. + + This patch updates the in-kernel dts files according to the latest cpus + and cpu bindings updates for ARM. + + Signed-off-by: Lorenzo Pieralisi + Acked-by: Maxime Ripard + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 12:42:45.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 12:43:52.000000000 +0000 +@@ -17,7 +17,9 @@ + + cpus { + cpu@0 { ++ device_type = "cpu"; + compatible = "arm,cortex-a8"; ++ reg = <0x0>; + }; + }; + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun5i-a13.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun5i-a13.dtsi 2014-05-05 11:51:42.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun5i-a13.dtsi 2014-05-05 12:43:52.000000000 +0000 +@@ -18,7 +18,9 @@ + + cpus { + cpu@0 { ++ device_type = "cpu"; + compatible = "arm,cortex-a8"; ++ reg = <0x0>; + }; + }; + +Index: linux-3.10-3.10.11/dummy/rpi_1058_ed58fb796257c770cd9f1de07b49ed9a054f93eb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1058_ed58fb796257c770cd9f1de07b49ed9a054f93eb.txt 2014-05-05 12:43:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1059_464de2dc1539e6355fad1342ad106f08f7642edd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1059_464de2dc1539e6355fad1342ad106f08f7642edd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1059_464de2dc1539e6355fad1342ad106f08f7642edd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1059_464de2dc1539e6355fad1342ad106f08f7642edd.patch 2014-05-05 12:43:54.000000000 +0000 @@ -0,0 +1,65 @@ +commit 464de2dc1539e6355fad1342ad106f08f7642edd +Author: Arnd Bergmann +Date: Mon Jun 10 16:48:36 2013 +0200 + + ARM: dts: add missing cpu #address-cell values + + commit 8b2efa896cc618e055e90c9d9600e7c8388ae3b7 upstream. + + A recent series has added CPU numbers to a lot of dts files, + but unfortunately in a few cases the #address-cells + and #size-cells values are missing, which causes build warnings. + This adds the missing ones for sunxi and sama5 that I found + through build testing. + + Signed-off-by: Arnd Bergmann + Cc: Lorenzo Pieralisi + Cc: Maxime Ripard + Cc: Nicolas Ferre + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sama5d3.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sama5d3.dtsi 2014-05-05 12:43:51.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sama5d3.dtsi 2014-05-05 12:43:53.000000000 +0000 +@@ -35,6 +35,8 @@ + ssc1 = &ssc1; + }; + cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 12:43:52.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun4i-a10.dtsi 2014-05-05 12:43:53.000000000 +0000 +@@ -16,6 +16,8 @@ + interrupt-parent = <&intc>; + + cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a8"; +Index: linux-3.10-3.10.11/arch/arm/boot/dts/sun5i-a13.dtsi +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/sun5i-a13.dtsi 2014-05-05 12:43:52.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/sun5i-a13.dtsi 2014-05-05 12:43:53.000000000 +0000 +@@ -17,6 +17,8 @@ + interrupt-parent = <&intc>; + + cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a8"; +Index: linux-3.10-3.10.11/dummy/rpi_1059_464de2dc1539e6355fad1342ad106f08f7642edd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1059_464de2dc1539e6355fad1342ad106f08f7642edd.txt 2014-05-05 12:43:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1060_008fe511c11fa20d1060c9e2ddb9c829ac44e0a7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1060_008fe511c11fa20d1060c9e2ddb9c829ac44e0a7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1060_008fe511c11fa20d1060c9e2ddb9c829ac44e0a7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1060_008fe511c11fa20d1060c9e2ddb9c829ac44e0a7.patch 2014-05-05 12:43:55.000000000 +0000 @@ -0,0 +1,150 @@ +commit 008fe511c11fa20d1060c9e2ddb9c829ac44e0a7 +Author: Christoffer Dall +Date: Mon Aug 5 18:08:41 2013 -0700 + + ARM: KVM: Fix 64-bit coprocessor handling + + commit 240e99cbd00aa541b572480e3ea7ecb0d480bc79 upstream. + + The PAR was exported as CRn == 7 and CRm == 0, but in fact the primary + coprocessor register number was determined by CRm for 64-bit coprocessor + registers as the user space API was modeled after the coprocessor + access instructions (see the ARM ARM rev. C - B3-1445). + + However, just changing the CRn to CRm breaks the sorting check when + booting the kernel, because the internal kernel logic always treats CRn + as the primary register number, and it makes the table sorting + impossible to understand for humans. + + Alternatively we could change the logic to always have CRn == CRm, but + that becomes unclear in the number of ways we do look up of a coprocessor + register. We could also have a separate 64-bit table but that feels + somewhat over-engineered. Instead, keep CRn the primary representation + of the primary coproc. register number in-kernel and always export the + primary number as CRm as per the existing user space ABI. + + Note: The TTBR registers just magically worked because they happened to + follow the CRn(0) regs and were considered CRn(0) in the in-kernel + representation. + + Signed-off-by: Christoffer Dall + Signed-off-by: Kim Phillips + Cc: Gleb Natapov + Cc: Paolo Bonzini + Cc: Russell King + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/kvm/coproc.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/kvm/coproc.c 2014-05-05 11:51:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/kvm/coproc.c 2014-05-05 12:43:54.000000000 +0000 +@@ -146,7 +146,11 @@ + #define access_pmintenclr pm_fake + + /* Architected CP15 registers. +- * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 ++ * CRn denotes the primary register number, but is copied to the CRm in the ++ * user space API for 64-bit register access in line with the terminology used ++ * in the ARM ARM. ++ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit ++ * registers preceding 32-bit ones. + */ + static const struct coproc_reg cp15_regs[] = { + /* CSSELR: swapped by interrupt.S. */ +@@ -154,8 +158,8 @@ + NULL, reset_unknown, c0_CSSELR }, + + /* TTBR0/TTBR1: swapped by interrupt.S. */ +- { CRm( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 }, +- { CRm( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 }, ++ { CRm64( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 }, ++ { CRm64( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 }, + + /* TTBCR: swapped by interrupt.S. */ + { CRn( 2), CRm( 0), Op1( 0), Op2( 2), is32, +@@ -182,7 +186,7 @@ + NULL, reset_unknown, c6_IFAR }, + + /* PAR swapped by interrupt.S */ +- { CRn( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR }, ++ { CRm64( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR }, + + /* + * DC{C,I,CI}SW operations: +@@ -399,12 +403,13 @@ + | KVM_REG_ARM_OPC1_MASK)) + return false; + params->is_64bit = true; +- params->CRm = ((id & KVM_REG_ARM_CRM_MASK) ++ /* CRm to CRn: see cp15_to_index for details */ ++ params->CRn = ((id & KVM_REG_ARM_CRM_MASK) + >> KVM_REG_ARM_CRM_SHIFT); + params->Op1 = ((id & KVM_REG_ARM_OPC1_MASK) + >> KVM_REG_ARM_OPC1_SHIFT); + params->Op2 = 0; +- params->CRn = 0; ++ params->CRm = 0; + return true; + default: + return false; +@@ -898,7 +903,14 @@ + if (reg->is_64) { + val |= KVM_REG_SIZE_U64; + val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT); +- val |= (reg->CRm << KVM_REG_ARM_CRM_SHIFT); ++ /* ++ * CRn always denotes the primary coproc. reg. nr. for the ++ * in-kernel representation, but the user space API uses the ++ * CRm for the encoding, because it is modelled after the ++ * MRRC/MCRR instructions: see the ARM ARM rev. c page ++ * B3-1445 ++ */ ++ val |= (reg->CRn << KVM_REG_ARM_CRM_SHIFT); + } else { + val |= KVM_REG_SIZE_U32; + val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT); +Index: linux-3.10-3.10.11/arch/arm/kvm/coproc.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/kvm/coproc.h 2014-05-05 11:51:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/kvm/coproc.h 2014-05-05 12:43:54.000000000 +0000 +@@ -135,6 +135,8 @@ + return -1; + if (i1->CRn != i2->CRn) + return i1->CRn - i2->CRn; ++ if (i1->is_64 != i2->is_64) ++ return i2->is_64 - i1->is_64; + if (i1->CRm != i2->CRm) + return i1->CRm - i2->CRm; + if (i1->Op1 != i2->Op1) +@@ -145,6 +147,7 @@ + + #define CRn(_x) .CRn = _x + #define CRm(_x) .CRm = _x ++#define CRm64(_x) .CRn = _x, .CRm = 0 + #define Op1(_x) .Op1 = _x + #define Op2(_x) .Op2 = _x + #define is64 .is_64 = true +Index: linux-3.10-3.10.11/arch/arm/kvm/coproc_a15.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/kvm/coproc_a15.c 2014-05-05 11:51:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/kvm/coproc_a15.c 2014-05-05 12:43:54.000000000 +0000 +@@ -114,7 +114,11 @@ + + /* + * A15-specific CP15 registers. +- * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 ++ * CRn denotes the primary register number, but is copied to the CRm in the ++ * user space API for 64-bit register access in line with the terminology used ++ * in the ARM ARM. ++ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit ++ * registers preceding 32-bit ones. + */ + static const struct coproc_reg a15_regs[] = { + /* MPIDR: we use VMPIDR for guest access. */ +Index: linux-3.10-3.10.11/dummy/rpi_1060_008fe511c11fa20d1060c9e2ddb9c829ac44e0a7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1060_008fe511c11fa20d1060c9e2ddb9c829ac44e0a7.txt 2014-05-05 12:43:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1061_1f96d83b38937294584ede9473c2b2961528f287.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1061_1f96d83b38937294584ede9473c2b2961528f287.patch --- linux-3.10.11/debian/patches/rpi/rpi_1061_1f96d83b38937294584ede9473c2b2961528f287.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1061_1f96d83b38937294584ede9473c2b2961528f287.patch 2014-05-05 12:43:56.000000000 +0000 @@ -0,0 +1,39 @@ +commit 1f96d83b38937294584ede9473c2b2961528f287 +Author: Will Deacon +Date: Tue Aug 20 11:47:41 2013 +0100 + + arm64: perf: fix group validation when using enable_on_exec + + commit 8455e6ec70f33b0e8c3ffd47067e00481f09f454 upstream. + + This is a port of cb2d8b342aa0 ("ARM: 7698/1: perf: fix group validation + when using enable_on_exec") to arm64, which fixes the event validation + checking so that events in the OFF state are still considered when + enable_on_exec is true. + + Signed-off-by: Will Deacon + Signed-off-by: Catalin Marinas + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm64/kernel/perf_event.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm64/kernel/perf_event.c 2014-05-05 11:51:41.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm64/kernel/perf_event.c 2014-05-05 12:43:55.000000000 +0000 +@@ -325,7 +325,10 @@ + if (is_software_event(event)) + return 1; + +- if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) ++ if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) ++ return 1; ++ ++ if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) + return 1; + + return armpmu->get_event_idx(hw_events, &fake_event) >= 0; +Index: linux-3.10-3.10.11/dummy/rpi_1061_1f96d83b38937294584ede9473c2b2961528f287.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1061_1f96d83b38937294584ede9473c2b2961528f287.txt 2014-05-05 12:43:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1062_0fe9a0dc92a64c088e76fcd3d35b2ba36b4d7f3c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1062_0fe9a0dc92a64c088e76fcd3d35b2ba36b4d7f3c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1062_0fe9a0dc92a64c088e76fcd3d35b2ba36b4d7f3c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1062_0fe9a0dc92a64c088e76fcd3d35b2ba36b4d7f3c.patch 2014-05-05 12:43:56.000000000 +0000 @@ -0,0 +1,35 @@ +commit 0fe9a0dc92a64c088e76fcd3d35b2ba36b4d7f3c +Author: Will Deacon +Date: Tue Aug 20 11:47:42 2013 +0100 + + arm64: perf: fix ARMv8 EVTYPE_MASK to include NSH bit + + commit 178cd9ce377232518ec17ff2ecab2e80fa60784c upstream. + + This is a port of f2fe09b055e2 ("ARM: 7663/1: perf: fix ARMv7 EVTYPE_MASK + to include NSH bit") to arm64, which fixes the broken evtype mask to + include the NSH bit, allowing profiling at EL2. + + Signed-off-by: Will Deacon + Signed-off-by: Catalin Marinas + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm64/kernel/perf_event.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm64/kernel/perf_event.c 2014-05-05 12:43:55.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm64/kernel/perf_event.c 2014-05-05 12:43:56.000000000 +0000 +@@ -784,7 +784,7 @@ + /* + * PMXEVTYPER: Event selection reg + */ +-#define ARMV8_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */ ++#define ARMV8_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */ + #define ARMV8_EVTYPE_EVENT 0xff /* Mask for EVENT bits */ + + /* +Index: linux-3.10-3.10.11/dummy/rpi_1062_0fe9a0dc92a64c088e76fcd3d35b2ba36b4d7f3c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1062_0fe9a0dc92a64c088e76fcd3d35b2ba36b4d7f3c.txt 2014-05-05 12:43:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1063_3e4d5c23583779763a3393ba1bcc2ad4ba481fa2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1063_3e4d5c23583779763a3393ba1bcc2ad4ba481fa2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1063_3e4d5c23583779763a3393ba1bcc2ad4ba481fa2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1063_3e4d5c23583779763a3393ba1bcc2ad4ba481fa2.patch 2014-05-05 12:43:57.000000000 +0000 @@ -0,0 +1,104 @@ +commit 3e4d5c23583779763a3393ba1bcc2ad4ba481fa2 +Author: Peter Maydell +Date: Thu Aug 22 17:47:48 2013 +0100 + + ARM: PCI: versatile: Fix map_irq function to match hardware + + commit f9b71fef12f0d6ac5c7051cfd87f7700f78c56b6 upstream. + + The PCI controller code for the Versatile board has never had the + correct IRQ mapping for hardware. For many years it had an odd + mapping ("all interrupts are int 27") which aligned with the + equivalent bug in QEMU. However as of commit 1bc39ac5dab265 + the mapping changed and no longer matched either hardware or QEMU, + with the result that any PCI card beyond the first in QEMU would + not have functioning interrupts; for example a boot with a SCSI + controller would time out as follows: + + ------------ + sym0: <895a> rev 0x0 at pci 0000:00:0d.0 irq 92 + sym0: SCSI BUS has been reset. + scsi0 : sym-2.2.3 + [...] + scsi 0:0:0:0: ABORT operation started + scsi 0:0:0:0: ABORT operation timed-out. + scsi 0:0:0:0: DEVICE RESET operation started + scsi 0:0:0:0: DEVICE RESET operation timed-out. + scsi 0:0:0:0: BUS RESET operation started + scsi 0:0:0:0: BUS RESET operation timed-out. + scsi 0:0:0:0: HOST RESET operation started + sym0: SCSI BUS has been reset + ------------ + + Fix the mapping so that it matches real hardware (checked against the + schematics for PB926 and backplane, and tested against the hardware). + This allows PCI cards using interrupts to work on hardware for the + first time; this change will also work with QEMU 1.5 or later, where + the equivalent bugs in the modelling of the hardware have been fixed. + + Although QEMU will attempt to autodetect whether the kernel is + expecting the long-standing "everything is int 27" mapping or the one + hardware has, for certainty we force it into "definitely behave like + hardware mode"; this will avoid unexpected surprises later if we + implement sparse irqs. This is harmless on hardware. + + Thanks to Paul Gortmaker for bisecting the problem and finding an initial + solution, to Russell King for providing the correct interrupt mapping, + and to Guenter Roeck for providing an initial version of this patch + and prodding me into relocating the hardware and retesting everything. + + Signed-off-by: Peter Maydell + Reviewed-by: Linus Walleij + Signed-off-by: Kevin Hilman + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/mach-versatile/pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mach-versatile/pci.c 2014-05-05 11:51:40.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-versatile/pci.c 2014-05-05 12:43:57.000000000 +0000 +@@ -295,6 +295,19 @@ + __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2); + + /* ++ * For many years the kernel and QEMU were symbiotically buggy ++ * in that they both assumed the same broken IRQ mapping. ++ * QEMU therefore attempts to auto-detect old broken kernels ++ * so that they still work on newer QEMU as they did on old ++ * QEMU. Since we now use the correct (ie matching-hardware) ++ * IRQ mapping we write a definitely different value to a ++ * PCI_INTERRUPT_LINE register to tell QEMU that we expect ++ * real hardware behaviour and it need not be backwards ++ * compatible for us. This write is harmless on real hardware. ++ */ ++ __raw_writel(0, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE); ++ ++ /* + * Do not to map Versatile FPGA PCI device into memory space + */ + pci_slot_ignore |= (1 << myslot); +@@ -327,13 +340,13 @@ + { + int irq; + +- /* slot, pin, irq +- * 24 1 IRQ_SIC_PCI0 +- * 25 1 IRQ_SIC_PCI1 +- * 26 1 IRQ_SIC_PCI2 +- * 27 1 IRQ_SIC_PCI3 ++ /* ++ * Slot INTA INTB INTC INTD ++ * 31 PCI1 PCI2 PCI3 PCI0 ++ * 30 PCI0 PCI1 PCI2 PCI3 ++ * 29 PCI3 PCI0 PCI1 PCI2 + */ +- irq = IRQ_SIC_PCI0 + ((slot - 24 + pin - 1) & 3); ++ irq = IRQ_SIC_PCI0 + ((slot + 2 + pin - 1) & 3); + + return irq; + } +Index: linux-3.10-3.10.11/dummy/rpi_1063_3e4d5c23583779763a3393ba1bcc2ad4ba481fa2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1063_3e4d5c23583779763a3393ba1bcc2ad4ba481fa2.txt 2014-05-05 12:43:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1064_d6e770beb3489067fc68e0d468c99f0e44a42052.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1064_d6e770beb3489067fc68e0d468c99f0e44a42052.patch --- linux-3.10.11/debian/patches/rpi/rpi_1064_d6e770beb3489067fc68e0d468c99f0e44a42052.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1064_d6e770beb3489067fc68e0d468c99f0e44a42052.patch 2014-05-05 12:43:58.000000000 +0000 @@ -0,0 +1,106 @@ +commit d6e770beb3489067fc68e0d468c99f0e44a42052 +Author: Peter Maydell +Date: Thu Aug 22 17:47:49 2013 +0100 + + ARM: PCI: versatile: Fix PCI I/O + + commit 829f9fedee30cde2ec15e88d57ec11074db791e2 upstream. + + The versatile PCI controller code was confused between the + PCI I/O window (at 0x43000000) and the first PCI memory + window (at 0x44000000). Pass the correct base address to + pci_remap_io() so that PCI I/O accesses work. + + Since the first PCI memory window isn't used at all (it's + an odd size), rename the associated variables and labels + so that it's clear that it isn't related to the I/O window. + + This has been tested and confirmed to fix PCI I/O accesses + both on physical PB926+PCI backplane hardware and on QEMU. + + Signed-off-by: Peter Maydell + Reviewed-by: Linus Walleij + Signed-off-by: Kevin Hilman + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/mach-versatile/include/mach/platform.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mach-versatile/include/mach/platform.h 2014-05-05 11:51:40.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-versatile/include/mach/platform.h 2014-05-05 12:43:57.000000000 +0000 +@@ -231,12 +231,14 @@ + /* PCI space */ + #define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */ + #define VERSATILE_PCI_CFG_BASE 0x42000000 ++#define VERSATILE_PCI_IO_BASE 0x43000000 + #define VERSATILE_PCI_MEM_BASE0 0x44000000 + #define VERSATILE_PCI_MEM_BASE1 0x50000000 + #define VERSATILE_PCI_MEM_BASE2 0x60000000 + /* Sizes of above maps */ + #define VERSATILE_PCI_BASE_SIZE 0x01000000 + #define VERSATILE_PCI_CFG_BASE_SIZE 0x02000000 ++#define VERSATILE_PCI_IO_BASE_SIZE 0x01000000 + #define VERSATILE_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */ + #define VERSATILE_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */ + #define VERSATILE_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */ +Index: linux-3.10-3.10.11/arch/arm/mach-versatile/pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mach-versatile/pci.c 2014-05-05 12:43:57.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-versatile/pci.c 2014-05-05 12:43:57.000000000 +0000 +@@ -170,8 +170,8 @@ + .write = versatile_write_config, + }; + +-static struct resource io_mem = { +- .name = "PCI I/O space", ++static struct resource unused_mem = { ++ .name = "PCI unused", + .start = VERSATILE_PCI_MEM_BASE0, + .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, + .flags = IORESOURCE_MEM, +@@ -195,9 +195,9 @@ + { + int ret = 0; + +- ret = request_resource(&iomem_resource, &io_mem); ++ ret = request_resource(&iomem_resource, &unused_mem); + if (ret) { +- printk(KERN_ERR "PCI: unable to allocate I/O " ++ printk(KERN_ERR "PCI: unable to allocate unused " + "memory region (%d)\n", ret); + goto out; + } +@@ -205,7 +205,7 @@ + if (ret) { + printk(KERN_ERR "PCI: unable to allocate non-prefetchable " + "memory region (%d)\n", ret); +- goto release_io_mem; ++ goto release_unused_mem; + } + ret = request_resource(&iomem_resource, &pre_mem); + if (ret) { +@@ -225,8 +225,8 @@ + + release_non_mem: + release_resource(&non_mem); +- release_io_mem: +- release_resource(&io_mem); ++ release_unused_mem: ++ release_resource(&unused_mem); + out: + return ret; + } +@@ -246,7 +246,7 @@ + goto out; + } + +- ret = pci_ioremap_io(0, VERSATILE_PCI_MEM_BASE0); ++ ret = pci_ioremap_io(0, VERSATILE_PCI_IO_BASE); + if (ret) + goto out; + +Index: linux-3.10-3.10.11/dummy/rpi_1064_d6e770beb3489067fc68e0d468c99f0e44a42052.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1064_d6e770beb3489067fc68e0d468c99f0e44a42052.txt 2014-05-05 12:43:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1065_d9a004a0a3bb56b62f36a460ec61c76112dd8442.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1065_d9a004a0a3bb56b62f36a460ec61c76112dd8442.patch --- linux-3.10.11/debian/patches/rpi/rpi_1065_d9a004a0a3bb56b62f36a460ec61c76112dd8442.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1065_d9a004a0a3bb56b62f36a460ec61c76112dd8442.patch 2014-05-05 12:43:59.000000000 +0000 @@ -0,0 +1,43 @@ +commit d9a004a0a3bb56b62f36a460ec61c76112dd8442 +Author: Peter Maydell +Date: Thu Aug 22 17:47:50 2013 +0100 + + ARM: PCI: versatile: Fix SMAP register offsets + + commit 99f2b130370b904ca5300079243fdbcafa2c708b upstream. + + The SMAP register offsets in the versatile PCI controller code were + all off by four. (This didn't have any observable bad effects + because on this board PHYS_OFFSET is zero, and (a) writing zero to + the flags register at offset 0x10 has no effect and (b) the reset + value of the SMAP register is zero anyway, so failing to write SMAP2 + didn't matter.) + + Signed-off-by: Peter Maydell + Reviewed-by: Linus Walleij + Signed-off-by: Kevin Hilman + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/mach-versatile/pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mach-versatile/pci.c 2014-05-05 12:43:57.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-versatile/pci.c 2014-05-05 12:43:58.000000000 +0000 +@@ -43,9 +43,9 @@ + #define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0) + #define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4) + #define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) +-#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10) +-#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) +-#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) ++#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) ++#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) ++#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c) + #define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc) + + #define DEVICE_ID_OFFSET 0x00 +Index: linux-3.10-3.10.11/dummy/rpi_1065_d9a004a0a3bb56b62f36a460ec61c76112dd8442.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1065_d9a004a0a3bb56b62f36a460ec61c76112dd8442.txt 2014-05-05 12:43:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1066_faa94b0365522a939cd10d05d526a355a7eeaadf.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1066_faa94b0365522a939cd10d05d526a355a7eeaadf.patch --- linux-3.10.11/debian/patches/rpi/rpi_1066_faa94b0365522a939cd10d05d526a355a7eeaadf.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1066_faa94b0365522a939cd10d05d526a355a7eeaadf.patch 2014-05-05 12:44:00.000000000 +0000 @@ -0,0 +1,38 @@ +commit faa94b0365522a939cd10d05d526a355a7eeaadf +Author: Paul Mackerras +Date: Tue Aug 6 14:13:44 2013 +1000 + + KVM: PPC: Book3S: Fix compile error in XICS emulation + + commit 7bfa9ad55d691f2b836b576769b11eca2cf50816 upstream. + + Commit 8e44ddc3f3 ("powerpc/kvm/book3s: Add support for H_IPOLL and + H_XIRR_X in XICS emulation") added a call to get_tb() but didn't + include the header that defines it, and on some configs this means + book3s_xics.c fails to compile: + + arch/powerpc/kvm/book3s_xics.c: In function ‘kvmppc_xics_hcall’: + arch/powerpc/kvm/book3s_xics.c:812:3: error: implicit declaration of function ‘get_tb’ [-Werror=implicit-function-declaration] + + Signed-off-by: Paul Mackerras + Signed-off-by: Alexander Graf + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/kvm/book3s_xics.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kvm/book3s_xics.c 2014-05-05 11:51:39.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kvm/book3s_xics.c 2014-05-05 12:43:59.000000000 +0000 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include + #include +Index: linux-3.10-3.10.11/dummy/rpi_1066_faa94b0365522a939cd10d05d526a355a7eeaadf.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1066_faa94b0365522a939cd10d05d526a355a7eeaadf.txt 2014-05-05 12:43:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1067_a6025b95e6d05833f19eaca2f4e181bf77a854ed.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1067_a6025b95e6d05833f19eaca2f4e181bf77a854ed.patch --- linux-3.10.11/debian/patches/rpi/rpi_1067_a6025b95e6d05833f19eaca2f4e181bf77a854ed.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1067_a6025b95e6d05833f19eaca2f4e181bf77a854ed.patch 2014-05-05 12:44:01.000000000 +0000 @@ -0,0 +1,88 @@ +commit a6025b95e6d05833f19eaca2f4e181bf77a854ed +Author: Sarah Sharp +Date: Thu Aug 8 10:08:34 2013 -0700 + + xhci-plat: Don't enable legacy PCI interrupts. + + commit 52fb61250a7a132b0cfb9f4a1060a1f3c49e5a25 upstream. + + The xHCI platform driver calls into usb_add_hcd to register the irq for + its platform device. It does not want the xHCI generic driver to + register an interrupt for it at all. The original code did that by + setting the XHCI_BROKEN_MSI quirk, which tells the xHCI driver to not + enable MSI or MSI-X for a PCI host. + + Unfortunately, if CONFIG_PCI is enabled, and CONFIG_USB_DW3 is enabled, + the xHCI generic driver will attempt to register a legacy PCI interrupt + for the xHCI platform device in xhci_try_enable_msi(). This will result + in a bogus irq being registered, since the underlying device is a + platform_device, not a pci_device, and thus the pci_device->irq pointer + will be bogus. + + Add a new quirk, XHCI_PLAT, so that the xHCI generic driver can + distinguish between a PCI device that can't handle MSI or MSI-X, and a + platform device that should not have its interrupts touched at all. + This quirk may be useful in the future, in case other corner cases like + this arise. + + This patch should be backported to kernels as old as 3.9, that + contain the commit 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb "USB: xhci: + correctly enable interrupts". + + Signed-off-by: Sarah Sharp + Reported-by: Yu Y Wang + Tested-by: Yu Y Wang + Reviewed-by: Felipe Balbi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/xhci-plat.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci-plat.c 2014-05-05 11:51:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci-plat.c 2014-05-05 12:44:00.000000000 +0000 +@@ -24,7 +24,7 @@ + * here that the generic code does not try to make a pci_dev from our + * dev struct in order to setup MSI + */ +- xhci->quirks |= XHCI_BROKEN_MSI; ++ xhci->quirks |= XHCI_PLAT; + } + + /* called during probe() after chip reset completes */ +Index: linux-3.10-3.10.11/drivers/usb/host/xhci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci.c 2014-05-05 11:51:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci.c 2014-05-05 12:44:00.000000000 +0000 +@@ -342,9 +342,14 @@ + static int xhci_try_enable_msi(struct usb_hcd *hcd) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); +- struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); ++ struct pci_dev *pdev; + int ret; + ++ /* The xhci platform device has set up IRQs through usb_add_hcd. */ ++ if (xhci->quirks & XHCI_PLAT) ++ return 0; ++ ++ pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); + /* + * Some Fresco Logic host controllers advertise MSI, but fail to + * generate interrupts. Don't even try to enable MSI. +Index: linux-3.10-3.10.11/drivers/usb/host/xhci.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci.h 2014-05-05 11:51:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci.h 2014-05-05 12:44:00.000000000 +0000 +@@ -1516,6 +1516,7 @@ + #define XHCI_SPURIOUS_REBOOT (1 << 13) + #define XHCI_COMP_MODE_QUIRK (1 << 14) + #define XHCI_AVOID_BEI (1 << 15) ++#define XHCI_PLAT (1 << 16) + unsigned int num_active_eps; + unsigned int limit_active_eps; + /* There are two roothubs to keep track of bus suspend info for */ +Index: linux-3.10-3.10.11/dummy/rpi_1067_a6025b95e6d05833f19eaca2f4e181bf77a854ed.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1067_a6025b95e6d05833f19eaca2f4e181bf77a854ed.txt 2014-05-05 12:44:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1068_54d8c40da1d8763cfa5699516626f8ed37db3eed.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1068_54d8c40da1d8763cfa5699516626f8ed37db3eed.patch --- linux-3.10.11/debian/patches/rpi/rpi_1068_54d8c40da1d8763cfa5699516626f8ed37db3eed.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1068_54d8c40da1d8763cfa5699516626f8ed37db3eed.patch 2014-05-05 12:44:01.000000000 +0000 @@ -0,0 +1,82 @@ +commit 54d8c40da1d8763cfa5699516626f8ed37db3eed +Author: Shawn Nematbakhsh +Date: Mon Aug 19 10:36:13 2013 -0700 + + usb: xhci: Disable runtime PM suspend for quirky controllers + + commit c8476fb855434c733099079063990e5bfa7ecad6 upstream. + + If a USB controller with XHCI_RESET_ON_RESUME goes to runtime suspend, + a reset will be performed upon runtime resume. Any previously suspended + devices attached to the controller will be re-enumerated at this time. + This will cause problems, for example, if an open system call on the + device triggered the resume (the open call will fail). + + Note that this change is only relevant when persist_enabled is not set + for USB devices. + + This patch should be backported to kernels as old as 3.0, that + contain the commit c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 "xhci: Add + reset on resume quirk for asrock p67 host". + + Signed-off-by: Shawn Nematbakhsh + Signed-off-by: Sarah Sharp + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/xhci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci.c 2014-05-05 12:44:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci.c 2014-05-05 12:44:01.000000000 +0000 +@@ -3511,10 +3511,21 @@ + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *virt_dev; ++ struct device *dev = hcd->self.controller; + unsigned long flags; + u32 state; + int i, ret; + ++#ifndef CONFIG_USB_DEFAULT_PERSIST ++ /* ++ * We called pm_runtime_get_noresume when the device was attached. ++ * Decrement the counter here to allow controller to runtime suspend ++ * if no devices remain. ++ */ ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ pm_runtime_put_noidle(dev); ++#endif ++ + ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); + /* If the host is halted due to driver unload, we still need to free the + * device. +@@ -3586,6 +3597,7 @@ + int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ struct device *dev = hcd->self.controller; + unsigned long flags; + int timeleft; + int ret; +@@ -3638,6 +3650,16 @@ + goto disable_slot; + } + udev->slot_id = xhci->slot_id; ++ ++#ifndef CONFIG_USB_DEFAULT_PERSIST ++ /* ++ * If resetting upon resume, we can't put the controller into runtime ++ * suspend if there is a device attached. ++ */ ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ pm_runtime_get_noresume(dev); ++#endif ++ + /* Is this a LS or FS device under a HS hub? */ + /* Hub or peripherial? */ + return 1; +Index: linux-3.10-3.10.11/dummy/rpi_1068_54d8c40da1d8763cfa5699516626f8ed37db3eed.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1068_54d8c40da1d8763cfa5699516626f8ed37db3eed.txt 2014-05-05 12:44:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1069_734b2fe93f4bcce29f7d971a106ea94e263e8676.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1069_734b2fe93f4bcce29f7d971a106ea94e263e8676.patch --- linux-3.10.11/debian/patches/rpi/rpi_1069_734b2fe93f4bcce29f7d971a106ea94e263e8676.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1069_734b2fe93f4bcce29f7d971a106ea94e263e8676.patch 2014-05-05 12:44:02.000000000 +0000 @@ -0,0 +1,123 @@ +commit 734b2fe93f4bcce29f7d971a106ea94e263e8676 +Author: Felipe Balbi +Date: Thu Jun 27 10:00:18 2013 +0300 + + usb: dwc3: gadget: don't request IRQs in atomic + + commit b0d7ffd44ba9cd2dfbf299674418193a5f9ed21a upstream. + + We cannot request an IRQ with spinlocks held + as that would trigger a sleeping inside + spinlock warning. + + Reported-by: Stephen Boyd + Signed-off-by: Felipe Balbi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/dwc3/gadget.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/dwc3/gadget.c 2014-05-05 11:51:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/dwc3/gadget.c 2014-05-05 12:44:02.000000000 +0000 +@@ -1508,6 +1508,15 @@ + int irq; + u32 reg; + ++ irq = platform_get_irq(to_platform_device(dwc->dev), 0); ++ ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, ++ IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); ++ if (ret) { ++ dev_err(dwc->dev, "failed to request irq #%d --> %d\n", ++ irq, ret); ++ goto err0; ++ } ++ + spin_lock_irqsave(&dwc->lock, flags); + + if (dwc->gadget_driver) { +@@ -1515,7 +1524,7 @@ + dwc->gadget.name, + dwc->gadget_driver->driver.name); + ret = -EBUSY; +- goto err0; ++ goto err1; + } + + dwc->gadget_driver = driver; +@@ -1551,42 +1560,38 @@ + ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); + if (ret) { + dev_err(dwc->dev, "failed to enable %s\n", dep->name); +- goto err0; ++ goto err2; + } + + dep = dwc->eps[1]; + ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); + if (ret) { + dev_err(dwc->dev, "failed to enable %s\n", dep->name); +- goto err1; ++ goto err3; + } + + /* begin to receive SETUP packets */ + dwc->ep0state = EP0_SETUP_PHASE; + dwc3_ep0_out_start(dwc); + +- irq = platform_get_irq(to_platform_device(dwc->dev), 0); +- ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, +- IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); +- if (ret) { +- dev_err(dwc->dev, "failed to request irq #%d --> %d\n", +- irq, ret); +- goto err1; +- } +- + dwc3_gadget_enable_irq(dwc); + + spin_unlock_irqrestore(&dwc->lock, flags); + + return 0; + +-err1: ++err3: + __dwc3_gadget_ep_disable(dwc->eps[0]); + +-err0: ++err2: + dwc->gadget_driver = NULL; ++ ++err1: + spin_unlock_irqrestore(&dwc->lock, flags); + ++ free_irq(irq, dwc); ++ ++err0: + return ret; + } + +@@ -1600,9 +1605,6 @@ + spin_lock_irqsave(&dwc->lock, flags); + + dwc3_gadget_disable_irq(dwc); +- irq = platform_get_irq(to_platform_device(dwc->dev), 0); +- free_irq(irq, dwc); +- + __dwc3_gadget_ep_disable(dwc->eps[0]); + __dwc3_gadget_ep_disable(dwc->eps[1]); + +@@ -1610,6 +1612,9 @@ + + spin_unlock_irqrestore(&dwc->lock, flags); + ++ irq = platform_get_irq(to_platform_device(dwc->dev), 0); ++ free_irq(irq, dwc); ++ + return 0; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1069_734b2fe93f4bcce29f7d971a106ea94e263e8676.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1069_734b2fe93f4bcce29f7d971a106ea94e263e8676.txt 2014-05-05 12:44:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1070_d5cc290b92837eb9844579e297e969cc7a804da0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1070_d5cc290b92837eb9844579e297e969cc7a804da0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1070_d5cc290b92837eb9844579e297e969cc7a804da0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1070_d5cc290b92837eb9844579e297e969cc7a804da0.patch 2014-05-05 12:44:03.000000000 +0000 @@ -0,0 +1,51 @@ +commit d5cc290b92837eb9844579e297e969cc7a804da0 +Author: Oleg Nesterov +Date: Sun Sep 15 17:50:26 2013 +0200 + + tty: disassociate_ctty() sends the extra SIGCONT + + commit 03e1261778cca782d41a3d8e3945ca88cf93e01e upstream. + + Starting from v3.10 (probably commit f91e2590410b: "tty: Signal + foreground group processes in hangup") disassociate_ctty() sends SIGCONT + if tty && on_exit. This breaks LSB test-suite, in particular test8 in + _exit.c and test40 in sigcon5.c. + + Put the "!on_exit" check back to restore the old behaviour. + + Review by Peter Hurley: + "Yes, this regression was introduced by me in that commit. The effect + of the regression is that ptys will receive a SIGCONT when, in similar + circumstances, ttys would not. + + The fact that two test vectors accidentally tripped over this + regression suggests that some other apps may as well. + + Thanks for catching this" + + Signed-off-by: Oleg Nesterov + Reported-by: Karel Srot + Reviewed-by: Peter Hurley + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/tty/tty_io.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/tty_io.c 2014-05-05 11:51:37.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/tty_io.c 2014-05-05 12:44:03.000000000 +0000 +@@ -850,7 +850,8 @@ + struct pid *tty_pgrp = tty_get_pgrp(tty); + if (tty_pgrp) { + kill_pgrp(tty_pgrp, SIGHUP, on_exit); +- kill_pgrp(tty_pgrp, SIGCONT, on_exit); ++ if (!on_exit) ++ kill_pgrp(tty_pgrp, SIGCONT, on_exit); + put_pid(tty_pgrp); + } + } +Index: linux-3.10-3.10.11/dummy/rpi_1070_d5cc290b92837eb9844579e297e969cc7a804da0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1070_d5cc290b92837eb9844579e297e969cc7a804da0.txt 2014-05-05 12:44:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1071_9b8ace6745bf4722ff9c48089f5b0723478a849b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1071_9b8ace6745bf4722ff9c48089f5b0723478a849b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1071_9b8ace6745bf4722ff9c48089f5b0723478a849b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1071_9b8ace6745bf4722ff9c48089f5b0723478a849b.patch 2014-05-05 12:44:04.000000000 +0000 @@ -0,0 +1,104 @@ +commit 9b8ace6745bf4722ff9c48089f5b0723478a849b +Author: Jeff Layton +Date: Thu Sep 5 08:38:10 2013 -0400 + + cifs: ensure that srv_mutex is held when dealing with ssocket pointer + + commit 73e216a8a42c0ef3d08071705c946c38fdbe12b0 upstream. + + Oleksii reported that he had seen an oops similar to this: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000088 + IP: [] sock_sendmsg+0x93/0xd0 + PGD 0 + Oops: 0000 [#1] PREEMPT SMP + Modules linked in: ipt_MASQUERADE xt_REDIRECT xt_tcpudp iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack ip_tables x_tables carl9170 ath usb_storage f2fs nfnetlink_log nfnetlink md4 cifs dns_resolver hid_generic usbhid hid af_packet uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core videodev rfcomm btusb bnep bluetooth qmi_wwan qcserial cdc_wdm usb_wwan usbnet usbserial mii snd_hda_codec_hdmi snd_hda_codec_realtek iwldvm mac80211 coretemp intel_powerclamp kvm_intel kvm iwlwifi snd_hda_intel cfg80211 snd_hda_codec xhci_hcd e1000e ehci_pci snd_hwdep sdhci_pci snd_pcm ehci_hcd microcode psmouse sdhci thinkpad_acpi mmc_core i2c_i801 pcspkr usbcore hwmon snd_timer snd_page_alloc snd ptp rfkill pps_core soundcore evdev usb_common vboxnetflt(O) vboxdrv(O)Oops#2 Part8 + loop tun binfmt_misc fuse msr acpi_call(O) ipv6 autofs4 + CPU: 0 PID: 21612 Comm: kworker/0:1 Tainted: G W O 3.10.1SIGN #28 + Hardware name: LENOVO 2306CTO/2306CTO, BIOS G2ET92WW (2.52 ) 02/22/2013 + Workqueue: cifsiod cifs_echo_request [cifs] + task: ffff8801e1f416f0 ti: ffff880148744000 task.ti: ffff880148744000 + RIP: 0010:[] [] sock_sendmsg+0x93/0xd0 + RSP: 0000:ffff880148745b00 EFLAGS: 00010246 + RAX: 0000000000000000 RBX: ffff880148745b78 RCX: 0000000000000048 + RDX: ffff880148745c90 RSI: ffff880181864a00 RDI: ffff880148745b78 + RBP: ffff880148745c48 R08: 0000000000000048 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000000 R12: ffff880181864a00 + R13: ffff880148745c90 R14: 0000000000000048 R15: 0000000000000048 + FS: 0000000000000000(0000) GS:ffff88021e200000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000088 CR3: 000000020c42c000 CR4: 00000000001407b0 + Oops#2 Part7 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + Stack: + ffff880148745b30 ffffffff810c4af9 0000004848745b30 ffff880181864a00 + ffffffff81ffbc40 0000000000000000 ffff880148745c90 ffffffff810a5aab + ffff880148745bc0 ffffffff81ffbc40 ffff880148745b60 ffffffff815a9fb8 + Call Trace: + [] ? finish_task_switch+0x49/0xe0 + [] ? lock_timer_base.isra.36+0x2b/0x50 + [] ? _raw_spin_unlock_irqrestore+0x18/0x40 + [] ? try_to_del_timer_sync+0x4f/0x70 + [] ? _raw_spin_unlock_bh+0x1f/0x30 + [] kernel_sendmsg+0x37/0x50 + [] smb_send_kvec+0xd0/0x1d0 [cifs] + [] smb_send_rqst+0x83/0x1f0 [cifs] + [] cifs_call_async+0xec/0x1b0 [cifs] + [] ? free_rsp_buf+0x40/0x40 [cifs] + Oops#2 Part6 + [] SMB2_echo+0x8e/0xb0 [cifs] + [] cifs_echo_request+0x79/0xa0 [cifs] + [] process_one_work+0x173/0x4a0 + [] worker_thread+0x121/0x3a0 + [] ? manage_workers.isra.27+0x2b0/0x2b0 + [] kthread+0xc0/0xd0 + [] ? kthread_create_on_node+0x120/0x120 + [] ret_from_fork+0x7c/0xb0 + [] ? kthread_create_on_node+0x120/0x120 + Code: 84 24 b8 00 00 00 4c 89 f1 4c 89 ea 4c 89 e6 48 89 df 4c 89 60 18 48 c7 40 28 00 00 00 00 4c 89 68 30 44 89 70 14 49 8b 44 24 28 90 88 00 00 00 3d ef fd ff ff 74 10 48 8d 65 e0 5b 41 5c 41 + RIP [] sock_sendmsg+0x93/0xd0 + RSP + CR2: 0000000000000088 + + The client was in the middle of trying to send a frame when the + server->ssocket pointer got zeroed out. In most places, that we access + that pointer, the srv_mutex is held. There's only one spot that I see + that the server->ssocket pointer gets set and the srv_mutex isn't held. + This patch corrects that. + + The upstream bug report was here: + + https://bugzilla.kernel.org/show_bug.cgi?id=60557 + + Reported-by: Oleksii Shevchuk + Signed-off-by: Jeff Layton + Signed-off-by: Steve French + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/cifs/connect.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/cifs/connect.c 2014-05-05 11:51:37.000000000 +0000 ++++ linux-3.10-3.10.11/fs/cifs/connect.c 2014-05-05 12:44:03.000000000 +0000 +@@ -377,6 +377,7 @@ + try_to_freeze(); + + /* we should try only the port we connected to before */ ++ mutex_lock(&server->srv_mutex); + rc = generic_ip_connect(server); + if (rc) { + cifs_dbg(FYI, "reconnect error %d\n", rc); +@@ -388,6 +389,7 @@ + server->tcpStatus = CifsNeedNegotiate; + spin_unlock(&GlobalMid_Lock); + } ++ mutex_unlock(&server->srv_mutex); + } while (server->tcpStatus == CifsNeedReconnect); + + return rc; +Index: linux-3.10-3.10.11/dummy/rpi_1071_9b8ace6745bf4722ff9c48089f5b0723478a849b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1071_9b8ace6745bf4722ff9c48089f5b0723478a849b.txt 2014-05-05 12:44:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1072_af66f40c4cb1d31b3b403d5f9a8471261a0cc945.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1072_af66f40c4cb1d31b3b403d5f9a8471261a0cc945.patch --- linux-3.10.11/debian/patches/rpi/rpi_1072_af66f40c4cb1d31b3b403d5f9a8471261a0cc945.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1072_af66f40c4cb1d31b3b403d5f9a8471261a0cc945.patch 2014-05-05 12:44:05.000000000 +0000 @@ -0,0 +1,34 @@ +commit af66f40c4cb1d31b3b403d5f9a8471261a0cc945 +Author: Pavel Shilovsky +Date: Thu Sep 5 15:04:04 2013 +0400 + + CIFS: Fix a memory leak when a lease break comes + + commit 1a05096de82f3cd672c76389f63964952678506f upstream. + + This happens when we receive a lease break from a server, then + find an appropriate lease key in opened files and schedule the + oplock_break slow work. lw pointer isn't freed in this case. + + Signed-off-by: Pavel Shilovsky + Signed-off-by: Steve French + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/cifs/smb2misc.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/cifs/smb2misc.c 2014-05-05 11:51:37.000000000 +0000 ++++ linux-3.10-3.10.11/fs/cifs/smb2misc.c 2014-05-05 12:44:04.000000000 +0000 +@@ -469,6 +469,7 @@ + + queue_work(cifsiod_wq, &cfile->oplock_break); + ++ kfree(lw); + spin_unlock(&cifs_file_list_lock); + spin_unlock(&cifs_tcp_ses_lock); + return true; +Index: linux-3.10-3.10.11/dummy/rpi_1072_af66f40c4cb1d31b3b403d5f9a8471261a0cc945.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1072_af66f40c4cb1d31b3b403d5f9a8471261a0cc945.txt 2014-05-05 12:44:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1073_b08d9b572074b3d0899349070bb61688ad6eb630.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1073_b08d9b572074b3d0899349070bb61688ad6eb630.patch --- linux-3.10.11/debian/patches/rpi/rpi_1073_b08d9b572074b3d0899349070bb61688ad6eb630.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1073_b08d9b572074b3d0899349070bb61688ad6eb630.patch 2014-05-05 12:44:06.000000000 +0000 @@ -0,0 +1,208 @@ +commit b08d9b572074b3d0899349070bb61688ad6eb630 +Author: Pavel Shilovsky +Date: Thu Sep 5 15:00:07 2013 +0400 + + CIFS: Fix missing lease break + + commit 933d4b36576c951d0371bbfed05ec0135d516a6e upstream. + + If a server sends a lease break to a connection that doesn't have + opens with a lease key specified in the server response, we can't + find an open file to send an ack. Fix this by walking through + all connections we have. + + Signed-off-by: Pavel Shilovsky + Signed-off-by: Steve French + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/cifs/smb2misc.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/cifs/smb2misc.c 2014-05-05 12:44:04.000000000 +0000 ++++ linux-3.10-3.10.11/fs/cifs/smb2misc.c 2014-05-05 12:44:05.000000000 +0000 +@@ -413,19 +413,76 @@ + } + + static bool +-smb2_is_valid_lease_break(char *buffer, struct TCP_Server_Info *server) ++smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp, ++ struct smb2_lease_break_work *lw) ++{ ++ bool found; ++ __u8 lease_state; ++ struct list_head *tmp; ++ struct cifsFileInfo *cfile; ++ struct cifs_pending_open *open; ++ struct cifsInodeInfo *cinode; ++ int ack_req = le32_to_cpu(rsp->Flags & ++ SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED); ++ ++ lease_state = smb2_map_lease_to_oplock(rsp->NewLeaseState); ++ ++ list_for_each(tmp, &tcon->openFileList) { ++ cfile = list_entry(tmp, struct cifsFileInfo, tlist); ++ cinode = CIFS_I(cfile->dentry->d_inode); ++ ++ if (memcmp(cinode->lease_key, rsp->LeaseKey, ++ SMB2_LEASE_KEY_SIZE)) ++ continue; ++ ++ cifs_dbg(FYI, "found in the open list\n"); ++ cifs_dbg(FYI, "lease key match, lease break 0x%d\n", ++ le32_to_cpu(rsp->NewLeaseState)); ++ ++ smb2_set_oplock_level(cinode, lease_state); ++ ++ if (ack_req) ++ cfile->oplock_break_cancelled = false; ++ else ++ cfile->oplock_break_cancelled = true; ++ ++ queue_work(cifsiod_wq, &cfile->oplock_break); ++ kfree(lw); ++ return true; ++ } ++ ++ found = false; ++ list_for_each_entry(open, &tcon->pending_opens, olist) { ++ if (memcmp(open->lease_key, rsp->LeaseKey, ++ SMB2_LEASE_KEY_SIZE)) ++ continue; ++ ++ if (!found && ack_req) { ++ found = true; ++ memcpy(lw->lease_key, open->lease_key, ++ SMB2_LEASE_KEY_SIZE); ++ lw->tlink = cifs_get_tlink(open->tlink); ++ queue_work(cifsiod_wq, &lw->lease_break); ++ } ++ ++ cifs_dbg(FYI, "found in the pending open list\n"); ++ cifs_dbg(FYI, "lease key match, lease break 0x%d\n", ++ le32_to_cpu(rsp->NewLeaseState)); ++ ++ open->oplock = lease_state; ++ } ++ return found; ++} ++ ++static bool ++smb2_is_valid_lease_break(char *buffer) + { + struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer; + struct list_head *tmp, *tmp1, *tmp2; ++ struct TCP_Server_Info *server; + struct cifs_ses *ses; + struct cifs_tcon *tcon; +- struct cifsInodeInfo *cinode; +- struct cifsFileInfo *cfile; +- struct cifs_pending_open *open; + struct smb2_lease_break_work *lw; +- bool found; +- int ack_req = le32_to_cpu(rsp->Flags & +- SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED); + + lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL); + if (!lw) +@@ -438,72 +495,26 @@ + + /* look up tcon based on tid & uid */ + spin_lock(&cifs_tcp_ses_lock); +- list_for_each(tmp, &server->smb_ses_list) { +- ses = list_entry(tmp, struct cifs_ses, smb_ses_list); ++ list_for_each(tmp, &cifs_tcp_ses_list) { ++ server = list_entry(tmp, struct TCP_Server_Info, tcp_ses_list); + +- spin_lock(&cifs_file_list_lock); +- list_for_each(tmp1, &ses->tcon_list) { +- tcon = list_entry(tmp1, struct cifs_tcon, tcon_list); +- +- cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks); +- list_for_each(tmp2, &tcon->openFileList) { +- cfile = list_entry(tmp2, struct cifsFileInfo, +- tlist); +- cinode = CIFS_I(cfile->dentry->d_inode); +- +- if (memcmp(cinode->lease_key, rsp->LeaseKey, +- SMB2_LEASE_KEY_SIZE)) +- continue; +- +- cifs_dbg(FYI, "found in the open list\n"); +- cifs_dbg(FYI, "lease key match, lease break 0x%d\n", +- le32_to_cpu(rsp->NewLeaseState)); +- +- smb2_set_oplock_level(cinode, +- smb2_map_lease_to_oplock(rsp->NewLeaseState)); +- +- if (ack_req) +- cfile->oplock_break_cancelled = false; +- else +- cfile->oplock_break_cancelled = true; +- +- queue_work(cifsiod_wq, &cfile->oplock_break); +- +- kfree(lw); +- spin_unlock(&cifs_file_list_lock); +- spin_unlock(&cifs_tcp_ses_lock); +- return true; +- } ++ list_for_each(tmp1, &server->smb_ses_list) { ++ ses = list_entry(tmp1, struct cifs_ses, smb_ses_list); + +- found = false; +- list_for_each_entry(open, &tcon->pending_opens, olist) { +- if (memcmp(open->lease_key, rsp->LeaseKey, +- SMB2_LEASE_KEY_SIZE)) +- continue; +- +- if (!found && ack_req) { +- found = true; +- memcpy(lw->lease_key, open->lease_key, +- SMB2_LEASE_KEY_SIZE); +- lw->tlink = cifs_get_tlink(open->tlink); +- queue_work(cifsiod_wq, +- &lw->lease_break); ++ spin_lock(&cifs_file_list_lock); ++ list_for_each(tmp2, &ses->tcon_list) { ++ tcon = list_entry(tmp2, struct cifs_tcon, ++ tcon_list); ++ cifs_stats_inc( ++ &tcon->stats.cifs_stats.num_oplock_brks); ++ if (smb2_tcon_has_lease(tcon, rsp, lw)) { ++ spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cifs_tcp_ses_lock); ++ return true; + } +- +- cifs_dbg(FYI, "found in the pending open list\n"); +- cifs_dbg(FYI, "lease key match, lease break 0x%d\n", +- le32_to_cpu(rsp->NewLeaseState)); +- +- open->oplock = +- smb2_map_lease_to_oplock(rsp->NewLeaseState); +- } +- if (found) { +- spin_unlock(&cifs_file_list_lock); +- spin_unlock(&cifs_tcp_ses_lock); +- return true; + } ++ spin_unlock(&cifs_file_list_lock); + } +- spin_unlock(&cifs_file_list_lock); + } + spin_unlock(&cifs_tcp_ses_lock); + kfree(lw); +@@ -529,7 +540,7 @@ + if (rsp->StructureSize != + smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) { + if (le16_to_cpu(rsp->StructureSize) == 44) +- return smb2_is_valid_lease_break(buffer, server); ++ return smb2_is_valid_lease_break(buffer); + else + return false; + } +Index: linux-3.10-3.10.11/dummy/rpi_1073_b08d9b572074b3d0899349070bb61688ad6eb630.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1073_b08d9b572074b3d0899349070bb61688ad6eb630.txt 2014-05-05 12:44:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1074_ac78ae630c039e548e2b8d41b6036f240386d770.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1074_ac78ae630c039e548e2b8d41b6036f240386d770.patch --- linux-3.10.11/debian/patches/rpi/rpi_1074_ac78ae630c039e548e2b8d41b6036f240386d770.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1074_ac78ae630c039e548e2b8d41b6036f240386d770.patch 2014-05-05 12:44:06.000000000 +0000 @@ -0,0 +1,37 @@ +commit ac78ae630c039e548e2b8d41b6036f240386d770 +Author: Alan Stern +Date: Mon Aug 26 15:01:40 2013 -0400 + + USB: OHCI: Allow runtime PM without system sleep + + commit 69820e01aa756b8d228143d997f71523c1e97984 upstream. + + Since ohci-hcd supports runtime PM, the .pm field in its pci_driver + structure should be protected by CONFIG_PM rather than + CONFIG_PM_SLEEP. + + Without this change, OHCI controllers won't do runtime suspend if + system suspend or hibernation isn't enabled. + + Signed-off-by: Alan Stern + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/ohci-pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/ohci-pci.c 2014-05-05 11:51:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/ohci-pci.c 2014-05-05 12:44:06.000000000 +0000 +@@ -371,7 +371,7 @@ + .remove = usb_hcd_pci_remove, + .shutdown = usb_hcd_pci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +Index: linux-3.10-3.10.11/dummy/rpi_1074_ac78ae630c039e548e2b8d41b6036f240386d770.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1074_ac78ae630c039e548e2b8d41b6036f240386d770.txt 2014-05-05 12:44:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1075_979ad974d2d7d1e98e21b582a11acdf0713914e6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1075_979ad974d2d7d1e98e21b582a11acdf0713914e6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1075_979ad974d2d7d1e98e21b582a11acdf0713914e6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1075_979ad974d2d7d1e98e21b582a11acdf0713914e6.patch 2014-05-05 12:44:07.000000000 +0000 @@ -0,0 +1,37 @@ +commit 979ad974d2d7d1e98e21b582a11acdf0713914e6 +Author: Andy Lutomirski +Date: Thu Aug 22 11:39:15 2013 -0700 + + net: Check the correct namespace when spoofing pid over SCM_RIGHTS + + commit d661684cf6820331feae71146c35da83d794467e upstream. + + This is a security bug. + + The follow-up will fix nsproxy to discourage this type of issue from + happening again. + + Signed-off-by: Andy Lutomirski + Reviewed-by: "Eric W. Biederman" + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/scm.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/scm.c 2014-05-05 11:51:36.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/scm.c 2014-05-05 12:44:07.000000000 +0000 +@@ -54,7 +54,7 @@ + return -EINVAL; + + if ((creds->pid == task_tgid_vnr(current) || +- ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) && ++ ns_capable(task_active_pid_ns(current)->user_ns, CAP_SYS_ADMIN)) && + ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || + uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) && + ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || +Index: linux-3.10-3.10.11/dummy/rpi_1075_979ad974d2d7d1e98e21b582a11acdf0713914e6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1075_979ad974d2d7d1e98e21b582a11acdf0713914e6.txt 2014-05-05 12:44:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1076_6b844e7d601f709942cf15e5f5808953f5382402.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1076_6b844e7d601f709942cf15e5f5808953f5382402.patch --- linux-3.10.11/debian/patches/rpi/rpi_1076_6b844e7d601f709942cf15e5f5808953f5382402.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1076_6b844e7d601f709942cf15e5f5808953f5382402.patch 2014-05-05 12:44:08.000000000 +0000 @@ -0,0 +1,38 @@ +commit 6b844e7d601f709942cf15e5f5808953f5382402 +Author: Dan Carpenter +Date: Tue Aug 20 11:57:35 2013 +0300 + + staging: comedi: dt282x: dt282x_ai_insn_read() always fails + + commit 2c4283ca7cdcc6605859c836fc536fcd83a4525f upstream. + + In dt282x_ai_insn_read() we call this macro like: + wait_for(!mux_busy(), comedi_error(dev, "timeout\n"); return -ETIME;); + Because the if statement doesn't have curly braces it means we always + return -ETIME and the function never succeeds. + + Signed-off-by: Dan Carpenter + Acked-by: Ian Abbott + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/comedi/drivers/dt282x.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/comedi/drivers/dt282x.c 2014-05-05 11:51:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/comedi/drivers/dt282x.c 2014-05-05 12:44:07.000000000 +0000 +@@ -269,8 +269,9 @@ + } \ + udelay(5); \ + } \ +- if (_i) \ ++ if (_i) { \ + b \ ++ } \ + } while (0) + + static int prep_ai_dma(struct comedi_device *dev, int chan, int size); +Index: linux-3.10-3.10.11/dummy/rpi_1076_6b844e7d601f709942cf15e5f5808953f5382402.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1076_6b844e7d601f709942cf15e5f5808953f5382402.txt 2014-05-05 12:44:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1077_abea758371f89b0cdb5f0b2dad24674e0148f2ee.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1077_abea758371f89b0cdb5f0b2dad24674e0148f2ee.patch --- linux-3.10.11/debian/patches/rpi/rpi_1077_abea758371f89b0cdb5f0b2dad24674e0148f2ee.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1077_abea758371f89b0cdb5f0b2dad24674e0148f2ee.patch 2014-05-05 12:44:09.000000000 +0000 @@ -0,0 +1,65 @@ +commit abea758371f89b0cdb5f0b2dad24674e0148f2ee +Author: Marek Vasut +Date: Sat Jun 29 22:20:00 2013 +0100 + + iio: mxs-lradc: Fix misuse of iio->trig + + commit e1b1fa66a0398f0b52ae79a2bdc7de87c205d074 upstream. + + The struct iio_dev .trig field is to be used only by the IIO core, + the driver shall not fill this field. This fixes ugly crash when + the driver is compiled as a module and the module is rmmod'd. + + Signed-off-by: Marek Vasut + Cc: Fabio Estevam + Cc: Jonathan Cameron + Cc: Shawn Guo + Signed-off-by: Jonathan Cameron + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/iio/adc/mxs-lradc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/iio/adc/mxs-lradc.c 2014-05-05 11:51:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/iio/adc/mxs-lradc.c 2014-05-05 12:44:08.000000000 +0000 +@@ -661,12 +661,13 @@ + { + int ret; + struct iio_trigger *trig; ++ struct mxs_lradc *lradc = iio_priv(iio); + + trig = iio_trigger_alloc("%s-dev%i", iio->name, iio->id); + if (trig == NULL) + return -ENOMEM; + +- trig->dev.parent = iio->dev.parent; ++ trig->dev.parent = lradc->dev; + iio_trigger_set_drvdata(trig, iio); + trig->ops = &mxs_lradc_trigger_ops; + +@@ -676,15 +677,17 @@ + return ret; + } + +- iio->trig = trig; ++ lradc->trig = trig; + + return 0; + } + + static void mxs_lradc_trigger_remove(struct iio_dev *iio) + { +- iio_trigger_unregister(iio->trig); +- iio_trigger_free(iio->trig); ++ struct mxs_lradc *lradc = iio_priv(iio); ++ ++ iio_trigger_unregister(lradc->trig); ++ iio_trigger_free(lradc->trig); + } + + static int mxs_lradc_buffer_preenable(struct iio_dev *iio) +Index: linux-3.10-3.10.11/dummy/rpi_1077_abea758371f89b0cdb5f0b2dad24674e0148f2ee.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1077_abea758371f89b0cdb5f0b2dad24674e0148f2ee.txt 2014-05-05 12:44:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1078_f7e0ca347bcb540e2894833eccc33f9a65f4c822.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1078_f7e0ca347bcb540e2894833eccc33f9a65f4c822.patch --- linux-3.10.11/debian/patches/rpi/rpi_1078_f7e0ca347bcb540e2894833eccc33f9a65f4c822.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1078_f7e0ca347bcb540e2894833eccc33f9a65f4c822.patch 2014-05-05 12:44:09.000000000 +0000 @@ -0,0 +1,52 @@ +commit f7e0ca347bcb540e2894833eccc33f9a65f4c822 +Author: Marek Vasut +Date: Wed Jul 3 22:25:00 2013 +0100 + + iio: mxs-lradc: Remove useless check in read_raw + + commit 2a961d0995cdadbfba565b28beada59c5ae7ebae upstream. + + The removed check in the read_raw implementation was always true, + therefore remove it. This also fixes a bug, by closely inspecting + the code, one can notice the iio_validate_scan_mask_onehot() will + always return 1 and therefore the subsequent condition will always + succeed, therefore making the mxs_lradc_read_raw() function always + return -EINVAL; . + + Signed-off-by: Marek Vasut + Tested-by: Otavio Salvador + Acked-by: Hector Palacios + Signed-off-by: Jonathan Cameron + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/iio/adc/mxs-lradc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/iio/adc/mxs-lradc.c 2014-05-05 12:44:08.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/iio/adc/mxs-lradc.c 2014-05-05 12:44:09.000000000 +0000 +@@ -234,7 +234,6 @@ + { + struct mxs_lradc *lradc = iio_priv(iio_dev); + int ret; +- unsigned long mask; + + if (m != IIO_CHAN_INFO_RAW) + return -EINVAL; +@@ -243,12 +242,6 @@ + if (chan->channel > LRADC_MAX_TOTAL_CHANS) + return -EINVAL; + +- /* Validate the channel if it doesn't intersect with reserved chans. */ +- bitmap_set(&mask, chan->channel, 1); +- ret = iio_validate_scan_mask_onehot(iio_dev, &mask); +- if (ret) +- return -EINVAL; +- + /* + * See if there is no buffered operation in progess. If there is, simply + * bail out. This can be improved to support both buffered and raw IO at +Index: linux-3.10-3.10.11/dummy/rpi_1078_f7e0ca347bcb540e2894833eccc33f9a65f4c822.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1078_f7e0ca347bcb540e2894833eccc33f9a65f4c822.txt 2014-05-05 12:44:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1079_3fa0d2f124263d0080f266c4c7bfc60153f29b91.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1079_3fa0d2f124263d0080f266c4c7bfc60153f29b91.patch --- linux-3.10.11/debian/patches/rpi/rpi_1079_3fa0d2f124263d0080f266c4c7bfc60153f29b91.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1079_3fa0d2f124263d0080f266c4c7bfc60153f29b91.patch 2014-05-05 12:44:10.000000000 +0000 @@ -0,0 +1,50 @@ +commit 3fa0d2f124263d0080f266c4c7bfc60153f29b91 +Author: Mika Westerberg +Date: Mon Sep 2 13:30:25 2013 +0300 + + ACPI / LPSS: don't crash if a device has no MMIO resources + + commit af65cfe9aeae03e0682bebdf4db94582d75562dd upstream. + + Intel LPSS devices that are enumerated from ACPI have both MMIO and IRQ + resources returned in their _CRS method. However, Apple Macbook Air with + Haswell has LPSS devices enumerated from PCI bus instead and _CRS method + returns only an interrupt number (but the device has _HID set that causes + the scan handler to match it). + + The current ACPI / LPSS code sets pdata->dev_desc only when MMIO resource + is found for the device and in case of Macbook Air it is never found. That + leads to a NULL pointer dereference in register_device_clock(). + + Correct this by always setting the pdata->dev_desc. + + Reported-and-tested-by: Imre Kaloz + Signed-off-by: Mika Westerberg + Signed-off-by: Rafael J. Wysocki + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/acpi/acpi_lpss.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/acpi/acpi_lpss.c 2014-05-05 11:51:35.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/acpi/acpi_lpss.c 2014-05-05 12:44:10.000000000 +0000 +@@ -155,12 +155,13 @@ + pdata->mmio_size = resource_size(&rentry->res); + pdata->mmio_base = ioremap(rentry->res.start, + pdata->mmio_size); +- pdata->dev_desc = dev_desc; + break; + } + + acpi_dev_free_resource_list(&resource_list); + ++ pdata->dev_desc = dev_desc; ++ + if (dev_desc->clk_required) { + ret = register_device_clock(adev, pdata); + if (ret) { +Index: linux-3.10-3.10.11/dummy/rpi_1079_3fa0d2f124263d0080f266c4c7bfc60153f29b91.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1079_3fa0d2f124263d0080f266c4c7bfc60153f29b91.txt 2014-05-05 12:44:10.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1080_3765762187edd49446c94884aa88c952cec41116.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1080_3765762187edd49446c94884aa88c952cec41116.patch --- linux-3.10.11/debian/patches/rpi/rpi_1080_3765762187edd49446c94884aa88c952cec41116.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1080_3765762187edd49446c94884aa88c952cec41116.patch 2014-05-05 12:44:11.000000000 +0000 @@ -0,0 +1,34 @@ +commit 3765762187edd49446c94884aa88c952cec41116 +Author: Dan Carpenter +Date: Fri Aug 16 10:16:59 2013 +0300 + + USB: mos7720: use GFP_ATOMIC under spinlock + + commit d0bd9a41186e076ea543c397ad8a67a6cf604b55 upstream. + + The write_parport_reg_nonblock() function shouldn't sleep because it's + called with spinlocks held. + + Signed-off-by: Dan Carpenter + Acked-by: Johan Hovold + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/mos7720.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/mos7720.c 2014-05-05 11:51:35.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/mos7720.c 2014-05-05 12:44:11.000000000 +0000 +@@ -374,7 +374,7 @@ + kfree(urbtrack); + return -ENOMEM; + } +- urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); ++ urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC); + if (!urbtrack->setup) { + usb_free_urb(urbtrack->urb); + kfree(urbtrack); +Index: linux-3.10-3.10.11/dummy/rpi_1080_3765762187edd49446c94884aa88c952cec41116.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1080_3765762187edd49446c94884aa88c952cec41116.txt 2014-05-05 12:44:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1081_7965eef853ccd9e30f1ee5d5df27a48b77a22a4b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1081_7965eef853ccd9e30f1ee5d5df27a48b77a22a4b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1081_7965eef853ccd9e30f1ee5d5df27a48b77a22a4b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1081_7965eef853ccd9e30f1ee5d5df27a48b77a22a4b.patch 2014-05-05 12:44:12.000000000 +0000 @@ -0,0 +1,36 @@ +commit 7965eef853ccd9e30f1ee5d5df27a48b77a22a4b +Author: Johan Hovold +Date: Mon Aug 19 13:05:45 2013 +0200 + + USB: mos7720: fix big-endian control requests + + commit 3b716caf190ccc6f2a09387210e0e6a26c1d81a4 upstream. + + Fix endianess bugs in parallel-port code which caused corrupt + control-requests to be issued on big-endian machines. + + Reported-by: kbuild test robot + Signed-off-by: Johan Hovold + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/mos7720.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/mos7720.c 2014-05-05 12:44:11.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/mos7720.c 2014-05-05 12:44:11.000000000 +0000 +@@ -382,8 +382,8 @@ + } + urbtrack->setup->bRequestType = (__u8)0x40; + urbtrack->setup->bRequest = (__u8)0x0e; +- urbtrack->setup->wValue = get_reg_value(reg, dummy); +- urbtrack->setup->wIndex = get_reg_index(reg); ++ urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy)); ++ urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg)); + urbtrack->setup->wLength = 0; + usb_fill_control_urb(urbtrack->urb, usbdev, + usb_sndctrlpipe(usbdev, 0), +Index: linux-3.10-3.10.11/dummy/rpi_1081_7965eef853ccd9e30f1ee5d5df27a48b77a22a4b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1081_7965eef853ccd9e30f1ee5d5df27a48b77a22a4b.txt 2014-05-05 12:44:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1082_b096d2211a059f6b22f089e3907e061409dbb6c5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1082_b096d2211a059f6b22f089e3907e061409dbb6c5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1082_b096d2211a059f6b22f089e3907e061409dbb6c5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1082_b096d2211a059f6b22f089e3907e061409dbb6c5.patch 2014-05-05 12:44:13.000000000 +0000 @@ -0,0 +1,37 @@ +commit b096d2211a059f6b22f089e3907e061409dbb6c5 +Author: Daniel Mack +Date: Wed Aug 21 11:17:21 2013 +0200 + + usb: ehci-mxc: check for pdata before dereferencing + + commit f375fc520d4df0cd9fcb570f33c103c6c0311f9e upstream. + + Commit 7e8d5cd93fac ("USB: Add EHCI support for MX27 and MX31 based + boards") introduced code that could potentially lead to a NULL pointer + dereference on driver removal. + + Fix this by checking for the value of pdata before dereferencing it. + + Signed-off-by: Daniel Mack + Reported-by: Dan Carpenter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/ehci-mxc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/ehci-mxc.c 2014-05-05 11:51:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/ehci-mxc.c 2014-05-05 12:44:12.000000000 +0000 +@@ -184,7 +184,7 @@ + if (pdata && pdata->exit) + pdata->exit(pdev); + +- if (pdata->otg) ++ if (pdata && pdata->otg) + usb_phy_shutdown(pdata->otg); + + clk_disable_unprepare(priv->usbclk); +Index: linux-3.10-3.10.11/dummy/rpi_1082_b096d2211a059f6b22f089e3907e061409dbb6c5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1082_b096d2211a059f6b22f089e3907e061409dbb6c5.txt 2014-05-05 12:44:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1083_c552e84c9bfd1b7feb5cd51e970b8110a31c4b89.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1083_c552e84c9bfd1b7feb5cd51e970b8110a31c4b89.patch --- linux-3.10.11/debian/patches/rpi/rpi_1083_c552e84c9bfd1b7feb5cd51e970b8110a31c4b89.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1083_c552e84c9bfd1b7feb5cd51e970b8110a31c4b89.patch 2014-05-05 12:44:14.000000000 +0000 @@ -0,0 +1,66 @@ +commit c552e84c9bfd1b7feb5cd51e970b8110a31c4b89 +Author: Oliver Neukum +Date: Tue Aug 6 14:22:59 2013 +0200 + + USB: cdc-wdm: fix race between interrupt handler and tasklet + + commit 6dd433e6cf2475ce8abec1b467720858c24450eb upstream. + + Both could want to submit the same URB. Some checks of the flag + intended to prevent that were missing. + + Signed-off-by: Oliver Neukum + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/class/cdc-wdm.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/class/cdc-wdm.c 2014-05-05 11:51:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/class/cdc-wdm.c 2014-05-05 12:44:13.000000000 +0000 +@@ -209,6 +209,7 @@ + static void wdm_int_callback(struct urb *urb) + { + int rv = 0; ++ int responding; + int status = urb->status; + struct wdm_device *desc; + struct usb_cdc_notification *dr; +@@ -262,8 +263,8 @@ + + spin_lock(&desc->iuspin); + clear_bit(WDM_READ, &desc->flags); +- set_bit(WDM_RESPONDING, &desc->flags); +- if (!test_bit(WDM_DISCONNECTING, &desc->flags) ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); ++ if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags) + && !test_bit(WDM_SUSPENDING, &desc->flags)) { + rv = usb_submit_urb(desc->response, GFP_ATOMIC); + dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", +@@ -685,16 +686,20 @@ + { + struct wdm_device *desc = container_of(work, struct wdm_device, rxwork); + unsigned long flags; +- int rv; ++ int rv = 0; ++ int responding; + + spin_lock_irqsave(&desc->iuspin, flags); + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + spin_unlock_irqrestore(&desc->iuspin, flags); + } else { ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irqrestore(&desc->iuspin, flags); +- rv = usb_submit_urb(desc->response, GFP_KERNEL); ++ if (!responding) ++ rv = usb_submit_urb(desc->response, GFP_KERNEL); + if (rv < 0 && rv != -EPERM) { + spin_lock_irqsave(&desc->iuspin, flags); ++ clear_bit(WDM_RESPONDING, &desc->flags); + if (!test_bit(WDM_DISCONNECTING, &desc->flags)) + schedule_work(&desc->rxwork); + spin_unlock_irqrestore(&desc->iuspin, flags); +Index: linux-3.10-3.10.11/dummy/rpi_1083_c552e84c9bfd1b7feb5cd51e970b8110a31c4b89.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1083_c552e84c9bfd1b7feb5cd51e970b8110a31c4b89.txt 2014-05-05 12:44:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1084_ec7329b595fa4ef248e1ef9bbb6b49cee416ac7c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1084_ec7329b595fa4ef248e1ef9bbb6b49cee416ac7c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1084_ec7329b595fa4ef248e1ef9bbb6b49cee416ac7c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1084_ec7329b595fa4ef248e1ef9bbb6b49cee416ac7c.patch 2014-05-05 12:44:14.000000000 +0000 @@ -0,0 +1,45 @@ +commit ec7329b595fa4ef248e1ef9bbb6b49cee416ac7c +Author: Laurent Pinchart +Date: Mon Apr 29 22:18:01 2013 +0200 + + usb: gadget: uvc: Fix error handling in uvc_queue_buffer() + + commit ebe864a6cb8e087ede047fa1fa6b6d06fcb9a9e4 upstream. + + The conversion to videobuf2 failed to check the return value of + vb2_qbuf(). Fix it. + + Reported-by: Michael Grzeschik + Signed-off-by: Laurent Pinchart + Tested-By: Michael Grzeschik + Signed-off-by: Felipe Balbi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/gadget/uvc_queue.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/gadget/uvc_queue.c 2014-05-05 11:51:33.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/gadget/uvc_queue.c 2014-05-05 12:44:14.000000000 +0000 +@@ -177,12 +177,16 @@ + + mutex_lock(&queue->mutex); + ret = vb2_qbuf(&queue->queue, buf); ++ if (ret < 0) ++ goto done; ++ + spin_lock_irqsave(&queue->irqlock, flags); + ret = (queue->flags & UVC_QUEUE_PAUSED) != 0; + queue->flags &= ~UVC_QUEUE_PAUSED; + spin_unlock_irqrestore(&queue->irqlock, flags); +- mutex_unlock(&queue->mutex); + ++done: ++ mutex_unlock(&queue->mutex); + return ret; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1084_ec7329b595fa4ef248e1ef9bbb6b49cee416ac7c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1084_ec7329b595fa4ef248e1ef9bbb6b49cee416ac7c.txt 2014-05-05 12:44:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1085_ddcc49fb2db6457861dbb0b99844b2a5b53b5c88.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1085_ddcc49fb2db6457861dbb0b99844b2a5b53b5c88.patch --- linux-3.10.11/debian/patches/rpi/rpi_1085_ddcc49fb2db6457861dbb0b99844b2a5b53b5c88.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1085_ddcc49fb2db6457861dbb0b99844b2a5b53b5c88.patch 2014-05-05 12:44:15.000000000 +0000 @@ -0,0 +1,77 @@ +commit ddcc49fb2db6457861dbb0b99844b2a5b53b5c88 +Author: Sarah Sharp +Date: Mon Aug 5 18:58:15 2013 -0700 + + usb: Don't fail port power resume on device disconnect. + + commit d49dad3e11638f66be4e16573ffaa8c46a09e3b3 upstream. + + Userspace can tell the kernel to power off any USB port, including ones + that are visible and connectible to users. When an attached USB device + goes into suspend, the port will be powered off if the + pm_qos_no_port_poweroff file for its port is set to 0, the device does + not have remote wakeup enabled, and the device is marked as persistent. + + If the user disconnects the USB device while the port is powered off, + the current code does not handle that properly. If you disconnect a + device, and then run `lsusb -v -s` for the device, the device disconnect + does not get handled by the USB core. The runtime resume of the port + fails, because hub_port_debounce_be_connected() returns -ETIMEDOUT. + + This means the port resume fails and khubd doesn't handle the USB device + disconnect. This leaves the device listed in lsusb, and the port's + runtime_status will be permanently marked as "error". + + Fix this by ignoring the return value of hub_port_debounce_be_connected. + Users can disconnect USB devices while the ports are powered off, and we + must be able to handle that. + + This patch should be backported to kernels as old as 3.9, that + contain the commit ad493e5e580546e6c3024b76a41535476da1546a "usb: add + usb port auto power off mechanism" + + Signed-off-by: Sarah Sharp + Cc: Lan Tianyu + Cc: Alan Stern + Cc: Rafael J. Wysocki + Signed-off-by: Sarah Sharp + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/core/port.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/port.c 2014-05-05 11:51:33.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/port.c 2014-05-05 12:44:15.000000000 +0000 +@@ -89,22 +89,19 @@ + retval = usb_hub_set_port_power(hdev, port1, true); + if (port_dev->child && !retval) { + /* +- * Wait for usb hub port to be reconnected in order to make +- * the resume procedure successful. ++ * Attempt to wait for usb hub port to be reconnected in order ++ * to make the resume procedure successful. The device may have ++ * disconnected while the port was powered off, so ignore the ++ * return status. + */ + retval = hub_port_debounce_be_connected(hub, port1); +- if (retval < 0) { ++ if (retval < 0) + dev_dbg(&port_dev->dev, "can't get reconnection after setting port power on, status %d\n", + retval); +- goto out; +- } + usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); +- +- /* Set return value to 0 if debounce successful */ + retval = 0; + } + +-out: + clear_bit(port1, hub->busy_bits); + usb_autopm_put_interface(intf); + return retval; +Index: linux-3.10-3.10.11/dummy/rpi_1085_ddcc49fb2db6457861dbb0b99844b2a5b53b5c88.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1085_ddcc49fb2db6457861dbb0b99844b2a5b53b5c88.txt 2014-05-05 12:44:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1086_94cc662c4bd9f8487d54262bbfc2307d9b1fc6b1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1086_94cc662c4bd9f8487d54262bbfc2307d9b1fc6b1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1086_94cc662c4bd9f8487d54262bbfc2307d9b1fc6b1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1086_94cc662c4bd9f8487d54262bbfc2307d9b1fc6b1.patch 2014-05-05 12:44:16.000000000 +0000 @@ -0,0 +1,41 @@ +commit 94cc662c4bd9f8487d54262bbfc2307d9b1fc6b1 +Author: Alan Stern +Date: Fri Aug 30 10:46:00 2013 -0400 + + USB: fix build error when CONFIG_PM_SLEEP isn't enabled + + commit 9d8924297cd9c256c23c02abae40202563452453 upstream. + + This patch fixes a build error that occurs when CONFIG_PM is enabled + and CONFIG_PM_SLEEP isn't: + + >> drivers/usb/host/ohci-pci.c:294:10: error: 'usb_hcd_pci_pm_ops' undeclared here (not in a function) + .pm = &usb_hcd_pci_pm_ops + + Since the usb_hcd_pci_pm_ops structure is defined and used when + CONFIG_PM is enabled, its declaration should not be protected by + CONFIG_PM_SLEEP. + + Signed-off-by: Alan Stern + Reported-by: kbuild test robot + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/usb/hcd.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/usb/hcd.h 2014-05-05 11:51:33.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/usb/hcd.h 2014-05-05 12:44:16.000000000 +0000 +@@ -410,7 +410,7 @@ + extern void usb_hcd_pci_remove(struct pci_dev *dev); + extern void usb_hcd_pci_shutdown(struct pci_dev *dev); + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + extern const struct dev_pm_ops usb_hcd_pci_pm_ops; + #endif + #endif /* CONFIG_PCI */ +Index: linux-3.10-3.10.11/dummy/rpi_1086_94cc662c4bd9f8487d54262bbfc2307d9b1fc6b1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1086_94cc662c4bd9f8487d54262bbfc2307d9b1fc6b1.txt 2014-05-05 12:44:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1087_ef7198be2830f7d6951512724203326746756a86.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1087_ef7198be2830f7d6951512724203326746756a86.patch --- linux-3.10.11/debian/patches/rpi/rpi_1087_ef7198be2830f7d6951512724203326746756a86.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1087_ef7198be2830f7d6951512724203326746756a86.patch 2014-05-05 12:44:17.000000000 +0000 @@ -0,0 +1,36 @@ +commit ef7198be2830f7d6951512724203326746756a86 +Author: Hans de Goede +Date: Sat Aug 3 16:37:48 2013 +0200 + + usb: config->desc.bLength may not exceed amount of data returned by the device + + commit b4f17a488ae2e09bfcf95c0e0b4219c246f1116a upstream. + + While reading the config parsing code I noticed this check is missing, without + this check config->desc.wTotalLength can end up with a value larger then the + dev->rawdescriptors length for the config, and when userspace then tries to + get the rawdescriptors bad things may happen. + + Signed-off-by: Hans de Goede + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/core/config.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/config.c 2014-05-05 11:51:33.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/config.c 2014-05-05 12:44:16.000000000 +0000 +@@ -424,7 +424,8 @@ + + memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); + if (config->desc.bDescriptorType != USB_DT_CONFIG || +- config->desc.bLength < USB_DT_CONFIG_SIZE) { ++ config->desc.bLength < USB_DT_CONFIG_SIZE || ++ config->desc.bLength > size) { + dev_err(ddev, "invalid descriptor for config index %d: " + "type = 0x%X, length = %d\n", cfgidx, + config->desc.bDescriptorType, config->desc.bLength); +Index: linux-3.10-3.10.11/dummy/rpi_1087_ef7198be2830f7d6951512724203326746756a86.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1087_ef7198be2830f7d6951512724203326746756a86.txt 2014-05-05 12:44:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1088_b504b4a1e3484b4b40a25ff228432df55cb24758.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1088_b504b4a1e3484b4b40a25ff228432df55cb24758.patch --- linux-3.10.11/debian/patches/rpi/rpi_1088_b504b4a1e3484b4b40a25ff228432df55cb24758.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1088_b504b4a1e3484b4b40a25ff228432df55cb24758.patch 2014-05-05 12:44:18.000000000 +0000 @@ -0,0 +1,153 @@ +commit b504b4a1e3484b4b40a25ff228432df55cb24758 +Author: Alan Stern +Date: Tue Jul 30 15:39:02 2013 -0400 + + USB: handle LPM errors during device suspend correctly + + commit aa5ceae24bf8dff1d6fe87c6c4b08e69c6d33550 upstream. + + The hub driver's usb_port_suspend() routine doesn't handle errors + related to Link Power Management properly. It always returns failure, + it doesn't try to clean up the wakeup setting, (in the case of system + sleep) it doesn't try to go ahead with the port suspend regardless, + and it doesn't try to apply the new power-off mechanism. + + This patch fixes these problems. + + Note: Sarah fixed this patch to apply against 3.11, since the original + commit (4fae6f0fa86f92e6bc7429371b1e177ad0aaac66 "USB: handle LPM errors + during device suspend correctly") called usb_disable_remote_wakeup, + which won't be added until 3.12. + + This patch should be backported to kernels as old as 3.5, that + contain the commit 8306095fd2c1100e8244c09bf560f97aca5a311d "USB: + Disable USB 3.0 LPM in critical sections.". There will be merge + conflicts, since LTM wasn't added until 3.6. + + Signed-off-by: Alan Stern + Signed-off-by: Sarah Sharp + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/core/hub.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/hub.c 2014-05-05 11:51:32.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/hub.c 2014-05-05 12:44:17.000000000 +0000 +@@ -2916,7 +2916,6 @@ + { + struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); + struct usb_port *port_dev = hub->ports[udev->portnum - 1]; +- enum pm_qos_flags_status pm_qos_stat; + int port1 = udev->portnum; + int status; + bool really_suspend = true; +@@ -2954,7 +2953,7 @@ + status); + /* bail if autosuspend is requested */ + if (PMSG_IS_AUTO(msg)) +- return status; ++ goto err_wakeup; + } + } + +@@ -2963,14 +2962,16 @@ + usb_set_usb2_hardware_lpm(udev, 0); + + if (usb_disable_ltm(udev)) { +- dev_err(&udev->dev, "%s Failed to disable LTM before suspend\n.", +- __func__); +- return -ENOMEM; ++ dev_err(&udev->dev, "Failed to disable LTM before suspend\n."); ++ status = -ENOMEM; ++ if (PMSG_IS_AUTO(msg)) ++ goto err_ltm; + } + if (usb_unlocked_disable_lpm(udev)) { +- dev_err(&udev->dev, "%s Failed to disable LPM before suspend\n.", +- __func__); +- return -ENOMEM; ++ dev_err(&udev->dev, "Failed to disable LPM before suspend\n."); ++ status = -ENOMEM; ++ if (PMSG_IS_AUTO(msg)) ++ goto err_lpm3; + } + + /* see 7.1.7.6 */ +@@ -2998,28 +2999,31 @@ + if (status) { + dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", + port1, status); +- /* paranoia: "should not happen" */ +- if (udev->do_remote_wakeup) { +- if (!hub_is_superspeed(hub->hdev)) { +- (void) usb_control_msg(udev, +- usb_sndctrlpipe(udev, 0), +- USB_REQ_CLEAR_FEATURE, +- USB_RECIP_DEVICE, +- USB_DEVICE_REMOTE_WAKEUP, 0, +- NULL, 0, +- USB_CTRL_SET_TIMEOUT); +- } else +- (void) usb_disable_function_remotewakeup(udev); +- +- } + ++ /* Try to enable USB3 LPM and LTM again */ ++ usb_unlocked_enable_lpm(udev); ++ err_lpm3: ++ usb_enable_ltm(udev); ++ err_ltm: + /* Try to enable USB2 hardware LPM again */ + if (udev->usb2_hw_lpm_capable == 1) + usb_set_usb2_hardware_lpm(udev, 1); + +- /* Try to enable USB3 LTM and LPM again */ +- usb_enable_ltm(udev); +- usb_unlocked_enable_lpm(udev); ++ if (udev->do_remote_wakeup) { ++ if (udev->speed < USB_SPEED_SUPER) ++ usb_control_msg(udev, usb_sndctrlpipe(udev, 0), ++ USB_REQ_CLEAR_FEATURE, ++ USB_RECIP_DEVICE, ++ USB_DEVICE_REMOTE_WAKEUP, 0, ++ NULL, 0, USB_CTRL_SET_TIMEOUT); ++ else ++ usb_control_msg(udev, usb_sndctrlpipe(udev, 0), ++ USB_REQ_CLEAR_FEATURE, ++ USB_RECIP_INTERFACE, ++ USB_INTRF_FUNC_SUSPEND, 0, ++ NULL, 0, USB_CTRL_SET_TIMEOUT); ++ } ++ err_wakeup: + + /* System sleep transitions should never fail */ + if (!PMSG_IS_AUTO(msg)) +@@ -3041,14 +3045,15 @@ + * Check whether current status meets the requirement of + * usb port power off mechanism + */ +- pm_qos_stat = dev_pm_qos_flags(&port_dev->dev, +- PM_QOS_FLAG_NO_POWER_OFF); +- if (!udev->do_remote_wakeup +- && pm_qos_stat != PM_QOS_FLAGS_ALL +- && udev->persist_enabled +- && !status) { +- pm_runtime_put_sync(&port_dev->dev); +- port_dev->did_runtime_put = true; ++ if (status == 0 && !udev->do_remote_wakeup && udev->persist_enabled) { ++ enum pm_qos_flags_status pm_qos_stat; ++ ++ pm_qos_stat = dev_pm_qos_flags(&port_dev->dev, ++ PM_QOS_FLAG_NO_POWER_OFF); ++ if (pm_qos_stat != PM_QOS_FLAGS_ALL) { ++ pm_runtime_put_sync(&port_dev->dev); ++ port_dev->did_runtime_put = true; ++ } + } + + usb_mark_last_busy(hub->hdev); +Index: linux-3.10-3.10.11/dummy/rpi_1088_b504b4a1e3484b4b40a25ff228432df55cb24758.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1088_b504b4a1e3484b4b40a25ff228432df55cb24758.txt 2014-05-05 12:44:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1089_e083505592ec12ab57fd930e286607583ecc641c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1089_e083505592ec12ab57fd930e286607583ecc641c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1089_e083505592ec12ab57fd930e286607583ecc641c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1089_e083505592ec12ab57fd930e286607583ecc641c.patch 2014-05-05 12:44:19.000000000 +0000 @@ -0,0 +1,56 @@ +commit e083505592ec12ab57fd930e286607583ecc641c +Author: Lan Tianyu +Date: Wed Jul 3 22:17:54 2013 +0800 + + usb: don't check pm qos NO_POWER_OFF flag in usb_port_suspend() + + commit 98a4f1ff7bea8002ab79d6776e30d27932e88244 upstream. + + The pm qos NO_POWER_OFF flag is checked twice during usb device suspend + to see if the usb port power off condition is met. This is redundant and + also will prevent the port from being powered off if the NO_POWER_OFF + flag is changed to 1 from 0 after the device was already suspended. + + More detail in the following link. + http://marc.info/?l=linux-usb&m=136543949130865&w=2 + + This patch should be backported to kernels as old as 3.7, that + contain the commit f7ac7787ad361e31a7972e2854ed8dc2eedfac3b "usb/acpi: + Use ACPI methods to power off ports." + + Signed-off-by: Lan Tianyu + Signed-off-by: Sarah Sharp + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/core/hub.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/hub.c 2014-05-05 12:44:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/hub.c 2014-05-05 12:44:18.000000000 +0000 +@@ -3041,19 +3041,9 @@ + usb_set_device_state(udev, USB_STATE_SUSPENDED); + } + +- /* +- * Check whether current status meets the requirement of +- * usb port power off mechanism +- */ + if (status == 0 && !udev->do_remote_wakeup && udev->persist_enabled) { +- enum pm_qos_flags_status pm_qos_stat; +- +- pm_qos_stat = dev_pm_qos_flags(&port_dev->dev, +- PM_QOS_FLAG_NO_POWER_OFF); +- if (pm_qos_stat != PM_QOS_FLAGS_ALL) { +- pm_runtime_put_sync(&port_dev->dev); +- port_dev->did_runtime_put = true; +- } ++ pm_runtime_put_sync(&port_dev->dev); ++ port_dev->did_runtime_put = true; + } + + usb_mark_last_busy(hub->hdev); +Index: linux-3.10-3.10.11/dummy/rpi_1089_e083505592ec12ab57fd930e286607583ecc641c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1089_e083505592ec12ab57fd930e286607583ecc641c.txt 2014-05-05 12:44:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1090_215840ab83bfdd15deca0a8b0f140369afab7f52.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1090_215840ab83bfdd15deca0a8b0f140369afab7f52.patch --- linux-3.10.11/debian/patches/rpi/rpi_1090_215840ab83bfdd15deca0a8b0f140369afab7f52.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1090_215840ab83bfdd15deca0a8b0f140369afab7f52.patch 2014-05-05 12:44:19.000000000 +0000 @@ -0,0 +1,71 @@ +commit 215840ab83bfdd15deca0a8b0f140369afab7f52 +Author: Tejun Heo +Date: Fri Jun 28 10:34:48 2013 -0700 + + rculist: list_first_or_null_rcu() should use list_entry_rcu() + + commit c34ac00caefbe49d40058ae7200bd58725cebb45 upstream. + + list_first_or_null() should test whether the list is empty and return + pointer to the first entry if not in a RCU safe manner. It's broken + in several ways. + + * It compares __kernel @__ptr with __rcu @__next triggering the + following sparse warning. + + net/core/dev.c:4331:17: error: incompatible types in comparison expression (different address spaces) + + * It doesn't perform rcu_dereference*() and computes the entry address + using container_of() directly from the __rcu pointer which is + inconsitent with other rculist interface. As a result, all three + in-kernel users - net/core/dev.c, macvlan, cgroup - are buggy. They + dereference the pointer w/o going through read barrier. + + * While ->next dereference passes through list_next_rcu(), the + compiler is still free to fetch ->next more than once and thus + nullify the "__ptr != __next" condition check. + + Fix it by making list_first_or_null_rcu() dereference ->next directly + using ACCESS_ONCE() and then use list_entry_rcu() on it like other + rculist accessors. + + v2: Paul pointed out that the compiler may fetch the pointer more than + once nullifying the condition check. ACCESS_ONCE() added on + ->next dereference. + + v3: Restored () around macro param which was accidentally removed. + Spotted by Paul. + + Signed-off-by: Tejun Heo + Reported-by: Fengguang Wu + Cc: Dipankar Sarma + Cc: "Paul E. McKenney" + Cc: "David S. Miller" + Cc: Li Zefan + Cc: Patrick McHardy + Signed-off-by: Paul E. McKenney + Reviewed-by: Josh Triplett + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/rculist.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/rculist.h 2014-05-05 11:51:31.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/rculist.h 2014-05-05 12:44:19.000000000 +0000 +@@ -267,8 +267,9 @@ + */ + #define list_first_or_null_rcu(ptr, type, member) \ + ({struct list_head *__ptr = (ptr); \ +- struct list_head __rcu *__next = list_next_rcu(__ptr); \ +- likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \ ++ struct list_head *__next = ACCESS_ONCE(__ptr->next); \ ++ likely(__ptr != __next) ? \ ++ list_entry_rcu(__next, type, member) : NULL; \ + }) + + /** +Index: linux-3.10-3.10.11/dummy/rpi_1090_215840ab83bfdd15deca0a8b0f140369afab7f52.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1090_215840ab83bfdd15deca0a8b0f140369afab7f52.txt 2014-05-05 12:44:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1091_a1b8ce5ac7db6a7c29a4ca658d5aff5384bd073e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1091_a1b8ce5ac7db6a7c29a4ca658d5aff5384bd073e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1091_a1b8ce5ac7db6a7c29a4ca658d5aff5384bd073e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1091_a1b8ce5ac7db6a7c29a4ca658d5aff5384bd073e.patch 2014-05-05 12:44:20.000000000 +0000 @@ -0,0 +1,38 @@ +commit a1b8ce5ac7db6a7c29a4ca658d5aff5384bd073e +Author: Mike Dyer +Date: Fri Aug 16 18:36:28 2013 +0100 + + ASoC: wm8960: Fix PLL register writes + + commit 85fa532b6ef920b32598df86b194571a7059a77c upstream. + + Bit 9 of PLL2,3 and 4 is reserved as '0'. The 24bit fractional part + should be split across each register in 8bit chunks. + + Signed-off-by: Mike Dyer + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/soc/codecs/wm8960.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/codecs/wm8960.c 2014-05-05 11:51:31.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/codecs/wm8960.c 2014-05-05 12:44:20.000000000 +0000 +@@ -857,9 +857,9 @@ + if (pll_div.k) { + reg |= 0x20; + +- snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); +- snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); +- snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); ++ snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff); ++ snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff); ++ snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff); + } + snd_soc_write(codec, WM8960_PLL1, reg); + +Index: linux-3.10-3.10.11/dummy/rpi_1091_a1b8ce5ac7db6a7c29a4ca658d5aff5384bd073e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1091_a1b8ce5ac7db6a7c29a4ca658d5aff5384bd073e.txt 2014-05-05 12:44:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1092_87d5b89a6a77f1e141d41c5447f6a4e83feb8d11.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1092_87d5b89a6a77f1e141d41c5447f6a4e83feb8d11.patch --- linux-3.10.11/debian/patches/rpi/rpi_1092_87d5b89a6a77f1e141d41c5447f6a4e83feb8d11.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1092_87d5b89a6a77f1e141d41c5447f6a4e83feb8d11.patch 2014-05-05 12:44:21.000000000 +0000 @@ -0,0 +1,44 @@ +commit 87d5b89a6a77f1e141d41c5447f6a4e83feb8d11 +Author: Steffen Trumtrar +Date: Mon Sep 9 18:09:12 2013 +0200 + + ASoC: mc13783: add spi errata fix + + commit 9f6f0afbb9fdabf6dcac642dfec457f28981e3f8 upstream. + + The MC13783 Chip Errata, Rev. 4 says, that depending on SPI clock + and main audio clock speed, the Audio Codec or Stereo DAC do sometimes + not start when programmed to do so. This is due to an internal clock + timing issue related to the loading of the SPI bits into the audio block. + + On an i.MX27 based system, this issue lead to switched audio channels under + certain circumstances: RTC + Touch + Audio are used and loaded at startup. + + The mentioned workaround of writing registers 40 and 41 two times is implemented + here. + + Signed-off-by: Steffen Trumtrar + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/soc/codecs/mc13783.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/codecs/mc13783.c 2014-05-05 11:51:31.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/codecs/mc13783.c 2014-05-05 12:44:21.000000000 +0000 +@@ -126,6 +126,10 @@ + + ret = mc13xxx_reg_write(priv->mc13xxx, reg, value); + ++ /* include errata fix for spi audio problems */ ++ if (reg == MC13783_AUDIO_CODEC || reg == MC13783_AUDIO_DAC) ++ ret = mc13xxx_reg_write(priv->mc13xxx, reg, value); ++ + mc13xxx_unlock(priv->mc13xxx); + + return ret; +Index: linux-3.10-3.10.11/dummy/rpi_1092_87d5b89a6a77f1e141d41c5447f6a4e83feb8d11.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1092_87d5b89a6a77f1e141d41c5447f6a4e83feb8d11.txt 2014-05-05 12:44:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1093_1159cd1ded90b41db788f84bf94644a810dd322a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1093_1159cd1ded90b41db788f84bf94644a810dd322a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1093_1159cd1ded90b41db788f84bf94644a810dd322a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1093_1159cd1ded90b41db788f84bf94644a810dd322a.patch 2014-05-05 12:44:22.000000000 +0000 @@ -0,0 +1,113 @@ +commit 1159cd1ded90b41db788f84bf94644a810dd322a +Author: H. Peter Anvin +Date: Fri Aug 30 15:43:03 2013 -0700 + + x86, smap: Handle csum_partial_copy_*_user() + + commit 7263dda41b5a28ae6566fd126d9b06ada73dd721 upstream. + + Add SMAP annotations to csum_partial_copy_to/from_user(). These + functions legitimately access user space and thus need to set the AC + flag. + + TODO: add explicit checks that the side with the kernel space pointer + really points into kernel space. + + Signed-off-by: H. Peter Anvin + Link: http://lkml.kernel.org/n/tip-2aps0u00eer658fd5xyanan7@git.kernel.org + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/include/asm/checksum_32.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/checksum_32.h 2014-05-05 11:51:31.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/checksum_32.h 2014-05-05 12:44:21.000000000 +0000 +@@ -49,9 +49,15 @@ + int len, __wsum sum, + int *err_ptr) + { ++ __wsum ret; ++ + might_sleep(); +- return csum_partial_copy_generic((__force void *)src, dst, +- len, sum, err_ptr, NULL); ++ stac(); ++ ret = csum_partial_copy_generic((__force void *)src, dst, ++ len, sum, err_ptr, NULL); ++ clac(); ++ ++ return ret; + } + + /* +@@ -176,10 +182,16 @@ + int len, __wsum sum, + int *err_ptr) + { ++ __wsum ret; ++ + might_sleep(); +- if (access_ok(VERIFY_WRITE, dst, len)) +- return csum_partial_copy_generic(src, (__force void *)dst, +- len, sum, NULL, err_ptr); ++ if (access_ok(VERIFY_WRITE, dst, len)) { ++ stac(); ++ ret = csum_partial_copy_generic(src, (__force void *)dst, ++ len, sum, NULL, err_ptr); ++ clac(); ++ return ret; ++ } + + if (len) + *err_ptr = -EFAULT; +Index: linux-3.10-3.10.11/arch/x86/lib/csum-wrappers_64.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/lib/csum-wrappers_64.c 2014-05-05 11:51:31.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/lib/csum-wrappers_64.c 2014-05-05 12:44:21.000000000 +0000 +@@ -6,6 +6,7 @@ + */ + #include + #include ++#include + + /** + * csum_partial_copy_from_user - Copy and checksum from user space. +@@ -52,8 +53,10 @@ + len -= 2; + } + } ++ stac(); + isum = csum_partial_copy_generic((__force const void *)src, + dst, len, isum, errp, NULL); ++ clac(); + if (unlikely(*errp)) + goto out_err; + +@@ -82,6 +85,8 @@ + csum_partial_copy_to_user(const void *src, void __user *dst, + int len, __wsum isum, int *errp) + { ++ __wsum ret; ++ + might_sleep(); + + if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { +@@ -105,8 +110,11 @@ + } + + *errp = 0; +- return csum_partial_copy_generic(src, (void __force *)dst, +- len, isum, NULL, errp); ++ stac(); ++ ret = csum_partial_copy_generic(src, (void __force *)dst, ++ len, isum, NULL, errp); ++ clac(); ++ return ret; + } + EXPORT_SYMBOL(csum_partial_copy_to_user); + +Index: linux-3.10-3.10.11/dummy/rpi_1093_1159cd1ded90b41db788f84bf94644a810dd322a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1093_1159cd1ded90b41db788f84bf94644a810dd322a.txt 2014-05-05 12:44:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1094_a168ad2687045d24e98b2525d1ee678c4f2a9a96.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1094_a168ad2687045d24e98b2525d1ee678c4f2a9a96.patch --- linux-3.10.11/debian/patches/rpi/rpi_1094_a168ad2687045d24e98b2525d1ee678c4f2a9a96.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1094_a168ad2687045d24e98b2525d1ee678c4f2a9a96.patch 2014-05-05 12:44:23.000000000 +0000 @@ -0,0 +1,113 @@ +commit a168ad2687045d24e98b2525d1ee678c4f2a9a96 +Author: Al Viro +Date: Sun Sep 1 20:35:01 2013 +0100 + + Introduce [compat_]save_altstack_ex() to unbreak x86 SMAP + + commit bd1c149aa9915b9abb6d83d0f01dfd2ace0680b5 upstream. + + For performance reasons, when SMAP is in use, SMAP is left open for an + entire put_user_try { ... } put_user_catch(); block, however, calling + __put_user() in the middle of that block will close SMAP as the + STAC..CLAC constructs intentionally do not nest. + + Furthermore, using __put_user() rather than put_user_ex() here is bad + for performance. + + Thus, introduce new [compat_]save_altstack_ex() helpers that replace + __[compat_]save_altstack() for x86, being currently the only + architecture which supports put_user_try { ... } put_user_catch(). + + Reported-by: H. Peter Anvin + Signed-off-by: Al Viro + Signed-off-by: H. Peter Anvin + Link: http://lkml.kernel.org/n/tip-es5p6y64if71k8p5u08agv9n@git.kernel.org + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/ia32/ia32_signal.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/ia32/ia32_signal.c 2014-05-05 11:51:30.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/ia32/ia32_signal.c 2014-05-05 12:44:22.000000000 +0000 +@@ -459,7 +459,7 @@ + else + put_user_ex(0, &frame->uc.uc_flags); + put_user_ex(0, &frame->uc.uc_link); +- err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp); ++ compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); + + if (ksig->ka.sa.sa_flags & SA_RESTORER) + restorer = ksig->ka.sa.sa_restorer; +Index: linux-3.10-3.10.11/arch/x86/kernel/signal.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/signal.c 2014-05-05 11:51:30.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/signal.c 2014-05-05 12:44:22.000000000 +0000 +@@ -364,7 +364,7 @@ + else + put_user_ex(0, &frame->uc.uc_flags); + put_user_ex(0, &frame->uc.uc_link); +- err |= __save_altstack(&frame->uc.uc_stack, regs->sp); ++ save_altstack_ex(&frame->uc.uc_stack, regs->sp); + + /* Set up to return from userspace. */ + restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); +@@ -429,7 +429,7 @@ + else + put_user_ex(0, &frame->uc.uc_flags); + put_user_ex(0, &frame->uc.uc_link); +- err |= __save_altstack(&frame->uc.uc_stack, regs->sp); ++ save_altstack_ex(&frame->uc.uc_stack, regs->sp); + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ +@@ -496,7 +496,7 @@ + else + put_user_ex(0, &frame->uc.uc_flags); + put_user_ex(0, &frame->uc.uc_link); +- err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp); ++ compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); + put_user_ex(0, &frame->uc.uc__pad0); + + if (ksig->ka.sa.sa_flags & SA_RESTORER) { +Index: linux-3.10-3.10.11/include/linux/compat.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/compat.h 2014-05-05 11:51:30.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/compat.h 2014-05-05 12:44:23.000000000 +0000 +@@ -669,6 +669,13 @@ + + int compat_restore_altstack(const compat_stack_t __user *uss); + int __compat_save_altstack(compat_stack_t __user *, unsigned long); ++#define compat_save_altstack_ex(uss, sp) do { \ ++ compat_stack_t __user *__uss = uss; \ ++ struct task_struct *t = current; \ ++ put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \ ++ put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \ ++ put_user_ex(t->sas_ss_size, &__uss->ss_size); \ ++} while (0); + + asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, + struct compat_timespec __user *interval); +Index: linux-3.10-3.10.11/include/linux/signal.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/signal.h 2014-05-05 11:51:30.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/signal.h 2014-05-05 12:44:23.000000000 +0000 +@@ -434,6 +434,14 @@ + int restore_altstack(const stack_t __user *); + int __save_altstack(stack_t __user *, unsigned long); + ++#define save_altstack_ex(uss, sp) do { \ ++ stack_t __user *__uss = uss; \ ++ struct task_struct *t = current; \ ++ put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \ ++ put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \ ++ put_user_ex(t->sas_ss_size, &__uss->ss_size); \ ++} while (0); ++ + #ifdef CONFIG_PROC_FS + struct seq_file; + extern void render_sigset_t(struct seq_file *, const char *, sigset_t *); +Index: linux-3.10-3.10.11/dummy/rpi_1094_a168ad2687045d24e98b2525d1ee678c4f2a9a96.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1094_a168ad2687045d24e98b2525d1ee678c4f2a9a96.txt 2014-05-05 12:44:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1095_5e3db40138469c967ea0d323eeb8143f2d46a6aa.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1095_5e3db40138469c967ea0d323eeb8143f2d46a6aa.patch --- linux-3.10.11/debian/patches/rpi/rpi_1095_5e3db40138469c967ea0d323eeb8143f2d46a6aa.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1095_5e3db40138469c967ea0d323eeb8143f2d46a6aa.patch 2014-05-05 12:44:25.000000000 +0000 @@ -0,0 +1,34 @@ +commit 5e3db40138469c967ea0d323eeb8143f2d46a6aa +Author: Aravind Gopalakrishnan +Date: Fri Aug 2 17:43:02 2013 -0500 + + pci_ids: Add PCI device ID functions 3 and 4 for newer F15h models. + + commit 6bdaa63c2957ac04e8d596880f732b79f9c06c3c upstream. + + Add PCI device IDs for AMD F15h, model 30h. They will be used in + amd_nb.c and amd64_edac.c + + Signed-off-by: Aravind Gopalakrishnan + Signed-off-by: Borislav Petkov + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/pci_ids.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/pci_ids.h 2014-05-05 11:51:30.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/pci_ids.h 2014-05-05 12:44:24.000000000 +0000 +@@ -518,6 +518,8 @@ + #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 + #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 + #define PCI_DEVICE_ID_AMD_15H_M10H_F3 0x1403 ++#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F3 0x141d ++#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F4 0x141e + #define PCI_DEVICE_ID_AMD_15H_NB_F0 0x1600 + #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 + #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 +Index: linux-3.10-3.10.11/dummy/rpi_1095_5e3db40138469c967ea0d323eeb8143f2d46a6aa.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1095_5e3db40138469c967ea0d323eeb8143f2d46a6aa.txt 2014-05-05 12:44:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1096_b50361f39ca5a27cdadbd53b7a7d46daa3cde151.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1096_b50361f39ca5a27cdadbd53b7a7d46daa3cde151.patch --- linux-3.10.11/debian/patches/rpi/rpi_1096_b50361f39ca5a27cdadbd53b7a7d46daa3cde151.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1096_b50361f39ca5a27cdadbd53b7a7d46daa3cde151.patch 2014-05-05 12:44:26.000000000 +0000 @@ -0,0 +1,66 @@ +commit b50361f39ca5a27cdadbd53b7a7d46daa3cde151 +Author: Aravind Gopalakrishnan +Date: Fri Aug 2 17:43:03 2013 -0500 + + x86, amd_nb: Clarify F15h, model 30h GART and L3 support + + commit 7d64ac6422092adbbdaa279ab32f9d4c90a84558 upstream. + + F15h, models 0x30 and later don't have a GART. Note that. Also check + CPUID leaf 0x80000006 for L3 prescence because there are models which + don't sport an L3 cache. + + Signed-off-by: Aravind Gopalakrishnan + [ Boris: rewrite commit message, cleanup comments. ] + Signed-off-by: Borislav Petkov + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/kernel/amd_nb.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/amd_nb.c 2014-05-05 11:51:29.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/amd_nb.c 2014-05-05 12:44:25.000000000 +0000 +@@ -20,6 +20,7 @@ + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, + {} + }; +@@ -27,6 +28,7 @@ + + static const struct pci_device_id amd_nb_link_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, + {} + }; +@@ -81,13 +83,20 @@ + next_northbridge(misc, amd_nb_misc_ids); + node_to_amd_nb(i)->link = link = + next_northbridge(link, amd_nb_link_ids); +- } ++ } + ++ /* GART present only on Fam15h upto model 0fh */ + if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 || +- boot_cpu_data.x86 == 0x15) ++ (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10)) + amd_northbridges.flags |= AMD_NB_GART; + + /* ++ * Check for L3 cache presence. ++ */ ++ if (!cpuid_edx(0x80000006)) ++ return 0; ++ ++ /* + * Some CPU families support L3 Cache Index Disable. There are some + * limitations because of E382 and E388 on family 0x10. + */ +Index: linux-3.10-3.10.11/dummy/rpi_1096_b50361f39ca5a27cdadbd53b7a7d46daa3cde151.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1096_b50361f39ca5a27cdadbd53b7a7d46daa3cde151.txt 2014-05-05 12:44:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1097_8ceb02f11454cf5102bfede5a6e112abe3990bb2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1097_8ceb02f11454cf5102bfede5a6e112abe3990bb2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1097_8ceb02f11454cf5102bfede5a6e112abe3990bb2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1097_8ceb02f11454cf5102bfede5a6e112abe3990bb2.patch 2014-05-05 12:44:27.000000000 +0000 @@ -0,0 +1,53 @@ +commit 8ceb02f11454cf5102bfede5a6e112abe3990bb2 +Author: Tony Luck +Date: Wed Jul 24 13:54:20 2013 -0700 + + x86/mce: Pay no attention to 'F' bit in MCACOD when parsing 'UC' errors + + commit 0ca06c0857aee11911f91621db14498496f2c2cd upstream. + + The 0x1000 bit of the MCACOD field of machine check MCi_STATUS + registers is only defined for corrected errors (where it means + that hardware may be filtering errors see SDM section 15.9.2.1). + + For uncorrected errors it may, or may not be set - so we should mask + it out when checking for the architecturaly defined recoverable + error signatures (see SDM 15.9.3.1 and 15.9.3.2) + + Acked-by: Naveen N. Rao + Signed-off-by: Tony Luck + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/include/asm/mce.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/mce.h 2014-05-05 11:51:29.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/mce.h 2014-05-05 12:44:26.000000000 +0000 +@@ -32,11 +32,20 @@ + #define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */ + #define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */ + #define MCI_STATUS_AR (1ULL<<55) /* Action required */ +-#define MCACOD 0xffff /* MCA Error Code */ ++ ++/* ++ * Note that the full MCACOD field of IA32_MCi_STATUS MSR is ++ * bits 15:0. But bit 12 is the 'F' bit, defined for corrected ++ * errors to indicate that errors are being filtered by hardware. ++ * We should mask out bit 12 when looking for specific signatures ++ * of uncorrected errors - so the F bit is deliberately skipped ++ * in this #define. ++ */ ++#define MCACOD 0xefff /* MCA Error Code */ + + /* Architecturally defined codes from SDM Vol. 3B Chapter 15 */ + #define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */ +-#define MCACOD_SCRUBMSK 0xfff0 ++#define MCACOD_SCRUBMSK 0xeff0 /* Skip bit 12 ('F' bit) */ + #define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */ + #define MCACOD_DATA 0x0134 /* Data Load */ + #define MCACOD_INSTR 0x0150 /* Instruction Fetch */ +Index: linux-3.10-3.10.11/dummy/rpi_1097_8ceb02f11454cf5102bfede5a6e112abe3990bb2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1097_8ceb02f11454cf5102bfede5a6e112abe3990bb2.txt 2014-05-05 12:44:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1098_c18c0f9da9d97ea6710804971b981456a40cd01a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1098_c18c0f9da9d97ea6710804971b981456a40cd01a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1098_c18c0f9da9d97ea6710804971b981456a40cd01a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1098_c18c0f9da9d97ea6710804971b981456a40cd01a.patch 2014-05-05 12:44:27.000000000 +0000 @@ -0,0 +1,93 @@ +commit c18c0f9da9d97ea6710804971b981456a40cd01a +Author: Rik van Riel +Date: Wed Jul 31 22:14:21 2013 -0400 + + sched/x86: Optimize switch_mm() for multi-threaded workloads + + commit 8f898fbbe5ee5e20a77c4074472a1fd088dc47d1 upstream. + + Dick Fowles, Don Zickus and Joe Mario have been working on + improvements to perf, and noticed heavy cache line contention + on the mm_cpumask, running linpack on a 60 core / 120 thread + system. + + The cause turned out to be unnecessary atomic accesses to the + mm_cpumask. When in lazy TLB mode, the CPU is only removed from + the mm_cpumask if there is a TLB flush event. + + Most of the time, no such TLB flush happens, and the kernel + skips the TLB reload. It can also skip the atomic memory + set & test. + + Here is a summary of Joe's test results: + + * The __schedule function dropped from 24% of all program cycles down + to 5.5%. + + * The cacheline contention/hotness for accesses to that bitmask went + from being the 1st/2nd hottest - down to the 84th hottest (0.3% of + all shared misses which is now quite cold) + + * The average load latency for the bit-test-n-set instruction in + __schedule dropped from 10k-15k cycles down to an average of 600 cycles. + + * The linpack program results improved from 133 GFlops to 144 GFlops. + Peak GFlops rose from 133 to 153. + + Reported-by: Don Zickus + Reported-by: Joe Mario + Tested-by: Joe Mario + Signed-off-by: Rik van Riel + Reviewed-by: Paul Turner + Acked-by: Linus Torvalds + Link: http://lkml.kernel.org/r/20130731221421.616d3d20@annuminas.surriel.com + [ Made the comments consistent around the modified code. ] + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/include/asm/mmu_context.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/mmu_context.h 2014-05-05 11:51:29.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/mmu_context.h 2014-05-05 12:44:27.000000000 +0000 +@@ -45,22 +45,28 @@ + /* Re-load page tables */ + load_cr3(next->pgd); + +- /* stop flush ipis for the previous mm */ ++ /* Stop flush ipis for the previous mm */ + cpumask_clear_cpu(cpu, mm_cpumask(prev)); + +- /* +- * load the LDT, if the LDT is different: +- */ ++ /* Load the LDT, if the LDT is different: */ + if (unlikely(prev->context.ldt != next->context.ldt)) + load_LDT_nolock(&next->context); + } + #ifdef CONFIG_SMP +- else { ++ else { + this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK); + BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next); + +- if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next))) { +- /* We were in lazy tlb mode and leave_mm disabled ++ if (!cpumask_test_cpu(cpu, mm_cpumask(next))) { ++ /* ++ * On established mms, the mm_cpumask is only changed ++ * from irq context, from ptep_clear_flush() while in ++ * lazy tlb mode, and here. Irqs are blocked during ++ * schedule, protecting us from simultaneous changes. ++ */ ++ cpumask_set_cpu(cpu, mm_cpumask(next)); ++ /* ++ * We were in lazy tlb mode and leave_mm disabled + * tlb flush IPI delivery. We must reload CR3 + * to make sure to use no freed page tables. + */ +Index: linux-3.10-3.10.11/dummy/rpi_1098_c18c0f9da9d97ea6710804971b981456a40cd01a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1098_c18c0f9da9d97ea6710804971b981456a40cd01a.txt 2014-05-05 12:44:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1099_dc780f7fc64b6ca11854cd5ac724b85fa1853495.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1099_dc780f7fc64b6ca11854cd5ac724b85fa1853495.patch --- linux-3.10.11/debian/patches/rpi/rpi_1099_dc780f7fc64b6ca11854cd5ac724b85fa1853495.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1099_dc780f7fc64b6ca11854cd5ac724b85fa1853495.patch 2014-05-05 12:44:28.000000000 +0000 @@ -0,0 +1,147 @@ +commit dc780f7fc64b6ca11854cd5ac724b85fa1853495 +Author: Takashi Iwai +Date: Mon Sep 2 12:33:02 2013 +0200 + + ALSA: hda - Re-setup HDMI pin and audio infoframe on stream switches + + commit b054087dbacee30a9dddaef2c9a96312146be04e upstream. + + When the transcoder:port mapping on Haswell HDMI/DP audio is changed + during the stream playback, the sound gets lost. Typically this + problem is seen when the user switches the graphics mode from eDP+DP + to DP-only configuration, where CRTC 1 is used for DP in the former + while CRTC 0 is used for the latter. + + The graphics controller notifies the change via the normal ELD update + procedure, so we get the intrinsic event. For enabling the sound + again, the HDMI audio driver needs to reset the pin and set up the + audio infoframe again. + + This patch achieves it by: + - keep the current status of channels and info frame setup in per_pin + struct, + - check the reconnection in the intrinsic event handler, + - reset the pin and the re-invoke hdmi_setup_audio_infoframe() + accordingly. + + The hdmi_setup_audio_infoframe() function has been changed, too, so + that it can be invoked without passing the substream instance. + + The patch is mostly based on the work by Mengdong Lin. + + Cc: Mengdong Lin + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_hdmi.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_hdmi.c 2014-05-05 11:51:29.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_hdmi.c 2014-05-05 12:44:28.000000000 +0000 +@@ -67,6 +67,8 @@ + struct delayed_work work; + struct snd_kcontrol *eld_ctl; + int repoll_count; ++ bool setup; /* the stream has been set up by prepare callback */ ++ int channels; /* current number of channels */ + bool non_pcm; + bool chmap_set; /* channel-map override by ALSA API? */ + unsigned char chmap[8]; /* ALSA API channel-map */ +@@ -868,18 +870,19 @@ + return true; + } + +-static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, +- bool non_pcm, +- struct snd_pcm_substream *substream) ++static void hdmi_setup_audio_infoframe(struct hda_codec *codec, ++ struct hdmi_spec_per_pin *per_pin, ++ bool non_pcm) + { +- struct hdmi_spec *spec = codec->spec; +- struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); + hda_nid_t pin_nid = per_pin->pin_nid; +- int channels = substream->runtime->channels; ++ int channels = per_pin->channels; + struct hdmi_eld *eld; + int ca; + union audio_infoframe ai; + ++ if (!channels) ++ return; ++ + eld = &per_pin->sink_eld; + if (!eld->monitor_present) + return; +@@ -1263,6 +1266,7 @@ + eld_changed = true; + } + if (update_eld) { ++ bool old_eld_valid = pin_eld->eld_valid; + pin_eld->eld_valid = eld->eld_valid; + eld_changed = pin_eld->eld_size != eld->eld_size || + memcmp(pin_eld->eld_buffer, eld->eld_buffer, +@@ -1272,6 +1276,18 @@ + eld->eld_size); + pin_eld->eld_size = eld->eld_size; + pin_eld->info = eld->info; ++ ++ /* Haswell-specific workaround: re-setup when the transcoder is ++ * changed during the stream playback ++ */ ++ if (codec->vendor_id == 0x80862807 && ++ eld->eld_valid && !old_eld_valid && per_pin->setup) { ++ snd_hda_codec_write(codec, pin_nid, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, ++ AMP_OUT_UNMUTE); ++ hdmi_setup_audio_infoframe(codec, per_pin, ++ per_pin->non_pcm); ++ } + } + mutex_unlock(&pin_eld->lock); + +@@ -1444,14 +1460,17 @@ + hda_nid_t cvt_nid = hinfo->nid; + struct hdmi_spec *spec = codec->spec; + int pin_idx = hinfo_to_pin_index(spec, hinfo); +- hda_nid_t pin_nid = get_pin(spec, pin_idx)->pin_nid; ++ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); ++ hda_nid_t pin_nid = per_pin->pin_nid; + bool non_pcm; + + non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); ++ per_pin->channels = substream->runtime->channels; ++ per_pin->setup = true; + + hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); + +- hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream); ++ hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); + + return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); + } +@@ -1491,6 +1510,9 @@ + snd_hda_spdif_ctls_unassign(codec, pin_idx); + per_pin->chmap_set = false; + memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); ++ ++ per_pin->setup = false; ++ per_pin->channels = 0; + } + + return 0; +@@ -1626,8 +1648,7 @@ + per_pin->chmap_set = true; + memcpy(per_pin->chmap, chmap, sizeof(chmap)); + if (prepared) +- hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm, +- substream); ++ hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); + + return 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1099_dc780f7fc64b6ca11854cd5ac724b85fa1853495.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1099_dc780f7fc64b6ca11854cd5ac724b85fa1853495.txt 2014-05-05 12:44:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1100_686edbc09d22070e8ff3edaf7a6f53f80b4517b0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1100_686edbc09d22070e8ff3edaf7a6f53f80b4517b0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1100_686edbc09d22070e8ff3edaf7a6f53f80b4517b0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1100_686edbc09d22070e8ff3edaf7a6f53f80b4517b0.patch 2014-05-05 12:44:29.000000000 +0000 @@ -0,0 +1,70 @@ +commit 686edbc09d22070e8ff3edaf7a6f53f80b4517b0 +Author: Anssi Hannula +Date: Sun Sep 1 14:36:47 2013 +0300 + + ALSA: hda - hdmi: Fallback to ALSA allocation when selecting CA + + commit 18e391862cceaf43ddb8eb5cca05e1a83abdebaa upstream. + + hdmi_channel_allocation() tries to find a HDMI channel allocation that + matches the number channels in the playback stream and contains only + speakers that the HDMI sink has reported as available via EDID. If no + such allocation is found, 0 (stereo audio) is used. + + Using CA 0 causes the audio causes the sink to discard everything except + the first two channels (front left and front right). + + However, the sink may be capable of receiving more channels than it has + speakers (and then perform downmix or discard the extra channels), in + which case it is preferable to use a CA that contains extra channels + than to use CA 0 which discards all the non-stereo channels. + + Additionally, it seems that HBR (HD) passthrough output does not work on + Intel HDMI codecs when CA is set to 0 (possibly the codec zeroes + channels not present in CA). This happens with all receivers that report + a 5.1 speaker mask since a HBR stream is carried on 8 channels to the + codec. + + Add a fallback in the CA selection so that the CA channel count at least + matches the stream channel count, even if the stream contains channels + not present in the sink speaker descriptor. + + Thanks to GrimGriefer at OpenELEC forums for discovering that changing + the sink speaker mask allowed HBR output. + + Reported-by: GrimGriefer + Reported-by: Ashecrow + Reported-by: Frank Zafka + Reported-by: Peter Frühberger + Signed-off-by: Anssi Hannula + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_hdmi.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_hdmi.c 2014-05-05 12:44:28.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_hdmi.c 2014-05-05 12:44:28.000000000 +0000 +@@ -553,6 +553,17 @@ + } + } + ++ if (!ca) { ++ /* if there was no match, select the regular ALSA channel ++ * allocation with the matching number of channels */ ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ if (channels == channel_allocations[i].channels) { ++ ca = channel_allocations[i].ca_index; ++ break; ++ } ++ } ++ } ++ + snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf)); + snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n", + ca, channels, buf); +Index: linux-3.10-3.10.11/dummy/rpi_1100_686edbc09d22070e8ff3edaf7a6f53f80b4517b0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1100_686edbc09d22070e8ff3edaf7a6f53f80b4517b0.txt 2014-05-05 12:44:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1101_ff70cfafb27ead6e06ba3d2e2f648fee7137d9e8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1101_ff70cfafb27ead6e06ba3d2e2f648fee7137d9e8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1101_ff70cfafb27ead6e06ba3d2e2f648fee7137d9e8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1101_ff70cfafb27ead6e06ba3d2e2f648fee7137d9e8.patch 2014-05-05 12:44:30.000000000 +0000 @@ -0,0 +1,34 @@ +commit ff70cfafb27ead6e06ba3d2e2f648fee7137d9e8 +Author: Takashi Iwai +Date: Mon Sep 9 10:20:48 2013 +0200 + + ALSA: hda - Add Toshiba Satellite C870 to MSI blacklist + + commit 83f72151352791836a1b9c1542614cc9bf71ac61 upstream. + + Toshiba Satellite C870 shows interrupt problems occasionally when + certain mixer controls like "Mic Switch" is toggled. This seems + worked around by not using MSI. + + Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=833585 + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/hda_intel.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/hda_intel.c 2014-05-05 12:41:46.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/hda_intel.c 2014-05-05 12:44:29.000000000 +0000 +@@ -3335,6 +3335,7 @@ + SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ + SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ + SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ ++ SND_PCI_QUIRK(0x1179, 0xfb44, "Toshiba Satellite C870", 0), /* AMD Hudson */ + SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ + SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */ + {} +Index: linux-3.10-3.10.11/dummy/rpi_1101_ff70cfafb27ead6e06ba3d2e2f648fee7137d9e8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1101_ff70cfafb27ead6e06ba3d2e2f648fee7137d9e8.txt 2014-05-05 12:44:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1102_25a870d4dc930531f545aa1ae0cdca281d99f980.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1102_25a870d4dc930531f545aa1ae0cdca281d99f980.patch --- linux-3.10.11/debian/patches/rpi/rpi_1102_25a870d4dc930531f545aa1ae0cdca281d99f980.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1102_25a870d4dc930531f545aa1ae0cdca281d99f980.patch 2014-05-05 12:44:30.000000000 +0000 @@ -0,0 +1,45 @@ +commit 25a870d4dc930531f545aa1ae0cdca281d99f980 +Author: Boris BREZILLON +Date: Tue Aug 27 15:19:21 2013 +0200 + + pinctrl: at91: fix get_pullup/down function return + + commit 05d3534a321d7fe4524b3b83bb20318282f3ec2c upstream. + + In PIO_PUSR and PIO_PPDSR register if a given bit is set 1 this means the + pullup/down for this pin (pin is represented as a bit position) is + disabled. + + Signed-off-by: Boris BREZILLON + Acked-by: Nicolas Ferre + Signed-off-by: Linus Walleij + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/pinctrl/pinctrl-at91.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/pinctrl/pinctrl-at91.c 2014-05-05 11:51:27.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/pinctrl/pinctrl-at91.c 2014-05-05 12:44:30.000000000 +0000 +@@ -325,7 +325,7 @@ + + static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin) + { +- return (readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1; ++ return !((readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1); + } + + static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) +@@ -445,7 +445,7 @@ + + static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) + { +- return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1; ++ return !((__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1); + } + + static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) +Index: linux-3.10-3.10.11/dummy/rpi_1102_25a870d4dc930531f545aa1ae0cdca281d99f980.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1102_25a870d4dc930531f545aa1ae0cdca281d99f980.txt 2014-05-05 12:44:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1103_263c784f2b66e18e34208a2f0e56df65c039d918.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1103_263c784f2b66e18e34208a2f0e56df65c039d918.patch --- linux-3.10.11/debian/patches/rpi/rpi_1103_263c784f2b66e18e34208a2f0e56df65c039d918.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1103_263c784f2b66e18e34208a2f0e56df65c039d918.patch 2014-05-05 12:44:31.000000000 +0000 @@ -0,0 +1,158 @@ +commit 263c784f2b66e18e34208a2f0e56df65c039d918 +Author: Jan Kara +Date: Sat Aug 17 10:07:17 2013 -0400 + + ext4: simplify truncation code in ext4_setattr() + + commit 5208386c501276df18fee464e21d3c58d2d79517 upstream. + + Merge conditions in ext4_setattr() handling inode size changes, also + move ext4_begin_ordered_truncate() call somewhat earlier because it + simplifies error recovery in case of failure. Also add error handling in + case i_disksize update fails. + + Signed-off-by: Jan Kara + Signed-off-by: "Theodore Ts'o" + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/ext4/inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/ext4/inode.c 2014-05-05 11:51:27.000000000 +0000 ++++ linux-3.10-3.10.11/fs/ext4/inode.c 2014-05-05 12:44:31.000000000 +0000 +@@ -4706,7 +4706,9 @@ + ext4_journal_stop(handle); + } + +- if (attr->ia_valid & ATTR_SIZE) { ++ if (attr->ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) { ++ handle_t *handle; ++ loff_t oldsize = inode->i_size; + + if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); +@@ -4714,73 +4716,60 @@ + if (attr->ia_size > sbi->s_bitmap_maxbytes) + return -EFBIG; + } +- } +- +- if (S_ISREG(inode->i_mode) && +- attr->ia_valid & ATTR_SIZE && +- (attr->ia_size < inode->i_size)) { +- handle_t *handle; +- +- handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); +- if (IS_ERR(handle)) { +- error = PTR_ERR(handle); +- goto err_out; +- } +- if (ext4_handle_valid(handle)) { +- error = ext4_orphan_add(handle, inode); +- orphan = 1; +- } +- EXT4_I(inode)->i_disksize = attr->ia_size; +- rc = ext4_mark_inode_dirty(handle, inode); +- if (!error) +- error = rc; +- ext4_journal_stop(handle); +- +- if (ext4_should_order_data(inode)) { +- error = ext4_begin_ordered_truncate(inode, ++ if (S_ISREG(inode->i_mode) && ++ (attr->ia_size < inode->i_size)) { ++ if (ext4_should_order_data(inode)) { ++ error = ext4_begin_ordered_truncate(inode, + attr->ia_size); +- if (error) { +- /* Do as much error cleanup as possible */ +- handle = ext4_journal_start(inode, +- EXT4_HT_INODE, 3); +- if (IS_ERR(handle)) { +- ext4_orphan_del(NULL, inode); ++ if (error) + goto err_out; +- } +- ext4_orphan_del(handle, inode); +- orphan = 0; +- ext4_journal_stop(handle); ++ } ++ handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); ++ if (IS_ERR(handle)) { ++ error = PTR_ERR(handle); ++ goto err_out; ++ } ++ if (ext4_handle_valid(handle)) { ++ error = ext4_orphan_add(handle, inode); ++ orphan = 1; ++ } ++ EXT4_I(inode)->i_disksize = attr->ia_size; ++ rc = ext4_mark_inode_dirty(handle, inode); ++ if (!error) ++ error = rc; ++ ext4_journal_stop(handle); ++ if (error) { ++ ext4_orphan_del(NULL, inode); + goto err_out; + } + } +- } +- +- if (attr->ia_valid & ATTR_SIZE) { +- if (attr->ia_size != inode->i_size) { +- loff_t oldsize = inode->i_size; + +- i_size_write(inode, attr->ia_size); +- /* +- * Blocks are going to be removed from the inode. Wait +- * for dio in flight. Temporarily disable +- * dioread_nolock to prevent livelock. +- */ +- if (orphan) { +- if (!ext4_should_journal_data(inode)) { +- ext4_inode_block_unlocked_dio(inode); +- inode_dio_wait(inode); +- ext4_inode_resume_unlocked_dio(inode); +- } else +- ext4_wait_for_tail_page_commit(inode); +- } +- /* +- * Truncate pagecache after we've waited for commit +- * in data=journal mode to make pages freeable. +- */ +- truncate_pagecache(inode, oldsize, inode->i_size); ++ i_size_write(inode, attr->ia_size); ++ /* ++ * Blocks are going to be removed from the inode. Wait ++ * for dio in flight. Temporarily disable ++ * dioread_nolock to prevent livelock. ++ */ ++ if (orphan) { ++ if (!ext4_should_journal_data(inode)) { ++ ext4_inode_block_unlocked_dio(inode); ++ inode_dio_wait(inode); ++ ext4_inode_resume_unlocked_dio(inode); ++ } else ++ ext4_wait_for_tail_page_commit(inode); + } +- ext4_truncate(inode); ++ /* ++ * Truncate pagecache after we've waited for commit ++ * in data=journal mode to make pages freeable. ++ */ ++ truncate_pagecache(inode, oldsize, inode->i_size); + } ++ /* ++ * We want to call ext4_truncate() even if attr->ia_size == ++ * inode->i_size for cases like truncation of fallocated space ++ */ ++ if (attr->ia_valid & ATTR_SIZE) ++ ext4_truncate(inode); + + if (!rc) { + setattr_copy(inode, attr); +Index: linux-3.10-3.10.11/dummy/rpi_1103_263c784f2b66e18e34208a2f0e56df65c039d918.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1103_263c784f2b66e18e34208a2f0e56df65c039d918.txt 2014-05-05 12:44:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1104_d31a13c733d14114da0c7f6cf01396a6a2e1ccb2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1104_d31a13c733d14114da0c7f6cf01396a6a2e1ccb2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1104_d31a13c733d14114da0c7f6cf01396a6a2e1ccb2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1104_d31a13c733d14114da0c7f6cf01396a6a2e1ccb2.patch 2014-05-05 12:44:32.000000000 +0000 @@ -0,0 +1,106 @@ +commit d31a13c733d14114da0c7f6cf01396a6a2e1ccb2 +Author: John W. Linville +Date: Fri Aug 9 13:36:21 2013 -0400 + + brcmsmac: Fix WARNING caused by lack of calls to dma_mapping_error() + + commit 67d0cf50bd32b66eab709871714e55725ee30ce4 upstream. + + The driver fails to check the results of DMA mapping in twp places, + which results in the following warning: + + [ 28.078515] ------------[ cut here ]------------ + [ 28.078529] WARNING: at lib/dma-debug.c:937 check_unmap+0x47e/0x930() + [ 28.078533] bcma-pci-bridge 0000:0e:00.0: DMA-API: device driver failed to check map error[device address=0x00000000b5d60d6c] [size=1876 bytes] [mapped as + single] + [ 28.078536] Modules linked in: bnep bluetooth vboxpci(O) vboxnetadp(O) vboxnetflt(O) vboxdrv(O) ipv6 b43 brcmsmac rtl8192cu rtl8192c_common rtlwifi mac802 + 11 brcmutil cfg80211 snd_hda_codec_conexant rng_core snd_hda_intel kvm_amd snd_hda_codec ssb kvm mmc_core snd_pcm snd_seq snd_timer snd_seq_device snd k8temp + cordic joydev serio_raw hwmon sr_mod sg pcmcia pcmcia_core soundcore cdrom i2c_nforce2 i2c_core forcedeth bcma snd_page_alloc autofs4 ext4 jbd2 mbcache crc1 + 6 scsi_dh_alua scsi_dh_hp_sw scsi_dh_rdac scsi_dh_emc scsi_dh ata_generic pata_amd + [ 28.078602] CPU: 1 PID: 2570 Comm: NetworkManager Tainted: G O 3.10.0-rc7-wl+ #42 + [ 28.078605] Hardware name: Hewlett-Packard HP Pavilion dv2700 Notebook PC/30D6, BIOS F.27 11/27/2008 + [ 28.078607] 0000000000000009 ffff8800bbb03ad8 ffffffff8144f898 ffff8800bbb03b18 + [ 28.078612] ffffffff8103e1eb 0000000000000002 ffff8800b719f480 ffff8800b7b9c010 + [ 28.078617] ffffffff824204c0 ffffffff81754d57 0000000000000754 ffff8800bbb03b78 + [ 28.078622] Call Trace: + [ 28.078624] [] dump_stack+0x19/0x1b + [ 28.078634] [] warn_slowpath_common+0x6b/0xa0 + [ 28.078638] [] warn_slowpath_fmt+0x41/0x50 + [ 28.078650] [] check_unmap+0x47e/0x930 + [ 28.078655] [] debug_dma_unmap_page+0x5c/0x70 + [ 28.078679] [] dma64_getnextrxp+0x10c/0x190 [brcmsmac] + [ 28.078691] [] dma_rx+0x62/0x240 [brcmsmac] + [ 28.078707] [] brcms_c_dpc+0x211/0x9d0 [brcmsmac] + [ 28.078717] [] ? brcms_dpc+0x27/0xf0 [brcmsmac] + [ 28.078731] [] brcms_dpc+0x47/0xf0 [brcmsmac] + [ 28.078736] [] tasklet_action+0x6c/0xf0 + --snip-- + [ 28.078974] [] SyS_sendmsg+0xd/0x20 + [ 28.078979] [] tracesys+0xdd/0xe2 + [ 28.078982] ---[ end trace 6164d1a08148e9c8 ]--- + [ 28.078984] Mapped at: + [ 28.078985] [] debug_dma_map_page+0x9d/0x150 + [ 28.078989] [] dma_rxfill+0x102/0x3d0 [brcmsmac] + [ 28.079001] [] brcms_c_init+0x87d/0x1100 [brcmsmac] + [ 28.079010] [] brcms_init+0x21/0x30 [brcmsmac] + [ 28.079018] [] brcms_c_up+0x150/0x430 [brcmsmac] + + As the patch adds a new failure mechanism to dma_rxfill(). When I changed the + comment at the start of the routine to add that information, I also polished + the wording. + + Signed-off-by: Larry Finger + Cc: Brett Rudley + Cc: Franky (Zhenhui) Lin + Cc: Hante Meuleman + Cc: brcm80211-dev-list@broadcom.com + Acked-by: Arend van Spriel + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmsmac/dma.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/brcm80211/brcmsmac/dma.c 2014-05-05 11:51:27.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmsmac/dma.c 2014-05-05 12:44:31.000000000 +0000 +@@ -1015,9 +1015,10 @@ + + /* + * post receive buffers +- * return false is refill failed completely and ring is empty this will stall +- * the rx dma and user might want to call rxfill again asap. This unlikely +- * happens on memory-rich NIC, but often on memory-constrained dongle ++ * Return false if refill failed completely or dma mapping failed. The ring ++ * is empty, which will stall the rx dma and user might want to call rxfill ++ * again asap. This is unlikely to happen on a memory-rich NIC, but often on ++ * memory-constrained dongle. + */ + bool dma_rxfill(struct dma_pub *pub) + { +@@ -1078,6 +1079,8 @@ + + pa = dma_map_single(di->dmadev, p->data, di->rxbufsize, + DMA_FROM_DEVICE); ++ if (dma_mapping_error(di->dmadev, pa)) ++ return false; + + /* save the free packet pointer */ + di->rxp[rxout] = p; +@@ -1284,7 +1287,11 @@ + + /* get physical address of buffer start */ + pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); +- ++ /* if mapping failed, free skb */ ++ if (dma_mapping_error(di->dmadev, pa)) { ++ brcmu_pkt_buf_free_skb(p); ++ return; ++ } + /* With a DMA segment list, Descriptor table is filled + * using the segment list instead of looping over + * buffers in multi-chain DMA. Therefore, EOF for SGLIST +Index: linux-3.10-3.10.11/dummy/rpi_1104_d31a13c733d14114da0c7f6cf01396a6a2e1ccb2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1104_d31a13c733d14114da0c7f6cf01396a6a2e1ccb2.txt 2014-05-05 12:44:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1105_31f34c79a7e8fb75c7bf7d61d56fc8eeff2a7886.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1105_31f34c79a7e8fb75c7bf7d61d56fc8eeff2a7886.patch --- linux-3.10.11/debian/patches/rpi/rpi_1105_31f34c79a7e8fb75c7bf7d61d56fc8eeff2a7886.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1105_31f34c79a7e8fb75c7bf7d61d56fc8eeff2a7886.patch 2014-05-05 12:44:33.000000000 +0000 @@ -0,0 +1,33 @@ +commit 31f34c79a7e8fb75c7bf7d61d56fc8eeff2a7886 +Author: Felix Fietkau +Date: Tue Aug 6 14:18:10 2013 +0200 + + ath9k: always clear ps filter bit on new assoc + + commit 026d5b07c03458f9c0ccd19c3850564a5409c325 upstream. + + Otherwise in some cases, EAPOL frames might be filtered during the + initial handshake, causing delays and assoc failures. + + Signed-off-by: Felix Fietkau + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/xmit.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/ath9k/xmit.c 2014-05-05 11:51:26.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/xmit.c 2014-05-05 12:44:32.000000000 +0000 +@@ -2387,6 +2387,7 @@ + for (acno = 0, ac = &an->ac[acno]; + acno < IEEE80211_NUM_ACS; acno++, ac++) { + ac->sched = false; ++ ac->clear_ps_filter = true; + ac->txq = sc->tx.txq_map[acno]; + INIT_LIST_HEAD(&ac->tid_q); + } +Index: linux-3.10-3.10.11/dummy/rpi_1105_31f34c79a7e8fb75c7bf7d61d56fc8eeff2a7886.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1105_31f34c79a7e8fb75c7bf7d61d56fc8eeff2a7886.txt 2014-05-05 12:44:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1106_8e4d4c932d23091953185297d40315e8ba76837f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1106_8e4d4c932d23091953185297d40315e8ba76837f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1106_8e4d4c932d23091953185297d40315e8ba76837f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1106_8e4d4c932d23091953185297d40315e8ba76837f.patch 2014-05-05 12:44:34.000000000 +0000 @@ -0,0 +1,111 @@ +commit 8e4d4c932d23091953185297d40315e8ba76837f +Author: Felix Fietkau +Date: Sat Aug 10 15:59:15 2013 +0200 + + ath9k: fix rx descriptor related race condition + + commit e96542e55a2aacf4bdeccfe2f17b77c4895b4df2 upstream. + + Similar to a race condition that exists in the tx path, the hardware + might re-read the 'next' pointer of a descriptor of the last completed + frame. This only affects non-EDMA (pre-AR93xx) devices. + + To deal with this race, defer clearing and re-linking a completed rx + descriptor until the next one has been processed. + + Signed-off-by: Felix Fietkau + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/ath9k.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/ath9k/ath9k.h 2014-05-05 11:51:26.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/ath9k.h 2014-05-05 12:44:33.000000000 +0000 +@@ -79,10 +79,6 @@ + sizeof(struct ath_buf_state)); \ + } while (0) + +-#define ATH_RXBUF_RESET(_bf) do { \ +- (_bf)->bf_stale = false; \ +- } while (0) +- + /** + * enum buffer_type - Buffer type flags + * +@@ -316,6 +312,7 @@ + struct ath_descdma rxdma; + struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; + ++ struct ath_buf *buf_hold; + struct sk_buff *frag; + + u32 ampdu_ref; +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/recv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/ath9k/recv.c 2014-05-05 11:51:26.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/recv.c 2014-05-05 12:44:33.000000000 +0000 +@@ -42,8 +42,6 @@ + struct ath_desc *ds; + struct sk_buff *skb; + +- ATH_RXBUF_RESET(bf); +- + ds = bf->bf_desc; + ds->ds_link = 0; /* link to null */ + ds->ds_data = bf->bf_buf_addr; +@@ -70,6 +68,14 @@ + sc->rx.rxlink = &ds->ds_link; + } + ++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_buf *bf) ++{ ++ if (sc->rx.buf_hold) ++ ath_rx_buf_link(sc, sc->rx.buf_hold); ++ ++ sc->rx.buf_hold = bf; ++} ++ + static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) + { + /* XXX block beacon interrupts */ +@@ -117,7 +123,6 @@ + + skb = bf->bf_mpdu; + +- ATH_RXBUF_RESET(bf); + memset(skb->data, 0, ah->caps.rx_status_len); + dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, + ah->caps.rx_status_len, DMA_TO_DEVICE); +@@ -432,6 +437,7 @@ + if (list_empty(&sc->rx.rxbuf)) + goto start_recv; + ++ sc->rx.buf_hold = NULL; + sc->rx.rxlink = NULL; + list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { + ath_rx_buf_link(sc, bf); +@@ -677,6 +683,9 @@ + } + + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); ++ if (bf == sc->rx.buf_hold) ++ return NULL; ++ + ds = bf->bf_desc; + + /* +@@ -1378,7 +1387,7 @@ + if (edma) { + ath_rx_edma_buf_link(sc, qtype); + } else { +- ath_rx_buf_link(sc, bf); ++ ath_rx_buf_relink(sc, bf); + ath9k_hw_rxena(ah); + } + } while (1); +Index: linux-3.10-3.10.11/dummy/rpi_1106_8e4d4c932d23091953185297d40315e8ba76837f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1106_8e4d4c932d23091953185297d40315e8ba76837f.txt 2014-05-05 12:44:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1107_4bd13a76d67743f11e4f05c60340a333f54bb92b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1107_4bd13a76d67743f11e4f05c60340a333f54bb92b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1107_4bd13a76d67743f11e4f05c60340a333f54bb92b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1107_4bd13a76d67743f11e4f05c60340a333f54bb92b.patch 2014-05-05 12:44:34.000000000 +0000 @@ -0,0 +1,35 @@ +commit 4bd13a76d67743f11e4f05c60340a333f54bb92b +Author: Felix Fietkau +Date: Tue Aug 13 12:33:28 2013 +0200 + + ath9k: avoid accessing MRC registers on single-chain devices + + commit a1c781bb20ac1e03280e420abd47a99eb8bbdd3b upstream. + + They are not implemented, and accessing them might trigger errors + + Signed-off-by: Felix Fietkau + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/ar9003_phy.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/ath9k/ar9003_phy.c 2014-05-05 11:51:26.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/ar9003_phy.c 2014-05-05 12:44:34.000000000 +0000 +@@ -1076,6 +1076,10 @@ + * is_on == 0 means MRC CCK is OFF (more noise imm) + */ + bool is_on = param ? 1 : 0; ++ ++ if (ah->caps.rx_chainmask == 1) ++ break; ++ + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, + AR_PHY_MRC_CCK_ENABLE, is_on); + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, +Index: linux-3.10-3.10.11/dummy/rpi_1107_4bd13a76d67743f11e4f05c60340a333f54bb92b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1107_4bd13a76d67743f11e4f05c60340a333f54bb92b.txt 2014-05-05 12:44:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1108_32a190b73789d7d26846ca52d4d7eaacbf9ad6b7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1108_32a190b73789d7d26846ca52d4d7eaacbf9ad6b7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1108_32a190b73789d7d26846ca52d4d7eaacbf9ad6b7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1108_32a190b73789d7d26846ca52d4d7eaacbf9ad6b7.patch 2014-05-05 12:44:35.000000000 +0000 @@ -0,0 +1,61 @@ +commit 32a190b73789d7d26846ca52d4d7eaacbf9ad6b7 +Author: Henrik Rydberg +Date: Sun Sep 1 15:31:44 2013 +0200 + + HID: Correct the USB IDs for the new Macbook Air 6 + + commit 8c89cc17b91992845bd635813cd162fe8dfcec6e upstream. + + A recent patch (9d9a04ee) added support for the new machine, but got + the sequence of USB ids wrong. Reports from both Ian and Linus T show + that the 0x0291 id is for ISO, not ANSI, which should have the missing + number 0x0290. This patchs moves the three numbers accordingly, fixing + the problem. + + Reported-and-tested-by: Ian Munsie + Tested-by: Linus G Thiel + Signed-off-by: Henrik Rydberg + Acked-by: Dmitry Torokhov + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-ids.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-ids.h 2014-05-05 11:51:26.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-ids.h 2014-05-05 12:44:35.000000000 +0000 +@@ -135,9 +135,9 @@ + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 +-#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0291 +-#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0292 +-#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0293 ++#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 ++#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 ++#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +Index: linux-3.10-3.10.11/drivers/input/mouse/bcm5974.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/input/mouse/bcm5974.c 2014-05-05 11:51:26.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/input/mouse/bcm5974.c 2014-05-05 12:44:35.000000000 +0000 +@@ -89,9 +89,9 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a + #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b + /* MacbookAir6,2 (unibody, June 2013) */ +-#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0291 +-#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0292 +-#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0293 ++#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 ++#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 ++#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +Index: linux-3.10-3.10.11/dummy/rpi_1108_32a190b73789d7d26846ca52d4d7eaacbf9ad6b7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1108_32a190b73789d7d26846ca52d4d7eaacbf9ad6b7.txt 2014-05-05 12:44:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1109_769eea247c41519e72675c72d0da8d95fd6b7c09.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1109_769eea247c41519e72675c72d0da8d95fd6b7c09.patch --- linux-3.10.11/debian/patches/rpi/rpi_1109_769eea247c41519e72675c72d0da8d95fd6b7c09.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1109_769eea247c41519e72675c72d0da8d95fd6b7c09.patch 2014-05-05 12:44:36.000000000 +0000 @@ -0,0 +1,49 @@ +commit 769eea247c41519e72675c72d0da8d95fd6b7c09 +Author: Kees Cook +Date: Wed Aug 28 22:30:49 2013 +0200 + + HID: pantherlord: validate output report details + + commit 412f30105ec6735224535791eed5cdc02888ecb4 upstream. + + A HID device could send a malicious output report that would cause the + pantherlord HID driver to write beyond the output report allocation + during initialization, causing a heap overflow: + + [ 310.939483] usb 1-1: New USB device found, idVendor=0e8f, idProduct=0003 + ... + [ 315.980774] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten + + CVE-2013-2892 + + Signed-off-by: Kees Cook + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-pl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-pl.c 2014-05-05 11:51:25.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-pl.c 2014-05-05 12:44:36.000000000 +0000 +@@ -132,8 +132,14 @@ + strong = &report->field[0]->value[2]; + weak = &report->field[0]->value[3]; + debug("detected single-field device"); +- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && +- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { ++ } else if (report->field[0]->maxusage == 1 && ++ report->field[0]->usage[0].hid == ++ (HID_UP_LED | 0x43) && ++ report->maxfield >= 4 && ++ report->field[0]->report_count >= 1 && ++ report->field[1]->report_count >= 1 && ++ report->field[2]->report_count >= 1 && ++ report->field[3]->report_count >= 1) { + report->field[0]->value[0] = 0x00; + report->field[1]->value[0] = 0x00; + strong = &report->field[2]->value[0]; +Index: linux-3.10-3.10.11/dummy/rpi_1109_769eea247c41519e72675c72d0da8d95fd6b7c09.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1109_769eea247c41519e72675c72d0da8d95fd6b7c09.txt 2014-05-05 12:44:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1110_469e7f80f25f79a4c11bed47027da81fcf30d045.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1110_469e7f80f25f79a4c11bed47027da81fcf30d045.patch --- linux-3.10.11/debian/patches/rpi/rpi_1110_469e7f80f25f79a4c11bed47027da81fcf30d045.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1110_469e7f80f25f79a4c11bed47027da81fcf30d045.patch 2014-05-05 12:44:37.000000000 +0000 @@ -0,0 +1,55 @@ +commit 469e7f80f25f79a4c11bed47027da81fcf30d045 +Author: Stefan Kriwanek +Date: Sun Aug 25 10:46:13 2013 +0200 + + HID: Fix Speedlink VAD Cezanne support for some devices + + commit 06bb5219118fb098f4b0c7dcb484b28a52bf1c14 upstream. + + Some devices of the "Speedlink VAD Cezanne" model need more aggressive fixing + than already done. + + I made sure through testing that this patch would not interfere with the proper + working of a device that is bug-free. (The driver drops EV_REL events with + abs(val) >= 256, which are not achievable even on the highest laser resolution + hardware setting.) + + Signed-off-by: Stefan Kriwanek + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-speedlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-speedlink.c 2014-05-05 11:51:25.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-speedlink.c 2014-05-05 12:44:36.000000000 +0000 +@@ -3,7 +3,7 @@ + * Fixes "jumpy" cursor and removes nonexistent keyboard LEDS from + * the HID descriptor. + * +- * Copyright (c) 2011 Stefan Kriwanek ++ * Copyright (c) 2011, 2013 Stefan Kriwanek + */ + + /* +@@ -46,8 +46,13 @@ + struct hid_usage *usage, __s32 value) + { + /* No other conditions due to usage_table. */ +- /* Fix "jumpy" cursor (invalid events sent by device). */ +- if (value == 256) ++ ++ /* This fixes the "jumpy" cursor occuring due to invalid events sent ++ * by the device. Some devices only send them with value==+256, others ++ * don't. However, catching abs(value)>=256 is restrictive enough not ++ * to interfere with devices that were bug-free (has been tested). ++ */ ++ if (abs(value) >= 256) + return 1; + /* Drop useless distance 0 events (on button clicks etc.) as well */ + if (value == 0) +Index: linux-3.10-3.10.11/dummy/rpi_1110_469e7f80f25f79a4c11bed47027da81fcf30d045.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1110_469e7f80f25f79a4c11bed47027da81fcf30d045.txt 2014-05-05 12:44:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1111_a3957df756ccf3a46c24c8e2d4f8b26c932357b3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1111_a3957df756ccf3a46c24c8e2d4f8b26c932357b3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1111_a3957df756ccf3a46c24c8e2d4f8b26c932357b3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1111_a3957df756ccf3a46c24c8e2d4f8b26c932357b3.patch 2014-05-05 12:44:38.000000000 +0000 @@ -0,0 +1,39 @@ +commit a3957df756ccf3a46c24c8e2d4f8b26c932357b3 +Author: Kees Cook +Date: Wed Aug 28 22:31:44 2013 +0200 + + HID: sensor-hub: validate feature report details + + commit 9e8910257397372633e74b333ef891f20c800ee4 upstream. + + A HID device could send a malicious feature report that would cause the + sensor-hub HID driver to read past the end of heap allocation, leaking + kernel memory contents to the caller. + + CVE-2013-2898 + + Signed-off-by: Kees Cook + Reviewed-by: Mika Westerberg + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-sensor-hub.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-sensor-hub.c 2014-05-05 11:51:25.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-sensor-hub.c 2014-05-05 12:44:37.000000000 +0000 +@@ -221,7 +221,8 @@ + + mutex_lock(&data->mutex); + report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); +- if (!report || (field_index >= report->maxfield)) { ++ if (!report || (field_index >= report->maxfield) || ++ report->field[field_index]->report_count < 1) { + ret = -EINVAL; + goto done_proc; + } +Index: linux-3.10-3.10.11/dummy/rpi_1111_a3957df756ccf3a46c24c8e2d4f8b26c932357b3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1111_a3957df756ccf3a46c24c8e2d4f8b26c932357b3.txt 2014-05-05 12:44:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1112_56085cec9ef90f5133effbcf71149d19ea2f5170.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1112_56085cec9ef90f5133effbcf71149d19ea2f5170.patch --- linux-3.10.11/debian/patches/rpi/rpi_1112_56085cec9ef90f5133effbcf71149d19ea2f5170.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1112_56085cec9ef90f5133effbcf71149d19ea2f5170.patch 2014-05-05 12:44:39.000000000 +0000 @@ -0,0 +1,81 @@ +commit 56085cec9ef90f5133effbcf71149d19ea2f5170 +Author: Kees Cook +Date: Wed Aug 28 22:29:55 2013 +0200 + + HID: validate HID report id size + + commit 43622021d2e2b82ea03d883926605bdd0525e1d1 upstream. + + The "Report ID" field of a HID report is used to build indexes of + reports. The kernel's index of these is limited to 256 entries, so any + malicious device that sets a Report ID greater than 255 will trigger + memory corruption on the host: + + [ 1347.156239] BUG: unable to handle kernel paging request at ffff88094958a878 + [ 1347.156261] IP: [] hid_register_report+0x2a/0x8b + + CVE-2013-2888 + + Signed-off-by: Kees Cook + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-core.c 2014-05-05 11:51:25.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-core.c 2014-05-05 12:44:38.000000000 +0000 +@@ -63,6 +63,8 @@ + struct hid_report_enum *report_enum = device->report_enum + type; + struct hid_report *report; + ++ if (id >= HID_MAX_IDS) ++ return NULL; + if (report_enum->report_id_hash[id]) + return report_enum->report_id_hash[id]; + +@@ -404,8 +406,10 @@ + + case HID_GLOBAL_ITEM_TAG_REPORT_ID: + parser->global.report_id = item_udata(item); +- if (parser->global.report_id == 0) { +- hid_err(parser->device, "report_id 0 is invalid\n"); ++ if (parser->global.report_id == 0 || ++ parser->global.report_id >= HID_MAX_IDS) { ++ hid_err(parser->device, "report_id %u is invalid\n", ++ parser->global.report_id); + return -1; + } + return 0; +@@ -575,7 +579,7 @@ + for (i = 0; i < HID_REPORT_TYPES; i++) { + struct hid_report_enum *report_enum = device->report_enum + i; + +- for (j = 0; j < 256; j++) { ++ for (j = 0; j < HID_MAX_IDS; j++) { + struct hid_report *report = report_enum->report_id_hash[j]; + if (report) + hid_free_report(report); +Index: linux-3.10-3.10.11/include/linux/hid.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/hid.h 2014-05-05 11:51:25.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/hid.h 2014-05-05 12:44:38.000000000 +0000 +@@ -393,10 +393,12 @@ + struct hid_device *device; /* associated device */ + }; + ++#define HID_MAX_IDS 256 ++ + struct hid_report_enum { + unsigned numbered; + struct list_head report_list; +- struct hid_report *report_id_hash[256]; ++ struct hid_report *report_id_hash[HID_MAX_IDS]; + }; + + #define HID_REPORT_TYPES 3 +Index: linux-3.10-3.10.11/dummy/rpi_1112_56085cec9ef90f5133effbcf71149d19ea2f5170.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1112_56085cec9ef90f5133effbcf71149d19ea2f5170.txt 2014-05-05 12:44:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1113_0697d8057661db5032a55dd5b0d115262c883cb4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1113_0697d8057661db5032a55dd5b0d115262c883cb4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1113_0697d8057661db5032a55dd5b0d115262c883cb4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1113_0697d8057661db5032a55dd5b0d115262c883cb4.patch 2014-05-05 12:44:39.000000000 +0000 @@ -0,0 +1,48 @@ +commit 0697d8057661db5032a55dd5b0d115262c883cb4 +Author: Kees Cook +Date: Wed Aug 28 22:31:52 2013 +0200 + + HID: picolcd_core: validate output report details + + commit 1e87a2456b0227ca4ab881e19a11bb99d164e792 upstream. + + A HID device could send a malicious output report that would cause the + picolcd HID driver to trigger a NULL dereference during attr file writing. + + [jkosina@suse.cz: changed + + report->maxfield < 1 + + to + + report->maxfield != 1 + + as suggested by Bruno]. + + CVE-2013-2899 + + Signed-off-by: Kees Cook + Reviewed-by: Bruno Prémont + Acked-by: Bruno Prémont + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-picolcd_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-picolcd_core.c 2014-05-05 11:51:24.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-picolcd_core.c 2014-05-05 12:44:39.000000000 +0000 +@@ -290,7 +290,7 @@ + buf += 10; + cnt -= 10; + } +- if (!report) ++ if (!report || report->maxfield != 1) + return -EINVAL; + + while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r')) +Index: linux-3.10-3.10.11/dummy/rpi_1113_0697d8057661db5032a55dd5b0d115262c883cb4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1113_0697d8057661db5032a55dd5b0d115262c883cb4.txt 2014-05-05 12:44:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1114_7c91362f8c00c6fb75da374c749a024d6d3563fb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1114_7c91362f8c00c6fb75da374c749a024d6d3563fb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1114_7c91362f8c00c6fb75da374c749a024d6d3563fb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1114_7c91362f8c00c6fb75da374c749a024d6d3563fb.patch 2014-05-05 12:44:40.000000000 +0000 @@ -0,0 +1,43 @@ +commit 7c91362f8c00c6fb75da374c749a024d6d3563fb +Author: Kees Cook +Date: Wed Aug 28 22:31:28 2013 +0200 + + HID: ntrig: validate feature report details + + commit 875b4e3763dbc941f15143dd1a18d10bb0be303b upstream. + + A HID device could send a malicious feature report that would cause the + ntrig HID driver to trigger a NULL dereference during initialization: + + [57383.031190] usb 3-1: New USB device found, idVendor=1b96, idProduct=0001 + ... + [57383.315193] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 + [57383.315308] IP: [] ntrig_probe+0x25e/0x420 [hid_ntrig] + + CVE-2013-2896 + + Signed-off-by: Kees Cook + Signed-off-by: Rafi Rubin + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-ntrig.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-ntrig.c 2014-05-05 11:51:24.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-ntrig.c 2014-05-05 12:44:40.000000000 +0000 +@@ -115,7 +115,8 @@ + struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. + report_id_hash[0x0d]; + +- if (!report) ++ if (!report || report->maxfield < 1 || ++ report->field[0]->report_count < 1) + return -EINVAL; + + hid_hw_request(hdev, report, HID_REQ_GET_REPORT); +Index: linux-3.10-3.10.11/dummy/rpi_1114_7c91362f8c00c6fb75da374c749a024d6d3563fb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1114_7c91362f8c00c6fb75da374c749a024d6d3563fb.txt 2014-05-05 12:44:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1115_69f2af2ddcfd0d9984e764bdf0953a8d9248755a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1115_69f2af2ddcfd0d9984e764bdf0953a8d9248755a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1115_69f2af2ddcfd0d9984e764bdf0953a8d9248755a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1115_69f2af2ddcfd0d9984e764bdf0953a8d9248755a.patch 2014-05-05 12:44:41.000000000 +0000 @@ -0,0 +1,75 @@ +commit 69f2af2ddcfd0d9984e764bdf0953a8d9248755a +Author: Bruno Prémont +Date: Sat Aug 31 14:07:48 2013 +0200 + + HID: picolcd: Prevent NULL pointer dereference on _remove() + + commit 1cde501bb4655e98fb832194beb88ac73be5a05d upstream. + + When picolcd is switched into bootloader mode (for FW flashing) make + sure not to try to dereference NULL-pointers of feature-devices during + unplug/unbind. + + This fixes following BUG: + BUG: unable to handle kernel NULL pointer dereference at 00000298 + IP: [] picolcd_exit_framebuffer+0x1b/0x80 [hid_picolcd] + *pde = 00000000 + Oops: 0000 [#1] + Modules linked in: hid_picolcd syscopyarea sysfillrect sysimgblt fb_sys_fops + CPU: 0 PID: 15 Comm: khubd Not tainted 3.11.0-rc7-00002-g50d62d4 #2 + EIP: 0060:[] EFLAGS: 00010292 CPU: 0 + EIP is at picolcd_exit_framebuffer+0x1b/0x80 [hid_picolcd] + Call Trace: + [] picolcd_remove+0xcb/0x120 [hid_picolcd] + [] hid_device_remove+0x59/0xc0 + [] __device_release_driver+0x5a/0xb0 + [] device_release_driver+0x1f/0x30 + [] bus_remove_device+0x9d/0xd0 + [] device_del+0xd5/0x150 + [] hid_destroy_device+0x24/0x60 + [] usbhid_disconnect+0x1b/0x40 + ... + + Signed-off-by: Bruno Prémont + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-picolcd_cir.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-picolcd_cir.c 2014-05-05 11:51:24.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-picolcd_cir.c 2014-05-05 12:44:41.000000000 +0000 +@@ -145,6 +145,7 @@ + struct rc_dev *rdev = data->rc_dev; + + data->rc_dev = NULL; +- rc_unregister_device(rdev); ++ if (rdev) ++ rc_unregister_device(rdev); + } + +Index: linux-3.10-3.10.11/drivers/hid/hid-picolcd_fb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-picolcd_fb.c 2014-05-05 11:51:24.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-picolcd_fb.c 2014-05-05 12:44:41.000000000 +0000 +@@ -593,10 +593,14 @@ + void picolcd_exit_framebuffer(struct picolcd_data *data) + { + struct fb_info *info = data->fb_info; +- struct picolcd_fb_data *fbdata = info->par; ++ struct picolcd_fb_data *fbdata; + unsigned long flags; + ++ if (!info) ++ return; ++ + device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); ++ fbdata = info->par; + + /* disconnect framebuffer from HID dev */ + spin_lock_irqsave(&fbdata->lock, flags); +Index: linux-3.10-3.10.11/dummy/rpi_1115_69f2af2ddcfd0d9984e764bdf0953a8d9248755a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1115_69f2af2ddcfd0d9984e764bdf0953a8d9248755a.txt 2014-05-05 12:44:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1116_65a839f4b7fd73d2a84c2d404c94a162751e8edb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1116_65a839f4b7fd73d2a84c2d404c94a162751e8edb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1116_65a839f4b7fd73d2a84c2d404c94a162751e8edb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1116_65a839f4b7fd73d2a84c2d404c94a162751e8edb.patch 2014-05-05 12:44:42.000000000 +0000 @@ -0,0 +1,65 @@ +commit 65a839f4b7fd73d2a84c2d404c94a162751e8edb +Author: Jiri Kosina +Date: Mon Sep 2 13:43:00 2013 +0200 + + HID: battery: don't do DMA from stack + + commit 6c2794a2984f4c17a58117a68703cc7640f01c5a upstream. + + Instead of using data from stack for DMA in hidinput_get_battery_property(), + allocate the buffer dynamically. + + Reported-by: Richard Ryniker + Reported-by: Alan Stern + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-input.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-input.c 2014-05-05 11:51:23.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-input.c 2014-05-05 12:44:41.000000000 +0000 +@@ -340,7 +340,7 @@ + { + struct hid_device *dev = container_of(psy, struct hid_device, battery); + int ret = 0; +- __u8 buf[2] = {}; ++ __u8 *buf; + + switch (prop) { + case POWER_SUPPLY_PROP_PRESENT: +@@ -349,13 +349,20 @@ + break; + + case POWER_SUPPLY_PROP_CAPACITY: ++ ++ buf = kmalloc(2 * sizeof(__u8), GFP_KERNEL); ++ if (!buf) { ++ ret = -ENOMEM; ++ break; ++ } + ret = dev->hid_get_raw_report(dev, dev->battery_report_id, +- buf, sizeof(buf), ++ buf, 2, + dev->battery_report_type); + + if (ret != 2) { + if (ret >= 0) + ret = -EINVAL; ++ kfree(buf); + break; + } + +@@ -364,6 +371,7 @@ + buf[1] <= dev->battery_max) + val->intval = (100 * (buf[1] - dev->battery_min)) / + (dev->battery_max - dev->battery_min); ++ kfree(buf); + break; + + case POWER_SUPPLY_PROP_MODEL_NAME: +Index: linux-3.10-3.10.11/dummy/rpi_1116_65a839f4b7fd73d2a84c2d404c94a162751e8edb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1116_65a839f4b7fd73d2a84c2d404c94a162751e8edb.txt 2014-05-05 12:44:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1117_d0de24dd0e200c83382cd3fff8e8c06cb6dcef2b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1117_d0de24dd0e200c83382cd3fff8e8c06cb6dcef2b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1117_d0de24dd0e200c83382cd3fff8e8c06cb6dcef2b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1117_d0de24dd0e200c83382cd3fff8e8c06cb6dcef2b.patch 2014-05-05 12:44:43.000000000 +0000 @@ -0,0 +1,137 @@ +commit d0de24dd0e200c83382cd3fff8e8c06cb6dcef2b +Author: Manoj Chourasia +Date: Mon Jul 22 15:33:13 2013 +0530 + + HID: hidraw: correctly deallocate memory on device disconnect + + commit 212a871a3934beccf43431608c27ed2e05a476ec upstream. + + This changes puts the commit 4fe9f8e203f back in place + with the fixes for slab corruption because of the commit. + + When a device is unplugged, wait for all processes that + have opened the device to close before deallocating the device. + + This commit was solving kernel crash because of the corruption in + rb tree of vmalloc. The rootcause was the device data pointer was + geting excessed after the memory associated with hidraw was freed. + + The commit 4fe9f8e203f was buggy as it was also freeing the hidraw + first and then calling delete operation on the list associated with + that hidraw leading to slab corruption. + + Signed-off-by: Manoj Chourasia + Tested-by: Peter Wu + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hidraw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hidraw.c 2014-05-05 11:51:23.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hidraw.c 2014-05-05 12:44:42.000000000 +0000 +@@ -113,7 +113,7 @@ + __u8 *buf; + int ret = 0; + +- if (!hidraw_table[minor]) { ++ if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { + ret = -ENODEV; + goto out; + } +@@ -261,7 +261,7 @@ + } + + mutex_lock(&minors_lock); +- if (!hidraw_table[minor]) { ++ if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { + err = -ENODEV; + goto out_unlock; + } +@@ -302,39 +302,38 @@ + return fasync_helper(fd, file, on, &list->fasync); + } + ++static void drop_ref(struct hidraw *hidraw, int exists_bit) ++{ ++ if (exists_bit) { ++ hid_hw_close(hidraw->hid); ++ hidraw->exist = 0; ++ if (hidraw->open) ++ wake_up_interruptible(&hidraw->wait); ++ } else { ++ --hidraw->open; ++ } ++ ++ if (!hidraw->open && !hidraw->exist) { ++ device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); ++ hidraw_table[hidraw->minor] = NULL; ++ kfree(hidraw); ++ } ++} ++ + static int hidraw_release(struct inode * inode, struct file * file) + { + unsigned int minor = iminor(inode); +- struct hidraw *dev; + struct hidraw_list *list = file->private_data; +- int ret; +- int i; + + mutex_lock(&minors_lock); +- if (!hidraw_table[minor]) { +- ret = -ENODEV; +- goto unlock; +- } + + list_del(&list->node); +- dev = hidraw_table[minor]; +- if (!--dev->open) { +- if (list->hidraw->exist) { +- hid_hw_power(dev->hid, PM_HINT_NORMAL); +- hid_hw_close(dev->hid); +- } else { +- kfree(list->hidraw); +- } +- } +- +- for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) +- kfree(list->buffer[i].value); + kfree(list); +- ret = 0; +-unlock: +- mutex_unlock(&minors_lock); + +- return ret; ++ drop_ref(hidraw_table[minor], 0); ++ ++ mutex_unlock(&minors_lock); ++ return 0; + } + + static long hidraw_ioctl(struct file *file, unsigned int cmd, +@@ -539,18 +538,9 @@ + struct hidraw *hidraw = hid->hidraw; + + mutex_lock(&minors_lock); +- hidraw->exist = 0; +- +- device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); + +- hidraw_table[hidraw->minor] = NULL; ++ drop_ref(hidraw, 1); + +- if (hidraw->open) { +- hid_hw_close(hid); +- wake_up_interruptible(&hidraw->wait); +- } else { +- kfree(hidraw); +- } + mutex_unlock(&minors_lock); + } + EXPORT_SYMBOL_GPL(hidraw_disconnect); +Index: linux-3.10-3.10.11/dummy/rpi_1117_d0de24dd0e200c83382cd3fff8e8c06cb6dcef2b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1117_d0de24dd0e200c83382cd3fff8e8c06cb6dcef2b.txt 2014-05-05 12:44:42.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1118_8bb7aacefb408f829835f3692dd34fab9801d86d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1118_8bb7aacefb408f829835f3692dd34fab9801d86d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1118_8bb7aacefb408f829835f3692dd34fab9801d86d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1118_8bb7aacefb408f829835f3692dd34fab9801d86d.patch 2014-05-05 12:44:44.000000000 +0000 @@ -0,0 +1,38 @@ +commit 8bb7aacefb408f829835f3692dd34fab9801d86d +Author: Kees Cook +Date: Wed Aug 28 22:32:01 2013 +0200 + + HID: check for NULL field when setting values + + commit be67b68d52fa28b9b721c47bb42068f0c1214855 upstream. + + Defensively check that the field to be worked on is not NULL. + + Signed-off-by: Kees Cook + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-core.c 2014-05-05 12:44:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-core.c 2014-05-05 12:44:43.000000000 +0000 +@@ -1156,7 +1156,12 @@ + + int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) + { +- unsigned size = field->report_size; ++ unsigned size; ++ ++ if (!field) ++ return -1; ++ ++ size = field->report_size; + + hid_dump_input(field->report->device, field->usage + offset, value); + +Index: linux-3.10-3.10.11/dummy/rpi_1118_8bb7aacefb408f829835f3692dd34fab9801d86d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1118_8bb7aacefb408f829835f3692dd34fab9801d86d.txt 2014-05-05 12:44:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1119_5f24e1842d5d65d479818b719adb1286d9925840.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1119_5f24e1842d5d65d479818b719adb1286d9925840.patch --- linux-3.10.11/debian/patches/rpi/rpi_1119_5f24e1842d5d65d479818b719adb1286d9925840.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1119_5f24e1842d5d65d479818b719adb1286d9925840.patch 2014-05-05 12:44:45.000000000 +0000 @@ -0,0 +1,46 @@ +commit 5f24e1842d5d65d479818b719adb1286d9925840 +Author: Vasily Titskiy +Date: Fri Aug 30 18:25:04 2013 -0400 + + HID: usbhid: quirk for N-Trig DuoSense Touch Screen + + commit 9e0bf92c223dabe0789714f8f85f6e26f8f9cda4 upstream. + + The DuoSense touchscreen device causes a 10 second timeout. This fix + removes the delay. + + Signed-off-by: Vasily Titskiy + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-ids.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-ids.h 2014-05-05 12:44:35.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-ids.h 2014-05-05 12:44:44.000000000 +0000 +@@ -646,6 +646,7 @@ + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012 + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013 + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014 ++#define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500 + + #define USB_VENDOR_ID_ONTRAK 0x0a07 + #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 +Index: linux-3.10-3.10.11/drivers/hid/usbhid/hid-quirks.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/usbhid/hid-quirks.c 2014-05-05 11:51:22.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/usbhid/hid-quirks.c 2014-05-05 12:44:44.000000000 +0000 +@@ -109,6 +109,8 @@ + { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, ++ + { 0, 0 } + }; + +Index: linux-3.10-3.10.11/dummy/rpi_1119_5f24e1842d5d65d479818b719adb1286d9925840.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1119_5f24e1842d5d65d479818b719adb1286d9925840.txt 2014-05-05 12:44:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1120_1d9d780fcd8df7c70312fdfe43ecc802b99b2e5c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1120_1d9d780fcd8df7c70312fdfe43ecc802b99b2e5c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1120_1d9d780fcd8df7c70312fdfe43ecc802b99b2e5c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1120_1d9d780fcd8df7c70312fdfe43ecc802b99b2e5c.patch 2014-05-05 12:44:45.000000000 +0000 @@ -0,0 +1,87 @@ +commit 1d9d780fcd8df7c70312fdfe43ecc802b99b2e5c +Author: Arun Kumar K +Date: Fri Jul 26 07:28:01 2013 -0300 + + media: exynos-gsc: Register v4l2 device + + commit d0b1c31349969973204fad21a076aecf131cc5e4 upstream. + + Gscaler video device registration was happening without reference to + a parent v4l2_dev causing probe to fail. The patch creates a parent + v4l2 device and uses it for the gsc m2m video device registration. + This fixes regression introduced with comit commit 1c1d86a1ea07506 + [media] v4l2: always require v4l2_dev, rename parent to dev_parent + + Signed-off-by: Arun Kumar K + Signed-off-by: Sylwester Nawrocki + Signed-off-by: Mauro Carvalho Chehab + Cc: stable@vger.kernel.org + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/platform/exynos-gsc/gsc-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/platform/exynos-gsc/gsc-core.c 2014-05-05 11:51:22.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/platform/exynos-gsc/gsc-core.c 2014-05-05 12:44:45.000000000 +0000 +@@ -1122,10 +1122,14 @@ + goto err_clk; + } + +- ret = gsc_register_m2m_device(gsc); ++ ret = v4l2_device_register(dev, &gsc->v4l2_dev); + if (ret) + goto err_clk; + ++ ret = gsc_register_m2m_device(gsc); ++ if (ret) ++ goto err_v4l2; ++ + platform_set_drvdata(pdev, gsc); + pm_runtime_enable(dev); + ret = pm_runtime_get_sync(&pdev->dev); +@@ -1147,6 +1151,8 @@ + pm_runtime_put(dev); + err_m2m: + gsc_unregister_m2m_device(gsc); ++err_v4l2: ++ v4l2_device_unregister(&gsc->v4l2_dev); + err_clk: + gsc_clk_put(gsc); + return ret; +@@ -1157,6 +1163,7 @@ + struct gsc_dev *gsc = platform_get_drvdata(pdev); + + gsc_unregister_m2m_device(gsc); ++ v4l2_device_unregister(&gsc->v4l2_dev); + + vb2_dma_contig_cleanup_ctx(gsc->alloc_ctx); + pm_runtime_disable(&pdev->dev); +Index: linux-3.10-3.10.11/drivers/media/platform/exynos-gsc/gsc-core.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/platform/exynos-gsc/gsc-core.h 2014-05-05 11:51:22.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/platform/exynos-gsc/gsc-core.h 2014-05-05 12:44:45.000000000 +0000 +@@ -343,6 +343,7 @@ + unsigned long state; + struct vb2_alloc_ctx *alloc_ctx; + struct video_device vdev; ++ struct v4l2_device v4l2_dev; + }; + + /** +Index: linux-3.10-3.10.11/drivers/media/platform/exynos-gsc/gsc-m2m.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/platform/exynos-gsc/gsc-m2m.c 2014-05-05 11:51:22.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/platform/exynos-gsc/gsc-m2m.c 2014-05-05 12:44:45.000000000 +0000 +@@ -751,6 +751,7 @@ + gsc->vdev.release = video_device_release_empty; + gsc->vdev.lock = &gsc->lock; + gsc->vdev.vfl_dir = VFL_DIR_M2M; ++ gsc->vdev.v4l2_dev = &gsc->v4l2_dev; + snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m", + GSC_MODULE_NAME, gsc->id); + +Index: linux-3.10-3.10.11/dummy/rpi_1120_1d9d780fcd8df7c70312fdfe43ecc802b99b2e5c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1120_1d9d780fcd8df7c70312fdfe43ecc802b99b2e5c.txt 2014-05-05 12:44:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1121_cb6ecb39fe845251412e34e1d10bb6f4a3652f2f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1121_cb6ecb39fe845251412e34e1d10bb6f4a3652f2f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1121_cb6ecb39fe845251412e34e1d10bb6f4a3652f2f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1121_cb6ecb39fe845251412e34e1d10bb6f4a3652f2f.patch 2014-05-05 12:44:46.000000000 +0000 @@ -0,0 +1,73 @@ +commit cb6ecb39fe845251412e34e1d10bb6f4a3652f2f +Author: Sylwester Nawrocki +Date: Mon Jul 29 06:53:59 2013 -0300 + + media: exynos4-is: Fix entity unregistration on error path + + commit d2b903b4427e417a73863cef36ad0796ea6b7404 upstream. + + This patch corrects media entities unregistration order to make sure + the fimc.N.capture and fimc-lite video nodes are unregistered with + fimc->lock mutex held. This prevents races between video device open() + and defered probing and NULL pointer dereference in open() callback + as follows: + [ 77.645000] Unable to handle kernel NULL pointer dereference at virtual address 00000290t + [ 77.655000] pgd = ee7a8000 + [ 77.660000] [00000290] *pgd=6e13c831, *pte=00000000, *ppte=00000000 + [ 77.665000] Internal error: Oops: 17 [#1] PREEMPT SMP ARM + [ 77.670000] Modules linked in: s5p_fimc ipv6 exynos_fimc_is exynos_fimc_lite + s5p_csis v4l2_mem2mem videobuf2_dma_contig videobuf2_memops exynos4_is_common videobuf2_core [last unloaded: s5p_fimc] + [ 77.685000] CPU: 0 PID : 2998 Comm: v4l_id Tainted: G W 3.10.0-next-20130709-00039-g39f491b-dirty #1548 + [ 77.695000] task: ee084000 ti: ee46e000 task.ti: ee46e000 + [ 77.700000] PC is at __mutex_lock_slowpath+0x54/0x368 + [ 77.705000] LR is at __mutex_lock_slowpath+0x24/0x368 + [ 77.710000] pc : [] lr : [] psr: 60000093 + [ 77.710000] sp : ee46fd70 ip : 000008c8 fp : c054e34c + [ 77.725000] r10: ee084000 r9 : 00000000 r8 : ee439480 + [ 77.730000] r7 : ee46e000 r6 : 60000013 r5 : 00000290 r4 : 0000028c + [ 77.735000] r3 : 00000000 r2 : 00000000 r1 : 20000093 r0 : 00000001 + [ 77.740000] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user + [ 77.750000] Control: 10c5387d Table: 6e7a804a DAC: 00000015 + [ 77.755000] Process v4l_id (pid: 2998, stack limit = 0xee46e238) + [ 77.760000] Stack: (0xee46fd70 to 0xee470000) + ... + [ 77.935000] [] (__mutex_lock_slowpath+0x54/0x368) from [] (mutex_lock+0xc/0x24) + [ 77.945000] [] (mutex_lock+0xc/0x24) from [] (fimc_lite_open+0x12c/0x2bc [exynos_fimc_lite]) + [ 77.955000] [] (fimc_lite_open+0x12c/0x2bc [exynos_fimc_lite]) from [] (v4l2_open+0xa0/0xe0) + [ 77.965000] [] (v4l2_open+0xa0/0xe0) from [] (chrdev_open+0x88/0x170) + [ 77.975000] [] (chrdev_open+0x88/0x170) from [] (do_dentry_open.isra.14+0x1d8/0x258) + [ 77.985000] [] (do_dentry_open.isra.14+0x1d8/0x258) from [] (finish_open+0x20/0x38) + [ 77.995000] [] (finish_open+0x20/0x38) from [] (do_last.isra.43+0x538/0xb1c) + [ 78.000000] [] (do_last.isra.43+0x538/0xb1c) from [] (path_openat+0xb4/0x5c4) + [ 78.010000] [] (path_openat+0xb4/0x5c4) from [] (do_filp_open+0x2c/0x80) + [ 78.020000] [] (do_filp_open+0x2c/0x80) from [] (do_sys_open+0xf4/0x1a8) + [ 78.025000] [] (do_sys_open+0xf4/0x1a8) from [] (ret_fast_syscall+0x0/0x30) + [ 78.035000] Code: 1a000093 e10f6000 f10c0080 e2845004 (e1953f9f) + + Reported-by: Andrzej Hajda + Signed-off-by: Sylwester Nawrocki + Signed-off-by: Kyungmin Park + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/platform/exynos4-is/media-dev.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/platform/exynos4-is/media-dev.c 2014-05-05 11:51:22.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/platform/exynos4-is/media-dev.c 2014-05-05 12:44:46.000000000 +0000 +@@ -1441,9 +1441,9 @@ + err_unlock: + mutex_unlock(&fmd->media_dev.graph_mutex); + err_clk: +- media_device_unregister(&fmd->media_dev); + fimc_md_put_clocks(fmd); + fimc_md_unregister_entities(fmd); ++ media_device_unregister(&fmd->media_dev); + err_md: + v4l2_device_unregister(&fmd->v4l2_dev); + return ret; +Index: linux-3.10-3.10.11/dummy/rpi_1121_cb6ecb39fe845251412e34e1d10bb6f4a3652f2f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1121_cb6ecb39fe845251412e34e1d10bb6f4a3652f2f.txt 2014-05-05 12:44:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1122_469641b2b568a9295396ff723573bdeaf2c4293e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1122_469641b2b568a9295396ff723573bdeaf2c4293e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1122_469641b2b568a9295396ff723573bdeaf2c4293e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1122_469641b2b568a9295396ff723573bdeaf2c4293e.patch 2014-05-05 12:44:47.000000000 +0000 @@ -0,0 +1,61 @@ +commit 469641b2b568a9295396ff723573bdeaf2c4293e +Author: Sachin Kamat +Date: Mon Jul 15 02:36:23 2013 -0300 + + media: s5p-g2d: Fix registration failure + + commit 8a09a4cc9bd9389dc6a3b5b2dd3a7d64d2fab7e1 upstream. + + Commit 1c1d86a1ea ("[media] v4l2: always require v4l2_dev, + rename parent to dev_parent") expects v4l2_dev to be always set. + It converted most of the drivers using the parent field of video_device + to v4l2_dev field. G2D driver did not set the parent field. Hence it got + left out. Without this patch we get the following boot warning and G2D + driver fails to register the video device. + WARNING: CPU: 0 PID: 1 at drivers/media/v4l2-core/v4l2-dev.c:775 __video_register_device+0xfc0/0x1028() + Modules linked in: + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.11.0-rc1-00001-g1c3e372-dirty #9 + [] (unwind_backtrace+0x0/0xf4) from [] (show_stack+0x10/0x14) + [] (show_stack+0x10/0x14) from [] (dump_stack+0x7c/0xb0) + [] (dump_stack+0x7c/0xb0) from [] (warn_slowpath_common+0x6c/0x88) + [] (warn_slowpath_common+0x6c/0x88) from [] (warn_slowpath_null+0x1c/0x24) + [] (warn_slowpath_null+0x1c/0x24) from [] (__video_register_device+0xfc0/0x1028) + [] (__video_register_device+0xfc0/0x1028) from [] (g2d_probe+0x1f8/0x398) + [] (g2d_probe+0x1f8/0x398) from [] (platform_drv_probe+0x14/0x18) + [] (platform_drv_probe+0x14/0x18) from [] (driver_probe_device+0x108/0x220) + [] (driver_probe_device+0x108/0x220) from [] (__driver_attach+0x8c/0x90) + [] (__driver_attach+0x8c/0x90) from [] (bus_for_each_dev+0x60/0x94) + [] (bus_for_each_dev+0x60/0x94) from [] (bus_add_driver+0x1c0/0x24c) + [] (bus_add_driver+0x1c0/0x24c) from [] (driver_register+0x78/0x140) + [] (driver_register+0x78/0x140) from [] (do_one_initcall+0xf8/0x144) + [] (do_one_initcall+0xf8/0x144) from [] (kernel_init_freeable+0x13c/0x1d8) + [] (kernel_init_freeable+0x13c/0x1d8) from [] (kernel_init+0xc/0x160) + [] (kernel_init+0xc/0x160) from [] (ret_from_fork+0x14/0x3c) + ---[ end trace 4e0ec028b0028e02 ]--- + s5p-g2d 12800000.g2d: Failed to register video device + s5p-g2d: probe of 12800000.g2d failed with error -22 + + Signed-off-by: Sachin Kamat + Cc: Hans Verkuil + Signed-off-by: Kamil Debski + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/platform/s5p-g2d/g2d.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/platform/s5p-g2d/g2d.c 2014-05-05 11:51:21.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/platform/s5p-g2d/g2d.c 2014-05-05 12:44:47.000000000 +0000 +@@ -784,6 +784,7 @@ + } + *vfd = g2d_videodev; + vfd->lock = &dev->mutex; ++ vfd->v4l2_dev = &dev->v4l2_dev; + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); + if (ret) { + v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); +Index: linux-3.10-3.10.11/dummy/rpi_1122_469641b2b568a9295396ff723573bdeaf2c4293e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1122_469641b2b568a9295396ff723573bdeaf2c4293e.txt 2014-05-05 12:44:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1123_bd7dcb5af0f8771fbcf2fd999545281ec7561d3e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1123_bd7dcb5af0f8771fbcf2fd999545281ec7561d3e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1123_bd7dcb5af0f8771fbcf2fd999545281ec7561d3e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1123_bd7dcb5af0f8771fbcf2fd999545281ec7561d3e.patch 2014-05-05 12:44:48.000000000 +0000 @@ -0,0 +1,40 @@ +commit bd7dcb5af0f8771fbcf2fd999545281ec7561d3e +Author: Andrzej Hajda +Date: Fri Jun 28 05:34:20 2013 -0300 + + media: DocBook: upgrade media_api DocBook version to 4.2 + + commit 8bfd4a68ecc003c1a142f35551be846d6b13e822 upstream. + + Fixes the last three errors of media_api DocBook validatation: + (...) + media_api.xml:414: element imagedata: validity error : Value "SVG" for attribute format of imagedata is not among the enumerated set + media_api.xml:432: element imagedata: validity error : Value "SVG" for attribute format of imagedata is not among the enumerated set + media_api.xml:452: element imagedata: validity error : Value "SVG" for attribute format of imagedata is not among the enumerated set + (...) + + Signed-off-by: Andrzej Hajda + Signed-off-by: Kyungmin Park + Signed-off-by: Hans Verkuil + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/Documentation/DocBook/media_api.tmpl +=================================================================== +--- linux-3.10-3.10.11.orig/Documentation/DocBook/media_api.tmpl 2014-05-05 11:51:21.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/DocBook/media_api.tmpl 2014-05-05 12:44:47.000000000 +0000 +@@ -1,6 +1,6 @@ + +- %media-entities; + + +Index: linux-3.10-3.10.11/dummy/rpi_1123_bd7dcb5af0f8771fbcf2fd999545281ec7561d3e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1123_bd7dcb5af0f8771fbcf2fd999545281ec7561d3e.txt 2014-05-05 12:44:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1124_ed6db5dcac3698346227a49afb2635dfcb784057.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1124_ed6db5dcac3698346227a49afb2635dfcb784057.patch --- linux-3.10.11/debian/patches/rpi/rpi_1124_ed6db5dcac3698346227a49afb2635dfcb784057.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1124_ed6db5dcac3698346227a49afb2635dfcb784057.patch 2014-05-05 12:44:49.000000000 +0000 @@ -0,0 +1,62 @@ +commit ed6db5dcac3698346227a49afb2635dfcb784057 +Author: Alexey Khoroshilov +Date: Wed Jul 3 16:17:34 2013 -0300 + + media: hdpvr: fix iteration over uninitialized lists in hdpvr_probe() + + commit 2e923a0527ac439e135b9961e58d3acd876bba10 upstream. + + free_buff_list and rec_buff_list are initialized in the middle of hdpvr_probe(), + but if something bad happens before that, error handling code calls hdpvr_delete(), + which contains iteration over the lists (via hdpvr_free_buffers()). + The patch moves the lists initialization to the beginning and by the way fixes + goto label in error handling of registering videodev. + Found by Linux Driver Verification project (linuxtesting.org). + + Signed-off-by: Alexey Khoroshilov + Signed-off-by: Hans Verkuil + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/usb/hdpvr/hdpvr-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/hdpvr/hdpvr-core.c 2014-05-05 11:51:21.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/hdpvr/hdpvr-core.c 2014-05-05 12:44:48.000000000 +0000 +@@ -311,6 +311,11 @@ + + dev->workqueue = 0; + ++ /* init video transfer queues first of all */ ++ /* to prevent oops in hdpvr_delete() on error paths */ ++ INIT_LIST_HEAD(&dev->free_buff_list); ++ INIT_LIST_HEAD(&dev->rec_buff_list); ++ + /* register v4l2_device early so it can be used for printks */ + if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { + dev_err(&interface->dev, "v4l2_device_register failed\n"); +@@ -333,10 +338,6 @@ + if (!dev->workqueue) + goto error; + +- /* init video transfer queues */ +- INIT_LIST_HEAD(&dev->free_buff_list); +- INIT_LIST_HEAD(&dev->rec_buff_list); +- + dev->options = hdpvr_default_options; + + if (default_video_input < HDPVR_VIDEO_INPUTS) +@@ -413,7 +414,7 @@ + video_nr[atomic_inc_return(&dev_nr)]); + if (retval < 0) { + v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); +- goto error; ++ goto reg_fail; + } + + /* let the user know what node this device is now attached to */ +Index: linux-3.10-3.10.11/dummy/rpi_1124_ed6db5dcac3698346227a49afb2635dfcb784057.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1124_ed6db5dcac3698346227a49afb2635dfcb784057.txt 2014-05-05 12:44:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1125_cd08ebc07c7cb27785b94a09e4b441e021ce302f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1125_cd08ebc07c7cb27785b94a09e4b441e021ce302f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1125_cd08ebc07c7cb27785b94a09e4b441e021ce302f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1125_cd08ebc07c7cb27785b94a09e4b441e021ce302f.patch 2014-05-05 12:44:50.000000000 +0000 @@ -0,0 +1,41 @@ +commit cd08ebc07c7cb27785b94a09e4b441e021ce302f +Author: Andrzej Hajda +Date: Fri Jun 28 05:44:22 2013 -0300 + + media: v4l2: added missing mutex.h include to v4l2-ctrls.h + + commit a19dec6ea94c036af68c31930c1c92681f55af41 upstream. + + This patch fixes following error: + include/media/v4l2-ctrls.h:193:15: error: field ‘_lock’ has incomplete type + include/media/v4l2-ctrls.h: In function ‘v4l2_ctrl_lock’: + include/media/v4l2-ctrls.h:570:2: error: implicit declaration of + function ‘mutex_lock’ [-Werror=implicit-function-declaration] + include/media/v4l2-ctrls.h: In function ‘v4l2_ctrl_unlock’: + include/media/v4l2-ctrls.h:579:2: error: implicit declaration of + function ‘mutex_unlock’ [-Werror=implicit-function-declaration] + + Signed-off-by: Andrzej Hajda + Signed-off-by: Kyungmin Park + Signed-off-by: Hans Verkuil + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/media/v4l2-ctrls.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/media/v4l2-ctrls.h 2014-05-05 11:51:21.000000000 +0000 ++++ linux-3.10-3.10.11/include/media/v4l2-ctrls.h 2014-05-05 12:44:49.000000000 +0000 +@@ -22,6 +22,7 @@ + #define _V4L2_CTRLS_H + + #include ++#include + #include + + /* forward references */ +Index: linux-3.10-3.10.11/dummy/rpi_1125_cd08ebc07c7cb27785b94a09e4b441e021ce302f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1125_cd08ebc07c7cb27785b94a09e4b441e021ce302f.txt 2014-05-05 12:44:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1126_4ff5ef250fb348707bad956e6eef7f84f1021675.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1126_4ff5ef250fb348707bad956e6eef7f84f1021675.patch --- linux-3.10.11/debian/patches/rpi/rpi_1126_4ff5ef250fb348707bad956e6eef7f84f1021675.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1126_4ff5ef250fb348707bad956e6eef7f84f1021675.patch 2014-05-05 12:44:50.000000000 +0000 @@ -0,0 +1,35 @@ +commit 4ff5ef250fb348707bad956e6eef7f84f1021675 +Author: Alexander Shiyan +Date: Sat Jun 15 08:09:57 2013 -0300 + + media: media: coda: Fix DT driver data pointer for i.MX27 + + commit 7b0dd9e60e714951b5400dd0740b3c4c3c3cb76f upstream. + + The data pointer should point to DT data, and not to the ID + array. + + Signed-off-by: Alexander Shiyan + Signed-off-by: Kamil Debski + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/platform/coda.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/platform/coda.c 2014-05-05 11:51:20.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/platform/coda.c 2014-05-05 12:44:50.000000000 +0000 +@@ -1933,7 +1933,7 @@ + + #ifdef CONFIG_OF + static const struct of_device_id coda_dt_ids[] = { +- { .compatible = "fsl,imx27-vpu", .data = &coda_platform_ids[CODA_IMX27] }, ++ { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] }, + { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] }, + { /* sentinel */ } + }; +Index: linux-3.10-3.10.11/dummy/rpi_1126_4ff5ef250fb348707bad956e6eef7f84f1021675.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1126_4ff5ef250fb348707bad956e6eef7f84f1021675.txt 2014-05-05 12:44:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1127_b3fcd91b96de3082d24636478a145bb50947c9eb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1127_b3fcd91b96de3082d24636478a145bb50947c9eb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1127_b3fcd91b96de3082d24636478a145bb50947c9eb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1127_b3fcd91b96de3082d24636478a145bb50947c9eb.patch 2014-05-05 12:44:51.000000000 +0000 @@ -0,0 +1,57 @@ +commit b3fcd91b96de3082d24636478a145bb50947c9eb +Author: Mauro Carvalho Chehab +Date: Fri Aug 9 08:53:26 2013 -0300 + + media: mb86a20s: Fix TS parallel mode + + commit 9d32069faacdc81fe1dcb5d297c32a3ac81da8f0 upstream. + + changeset 768e6dadd74 caused a regression on using mb86a20s + in parallel mode, as the parallel mode selection got + overriden by mb86a20s_init2. + + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/dvb-frontends/mb86a20s.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/dvb-frontends/mb86a20s.c 2014-05-05 11:51:20.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/dvb-frontends/mb86a20s.c 2014-05-05 12:44:51.000000000 +0000 +@@ -157,7 +157,6 @@ + { 0x45, 0x04 }, /* CN symbol 4 */ + { 0x48, 0x04 }, /* CN manual mode */ + +- { 0x50, 0xd5 }, { 0x51, 0x01 }, /* Serial */ + { 0x50, 0xd6 }, { 0x51, 0x1f }, + { 0x50, 0xd2 }, { 0x51, 0x03 }, + { 0x50, 0xd7 }, { 0x51, 0xbf }, +@@ -1860,16 +1859,15 @@ + dev_dbg(&state->i2c->dev, "%s: IF=%d, IF reg=0x%06llx\n", + __func__, state->if_freq, (long long)pll); + +- if (!state->config->is_serial) { ++ if (!state->config->is_serial) + regD5 &= ~1; + +- rc = mb86a20s_writereg(state, 0x50, 0xd5); +- if (rc < 0) +- goto err; +- rc = mb86a20s_writereg(state, 0x51, regD5); +- if (rc < 0) +- goto err; +- } ++ rc = mb86a20s_writereg(state, 0x50, 0xd5); ++ if (rc < 0) ++ goto err; ++ rc = mb86a20s_writereg(state, 0x51, regD5); ++ if (rc < 0) ++ goto err; + + rc = mb86a20s_writeregdata(state, mb86a20s_init2); + if (rc < 0) +Index: linux-3.10-3.10.11/dummy/rpi_1127_b3fcd91b96de3082d24636478a145bb50947c9eb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1127_b3fcd91b96de3082d24636478a145bb50947c9eb.txt 2014-05-05 12:44:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1128_d2310f7119ba394d3256c221886c048189dcfb91.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1128_d2310f7119ba394d3256c221886c048189dcfb91.patch --- linux-3.10.11/debian/patches/rpi/rpi_1128_d2310f7119ba394d3256c221886c048189dcfb91.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1128_d2310f7119ba394d3256c221886c048189dcfb91.patch 2014-05-05 12:44:52.000000000 +0000 @@ -0,0 +1,101 @@ +commit d2310f7119ba394d3256c221886c048189dcfb91 +Author: Bjørn Mork +Date: Wed Aug 14 05:24:39 2013 -0300 + + media: siano: fix divide error on 0 counters + + commit ec532503209053bbee0c7dac410031e50835e01a upstream. + + GIT_AUTHOR_DATE=1376465691 + I took a quick look at the code and wonder if the problem is caused by + an initial zero statistics message? This is all just a wild guess, but + if it is correct, then the attached untested patch might fix it... + Bjørn + >From d78a0599d5b5d4da384eae08bf7da316389dfbe5 Mon Sep 17 00:00:00 2001 + ts_packets and ets_packets counters can be 0. Don't fall over + if they are. Fixes: + [ 846.851711] divide error: 0000 [#1] SMP + [ 846.851806] Modules linked in: smsdvb dvb_core ir_lirc_codec lirc_dev ir_sanyo_decoder ir_mce_kbd_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_rc5_decoder ir_nec_decoder rc_hauppauge smsusb smsmdtv rc_core pci_stub vboxpci(O) vboxnetadp(O) vboxnetflt(O) vboxdrv(O) parport_pc ppdev lp parport cpufreq_userspace cpufreq_powersave cpufreq_stats cpufreq_conservative rfcomm bnep binfmt_misc uinput nfsd auth_rpcgss oid_registry nfs_acl nfs lockd dns_resolver fscache sunrpc ext4 jbd2 fuse tp_smapi(O) thinkpad_ec(O) loop firewire_sbp2 dm_crypt snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm_oss snd_mixer_oss snd_pcm thinkpad_acpi nvram snd_page_alloc hid_generic snd_seq_midi snd_seq_midi_event arc4 usbhid snd_rawmidi uvcvideo hid iwldvm coretemp kvm_intel mac8021 + 1 cdc_wdm + [ 846.853477] cdc_acm snd_seq videobuf2_vmalloc videobuf2_memops videobuf2_core videodev media kvm radeon r852 ttm joydev cdc_ether usbnet pcmcia mii sm_common nand btusb drm_kms_helper tpm_tis acpi_cpufreq bluetooth iwlwifi nand_ecc drm nand_ids i2c_i801 mtd snd_seq_device iTCO_wdt iTCO_vendor_support r592 memstick lpc_ich mperf tpm yenta_socket pcmcia_rsrc pcmcia_core cfg80211 snd_timer snd pcspkr i2c_algo_bit crc16 i2c_core tpm_bios processor mfd_core wmi psmouse mei_me rfkill mei serio_raw soundcore evdev battery button video ac microcode ext3 mbcache jbd md_mod dm_mirror dm_region_hash dm_log dm_mod sg sr_mod sd_mod cdrom crc_t10dif firewire_ohci sdhci_pci sdhci mmc_core firewire_core crc_itu_t thermal thermal_sys ahci libahci ehci_pci uhci_hcd ehci_hcd libata scsi_mod usbcore e1000 + e usb_common + [ 846.855310] ptp pps_core + [ 846.855356] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 3.10-2-amd64 #1 Debian 3.10.5-1 + [ 846.855490] Hardware name: LENOVO 4061WFA/4061WFA, BIOS 6FET92WW (3.22 ) 12/14/2011 + [ 846.855609] task: ffffffff81613400 ti: ffffffff81600000 task.ti: ffffffff81600000 + [ 846.855636] RIP: 0010:[] [] smsdvb_onresponse+0x264/0xa86 [smsdvb] + [ 846.863906] RSP: 0018:ffff88013bc03cf0 EFLAGS: 00010046 + [ 846.863906] RAX: 0000000000000000 RBX: ffff880133bf6000 RCX: 0000000000000000 + [ 846.863906] RDX: 0000000000000000 RSI: ffff88005d3b58c0 RDI: ffff880133bf6000 + [ 846.863906] RBP: ffff88005d1da000 R08: 0000000000000058 R09: 0000000000000015 + [ 846.863906] R10: 0000000000001a0d R11: 000000000000021a R12: ffff88005d3b58c0 + [ 846.863906] R13: ffff88005d1da008 R14: 00000000ffffff8d R15: ffff880036cf5060 + [ 846.863906] FS: 0000000000000000(0000) GS:ffff88013bc00000(0000) knlGS:0000000000000000 + [ 846.863906] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b + [ 846.863906] CR2: 00007f3a4b69ae50 CR3: 0000000036dac000 CR4: 00000000000407f0 + [ 846.863906] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + [ 846.863906] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + [ 846.863906] Stack: + [ 846.863906] ffff88007a102000 ffff88005d1da000 ffff88005d3b58c0 0000000000085824 + [ 846.863906] ffffffffa08c5aa3 ffff88005d1da000 ffff8800a6907390 ffff8800a69073b0 + [ 846.863906] ffff8800a6907000 ffffffffa08b642c 000000000000021a ffff8800a69073b0 + [ 846.863906] Call Trace: + [ 846.863906] + [ 846.863906] + [ 846.863906] [] ? smscore_onresponse+0x1d5/0x353 [smsmdtv] + [ 846.863906] [] ? smsusb_onresponse+0x146/0x192 [smsusb] + [ 846.863906] [] ? usb_hcd_giveback_urb+0x6c/0xac [usbcore] + [ 846.863906] [] ? ehci_urb_done+0x62/0x72 [ehci_hcd] + [ 846.863906] [] ? qh_completions+0x91/0x364 [ehci_hcd] + [ 846.863906] [] ? ehci_work+0x8a/0x68e [ehci_hcd] + [ 846.863906] [] ? timekeeping_get_ns.constprop.10+0xd/0x31 + [ 846.863906] [] ? update_cfs_rq_blocked_load+0xde/0xec + [ 846.863906] [] ? run_posix_cpu_timers+0x25/0x575 + [ 846.863906] [] ? ehci_irq+0x211/0x23d [ehci_hcd] + [ 846.863906] [] ? usb_hcd_irq+0x31/0x48 [usbcore] + [ 846.863906] [] ? handle_irq_event_percpu+0x49/0x1a4 + [ 846.863906] [] ? handle_irq_event+0x32/0x4b + [ 846.863906] [] ? handle_fasteoi_irq+0x80/0xb6 + [ 846.863906] [] ? handle_irq+0x18/0x20 + [ 846.863906] [] ? do_IRQ+0x40/0x95 + [ 846.863906] [] ? common_interrupt+0x6d/0x6d + [ 846.863906] + [ 846.863906] + [ 846.863906] [] ? arch_local_irq_enable+0x4/0x8 + [ 846.863906] [] ? cpuidle_enter_state+0x52/0xc1 + [ 846.863906] [] ? cpuidle_idle_call+0xd4/0x143 + [ 846.863906] [] ? arch_cpu_idle+0x5/0x17 + [ 846.863906] [] ? cpu_startup_entry+0x10d/0x187 + [ 846.863906] [] ? start_kernel+0x3e8/0x3f3 + [ 846.863906] [] ? repair_env_string+0x54/0x54 + [ 846.863906] [] ? x86_64_start_kernel+0xf2/0xfd + [ 846.863906] Code: 25 09 00 00 c6 83 da 08 00 00 03 8b 45 54 48 01 83 b6 08 00 00 8b 45 50 48 01 83 db 08 00 00 8b 4d 18 69 c1 ff ff 00 00 03 4d 14 <48> f7 f1 89 83 a8 09 00 00 e9 68 fe ff ff 48 8b 7f 10 e8 79 92 + [ 846.863906] RIP [] smsdvb_onresponse+0x264/0xa86 [smsdvb] + [ 846.863906] RSP + Reference: http://bugs.debian.org/719623 + + Reported-by: Johannes Rohr + Signed-off-by: Bjørn Mork + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/common/siano/smsdvb-main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/common/siano/smsdvb-main.c 2014-05-05 11:51:20.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/common/siano/smsdvb-main.c 2014-05-05 12:44:51.000000000 +0000 +@@ -275,7 +275,8 @@ + + /* Legacy PER/BER */ + tmp = p->ets_packets * 65535; +- do_div(tmp, p->ts_packets + p->ets_packets); ++ if (p->ts_packets + p->ets_packets) ++ do_div(tmp, p->ts_packets + p->ets_packets); + client->legacy_per = tmp; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1128_d2310f7119ba394d3256c221886c048189dcfb91.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1128_d2310f7119ba394d3256c221886c048189dcfb91.txt 2014-05-05 12:44:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1129_42cc8e56740efe9acc271f4780b81ac5ecef188c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1129_42cc8e56740efe9acc271f4780b81ac5ecef188c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1129_42cc8e56740efe9acc271f4780b81ac5ecef188c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1129_42cc8e56740efe9acc271f4780b81ac5ecef188c.patch 2014-05-05 12:44:53.000000000 +0000 @@ -0,0 +1,44 @@ +commit 42cc8e56740efe9acc271f4780b81ac5ecef188c +Author: Stefan Behrens +Date: Mon Aug 19 18:51:13 2013 +0200 + + Btrfs: don't allow the replace procedure on read only filesystems + + commit bbb651e469d99f0088e286fdeb54acca7bb4ad4e upstream. + + If you start the replace procedure on a read only filesystem, at + the end the procedure fails to write the updated dev_items to the + chunk tree. The problem is that this error is not indicated except + for a WARN_ON(). If the user now thinks that everything was done + as expected and destroys the source device (with mkfs or with a + hammer). The next mount fails with "failed to read chunk root" and + the filesystem is gone. + + This commit adds code to fail the attempt to start the replace + procedure if the filesystem is mounted read-only. + + Signed-off-by: Stefan Behrens + Signed-off-by: Josef Bacik + Signed-off-by: Chris Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/btrfs/ioctl.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/btrfs/ioctl.c 2014-05-05 11:51:20.000000000 +0000 ++++ linux-3.10-3.10.11/fs/btrfs/ioctl.c 2014-05-05 12:44:52.000000000 +0000 +@@ -3299,6 +3299,9 @@ + + switch (p->cmd) { + case BTRFS_IOCTL_DEV_REPLACE_CMD_START: ++ if (root->fs_info->sb->s_flags & MS_RDONLY) ++ return -EROFS; ++ + if (atomic_xchg( + &root->fs_info->mutually_exclusive_operation_running, + 1)) { +Index: linux-3.10-3.10.11/dummy/rpi_1129_42cc8e56740efe9acc271f4780b81ac5ecef188c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1129_42cc8e56740efe9acc271f4780b81ac5ecef188c.txt 2014-05-05 12:44:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1130_73e2c2b7c105e46344eb409575a4508f24a82eee.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1130_73e2c2b7c105e46344eb409575a4508f24a82eee.patch --- linux-3.10.11/debian/patches/rpi/rpi_1130_73e2c2b7c105e46344eb409575a4508f24a82eee.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1130_73e2c2b7c105e46344eb409575a4508f24a82eee.patch 2014-05-05 12:44:54.000000000 +0000 @@ -0,0 +1,52 @@ +commit 73e2c2b7c105e46344eb409575a4508f24a82eee +Author: Oleg Nesterov +Date: Wed Sep 11 17:47:26 2013 +0200 + + uprobes: Fix utask->depth accounting in handle_trampoline() + + commit 878b5a6efd38030c7a90895dc8346e8fb1e09b4c upstream. + + Currently utask->depth is simply the number of allocated/pending + return_instance's in uprobe_task->return_instances list. + + handle_trampoline() should decrement this counter every time we + handle/free an instance, but due to typo it does this only if + ->chained == T. This means that in the likely case this counter + is never decremented and the probed task can't report more than + MAX_URETPROBE_DEPTH events. + + Reported-by: Mikhail Kulemin + Reported-by: Hemant Kumar Shaw + Signed-off-by: Oleg Nesterov + Acked-by: Anton Arapov + Cc: masami.hiramatsu.pt@hitachi.com + Cc: srikar@linux.vnet.ibm.com + Cc: systemtap@sourceware.org + Link: http://lkml.kernel.org/r/20130911154726.GA8093@redhat.com + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/events/uprobes.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/events/uprobes.c 2014-05-05 11:51:19.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/events/uprobes.c 2014-05-05 12:44:53.000000000 +0000 +@@ -1682,12 +1682,10 @@ + tmp = ri; + ri = ri->next; + kfree(tmp); ++ utask->depth--; + + if (!chained) + break; +- +- utask->depth--; +- + BUG_ON(!ri); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1130_73e2c2b7c105e46344eb409575a4508f24a82eee.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1130_73e2c2b7c105e46344eb409575a4508f24a82eee.txt 2014-05-05 12:44:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1131_d041e861d49f1f558e9e18f2075345f8a37427dc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1131_d041e861d49f1f558e9e18f2075345f8a37427dc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1131_d041e861d49f1f558e9e18f2075345f8a37427dc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1131_d041e861d49f1f558e9e18f2075345f8a37427dc.patch 2014-05-05 12:44:55.000000000 +0000 @@ -0,0 +1,38 @@ +commit d041e861d49f1f558e9e18f2075345f8a37427dc +Author: Mark Brown +Date: Thu Aug 29 07:18:14 2013 -0700 + + leds: wm831x-status: Request a REG resource + + commit 61abeba5222895d6900b13115f5d8eba7988d7d6 upstream. + + The wm831x-status driver was not converted to use a REG resource when they + were introduced and the rest of the wm831x drivers converted, causing it + to fail to probe due to requesting the wrong resource type. + + Signed-off-by: Mark Brown + Signed-off-by: Bryan Wu + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/leds/leds-wm831x-status.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/leds/leds-wm831x-status.c 2014-05-05 11:51:19.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/leds/leds-wm831x-status.c 2014-05-05 12:44:54.000000000 +0000 +@@ -230,9 +230,9 @@ + int id = pdev->id % ARRAY_SIZE(chip_pdata->status); + int ret; + +- res = platform_get_resource(pdev, IORESOURCE_IO, 0); ++ res = platform_get_resource(pdev, IORESOURCE_REG, 0); + if (res == NULL) { +- dev_err(&pdev->dev, "No I/O resource\n"); ++ dev_err(&pdev->dev, "No register resource\n"); + ret = -EINVAL; + goto err; + } +Index: linux-3.10-3.10.11/dummy/rpi_1131_d041e861d49f1f558e9e18f2075345f8a37427dc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1131_d041e861d49f1f558e9e18f2075345f8a37427dc.txt 2014-05-05 12:44:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1132_2008c41d079db04dfc6d6a29bd8a7292ed1299a3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1132_2008c41d079db04dfc6d6a29bd8a7292ed1299a3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1132_2008c41d079db04dfc6d6a29bd8a7292ed1299a3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1132_2008c41d079db04dfc6d6a29bd8a7292ed1299a3.patch 2014-05-05 12:44:55.000000000 +0000 @@ -0,0 +1,48 @@ +commit 2008c41d079db04dfc6d6a29bd8a7292ed1299a3 +Author: Felix Fietkau +Date: Wed Aug 28 10:41:42 2013 +0200 + + MIPS: ath79: Fix ar933x watchdog clock + + commit a1191927ace7e6f827132aa9e062779eb3f11fa5 upstream. + + The watchdog device on the AR933x is connected to + the AHB clock, however the current code uses the + reference clock. Due to the wrong rate, the watchdog + driver can't calculate correct register values for + a given timeout value and the watchdog unexpectedly + restarts the system. + + The code uses the wrong value since the initial + commit 04225e1d227c8e68d685936ecf42ac175fec0e54 + (MIPS: ath79: add AR933X specific clock init) + + The patch fixes the code to use the correct clock + rate to avoid the problem. + + Signed-off-by: Felix Fietkau + Signed-off-by: Gabor Juhos + Cc: linux-mips@linux-mips.org + Patchwork: https://patchwork.linux-mips.org/patch/5777/ + Signed-off-by: Ralf Baechle + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/mips/ath79/clock.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/mips/ath79/clock.c 2014-05-05 11:51:19.000000000 +0000 ++++ linux-3.10-3.10.11/arch/mips/ath79/clock.c 2014-05-05 12:44:55.000000000 +0000 +@@ -164,7 +164,7 @@ + ath79_ahb_clk.rate = freq / t; + } + +- ath79_wdt_clk.rate = ath79_ref_clk.rate; ++ ath79_wdt_clk.rate = ath79_ahb_clk.rate; + ath79_uart_clk.rate = ath79_ref_clk.rate; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1132_2008c41d079db04dfc6d6a29bd8a7292ed1299a3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1132_2008c41d079db04dfc6d6a29bd8a7292ed1299a3.txt 2014-05-05 12:44:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1133_e041da063093c8f0a713b09560dc5bf6985e8a0a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1133_e041da063093c8f0a713b09560dc5bf6985e8a0a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1133_e041da063093c8f0a713b09560dc5bf6985e8a0a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1133_e041da063093c8f0a713b09560dc5bf6985e8a0a.patch 2014-05-05 12:44:56.000000000 +0000 @@ -0,0 +1,73 @@ +commit e041da063093c8f0a713b09560dc5bf6985e8a0a +Author: Gera Kazakov +Date: Mon Sep 9 15:47:06 2013 -0700 + + target: Fix >= v3.9+ regression in PR APTPL + ALUA metadata write-out + + commit f730f9158f6ee7b5c4d892af6b51a72194445ea4 upstream. + + This patch fixes a >= v3.9+ regression in __core_scsi3_write_aptpl_to_file() + + core_alua_write_tpg_metadata() write-out, where a return value of -EIO was + incorrectly being returned upon success. + + This bug was originally introduced in: + + commit 0e9b10a90f1c30f25dd6f130130240745ab14010 + Author: Al Viro + Date: Sat Feb 23 15:22:43 2013 -0500 + + target: writev() on single-element vector is pointless + + However, given that the return of core_scsi3_update_and_write_aptpl() + was not used to determine if a command should be returned with non GOOD + status, this bug was not being triggered in PR logic until v3.11-rc1 by + commit: + + commit 459f213ba162bd13e113d6f92a8fa6c780fd67ed + Author: Andy Grover + Date: Thu May 16 10:41:02 2013 -0700 + + target: Allocate aptpl_buf inside update_and_write_aptpl() + + So, go ahead and only return -EIO if kernel_write() returned a + negative value. + + Reported-by: Gera Kazakov + Signed-off-by: Gera Kazakov + Cc: Al Viro + Cc: Andy Grover + Signed-off-by: Nicholas Bellinger + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/target/target_core_alua.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/target/target_core_alua.c 2014-05-05 11:51:18.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/target/target_core_alua.c 2014-05-05 12:44:56.000000000 +0000 +@@ -730,7 +730,7 @@ + if (ret < 0) + pr_err("Error writing ALUA metadata file: %s\n", path); + fput(file); +- return ret ? -EIO : 0; ++ return (ret < 0) ? -EIO : 0; + } + + /* +Index: linux-3.10-3.10.11/drivers/target/target_core_pr.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/target/target_core_pr.c 2014-05-05 11:51:18.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/target/target_core_pr.c 2014-05-05 12:44:56.000000000 +0000 +@@ -1987,7 +1987,7 @@ + pr_debug("Error writing APTPL metadata file: %s\n", path); + fput(file); + +- return ret ? -EIO : 0; ++ return (ret < 0) ? -EIO : 0; + } + + static int +Index: linux-3.10-3.10.11/dummy/rpi_1133_e041da063093c8f0a713b09560dc5bf6985e8a0a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1133_e041da063093c8f0a713b09560dc5bf6985e8a0a.txt 2014-05-05 12:44:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1134_1b24e0e487698ae239764165495f45401d5930ce.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1134_1b24e0e487698ae239764165495f45401d5930ce.patch --- linux-3.10.11/debian/patches/rpi/rpi_1134_1b24e0e487698ae239764165495f45401d5930ce.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1134_1b24e0e487698ae239764165495f45401d5930ce.patch 2014-05-05 12:44:57.000000000 +0000 @@ -0,0 +1,125 @@ +commit 1b24e0e487698ae239764165495f45401d5930ce +Author: Alex Williamson +Date: Sat Jun 15 10:27:19 2013 -0600 + + intel-iommu: Fix leaks in pagetable freeing + + commit 3269ee0bd6686baf86630300d528500ac5b516d7 upstream. + + At best the current code only seems to free the leaf pagetables and + the root. If you're unlucky enough to have a large gap (like any + QEMU guest with more than 3G of memory), only the first chunk of leaf + pagetables are freed (plus the root). This is a massive memory leak. + This patch re-writes the pagetable freeing function to use a + recursive algorithm and manages to not only free all the pagetables, + but does it without any apparent performance loss versus the current + broken version. + + Signed-off-by: Alex Williamson + Reviewed-by: Marcelo Tosatti + Signed-off-by: Joerg Roedel + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/iommu/intel-iommu.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/iommu/intel-iommu.c 2014-05-05 11:51:18.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/iommu/intel-iommu.c 2014-05-05 12:44:57.000000000 +0000 +@@ -890,56 +890,54 @@ + return order; + } + ++static void dma_pte_free_level(struct dmar_domain *domain, int level, ++ struct dma_pte *pte, unsigned long pfn, ++ unsigned long start_pfn, unsigned long last_pfn) ++{ ++ pfn = max(start_pfn, pfn); ++ pte = &pte[pfn_level_offset(pfn, level)]; ++ ++ do { ++ unsigned long level_pfn; ++ struct dma_pte *level_pte; ++ ++ if (!dma_pte_present(pte) || dma_pte_superpage(pte)) ++ goto next; ++ ++ level_pfn = pfn & level_mask(level - 1); ++ level_pte = phys_to_virt(dma_pte_addr(pte)); ++ ++ if (level > 2) ++ dma_pte_free_level(domain, level - 1, level_pte, ++ level_pfn, start_pfn, last_pfn); ++ ++ /* If range covers entire pagetable, free it */ ++ if (!(start_pfn > level_pfn || ++ last_pfn < level_pfn + level_size(level))) { ++ dma_clear_pte(pte); ++ domain_flush_cache(domain, pte, sizeof(*pte)); ++ free_pgtable_page(level_pte); ++ } ++next: ++ pfn += level_size(level); ++ } while (!first_pte_in_page(++pte) && pfn <= last_pfn); ++} ++ + /* free page table pages. last level pte should already be cleared */ + static void dma_pte_free_pagetable(struct dmar_domain *domain, + unsigned long start_pfn, + unsigned long last_pfn) + { + int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; +- struct dma_pte *first_pte, *pte; +- int total = agaw_to_level(domain->agaw); +- int level; +- unsigned long tmp; +- int large_page = 2; + + BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); + BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); + BUG_ON(start_pfn > last_pfn); + + /* We don't need lock here; nobody else touches the iova range */ +- level = 2; +- while (level <= total) { +- tmp = align_to_level(start_pfn, level); +- +- /* If we can't even clear one PTE at this level, we're done */ +- if (tmp + level_size(level) - 1 > last_pfn) +- return; +- +- do { +- large_page = level; +- first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page); +- if (large_page > level) +- level = large_page + 1; +- if (!pte) { +- tmp = align_to_level(tmp + 1, level + 1); +- continue; +- } +- do { +- if (dma_pte_present(pte)) { +- free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); +- dma_clear_pte(pte); +- } +- pte++; +- tmp += level_size(level); +- } while (!first_pte_in_page(pte) && +- tmp + level_size(level) - 1 <= last_pfn); +- +- domain_flush_cache(domain, first_pte, +- (void *)pte - (void *)first_pte); +- +- } while (tmp && tmp + level_size(level) - 1 <= last_pfn); +- level++; +- } ++ dma_pte_free_level(domain, agaw_to_level(domain->agaw), ++ domain->pgd, 0, start_pfn, last_pfn); ++ + /* free pgd */ + if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) { + free_pgtable_page(domain->pgd); +Index: linux-3.10-3.10.11/dummy/rpi_1134_1b24e0e487698ae239764165495f45401d5930ce.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1134_1b24e0e487698ae239764165495f45401d5930ce.txt 2014-05-05 12:44:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1135_5a48788ca4d6dc78d1856d9ddeea1b1160097cc9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1135_5a48788ca4d6dc78d1856d9ddeea1b1160097cc9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1135_5a48788ca4d6dc78d1856d9ddeea1b1160097cc9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1135_5a48788ca4d6dc78d1856d9ddeea1b1160097cc9.patch 2014-05-05 12:44:58.000000000 +0000 @@ -0,0 +1,100 @@ +commit 5a48788ca4d6dc78d1856d9ddeea1b1160097cc9 +Author: Eric W. Biederman +Date: Thu Aug 29 13:56:50 2013 -0700 + + pidns: Fix hang in zap_pid_ns_processes by sending a potentially extra wakeup + + commit a606488513543312805fab2b93070cefe6a3016c upstream. + + Serge Hallyn writes: + + > Since commit af4b8a83add95ef40716401395b44a1b579965f4 it's been + > possible to get into a situation where a pidns reaper is + > , reparented to host pid 1, but never reaped. How to + > reproduce this is documented at + > + > https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1168526 + > (and see + > https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1168526/comments/13) + > In short, run repeated starts of a container whose init is + > + > Process.exit(0); + > + > sysrq-t when such a task is playing zombie shows: + > + > [ 131.132978] init x ffff88011fc14580 0 2084 2039 0x00000000 + > [ 131.132978] ffff880116e89ea8 0000000000000002 ffff880116e89fd8 0000000000014580 + > [ 131.132978] ffff880116e89fd8 0000000000014580 ffff8801172a0000 ffff8801172a0000 + > [ 131.132978] ffff8801172a0630 ffff88011729fff0 ffff880116e14650 ffff88011729fff0 + > [ 131.132978] Call Trace: + > [ 131.132978] [] schedule+0x29/0x70 + > [ 131.132978] [] do_exit+0x6e1/0xa40 + > [ 131.132978] [] ? signal_wake_up_state+0x1e/0x30 + > [ 131.132978] [] do_group_exit+0x3f/0xa0 + > [ 131.132978] [] SyS_exit_group+0x14/0x20 + > [ 131.132978] [] tracesys+0xe1/0xe6 + > + > Further debugging showed that every time this happened, zap_pid_ns_processes() + > started with nr_hashed being 3, while we were expecting it to drop to 2. + > Any time it didn't happen, nr_hashed was 1 or 2. So the reaper was + > waiting for nr_hashed to become 2, but free_pid() only wakes the reaper + > if nr_hashed hits 1. + + The issue is that when the task group leader of an init process exits + before other tasks of the init process when the init process finally + exits it will be a secondary task sleeping in zap_pid_ns_processes and + waiting to wake up when the number of hashed pids drops to two. This + case waits forever as free_pid only sends a wake up when the number of + hashed pids drops to 1. + + To correct this the simple strategy of sending a possibly unncessary + wake up when the number of hashed pids drops to 2 is adopted. + + Sending one extraneous wake up is relatively harmless, at worst we + waste a little cpu time in the rare case when a pid namespace + appropaches exiting. + + We can detect the case when the pid namespace drops to just two pids + hashed race free in free_pid. + + Dereferencing pid_ns->child_reaper with the pidmap_lock held is safe + without out the tasklist_lock because it is guaranteed that the + detach_pid will be called on the child_reaper before it is freed and + detach_pid calls __change_pid which calls free_pid which takes the + pidmap_lock. __change_pid only calls free_pid if this is the + last use of the pid. For a thread that is not the thread group leader + the threads pid will only ever have one user because a threads pid + is not allowed to be the pid of a process, of a process group or + a session. For a thread that is a thread group leader all of + the other threads of that process will be reaped before it is allowed + for the thread group leader to be reaped ensuring there will only + be one user of the threads pid as a process pid. Furthermore + because the thread is the init process of a pid namespace all of the + other processes in the pid namespace will have also been already freed + leading to the fact that the pid will not be used as a session pid or + a process group pid for any other running process. + + Acked-by: Serge Hallyn + Tested-by: Serge Hallyn + Reported-by: Serge Hallyn + Signed-off-by: "Eric W. Biederman" + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/pid.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/pid.c 2014-05-05 11:51:18.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/pid.c 2014-05-05 12:44:58.000000000 +0000 +@@ -264,6 +264,7 @@ + struct pid_namespace *ns = upid->ns; + hlist_del_rcu(&upid->pid_chain); + switch(--ns->nr_hashed) { ++ case 2: + case 1: + /* When all that is left in the pid namespace + * is the reaper wake up the reaper. The reaper +Index: linux-3.10-3.10.11/dummy/rpi_1135_5a48788ca4d6dc78d1856d9ddeea1b1160097cc9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1135_5a48788ca4d6dc78d1856d9ddeea1b1160097cc9.txt 2014-05-05 12:44:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1136_f608ebd760cb9b48a333700fdc10245e257d9fce.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1136_f608ebd760cb9b48a333700fdc10245e257d9fce.patch --- linux-3.10.11/debian/patches/rpi/rpi_1136_f608ebd760cb9b48a333700fdc10245e257d9fce.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1136_f608ebd760cb9b48a333700fdc10245e257d9fce.patch 2014-05-05 12:44:59.000000000 +0000 @@ -0,0 +1,66 @@ +commit f608ebd760cb9b48a333700fdc10245e257d9fce +Author: Oleg Nesterov +Date: Wed Sep 11 14:19:38 2013 -0700 + + pidns: fix vfork() after unshare(CLONE_NEWPID) + + commit e79f525e99b04390ca4d2366309545a836c03bf1 upstream. + + Commit 8382fcac1b81 ("pidns: Outlaw thread creation after + unshare(CLONE_NEWPID)") nacks CLONE_VM if the forking process unshared + pid_ns, this obviously breaks vfork: + + int main(void) + { + assert(unshare(CLONE_NEWUSER | CLONE_NEWPID) == 0); + assert(vfork() >= 0); + _exit(0); + return 0; + } + + fails without this patch. + + Change this check to use CLONE_SIGHAND instead. This also forbids + CLONE_THREAD automatically, and this is what the comment implies. + + We could probably even drop CLONE_SIGHAND and use CLONE_THREAD, but it + would be safer to not do this. The current check denies CLONE_SIGHAND + implicitely and there is no reason to change this. + + Eric said "CLONE_SIGHAND is fine. CLONE_THREAD would be even better. + Having shared signal handling between two different pid namespaces is + the case that we are fundamentally guarding against." + + Signed-off-by: Oleg Nesterov + Reported-by: Colin Walters + Acked-by: Andy Lutomirski + Reviewed-by: "Eric W. Biederman" + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/fork.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/fork.c 2014-05-05 11:51:17.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/fork.c 2014-05-05 12:44:58.000000000 +0000 +@@ -1171,10 +1171,11 @@ + return ERR_PTR(-EINVAL); + + /* +- * If the new process will be in a different pid namespace +- * don't allow the creation of threads. ++ * If the new process will be in a different pid namespace don't ++ * allow it to share a thread group or signal handlers with the ++ * forking task. + */ +- if ((clone_flags & (CLONE_VM|CLONE_NEWPID)) && ++ if ((clone_flags & (CLONE_SIGHAND | CLONE_NEWPID)) && + (task_active_pid_ns(current) != current->nsproxy->pid_ns)) + return ERR_PTR(-EINVAL); + +Index: linux-3.10-3.10.11/dummy/rpi_1136_f608ebd760cb9b48a333700fdc10245e257d9fce.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1136_f608ebd760cb9b48a333700fdc10245e257d9fce.txt 2014-05-05 12:44:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1137_3c46f72697d06f219222314b4372562973975995.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1137_3c46f72697d06f219222314b4372562973975995.patch --- linux-3.10.11/debian/patches/rpi/rpi_1137_3c46f72697d06f219222314b4372562973975995.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1137_3c46f72697d06f219222314b4372562973975995.patch 2014-05-05 12:45:02.000000000 +0000 @@ -0,0 +1,68 @@ +commit 3c46f72697d06f219222314b4372562973975995 +Author: Jie Liu +Date: Wed Sep 11 14:20:05 2013 -0700 + + ocfs2: fix the end cluster offset of FIEMAP + + commit 28e8be31803b19d0d8f76216cb11b480b8a98bec upstream. + + Call fiemap ioctl(2) with given start offset as well as an desired mapping + range should show extents if possible. However, we somehow figure out the + end offset of mapping via 'mapping_end -= cpos' before iterating the + extent records which would cause problems if the given fiemap length is + too small to a cluster size, e.g, + + Cluster size 4096: + debugfs.ocfs2 1.6.3 + Block Size Bits: 12 Cluster Size Bits: 12 + + The extended fiemap test utility From David: + https://gist.github.com/anonymous/6172331 + + # dd if=/dev/urandom of=/ocfs2/test_file bs=1M count=1000 + # ./fiemap /ocfs2/test_file 4096 10 + start: 4096, length: 10 + File /ocfs2/test_file has 0 extents: + # Logical Physical Length Flags + ^^^^^ <-- No extent is shown + + In this case, at ocfs2_fiemap(): cpos == mapping_end == 1. Hence the + loop of searching extent records was not executed at all. + + This patch remove the in question 'mapping_end -= cpos', and loops + until the cpos is larger than the mapping_end as usual. + + # ./fiemap /ocfs2/test_file 4096 10 + start: 4096, length: 10 + File /ocfs2/test_file has 1 extents: + # Logical Physical Length Flags + 0: 0000000000000000 0000000056a01000 0000000006a00000 0000 + + Signed-off-by: Jie Liu + Reported-by: David Weber + Tested-by: David Weber + Cc: Sunil Mushran + Cc: Mark Fashen + Cc: Joel Becker + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/ocfs2/extent_map.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/ocfs2/extent_map.c 2014-05-05 11:51:17.000000000 +0000 ++++ linux-3.10-3.10.11/fs/ocfs2/extent_map.c 2014-05-05 12:45:01.000000000 +0000 +@@ -781,7 +781,6 @@ + cpos = map_start >> osb->s_clustersize_bits; + mapping_end = ocfs2_clusters_for_bytes(inode->i_sb, + map_start + map_len); +- mapping_end -= cpos; + is_last = 0; + while (cpos < mapping_end && !is_last) { + u32 fe_flags; +Index: linux-3.10-3.10.11/dummy/rpi_1137_3c46f72697d06f219222314b4372562973975995.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1137_3c46f72697d06f219222314b4372562973975995.txt 2014-05-05 12:45:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1138_d96fa17975d6b1d1dd1264170ccdfabb254f71c2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1138_d96fa17975d6b1d1dd1264170ccdfabb254f71c2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1138_d96fa17975d6b1d1dd1264170ccdfabb254f71c2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1138_d96fa17975d6b1d1dd1264170ccdfabb254f71c2.patch 2014-05-05 12:45:03.000000000 +0000 @@ -0,0 +1,76 @@ +commit d96fa17975d6b1d1dd1264170ccdfabb254f71c2 +Author: Greg Thelen +Date: Wed Sep 11 14:23:08 2013 -0700 + + memcg: fix multiple large threshold notifications + + commit 2bff24a3707093c435ab3241c47dcdb5f16e432b upstream. + + A memory cgroup with (1) multiple threshold notifications and (2) at least + one threshold >=2G was not reliable. Specifically the notifications would + either not fire or would not fire in the proper order. + + The __mem_cgroup_threshold() signaling logic depends on keeping 64 bit + thresholds in sorted order. mem_cgroup_usage_register_event() sorts them + with compare_thresholds(), which returns the difference of two 64 bit + thresholds as an int. If the difference is positive but has bit[31] set, + then sort() treats the difference as negative and breaks sort order. + + This fix compares the two arbitrary 64 bit thresholds returning the + classic -1, 0, 1 result. + + The test below sets two notifications (at 0x1000 and 0x81001000): + cd /sys/fs/cgroup/memory + mkdir x + for x in 4096 2164264960; do + cgroup_event_listener x/memory.usage_in_bytes $x | sed "s/^/$x listener:/" & + done + echo $$ > x/cgroup.procs + anon_leaker 500M + + v3.11-rc7 fails to signal the 4096 event listener: + Leaking... + Done leaking pages. + + Patched v3.11-rc7 properly notifies: + Leaking... + 4096 listener:2013:8:31:14:13:36 + Done leaking pages. + + The fixed bug is old. It appears to date back to the introduction of + memcg threshold notifications in v2.6.34-rc1-116-g2e72b6347c94 "memcg: + implement memory thresholds" + + Signed-off-by: Greg Thelen + Acked-by: Michal Hocko + Acked-by: Kirill A. Shutemov + Acked-by: Johannes Weiner + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/memcontrol.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/memcontrol.c 2014-05-05 11:51:17.000000000 +0000 ++++ linux-3.10-3.10.11/mm/memcontrol.c 2014-05-05 12:45:02.000000000 +0000 +@@ -5584,7 +5584,13 @@ + const struct mem_cgroup_threshold *_a = a; + const struct mem_cgroup_threshold *_b = b; + +- return _a->threshold - _b->threshold; ++ if (_a->threshold > _b->threshold) ++ return 1; ++ ++ if (_a->threshold < _b->threshold) ++ return -1; ++ ++ return 0; + } + + static int mem_cgroup_oom_notify_cb(struct mem_cgroup *memcg) +Index: linux-3.10-3.10.11/dummy/rpi_1138_d96fa17975d6b1d1dd1264170ccdfabb254f71c2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1138_d96fa17975d6b1d1dd1264170ccdfabb254f71c2.txt 2014-05-05 12:45:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1139_8b89ae8a4914ee393c0db530735d933481272e97.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1139_8b89ae8a4914ee393c0db530735d933481272e97.patch --- linux-3.10.11/debian/patches/rpi/rpi_1139_8b89ae8a4914ee393c0db530735d933481272e97.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1139_8b89ae8a4914ee393c0db530735d933481272e97.patch 2014-05-05 12:45:04.000000000 +0000 @@ -0,0 +1,45 @@ +commit 8b89ae8a4914ee393c0db530735d933481272e97 +Author: Libin +Date: Wed Sep 11 14:20:38 2013 -0700 + + mm/huge_memory.c: fix potential NULL pointer dereference + + commit a8f531ebc33052642b4bd7b812eedf397108ce64 upstream. + + In collapse_huge_page() there is a race window between releasing the + mmap_sem read lock and taking the mmap_sem write lock, so find_vma() may + return NULL. So check the return value to avoid NULL pointer dereference. + + collapse_huge_page + khugepaged_alloc_page + up_read(&mm->mmap_sem) + down_write(&mm->mmap_sem) + vma = find_vma(mm, address) + + Signed-off-by: Libin + Acked-by: Kirill A. Shutemov + Reviewed-by: Wanpeng Li + Reviewed-by: Michal Hocko + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/huge_memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/huge_memory.c 2014-05-05 11:51:16.000000000 +0000 ++++ linux-3.10-3.10.11/mm/huge_memory.c 2014-05-05 12:45:03.000000000 +0000 +@@ -2286,6 +2286,8 @@ + goto out; + + vma = find_vma(mm, address); ++ if (!vma) ++ goto out; + hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; + hend = vma->vm_end & HPAGE_PMD_MASK; + if (address < hstart || address + HPAGE_PMD_SIZE > hend) +Index: linux-3.10-3.10.11/dummy/rpi_1139_8b89ae8a4914ee393c0db530735d933481272e97.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1139_8b89ae8a4914ee393c0db530735d933481272e97.txt 2014-05-05 12:45:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1140_1ca91545961a92067cb8ad3ebc1558c8d1574456.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1140_1ca91545961a92067cb8ad3ebc1558c8d1574456.patch --- linux-3.10.11/debian/patches/rpi/rpi_1140_1ca91545961a92067cb8ad3ebc1558c8d1574456.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1140_1ca91545961a92067cb8ad3ebc1558c8d1574456.patch 2014-05-05 12:45:04.000000000 +0000 @@ -0,0 +1,41 @@ +commit 1ca91545961a92067cb8ad3ebc1558c8d1574456 +Author: Eric W. Biederman +Date: Mon Mar 25 19:57:10 2013 -0700 + + proc: Restrict mounting the proc filesystem + + commit aee1c13dd0f6c2fc56e0e492b349ee8ac655880f upstream. + + Don't allow mounting the proc filesystem unless the caller has + CAP_SYS_ADMIN rights over the pid namespace. The principle here is if + you create or have capabilities over it you can mount it, otherwise + you get to live with what other people have mounted. + + Andy pointed out that this is needed to prevent users in a user + namespace from remounting proc and specifying different hidepid and gid + options on already existing proc mounts. + + Reported-by: Andy Lutomirski + Signed-off-by: "Eric W. Biederman" + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/proc/root.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/proc/root.c 2014-05-05 11:51:16.000000000 +0000 ++++ linux-3.10-3.10.11/fs/proc/root.c 2014-05-05 12:45:04.000000000 +0000 +@@ -110,7 +110,8 @@ + ns = task_active_pid_ns(current); + options = data; + +- if (!current_user_ns()->may_mount_proc) ++ if (!current_user_ns()->may_mount_proc || ++ !ns_capable(ns->user_ns, CAP_SYS_ADMIN)) + return ERR_PTR(-EPERM); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1140_1ca91545961a92067cb8ad3ebc1558c8d1574456.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1140_1ca91545961a92067cb8ad3ebc1558c8d1574456.txt 2014-05-05 12:45:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1141_4b5fe51a9a8e6d4c74a6f2717bf25e4132c551d3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1141_4b5fe51a9a8e6d4c74a6f2717bf25e4132c551d3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1141_4b5fe51a9a8e6d4c74a6f2717bf25e4132c551d3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1141_4b5fe51a9a8e6d4c74a6f2717bf25e4132c551d3.patch 2014-05-05 12:45:05.000000000 +0000 @@ -0,0 +1,71 @@ +commit 4b5fe51a9a8e6d4c74a6f2717bf25e4132c551d3 +Author: Jan Kara +Date: Thu Jul 25 11:49:11 2013 +0200 + + isofs: Refuse RW mount of the filesystem instead of making it RO + + commit 17b7f7cf58926844e1dd40f5eb5348d481deca6a upstream. + + Refuse RW mount of isofs filesystem. So far we just silently changed it + to RO mount but when the media is writeable, block layer won't notice + this change and thus will think device is used RW and will block eject + button of the drive. That is unexpected by users because for + non-writeable media eject button works just fine. + + Userspace mount(8) command handles this just fine and retries mounting + with MS_RDONLY set so userspace shouldn't see any regression. Plus any + tool mounting isofs is likely confronted with the case of read-only + media where block layer already refuses to mount the filesystem without + MS_RDONLY set so our behavior shouldn't be anything new for it. + + Reported-by: Hui Wang + Signed-off-by: Jan Kara + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/isofs/inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/isofs/inode.c 2014-05-05 11:51:16.000000000 +0000 ++++ linux-3.10-3.10.11/fs/isofs/inode.c 2014-05-05 12:45:05.000000000 +0000 +@@ -125,8 +125,8 @@ + + static int isofs_remount(struct super_block *sb, int *flags, char *data) + { +- /* we probably want a lot more here */ +- *flags |= MS_RDONLY; ++ if (!(*flags & MS_RDONLY)) ++ return -EROFS; + return 0; + } + +@@ -779,15 +779,6 @@ + */ + s->s_maxbytes = 0x80000000000LL; + +- /* +- * The CDROM is read-only, has no nodes (devices) on it, and since +- * all of the files appear to be owned by root, we really do not want +- * to allow suid. (suid or devices will not show up unless we have +- * Rock Ridge extensions) +- */ +- +- s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */; +- + /* Set this for reference. Its not currently used except on write + which we don't have .. */ + +@@ -1546,6 +1537,9 @@ + static struct dentry *isofs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) + { ++ /* We don't support read-write mounts */ ++ if (!(flags & MS_RDONLY)) ++ return ERR_PTR(-EACCES); + return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1141_4b5fe51a9a8e6d4c74a6f2717bf25e4132c551d3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1141_4b5fe51a9a8e6d4c74a6f2717bf25e4132c551d3.txt 2014-05-05 12:45:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1142_34db3c078aab40f22846b76c1a2c960c2a378f40.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1142_34db3c078aab40f22846b76c1a2c960c2a378f40.patch --- linux-3.10.11/debian/patches/rpi/rpi_1142_34db3c078aab40f22846b76c1a2c960c2a378f40.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1142_34db3c078aab40f22846b76c1a2c960c2a378f40.patch 2014-05-05 12:45:06.000000000 +0000 @@ -0,0 +1,52 @@ +commit 34db3c078aab40f22846b76c1a2c960c2a378f40 +Author: Borislav Petkov +Date: Tue Jul 23 20:01:23 2013 +0200 + + amd64_edac: Fix single-channel setups + + commit f0a56c480196a98479760862468cc95879df3de0 upstream. + + It can happen that configurations are running in a single-channel mode + even with a dual-channel memory controller, by, say, putting the DIMMs + only on the one channel and leaving the other empty. This causes a + problem in init_csrows which implicitly assumes that when the second + channel is enabled, i.e. channel 1, the struct dimm hierarchy will be + present. Which is not. + + So always allocate two channels unconditionally. + + This provides for the nice side effect that the data structures are + initialized so some day, when memory hotplug is supported, it should + just work out of the box when all of a sudden a second channel appears. + + Reported-and-tested-by: Roger Leigh + Signed-off-by: Borislav Petkov + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/edac/amd64_edac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/edac/amd64_edac.c 2014-05-05 11:51:16.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/edac/amd64_edac.c 2014-05-05 12:45:06.000000000 +0000 +@@ -2470,8 +2470,15 @@ + layers[0].size = pvt->csels[0].b_cnt; + layers[0].is_virt_csrow = true; + layers[1].type = EDAC_MC_LAYER_CHANNEL; +- layers[1].size = pvt->channel_count; ++ ++ /* ++ * Always allocate two channels since we can have setups with DIMMs on ++ * only one channel. Also, this simplifies handling later for the price ++ * of a couple of KBs tops. ++ */ ++ layers[1].size = 2; + layers[1].is_virt_csrow = false; ++ + mci = edac_mc_alloc(nid, ARRAY_SIZE(layers), layers, 0); + if (!mci) + goto err_siblings; +Index: linux-3.10-3.10.11/dummy/rpi_1142_34db3c078aab40f22846b76c1a2c960c2a378f40.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1142_34db3c078aab40f22846b76c1a2c960c2a378f40.txt 2014-05-05 12:45:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1143_579db19eca10b594acd9d4516814b599eb4486ec.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1143_579db19eca10b594acd9d4516814b599eb4486ec.patch --- linux-3.10.11/debian/patches/rpi/rpi_1143_579db19eca10b594acd9d4516814b599eb4486ec.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1143_579db19eca10b594acd9d4516814b599eb4486ec.patch 2014-05-05 12:45:07.000000000 +0000 @@ -0,0 +1,79 @@ +commit 579db19eca10b594acd9d4516814b599eb4486ec +Author: Alex Deucher +Date: Mon Aug 12 11:04:29 2013 -0400 + + drm/edid: add quirk for Medion MD30217PG + + commit 118bdbd86b39dbb843155054021d2c59058f1e05 upstream. + + This LCD monitor (1280x1024 native) has a completely + bogus detailed timing (640x350@70hz). User reports that + 1280x1024@60 has waves so prefer 1280x1024@75. + + Manufacturer: MED Model: 7b8 Serial#: 99188 + Year: 2005 Week: 5 + EDID Version: 1.3 + Analog Display Input, Input Voltage Level: 0.700/0.700 V + Sync: Separate + Max Image Size [cm]: horiz.: 34 vert.: 27 + Gamma: 2.50 + DPMS capabilities: Off; RGB/Color Display + First detailed timing is preferred mode + redX: 0.645 redY: 0.348 greenX: 0.280 greenY: 0.605 + blueX: 0.142 blueY: 0.071 whiteX: 0.313 whiteY: 0.329 + Supported established timings: + 720x400@70Hz + 640x480@60Hz + 640x480@72Hz + 640x480@75Hz + 800x600@56Hz + 800x600@60Hz + 800x600@72Hz + 800x600@75Hz + 1024x768@60Hz + 1024x768@70Hz + 1024x768@75Hz + 1280x1024@75Hz + Manufacturer's mask: 0 + Supported standard timings: + Supported detailed timing: + clock: 25.2 MHz Image Size: 337 x 270 mm + h_active: 640 h_sync: 688 h_sync_end 784 h_blank_end 800 h_border: 0 + v_active: 350 v_sync: 350 v_sync_end 352 v_blanking: 449 v_border: 0 + Monitor name: MD30217PG + Ranges: V min: 56 V max: 76 Hz, H min: 30 H max: 83 kHz, PixClock max 145 MHz + Serial No: 501099188 + EDID (in hex): + 00ffffffffffff0034a4b80774830100 + 050f010368221b962a0c55a559479b24 + 125054afcf00310a0101010101018180 + 000000000000d60980a0205e63103060 + 0200510e1100001e000000fc004d4433 + 3032313750470a202020000000fd0038 + 4c1e530e000a202020202020000000ff + 003530313039393138380a2020200078 + + Signed-off-by: Alex Deucher + Reported-by: friedrich@mailstation.de + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/drm_edid.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/drm_edid.c 2014-05-05 11:51:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/drm_edid.c 2014-05-05 12:45:06.000000000 +0000 +@@ -125,6 +125,9 @@ + + /* ViewSonic VA2026w */ + { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, ++ ++ /* Medion MD 30217 PG */ ++ { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, + }; + + /* +Index: linux-3.10-3.10.11/dummy/rpi_1143_579db19eca10b594acd9d4516814b599eb4486ec.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1143_579db19eca10b594acd9d4516814b599eb4486ec.txt 2014-05-05 12:45:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1144_4fdaa3d47985338f80d7262de700533a9e630d29.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1144_4fdaa3d47985338f80d7262de700533a9e630d29.patch --- linux-3.10.11/debian/patches/rpi/rpi_1144_4fdaa3d47985338f80d7262de700533a9e630d29.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1144_4fdaa3d47985338f80d7262de700533a9e630d29.patch 2014-05-05 12:45:08.000000000 +0000 @@ -0,0 +1,153 @@ +commit 4fdaa3d47985338f80d7262de700533a9e630d29 +Author: Richard Weinberger +Date: Sat Aug 17 18:46:00 2013 +0200 + + um: Implement probe_kernel_read() + + commit f75b1b1bedfb498cc43a992ce4d7ed8df3b1e770 upstream. + + UML needs it's own probe_kernel_read() to handle kernel + mode faults correctly. + The implementation uses mincore() on the host side to detect + whether a page is owned by the UML kernel process. + + This fixes also a possible crash when sysrq-t is used. + Starting with 3.10 sysrq-t calls probe_kernel_read() to + read details from the kernel workers. As kernel worker are + completely async pointers may turn NULL while reading them. + + Signed-off-by: Richard Weinberger + Cc: + Cc: + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/um/include/shared/os.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/um/include/shared/os.h 2014-05-05 11:51:15.000000000 +0000 ++++ linux-3.10-3.10.11/arch/um/include/shared/os.h 2014-05-05 12:45:07.000000000 +0000 +@@ -200,6 +200,7 @@ + extern int os_drop_memory(void *addr, int length); + extern int can_drop_memory(void); + extern void os_flush_stdout(void); ++extern int os_mincore(void *addr, unsigned long len); + + /* execvp.c */ + extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); +Index: linux-3.10-3.10.11/arch/um/kernel/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/arch/um/kernel/Makefile 2014-05-05 11:51:15.000000000 +0000 ++++ linux-3.10-3.10.11/arch/um/kernel/Makefile 2014-05-05 12:45:07.000000000 +0000 +@@ -13,7 +13,7 @@ + obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ + physmem.o process.o ptrace.o reboot.o sigio.o \ + signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ +- um_arch.o umid.o skas/ ++ um_arch.o umid.o maccess.o skas/ + + obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o + obj-$(CONFIG_GPROF) += gprof_syms.o +Index: linux-3.10-3.10.11/arch/um/kernel/maccess.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/um/kernel/maccess.c 2014-05-05 12:45:07.000000000 +0000 +@@ -0,0 +1,24 @@ ++/* ++ * Copyright (C) 2013 Richard Weinberger ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++ ++long probe_kernel_read(void *dst, const void *src, size_t size) ++{ ++ void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE); ++ ++ if ((unsigned long)src < PAGE_SIZE || size <= 0) ++ return -EFAULT; ++ ++ if (os_mincore(psrc, size + src - psrc) <= 0) ++ return -EFAULT; ++ ++ return __probe_kernel_read(dst, src, size); ++} +Index: linux-3.10-3.10.11/arch/um/os-Linux/process.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/um/os-Linux/process.c 2014-05-05 11:51:15.000000000 +0000 ++++ linux-3.10-3.10.11/arch/um/os-Linux/process.c 2014-05-05 12:45:07.000000000 +0000 +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -232,6 +233,57 @@ + return ok; + } + ++static int os_page_mincore(void *addr) ++{ ++ char vec[2]; ++ int ret; ++ ++ ret = mincore(addr, UM_KERN_PAGE_SIZE, vec); ++ if (ret < 0) { ++ if (errno == ENOMEM || errno == EINVAL) ++ return 0; ++ else ++ return -errno; ++ } ++ ++ return vec[0] & 1; ++} ++ ++int os_mincore(void *addr, unsigned long len) ++{ ++ char *vec; ++ int ret, i; ++ ++ if (len <= UM_KERN_PAGE_SIZE) ++ return os_page_mincore(addr); ++ ++ vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); ++ if (!vec) ++ return -ENOMEM; ++ ++ ret = mincore(addr, UM_KERN_PAGE_SIZE, vec); ++ if (ret < 0) { ++ if (errno == ENOMEM || errno == EINVAL) ++ ret = 0; ++ else ++ ret = -errno; ++ ++ goto out; ++ } ++ ++ for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) { ++ if (!(vec[i] & 1)) { ++ ret = 0; ++ goto out; ++ } ++ } ++ ++ ret = 1; ++out: ++ free(vec); ++ return ret; ++} ++ + void init_new_thread_signals(void) + { + set_handler(SIGSEGV); +Index: linux-3.10-3.10.11/dummy/rpi_1144_4fdaa3d47985338f80d7262de700533a9e630d29.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1144_4fdaa3d47985338f80d7262de700533a9e630d29.txt 2014-05-05 12:45:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1145_2ab0ad6af3a87818ea3525914be6779fca833801.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1145_2ab0ad6af3a87818ea3525914be6779fca833801.patch --- linux-3.10.11/debian/patches/rpi/rpi_1145_2ab0ad6af3a87818ea3525914be6779fca833801.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1145_2ab0ad6af3a87818ea3525914be6779fca833801.patch 2014-05-05 12:45:09.000000000 +0000 @@ -0,0 +1,35 @@ +commit 2ab0ad6af3a87818ea3525914be6779fca833801 +Author: majianpeng +Date: Tue Jul 16 15:45:48 2013 +0800 + + libceph: unregister request in __map_request failed and nofail == false + + commit 73d9f7eef3d98c3920e144797cc1894c6b005a1e upstream. + + For nofail == false request, if __map_request failed, the caller does + cleanup work, like releasing the relative pages. It doesn't make any sense + to retry this request. + + Signed-off-by: Jianpeng Ma + Reviewed-by: Sage Weil + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ceph/osd_client.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ceph/osd_client.c 2014-05-05 11:51:15.000000000 +0000 ++++ linux-3.10-3.10.11/net/ceph/osd_client.c 2014-05-05 12:45:08.000000000 +0000 +@@ -2130,6 +2130,8 @@ + dout("osdc_start_request failed map, " + " will retry %lld\n", req->r_tid); + rc = 0; ++ } else { ++ __unregister_request(osdc, req); + } + goto out_unlock; + } +Index: linux-3.10-3.10.11/dummy/rpi_1145_2ab0ad6af3a87818ea3525914be6779fca833801.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1145_2ab0ad6af3a87818ea3525914be6779fca833801.txt 2014-05-05 12:45:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1146_fd5e2dea537bbf0bfb09f79a8b34c148bb502735.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1146_fd5e2dea537bbf0bfb09f79a8b34c148bb502735.patch --- linux-3.10.11/debian/patches/rpi/rpi_1146_fd5e2dea537bbf0bfb09f79a8b34c148bb502735.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1146_fd5e2dea537bbf0bfb09f79a8b34c148bb502735.patch 2014-05-05 12:45:10.000000000 +0000 @@ -0,0 +1,35 @@ +commit fd5e2dea537bbf0bfb09f79a8b34c148bb502735 +Author: Sage Weil +Date: Wed Aug 28 17:17:29 2013 -0700 + + libceph: use pg_num_mask instead of pgp_num_mask for pg.seed calc + + commit 9542cf0bf9b1a3adcc2ef271edbcbdba03abf345 upstream. + + Fix a typo that used the wrong bitmask for the pg.seed calculation. This + is normally unnoticed because in most cases pg_num == pgp_num. It is, however, + a bug that is easily corrected. + + Signed-off-by: Sage Weil + Reviewed-by: Alex Elder + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ceph/osdmap.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ceph/osdmap.c 2014-05-05 11:51:14.000000000 +0000 ++++ linux-3.10-3.10.11/net/ceph/osdmap.c 2014-05-05 12:45:09.000000000 +0000 +@@ -1129,7 +1129,7 @@ + + /* pg_temp? */ + pgid.seed = ceph_stable_mod(pgid.seed, pool->pg_num, +- pool->pgp_num_mask); ++ pool->pg_num_mask); + pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid); + if (pg) { + *num = pg->len; +Index: linux-3.10-3.10.11/dummy/rpi_1146_fd5e2dea537bbf0bfb09f79a8b34c148bb502735.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1146_fd5e2dea537bbf0bfb09f79a8b34c148bb502735.txt 2014-05-05 12:45:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1147_4f8e2fc10e249dcae05898f4807d9cc450b070bb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1147_4f8e2fc10e249dcae05898f4807d9cc450b070bb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1147_4f8e2fc10e249dcae05898f4807d9cc450b070bb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1147_4f8e2fc10e249dcae05898f4807d9cc450b070bb.patch 2014-05-05 12:45:11.000000000 +0000 @@ -0,0 +1,34 @@ +commit 4f8e2fc10e249dcae05898f4807d9cc450b070bb +Author: majianpeng +Date: Tue Jul 16 19:36:21 2013 +0800 + + ceph: Don't forget the 'up_read(&osdc->map_sem)' if met error. + + commit 494ddd11be3e2621096bb425eed2886f8e8446d4 upstream. + + Signed-off-by: Jianpeng Ma + Reviewed-by: Sage Weil + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/ceph/ioctl.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/ceph/ioctl.c 2014-05-05 11:51:14.000000000 +0000 ++++ linux-3.10-3.10.11/fs/ceph/ioctl.c 2014-05-05 12:45:10.000000000 +0000 +@@ -196,8 +196,10 @@ + r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, len, + &dl.object_no, &dl.object_offset, + &olen); +- if (r < 0) ++ if (r < 0) { ++ up_read(&osdc->map_sem); + return -EIO; ++ } + dl.file_offset -= dl.object_offset; + dl.object_size = ceph_file_layout_object_size(ci->i_layout); + dl.block_size = ceph_file_layout_su(ci->i_layout); +Index: linux-3.10-3.10.11/dummy/rpi_1147_4f8e2fc10e249dcae05898f4807d9cc450b070bb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1147_4f8e2fc10e249dcae05898f4807d9cc450b070bb.txt 2014-05-05 12:45:10.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1148_be4c4b85002b3c20773c2c3d3e997bd1aedc1453.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1148_be4c4b85002b3c20773c2c3d3e997bd1aedc1453.patch --- linux-3.10.11/debian/patches/rpi/rpi_1148_be4c4b85002b3c20773c2c3d3e997bd1aedc1453.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1148_be4c4b85002b3c20773c2c3d3e997bd1aedc1453.patch 2014-05-05 12:45:11.000000000 +0000 @@ -0,0 +1,77 @@ +commit be4c4b85002b3c20773c2c3d3e997bd1aedc1453 +Author: Josh Durgin +Date: Mon Aug 26 17:55:38 2013 -0700 + + rbd: fix I/O error propagation for reads + + commit 17c1cc1d9293a568a00545469078e29555cc7f39 upstream. + + When a request returns an error, the driver needs to report the entire + extent of the request as completed. Writes already did this, since + they always set xferred = length, but reads were skipping that step if + an error other than -ENOENT occurred. Instead, rbd would end up + passing 0 xferred to blk_end_request(), which would always report + needing more data. This resulted in an assert failing when more data + was required by the block layer, but all the object requests were + done: + + [ 1868.719077] rbd: obj_request read result -108 xferred 0 + [ 1868.719077] + [ 1868.719518] end_request: I/O error, dev rbd1, sector 0 + [ 1868.719739] + [ 1868.719739] Assertion failure in rbd_img_obj_callback() at line 1736: + [ 1868.719739] + [ 1868.719739] rbd_assert(more ^ (which == img_request->obj_request_count)); + + Without this assert, reads that hit errors would hang forever, since + the block layer considered them incomplete. + + Fixes: http://tracker.ceph.com/issues/5647 + Signed-off-by: Josh Durgin + Reviewed-by: Alex Elder + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/block/rbd.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/block/rbd.c 2014-05-05 11:51:14.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/block/rbd.c 2014-05-05 12:45:11.000000000 +0000 +@@ -1565,11 +1565,12 @@ + obj_request, obj_request->img_request, obj_request->result, + xferred, length); + /* +- * ENOENT means a hole in the image. We zero-fill the +- * entire length of the request. A short read also implies +- * zero-fill to the end of the request. Either way we +- * update the xferred count to indicate the whole request +- * was satisfied. ++ * ENOENT means a hole in the image. We zero-fill the entire ++ * length of the request. A short read also implies zero-fill ++ * to the end of the request. An error requires the whole ++ * length of the request to be reported finished with an error ++ * to the block layer. In each case we update the xferred ++ * count to indicate the whole request was satisfied. + */ + rbd_assert(obj_request->type != OBJ_REQUEST_NODATA); + if (obj_request->result == -ENOENT) { +@@ -1578,14 +1579,13 @@ + else + zero_pages(obj_request->pages, 0, length); + obj_request->result = 0; +- obj_request->xferred = length; + } else if (xferred < length && !obj_request->result) { + if (obj_request->type == OBJ_REQUEST_BIO) + zero_bio_chain(obj_request->bio_list, xferred); + else + zero_pages(obj_request->pages, xferred, length); +- obj_request->xferred = length; + } ++ obj_request->xferred = length; + obj_request_done_set(obj_request); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1148_be4c4b85002b3c20773c2c3d3e997bd1aedc1453.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1148_be4c4b85002b3c20773c2c3d3e997bd1aedc1453.txt 2014-05-05 12:45:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1149_c0da08882ef2c738edacd5e7fbca671e663f9951.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1149_c0da08882ef2c738edacd5e7fbca671e663f9951.patch --- linux-3.10.11/debian/patches/rpi/rpi_1149_c0da08882ef2c738edacd5e7fbca671e663f9951.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1149_c0da08882ef2c738edacd5e7fbca671e663f9951.patch 2014-05-05 12:45:12.000000000 +0000 @@ -0,0 +1,65 @@ +commit c0da08882ef2c738edacd5e7fbca671e663f9951 +Author: Sergei Shtylyov +Date: Sat Aug 24 23:38:15 2013 -0400 + + mmc: tmio_mmc_dma: fix PIO fallback on SDHI + + commit f936f9b67b7f8c2eae01dd303a0e90bd777c4679 upstream. + + I'm testing SH-Mobile SDHI driver in DMA mode with a new DMA controller using + 'bonnie++' and getting DMA error after which the tmio_mmc_dma.c code falls back + to PIO but all commands time out after that. It turned out that the fallback + code calls tmio_mmc_enable_dma() with RX/TX channels already freed and pointers + to them cleared, so that the function bails out early instead of clearing the + DMA bit in the CTL_DMA_ENABLE register. The regression was introduced by commit + 162f43e31c5a376ec16336e5d0ac973373d54c89 (mmc: tmio: fix a deadlock). + Moving tmio_mmc_enable_dma() calls to the top of the PIO fallback code in + tmio_mmc_start_dma_{rx|tx}() helps. + + Signed-off-by: Sergei Shtylyov + Acked-by: Guennadi Liakhovetski + Signed-off-by: Chris Ball + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/mmc/host/tmio_mmc_dma.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/mmc/host/tmio_mmc_dma.c 2014-05-05 11:51:13.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mmc/host/tmio_mmc_dma.c 2014-05-05 12:45:12.000000000 +0000 +@@ -104,6 +104,7 @@ + pio: + if (!desc) { + /* DMA failed, fall back to PIO */ ++ tmio_mmc_enable_dma(host, false); + if (ret >= 0) + ret = -EIO; + host->chan_rx = NULL; +@@ -116,7 +117,6 @@ + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); +- tmio_mmc_enable_dma(host, false); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, +@@ -185,6 +185,7 @@ + pio: + if (!desc) { + /* DMA failed, fall back to PIO */ ++ tmio_mmc_enable_dma(host, false); + if (ret >= 0) + ret = -EIO; + host->chan_tx = NULL; +@@ -197,7 +198,6 @@ + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); +- tmio_mmc_enable_dma(host, false); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__, +Index: linux-3.10-3.10.11/dummy/rpi_1149_c0da08882ef2c738edacd5e7fbca671e663f9951.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1149_c0da08882ef2c738edacd5e7fbca671e663f9951.txt 2014-05-05 12:45:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1150_6830e9ab4b67cee41edd609fb7ebe14c66fca434.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1150_6830e9ab4b67cee41edd609fb7ebe14c66fca434.patch --- linux-3.10.11/debian/patches/rpi/rpi_1150_6830e9ab4b67cee41edd609fb7ebe14c66fca434.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1150_6830e9ab4b67cee41edd609fb7ebe14c66fca434.patch 2014-05-05 12:45:13.000000000 +0000 @@ -0,0 +1,36 @@ +commit 6830e9ab4b67cee41edd609fb7ebe14c66fca434 +Author: Grant Likely +Date: Wed Aug 28 21:24:17 2013 +0100 + + of: Fix missing memory initialization on FDT unflattening + + commit 0640332e073be9207f0784df43595c0c39716e42 upstream. + + Any calls to dt_alloc() need to be zeroed. This is a temporary fix, but + the allocation function itself needs to zero memory before returning + it. This is a follow up to patch 9e4012752, "of: fdt: fix memory + initialization for expanded DT" which fixed one call site but missed + another. + + Signed-off-by: Grant Likely + Acked-by: Wladislav Wiebe + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/of/base.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/of/base.c 2014-05-05 11:51:13.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/of/base.c 2014-05-05 12:45:13.000000000 +0000 +@@ -1629,6 +1629,7 @@ + ap = dt_alloc(sizeof(*ap) + len + 1, 4); + if (!ap) + continue; ++ memset(ap, 0, sizeof(*ap) + len + 1); + ap->alias = start; + of_alias_add(ap, np, id, start, len); + } +Index: linux-3.10-3.10.11/dummy/rpi_1150_6830e9ab4b67cee41edd609fb7ebe14c66fca434.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1150_6830e9ab4b67cee41edd609fb7ebe14c66fca434.txt 2014-05-05 12:45:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1151_497587f84f16a5775b91d0a1051930ae8997d02d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1151_497587f84f16a5775b91d0a1051930ae8997d02d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1151_497587f84f16a5775b91d0a1051930ae8997d02d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1151_497587f84f16a5775b91d0a1051930ae8997d02d.patch 2014-05-05 12:45:14.000000000 +0000 @@ -0,0 +1,70 @@ +commit 497587f84f16a5775b91d0a1051930ae8997d02d +Author: Brian Norris +Date: Thu Jul 18 01:17:02 2013 -0700 + + mtd: nand: fix NAND_BUSWIDTH_AUTO for x16 devices + + commit 68e8078072e802e77134664f11d2ffbfbd2f8fbe upstream. + + The code for NAND_BUSWIDTH_AUTO is broken. According to Alexander: + + "I have a problem with attach NAND UBI in 16 bit mode. + NAND works fine if I specify NAND_BUSWIDTH_16 option, but not + working with NAND_BUSWIDTH_AUTO option. In second case NAND + chip is identifyed with ONFI." + + See his report for the rest of the details: + + http://lists.infradead.org/pipermail/linux-mtd/2013-July/047515.html + + Anyway, the problem is that nand_set_defaults() is called twice, we + intend it to reset the chip functions to their x16 buswidth verions + if the buswidth changed from x8 to x16; however, nand_set_defaults() + does exactly nothing if called a second time. + + Fix this by hacking nand_set_defaults() to reset the buswidth-dependent + functions if they were set to the x8 version the first time. Note that + this does not do anything to reset from x16 to x8, but that's not the + supported use case for NAND_BUSWIDTH_AUTO anyway. + + Signed-off-by: Brian Norris + Reported-by: Alexander Shiyan + Tested-by: Alexander Shiyan + Cc: Matthieu Castet + Signed-off-by: Artem Bityutskiy + Signed-off-by: David Woodhouse + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/mtd/nand/nand_base.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/mtd/nand/nand_base.c 2014-05-05 11:51:13.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mtd/nand/nand_base.c 2014-05-05 12:45:13.000000000 +0000 +@@ -2793,7 +2793,9 @@ + + if (!chip->select_chip) + chip->select_chip = nand_select_chip; +- if (!chip->read_byte) ++ ++ /* If called twice, pointers that depend on busw may need to be reset */ ++ if (!chip->read_byte || chip->read_byte == nand_read_byte) + chip->read_byte = busw ? nand_read_byte16 : nand_read_byte; + if (!chip->read_word) + chip->read_word = nand_read_word; +@@ -2801,9 +2803,9 @@ + chip->block_bad = nand_block_bad; + if (!chip->block_markbad) + chip->block_markbad = nand_default_block_markbad; +- if (!chip->write_buf) ++ if (!chip->write_buf || chip->write_buf == nand_write_buf) + chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; +- if (!chip->read_buf) ++ if (!chip->read_buf || chip->read_buf == nand_read_buf) + chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; + if (!chip->scan_bbt) + chip->scan_bbt = nand_default_bbt; +Index: linux-3.10-3.10.11/dummy/rpi_1151_497587f84f16a5775b91d0a1051930ae8997d02d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1151_497587f84f16a5775b91d0a1051930ae8997d02d.txt 2014-05-05 12:45:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1152_d662986b4f282ed5d9e42e6dbd5e6dbb2b5e7d0b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1152_d662986b4f282ed5d9e42e6dbd5e6dbb2b5e7d0b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1152_d662986b4f282ed5d9e42e6dbd5e6dbb2b5e7d0b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1152_d662986b4f282ed5d9e42e6dbd5e6dbb2b5e7d0b.patch 2014-05-05 12:45:15.000000000 +0000 @@ -0,0 +1,34 @@ +commit d662986b4f282ed5d9e42e6dbd5e6dbb2b5e7d0b +Author: Mark Brown +Date: Thu Aug 29 12:21:01 2013 +0100 + + clk: wm831x: Initialise wm831x pointer on init + + commit 08442ce993deeb15a070c14cc3f3459e87d111e0 upstream. + + Otherwise any attempt to interact with the hardware will crash. This is + what happens when drivers get written blind. + + Signed-off-by: Mark Brown + Signed-off-by: Mike Turquette + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/clk/clk-wm831x.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/clk/clk-wm831x.c 2014-05-05 11:51:12.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/clk/clk-wm831x.c 2014-05-05 12:45:14.000000000 +0000 +@@ -360,6 +360,8 @@ + if (!clkdata) + return -ENOMEM; + ++ clkdata->wm831x = wm831x; ++ + /* XTAL_ENA can only be set via OTP/InstantConfig so just read once */ + ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2); + if (ret < 0) { +Index: linux-3.10-3.10.11/dummy/rpi_1152_d662986b4f282ed5d9e42e6dbd5e6dbb2b5e7d0b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1152_d662986b4f282ed5d9e42e6dbd5e6dbb2b5e7d0b.txt 2014-05-05 12:45:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1153_3002e63bec05766a5af794b09d9cec34fda60519.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1153_3002e63bec05766a5af794b09d9cec34fda60519.patch --- linux-3.10.11/debian/patches/rpi/rpi_1153_3002e63bec05766a5af794b09d9cec34fda60519.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1153_3002e63bec05766a5af794b09d9cec34fda60519.patch 2014-05-05 12:45:16.000000000 +0000 @@ -0,0 +1,62 @@ +commit 3002e63bec05766a5af794b09d9cec34fda60519 +Author: Maxim Patlasov +Date: Mon Aug 12 20:39:30 2013 +0400 + + fuse: postpone end_page_writeback() in fuse_writepage_locked() + + commit 4a4ac4eba1010ef9a804569058ab29e3450c0315 upstream. + + The patch fixes a race between ftruncate(2), mmap-ed write and write(2): + + 1) An user makes a page dirty via mmap-ed write. + 2) The user performs shrinking truncate(2) intended to purge the page. + 3) Before fuse_do_setattr calls truncate_pagecache, the page goes to + writeback. fuse_writepage_locked fills FUSE_WRITE request and releases + the original page by end_page_writeback. + 4) fuse_do_setattr() completes and successfully returns. Since now, i_mutex + is free. + 5) Ordinary write(2) extends i_size back to cover the page. Note that + fuse_send_write_pages do wait for fuse writeback, but for another + page->index. + 6) fuse_writepage_locked proceeds by queueing FUSE_WRITE request. + fuse_send_writepage is supposed to crop inarg->size of the request, + but it doesn't because i_size has already been extended back. + + Moving end_page_writeback to the end of fuse_writepage_locked fixes the + race because now the fact that truncate_pagecache is successfully returned + infers that fuse_writepage_locked has already called end_page_writeback. + And this, in turn, infers that fuse_flush_writepages has already called + fuse_send_writepage, and the latter used valid (shrunk) i_size. write(2) + could not extend it because of i_mutex held by ftruncate(2). + + Signed-off-by: Maxim Patlasov + Signed-off-by: Miklos Szeredi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/fuse/file.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/file.c 2014-05-05 11:51:12.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/file.c 2014-05-05 12:45:15.000000000 +0000 +@@ -1530,7 +1530,6 @@ + + inc_bdi_stat(mapping->backing_dev_info, BDI_WRITEBACK); + inc_zone_page_state(tmp_page, NR_WRITEBACK_TEMP); +- end_page_writeback(page); + + spin_lock(&fc->lock); + list_add(&req->writepages_entry, &fi->writepages); +@@ -1538,6 +1537,8 @@ + fuse_flush_writepages(inode); + spin_unlock(&fc->lock); + ++ end_page_writeback(page); ++ + return 0; + + err_free: +Index: linux-3.10-3.10.11/dummy/rpi_1153_3002e63bec05766a5af794b09d9cec34fda60519.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1153_3002e63bec05766a5af794b09d9cec34fda60519.txt 2014-05-05 12:45:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1154_eb97a45d12c9517b7846ebe3c97ee554b777ad34.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1154_eb97a45d12c9517b7846ebe3c97ee554b777ad34.patch --- linux-3.10.11/debian/patches/rpi/rpi_1154_eb97a45d12c9517b7846ebe3c97ee554b777ad34.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1154_eb97a45d12c9517b7846ebe3c97ee554b777ad34.patch 2014-05-05 12:45:17.000000000 +0000 @@ -0,0 +1,44 @@ +commit eb97a45d12c9517b7846ebe3c97ee554b777ad34 +Author: Anand Avati +Date: Tue Aug 20 02:21:07 2013 -0400 + + fuse: invalidate inode attributes on xattr modification + + commit d331a415aef98717393dda0be69b7947da08eba3 upstream. + + Calls like setxattr and removexattr result in updation of ctime. + Therefore invalidate inode attributes to force a refresh. + + Signed-off-by: Anand Avati + Reviewed-by: Brian Foster + Signed-off-by: Miklos Szeredi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/fuse/dir.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/dir.c 2014-05-05 11:51:11.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/dir.c 2014-05-05 12:45:16.000000000 +0000 +@@ -1753,6 +1753,8 @@ + fc->no_setxattr = 1; + err = -EOPNOTSUPP; + } ++ if (!err) ++ fuse_invalidate_attr(inode); + return err; + } + +@@ -1882,6 +1884,8 @@ + fc->no_removexattr = 1; + err = -EOPNOTSUPP; + } ++ if (!err) ++ fuse_invalidate_attr(inode); + return err; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1154_eb97a45d12c9517b7846ebe3c97ee554b777ad34.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1154_eb97a45d12c9517b7846ebe3c97ee554b777ad34.txt 2014-05-05 12:45:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1155_4e208303119d234347b1f4337b84d47306e73811.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1155_4e208303119d234347b1f4337b84d47306e73811.patch --- linux-3.10.11/debian/patches/rpi/rpi_1155_4e208303119d234347b1f4337b84d47306e73811.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1155_4e208303119d234347b1f4337b84d47306e73811.patch 2014-05-05 12:45:18.000000000 +0000 @@ -0,0 +1,182 @@ +commit 4e208303119d234347b1f4337b84d47306e73811 +Author: Maxim Patlasov +Date: Fri Aug 30 17:06:04 2013 +0400 + + fuse: hotfix truncate_pagecache() issue + + commit 06a7c3c2781409af95000c60a5df743fd4e2f8b4 upstream. + + The way how fuse calls truncate_pagecache() from fuse_change_attributes() + is completely wrong. Because, w/o i_mutex held, we never sure whether + 'oldsize' and 'attr->size' are valid by the time of execution of + truncate_pagecache(inode, oldsize, attr->size). In fact, as soon as we + released fc->lock in the middle of fuse_change_attributes(), we completely + loose control of actions which may happen with given inode until we reach + truncate_pagecache. The list of potentially dangerous actions includes + mmap-ed reads and writes, ftruncate(2) and write(2) extending file size. + + The typical outcome of doing truncate_pagecache() with outdated arguments + is data corruption from user point of view. This is (in some sense) + acceptable in cases when the issue is triggered by a change of the file on + the server (i.e. externally wrt fuse operation), but it is absolutely + intolerable in scenarios when a single fuse client modifies a file without + any external intervention. A real life case I discovered by fsx-linux + looked like this: + + 1. Shrinking ftruncate(2) comes to fuse_do_setattr(). The latter sends + FUSE_SETATTR to the server synchronously, but before getting fc->lock ... + 2. fuse_dentry_revalidate() is asynchronously called. It sends FUSE_LOOKUP + to the server synchronously, then calls fuse_change_attributes(). The + latter updates i_size, releases fc->lock, but before comparing oldsize vs + attr->size.. + 3. fuse_do_setattr() from the first step proceeds by acquiring fc->lock and + updating attributes and i_size, but now oldsize is equal to + outarg.attr.size because i_size has just been updated (step 2). Hence, + fuse_do_setattr() returns w/o calling truncate_pagecache(). + 4. As soon as ftruncate(2) completes, the user extends file size by + write(2) making a hole in the middle of file, then reads data from the hole + either by read(2) or mmap-ed read. The user expects to get zero data from + the hole, but gets stale data because truncate_pagecache() is not executed + yet. + + The scenario above illustrates one side of the problem: not truncating the + page cache even though we should. Another side corresponds to truncating + page cache too late, when the state of inode changed significantly. + Theoretically, the following is possible: + + 1. As in the previous scenario fuse_dentry_revalidate() discovered that + i_size changed (due to our own fuse_do_setattr()) and is going to call + truncate_pagecache() for some 'new_size' it believes valid right now. But + by the time that particular truncate_pagecache() is called ... + 2. fuse_do_setattr() returns (either having called truncate_pagecache() or + not -- it doesn't matter). + 3. The file is extended either by write(2) or ftruncate(2) or fallocate(2). + 4. mmap-ed write makes a page in the extended region dirty. + + The result will be the lost of data user wrote on the fourth step. + + The patch is a hotfix resolving the issue in a simplistic way: let's skip + dangerous i_size update and truncate_pagecache if an operation changing + file size is in progress. This simplistic approach looks correct for the + cases w/o external changes. And to handle them properly, more sophisticated + and intrusive techniques (e.g. NFS-like one) would be required. I'd like to + postpone it until the issue is well discussed on the mailing list(s). + + Changed in v2: + - improved patch description to cover both sides of the issue. + + Signed-off-by: Maxim Patlasov + Signed-off-by: Miklos Szeredi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/fuse/dir.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/dir.c 2014-05-05 12:45:16.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/dir.c 2014-05-05 12:45:17.000000000 +0000 +@@ -1594,6 +1594,7 @@ + struct file *file) + { + struct fuse_conn *fc = get_fuse_conn(inode); ++ struct fuse_inode *fi = get_fuse_inode(inode); + struct fuse_req *req; + struct fuse_setattr_in inarg; + struct fuse_attr_out outarg; +@@ -1621,8 +1622,10 @@ + if (IS_ERR(req)) + return PTR_ERR(req); + +- if (is_truncate) ++ if (is_truncate) { + fuse_set_nowrite(inode); ++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ } + + memset(&inarg, 0, sizeof(inarg)); + memset(&outarg, 0, sizeof(outarg)); +@@ -1684,12 +1687,14 @@ + invalidate_inode_pages2(inode->i_mapping); + } + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + return 0; + + error: + if (is_truncate) + fuse_release_nowrite(inode); + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + return err; + } + +Index: linux-3.10-3.10.11/fs/fuse/file.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/file.c 2014-05-05 12:45:15.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/file.c 2014-05-05 12:45:17.000000000 +0000 +@@ -630,7 +630,8 @@ + struct fuse_inode *fi = get_fuse_inode(inode); + + spin_lock(&fc->lock); +- if (attr_ver == fi->attr_version && size < inode->i_size) { ++ if (attr_ver == fi->attr_version && size < inode->i_size && ++ !test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) { + fi->attr_version = ++fc->attr_version; + i_size_write(inode, size); + } +@@ -1033,12 +1034,16 @@ + { + struct inode *inode = mapping->host; + struct fuse_conn *fc = get_fuse_conn(inode); ++ struct fuse_inode *fi = get_fuse_inode(inode); + int err = 0; + ssize_t res = 0; + + if (is_bad_inode(inode)) + return -EIO; + ++ if (inode->i_size < pos + iov_iter_count(ii)) ++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ + do { + struct fuse_req *req; + ssize_t count; +@@ -1074,6 +1079,7 @@ + if (res > 0) + fuse_write_update_size(inode, pos); + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + fuse_invalidate_attr(inode); + + return res > 0 ? res : err; +Index: linux-3.10-3.10.11/fs/fuse/fuse_i.h +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/fuse_i.h 2014-05-05 11:51:11.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/fuse_i.h 2014-05-05 12:45:17.000000000 +0000 +@@ -115,6 +115,8 @@ + enum { + /** Advise readdirplus */ + FUSE_I_ADVISE_RDPLUS, ++ /** An operation changing file size is in progress */ ++ FUSE_I_SIZE_UNSTABLE, + }; + + struct fuse_conn; +Index: linux-3.10-3.10.11/fs/fuse/inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/inode.c 2014-05-05 11:51:11.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/inode.c 2014-05-05 12:45:17.000000000 +0000 +@@ -201,7 +201,8 @@ + struct timespec old_mtime; + + spin_lock(&fc->lock); +- if (attr_version != 0 && fi->attr_version > attr_version) { ++ if ((attr_version != 0 && fi->attr_version > attr_version) || ++ test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) { + spin_unlock(&fc->lock); + return; + } +Index: linux-3.10-3.10.11/dummy/rpi_1155_4e208303119d234347b1f4337b84d47306e73811.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1155_4e208303119d234347b1f4337b84d47306e73811.txt 2014-05-05 12:45:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1156_e5362560a01dd6fac5922434e16b16a1accea504.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1156_e5362560a01dd6fac5922434e16b16a1accea504.patch --- linux-3.10.11/debian/patches/rpi/rpi_1156_e5362560a01dd6fac5922434e16b16a1accea504.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1156_e5362560a01dd6fac5922434e16b16a1accea504.patch 2014-05-05 12:45:18.000000000 +0000 @@ -0,0 +1,42 @@ +commit e5362560a01dd6fac5922434e16b16a1accea504 +Author: Miklos Szeredi +Date: Tue Sep 3 14:28:38 2013 +0200 + + fuse: readdir: check for slash in names + + commit efeb9e60d48f7778fdcad4a0f3ad9ea9b19e5dfd upstream. + + Userspace can add names containing a slash character to the directory + listing. Don't allow this as it could cause all sorts of trouble. + + Signed-off-by: Miklos Szeredi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/fuse/dir.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/dir.c 2014-05-05 12:45:17.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/dir.c 2014-05-05 12:45:18.000000000 +0000 +@@ -1175,6 +1175,8 @@ + return -EIO; + if (reclen > nbytes) + break; ++ if (memchr(dirent->name, '/', dirent->namelen) != NULL) ++ return -EIO; + + over = filldir(dstbuf, dirent->name, dirent->namelen, + file->f_pos, dirent->ino, dirent->type); +@@ -1323,6 +1325,8 @@ + return -EIO; + if (reclen > nbytes) + break; ++ if (memchr(dirent->name, '/', dirent->namelen) != NULL) ++ return -EIO; + + if (!over) { + /* We fill entries into dstbuf only as much as +Index: linux-3.10-3.10.11/dummy/rpi_1156_e5362560a01dd6fac5922434e16b16a1accea504.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1156_e5362560a01dd6fac5922434e16b16a1accea504.txt 2014-05-05 12:45:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1157_cff43fc8785eb4f8b3fa5a1030890fd8cad0cbdd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1157_cff43fc8785eb4f8b3fa5a1030890fd8cad0cbdd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1157_cff43fc8785eb4f8b3fa5a1030890fd8cad0cbdd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1157_cff43fc8785eb4f8b3fa5a1030890fd8cad0cbdd.patch 2014-05-05 12:45:19.000000000 +0000 @@ -0,0 +1,24 @@ +commit cff43fc8785eb4f8b3fa5a1030890fd8cad0cbdd +Author: Greg Kroah-Hartman +Date: Thu Sep 26 17:18:49 2013 -0700 + + Linux 3.10.13 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:43:40.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:45:19.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 12 ++SUBLEVEL = 13 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1157_cff43fc8785eb4f8b3fa5a1030890fd8cad0cbdd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1157_cff43fc8785eb4f8b3fa5a1030890fd8cad0cbdd.txt 2014-05-05 12:45:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1158_65e8f55e673adae0177488ddb20444076f702a47.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1158_65e8f55e673adae0177488ddb20444076f702a47.patch --- linux-3.10.11/debian/patches/rpi/rpi_1158_65e8f55e673adae0177488ddb20444076f702a47.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1158_65e8f55e673adae0177488ddb20444076f702a47.patch 2014-05-05 12:45:20.000000000 +0000 @@ -0,0 +1,56 @@ +commit 65e8f55e673adae0177488ddb20444076f702a47 +Author: Rafael J. Wysocki +Date: Sat Sep 14 03:38:20 2013 +0200 + + PCI / ACPI / PM: Clear pme_poll for devices in D3cold on wakeup + + commit 834145156bedadfb50121f0bc5e9d9f9f942bcca upstream. + + Commit 448bd85 (PCI/PM: add PCIe runtime D3cold support) added a + piece of code to pci_acpi_wake_dev() causing that function to behave + in a special way for devices in D3cold (so that their configuration + registers are not accessed before those devices are resumed). + However, it didn't take the clearing of the pme_poll flag into + account. That has to be done for all devices, even if they are in + D3cold, or pci_pme_list_scan() will not know that wakeup has been + signaled for the device and will poll its PME Status bit + unnecessarily. + + Fix the problem by moving the clearing of the pme_poll flag in + pci_acpi_wake_dev() before the code introduced by commit 448bd85. + + Reported-and-tested-by: David E. Box + Signed-off-by: Rafael J. Wysocki + Acked-by: Bjorn Helgaas + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/pci/pci-acpi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/pci/pci-acpi.c 2014-05-05 11:51:10.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/pci/pci-acpi.c 2014-05-05 12:45:19.000000000 +0000 +@@ -47,6 +47,9 @@ + if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) + return; + ++ if (pci_dev->pme_poll) ++ pci_dev->pme_poll = false; ++ + if (pci_dev->current_state == PCI_D3cold) { + pci_wakeup_event(pci_dev); + pm_runtime_resume(&pci_dev->dev); +@@ -57,9 +60,6 @@ + if (pci_dev->pme_support) + pci_check_pme_status(pci_dev); + +- if (pci_dev->pme_poll) +- pci_dev->pme_poll = false; +- + pci_wakeup_event(pci_dev); + pm_runtime_resume(&pci_dev->dev); + +Index: linux-3.10-3.10.11/dummy/rpi_1158_65e8f55e673adae0177488ddb20444076f702a47.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1158_65e8f55e673adae0177488ddb20444076f702a47.txt 2014-05-05 12:45:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1159_22df37406d8f90135b77ec6deb9950b68bcf3f4e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1159_22df37406d8f90135b77ec6deb9950b68bcf3f4e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1159_22df37406d8f90135b77ec6deb9950b68bcf3f4e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1159_22df37406d8f90135b77ec6deb9950b68bcf3f4e.patch 2014-05-05 12:45:21.000000000 +0000 @@ -0,0 +1,35 @@ +commit 22df37406d8f90135b77ec6deb9950b68bcf3f4e +Author: Fabio Porcedda +Date: Mon Sep 16 11:47:50 2013 +0200 + + net: usb: cdc_ether: Use wwan interface for Telit modules + + commit 0092820407901a0b2c4e343e85f96bb7abfcded1 upstream. + + Signed-off-by: Fabio Porcedda + Acked-by: Oliver Neukum + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/usb/cdc_ether.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/usb/cdc_ether.c 2014-05-05 11:51:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/usb/cdc_ether.c 2014-05-05 12:45:20.000000000 +0000 +@@ -709,6 +709,11 @@ + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, + }, { ++ /* Telit modules */ ++ USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), ++ .driver_info = (kernel_ulong_t) &wwan_info, ++}, { + USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +Index: linux-3.10-3.10.11/dummy/rpi_1159_22df37406d8f90135b77ec6deb9950b68bcf3f4e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1159_22df37406d8f90135b77ec6deb9950b68bcf3f4e.txt 2014-05-05 12:45:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1160_b1bf3479808bfb56cec46edf5dd9f47364715f46.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1160_b1bf3479808bfb56cec46edf5dd9f47364715f46.patch --- linux-3.10.11/debian/patches/rpi/rpi_1160_b1bf3479808bfb56cec46edf5dd9f47364715f46.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1160_b1bf3479808bfb56cec46edf5dd9f47364715f46.patch 2014-05-05 12:45:22.000000000 +0000 @@ -0,0 +1,34 @@ +commit b1bf3479808bfb56cec46edf5dd9f47364715f46 +Author: Miklos Szeredi +Date: Mon Sep 16 14:51:59 2013 +0200 + + cifs: fix filp leak in cifs_atomic_open() + + commit dfb1d61b0e9f9e2c542e9adc8d970689f4114ff6 upstream. + + If an error occurs after having called finish_open() then fput() needs to + be called on the already opened file. + + Signed-off-by: Miklos Szeredi + Cc: Steve French + Signed-off-by: Al Viro + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/cifs/dir.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/cifs/dir.c 2014-05-05 11:51:09.000000000 +0000 ++++ linux-3.10-3.10.11/fs/cifs/dir.c 2014-05-05 12:45:21.000000000 +0000 +@@ -491,6 +491,7 @@ + if (server->ops->close) + server->ops->close(xid, tcon, &fid); + cifs_del_pending_open(&open); ++ fput(file); + rc = -ENOMEM; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1160_b1bf3479808bfb56cec46edf5dd9f47364715f46.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1160_b1bf3479808bfb56cec46edf5dd9f47364715f46.txt 2014-05-05 12:45:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1161_86f7c9950b9378ed4d9e9bf8fbdf515d03fa6820.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1161_86f7c9950b9378ed4d9e9bf8fbdf515d03fa6820.patch --- linux-3.10.11/debian/patches/rpi/rpi_1161_86f7c9950b9378ed4d9e9bf8fbdf515d03fa6820.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1161_86f7c9950b9378ed4d9e9bf8fbdf515d03fa6820.patch 2014-05-05 12:45:23.000000000 +0000 @@ -0,0 +1,51 @@ +commit 86f7c9950b9378ed4d9e9bf8fbdf515d03fa6820 +Author: Rafał Miłecki +Date: Sun Sep 15 00:22:47 2013 +0200 + + bgmac: fix internal switch initialization + + commit 6a391e7bf26c04a6df5f77290e1146941d210d49 upstream. + + Some devices (BCM4749, BCM5357, BCM53572) have internal switch that + requires initialization. We already have code for this, but because + of the typo in code it was never working. This resulted in network not + working for some routers and possibility of soft-bricking them. + + Use correct bit for switch initialization and fix typo in the define. + + Signed-off-by: Rafał Miłecki + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bgmac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/broadcom/bgmac.c 2014-05-05 11:51:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bgmac.c 2014-05-05 12:45:22.000000000 +0000 +@@ -908,7 +908,7 @@ + struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc; + u8 et_swtype = 0; + u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY | +- BGMAC_CHIPCTL_1_IF_TYPE_RMII; ++ BGMAC_CHIPCTL_1_IF_TYPE_MII; + char buf[2]; + + if (bcm47xx_nvram_getenv("et_swtype", buf, 1) > 0) { +Index: linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bgmac.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/broadcom/bgmac.h 2014-05-05 11:51:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bgmac.h 2014-05-05 12:45:22.000000000 +0000 +@@ -333,7 +333,7 @@ + + #define BGMAC_CHIPCTL_1_IF_TYPE_MASK 0x00000030 + #define BGMAC_CHIPCTL_1_IF_TYPE_RMII 0x00000000 +-#define BGMAC_CHIPCTL_1_IF_TYPE_MI 0x00000010 ++#define BGMAC_CHIPCTL_1_IF_TYPE_MII 0x00000010 + #define BGMAC_CHIPCTL_1_IF_TYPE_RGMII 0x00000020 + #define BGMAC_CHIPCTL_1_SW_TYPE_MASK 0x000000C0 + #define BGMAC_CHIPCTL_1_SW_TYPE_EPHY 0x00000000 +Index: linux-3.10-3.10.11/dummy/rpi_1161_86f7c9950b9378ed4d9e9bf8fbdf515d03fa6820.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1161_86f7c9950b9378ed4d9e9bf8fbdf515d03fa6820.txt 2014-05-05 12:45:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1162_beb6f0e8d246adca601d786d206d414d1d0a549b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1162_beb6f0e8d246adca601d786d206d414d1d0a549b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1162_beb6f0e8d246adca601d786d206d414d1d0a549b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1162_beb6f0e8d246adca601d786d206d414d1d0a549b.patch 2014-05-05 12:45:23.000000000 +0000 @@ -0,0 +1,46 @@ +commit beb6f0e8d246adca601d786d206d414d1d0a549b +Author: Stanislaw Gruszka +Date: Mon Aug 26 15:18:53 2013 +0200 + + rt2800: fix wrong TX power compensation + + commit 6e956da2027c767859128b9bfef085cf2a8e233b upstream. + + We should not do temperature compensation on devices without + EXTERNAL_TX_ALC bit set (called DynamicTxAgcControl on vendor driver). + Such devices can have totally bogus TSSI parameters on the EEPROM, + but still threaded by us as valid and result doing wrong TX power + calculations. + + This fix inability to connect to AP on slightly longer distance on + some Ralink chips/devices. + + Reported-and-tested-by: Fabien ADAM + Signed-off-by: Stanislaw Gruszka + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/rt2x00/rt2800lib.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/rt2x00/rt2800lib.c 2014-05-05 11:51:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/rt2x00/rt2800lib.c 2014-05-05 12:45:23.000000000 +0000 +@@ -2767,6 +2767,13 @@ + int i; + + /* ++ * First check if temperature compensation is supported. ++ */ ++ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); ++ if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC)) ++ return 0; ++ ++ /* + * Read TSSI boundaries for temperature compensation from + * the EEPROM. + * +Index: linux-3.10-3.10.11/dummy/rpi_1162_beb6f0e8d246adca601d786d206d414d1d0a549b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1162_beb6f0e8d246adca601d786d206d414d1d0a549b.txt 2014-05-05 12:45:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1163_63946e8616205dafe39b4d88f9fc3dc7c4fd79aa.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1163_63946e8616205dafe39b4d88f9fc3dc7c4fd79aa.patch --- linux-3.10.11/debian/patches/rpi/rpi_1163_63946e8616205dafe39b4d88f9fc3dc7c4fd79aa.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1163_63946e8616205dafe39b4d88f9fc3dc7c4fd79aa.patch 2014-05-05 12:45:24.000000000 +0000 @@ -0,0 +1,112 @@ +commit 63946e8616205dafe39b4d88f9fc3dc7c4fd79aa +Author: John Stultz +Date: Wed Sep 11 16:50:56 2013 -0700 + + timekeeping: Fix HRTICK related deadlock from ntp lock changes + + commit 7bd36014460f793c19e7d6c94dab67b0afcfcb7f upstream. + + Gerlando Falauto reported that when HRTICK is enabled, it is + possible to trigger system deadlocks. These were hard to + reproduce, as HRTICK has been broken in the past, but seemed + to be connected to the timekeeping_seq lock. + + Since seqlock/seqcount's aren't supported w/ lockdep, I added + some extra spinlock based locking and triggered the following + lockdep output: + + [ 15.849182] ntpd/4062 is trying to acquire lock: + [ 15.849765] (&(&pool->lock)->rlock){..-...}, at: [] __queue_work+0x145/0x480 + [ 15.850051] + [ 15.850051] but task is already holding lock: + [ 15.850051] (timekeeper_lock){-.-.-.}, at: [] do_adjtimex+0x7f/0x100 + + + + [ 15.850051] Chain exists of: &(&pool->lock)->rlock --> &p->pi_lock --> timekeeper_lock + [ 15.850051] Possible unsafe locking scenario: + [ 15.850051] + [ 15.850051] CPU0 CPU1 + [ 15.850051] ---- ---- + [ 15.850051] lock(timekeeper_lock); + [ 15.850051] lock(&p->pi_lock); + [ 15.850051] lock(timekeeper_lock); + [ 15.850051] lock(&(&pool->lock)->rlock); + [ 15.850051] + [ 15.850051] *** DEADLOCK *** + + The deadlock was introduced by 06c017fdd4dc48451a ("timekeeping: + Hold timekeepering locks in do_adjtimex and hardpps") in 3.10 + + This patch avoids this deadlock, by moving the call to + schedule_delayed_work() outside of the timekeeper lock + critical section. + + Reported-by: Gerlando Falauto + Tested-by: Lin Ming + Signed-off-by: John Stultz + Cc: Mathieu Desnoyers + Link: http://lkml.kernel.org/r/1378943457-27314-1-git-send-email-john.stultz@linaro.org + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/timex.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/timex.h 2014-05-05 11:51:08.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/timex.h 2014-05-05 12:45:24.000000000 +0000 +@@ -141,6 +141,7 @@ + extern void hardpps(const struct timespec *, const struct timespec *); + + int read_current_timer(unsigned long *timer_val); ++void ntp_notify_cmos_timer(void); + + /* The clock frequency of the i8253/i8254 PIT */ + #define PIT_TICK_RATE 1193182ul +Index: linux-3.10-3.10.11/kernel/time/ntp.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/time/ntp.c 2014-05-05 11:51:08.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/time/ntp.c 2014-05-05 12:45:24.000000000 +0000 +@@ -516,13 +516,13 @@ + schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next)); + } + +-static void notify_cmos_timer(void) ++void ntp_notify_cmos_timer(void) + { + schedule_delayed_work(&sync_cmos_work, 0); + } + + #else +-static inline void notify_cmos_timer(void) { } ++void ntp_notify_cmos_timer(void) { } + #endif + + +@@ -687,8 +687,6 @@ + if (!(time_status & STA_NANO)) + txc->time.tv_usec /= NSEC_PER_USEC; + +- notify_cmos_timer(); +- + return result; + } + +Index: linux-3.10-3.10.11/kernel/time/timekeeping.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/time/timekeeping.c 2014-05-05 11:51:08.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/time/timekeeping.c 2014-05-05 12:45:24.000000000 +0000 +@@ -1682,6 +1682,8 @@ + write_seqcount_end(&timekeeper_seq); + raw_spin_unlock_irqrestore(&timekeeper_lock, flags); + ++ ntp_notify_cmos_timer(); ++ + return ret; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1163_63946e8616205dafe39b4d88f9fc3dc7c4fd79aa.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1163_63946e8616205dafe39b4d88f9fc3dc7c4fd79aa.txt 2014-05-05 12:45:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1164_013b14c3067f0d55ab115405647d9f035f67737e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1164_013b14c3067f0d55ab115405647d9f035f67737e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1164_013b14c3067f0d55ab115405647d9f035f67737e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1164_013b14c3067f0d55ab115405647d9f035f67737e.patch 2014-05-05 12:45:25.000000000 +0000 @@ -0,0 +1,95 @@ +commit 013b14c3067f0d55ab115405647d9f035f67737e +Author: Stanislaw Gruszka +Date: Wed Sep 4 15:16:03 2013 +0200 + + sched/cputime: Do not scale when utime == 0 + + commit 5a8e01f8fa51f5cbce8f37acc050eb2319d12956 upstream. + + scale_stime() silently assumes that stime < rtime, otherwise + when stime == rtime and both values are big enough (operations + on them do not fit in 32 bits), the resulting scaling stime can + be bigger than rtime. In consequence utime = rtime - stime + results in negative value. + + User space visible symptoms of the bug are overflowed TIME + values on ps/top, for example: + + $ ps aux | grep rcu + root 8 0.0 0.0 0 0 ? S 12:42 0:00 [rcuc/0] + root 9 0.0 0.0 0 0 ? S 12:42 0:00 [rcub/0] + root 10 62422329 0.0 0 0 ? R 12:42 21114581:37 [rcu_preempt] + root 11 0.1 0.0 0 0 ? S 12:42 0:02 [rcuop/0] + root 12 62422329 0.0 0 0 ? S 12:42 21114581:35 [rcuop/1] + root 10 62422329 0.0 0 0 ? R 12:42 21114581:37 [rcu_preempt] + + or overflowed utime values read directly from /proc/$PID/stat + + Reference: + + https://lkml.org/lkml/2013/8/20/259 + + Reported-and-tested-by: Sergey Senozhatsky + Signed-off-by: Stanislaw Gruszka + Cc: stable@vger.kernel.org + Cc: Frederic Weisbecker + Cc: Peter Zijlstra + Cc: Paul E. McKenney + Cc: Borislav Petkov + Link: http://lkml.kernel.org/r/20130904131602.GC2564@redhat.com + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/sched/cputime.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/sched/cputime.c 2014-05-05 11:51:05.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/sched/cputime.c 2014-05-05 12:45:25.000000000 +0000 +@@ -558,7 +558,7 @@ + struct cputime *prev, + cputime_t *ut, cputime_t *st) + { +- cputime_t rtime, stime, utime, total; ++ cputime_t rtime, stime, utime; + + if (vtime_accounting_enabled()) { + *ut = curr->utime; +@@ -566,9 +566,6 @@ + return; + } + +- stime = curr->stime; +- total = stime + curr->utime; +- + /* + * Tick based cputime accounting depend on random scheduling + * timeslices of a task to be interrupted or not by the timer. +@@ -589,13 +586,19 @@ + if (prev->stime + prev->utime >= rtime) + goto out; + +- if (total) { ++ stime = curr->stime; ++ utime = curr->utime; ++ ++ if (utime == 0) { ++ stime = rtime; ++ } else if (stime == 0) { ++ utime = rtime; ++ } else { ++ cputime_t total = stime + utime; ++ + stime = scale_stime((__force u64)stime, + (__force u64)rtime, (__force u64)total); + utime = rtime - stime; +- } else { +- stime = rtime; +- utime = 0; + } + + /* +Index: linux-3.10-3.10.11/dummy/rpi_1164_013b14c3067f0d55ab115405647d9f035f67737e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1164_013b14c3067f0d55ab115405647d9f035f67737e.txt 2014-05-05 12:45:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1165_51f5294797f14185f9b25ad0972a4abbbeff70c6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1165_51f5294797f14185f9b25ad0972a4abbbeff70c6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1165_51f5294797f14185f9b25ad0972a4abbbeff70c6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1165_51f5294797f14185f9b25ad0972a4abbbeff70c6.patch 2014-05-05 12:45:26.000000000 +0000 @@ -0,0 +1,93 @@ +commit 51f5294797f14185f9b25ad0972a4abbbeff70c6 +Author: Daisuke Nishimura +Date: Tue Sep 10 18:16:36 2013 +0900 + + sched/fair: Fix small race where child->se.parent,cfs_rq might point to invalid ones + + commit 6c9a27f5da9609fca46cb2b183724531b48f71ad upstream. + + There is a small race between copy_process() and cgroup_attach_task() + where child->se.parent,cfs_rq points to invalid (old) ones. + + parent doing fork() | someone moving the parent to another cgroup + -------------------------------+--------------------------------------------- + copy_process() + + dup_task_struct() + -> parent->se is copied to child->se. + se.parent,cfs_rq of them point to old ones. + + cgroup_attach_task() + + cgroup_task_migrate() + -> parent->cgroup is updated. + + cpu_cgroup_attach() + + sched_move_task() + + task_move_group_fair() + +- set_task_rq() + -> se.parent,cfs_rq of parent + are updated. + + + cgroup_fork() + -> parent->cgroup is copied to child->cgroup. (*1) + + sched_fork() + + task_fork_fair() + -> se.parent,cfs_rq of child are accessed + while they point to old ones. (*2) + + In the worst case, this bug can lead to "use-after-free" and cause a panic, + because it's new cgroup's refcount that is incremented at (*1), + so the old cgroup(and related data) can be freed before (*2). + + In fact, a panic caused by this bug was originally caught in RHEL6.4. + + BUG: unable to handle kernel NULL pointer dereference at (null) + IP: [] sched_slice+0x6e/0xa0 + [...] + Call Trace: + [] place_entity+0x75/0xa0 + [] task_fork_fair+0xaa/0x160 + [] sched_fork+0x6b/0x140 + [] copy_process+0x5b2/0x1450 + [] ? wake_up_new_task+0xd9/0x130 + [] do_fork+0x94/0x460 + [] ? sys_wait4+0xae/0x100 + [] sys_clone+0x28/0x30 + [] stub_clone+0x13/0x20 + [] ? system_call_fastpath+0x16/0x1b + + Signed-off-by: Daisuke Nishimura + Signed-off-by: Peter Zijlstra + Link: http://lkml.kernel.org/r/039601ceae06$733d3130$59b79390$@mxp.nes.nec.co.jp + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/sched/fair.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/sched/fair.c 2014-05-05 11:51:05.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/sched/fair.c 2014-05-05 12:45:25.000000000 +0000 +@@ -5778,11 +5778,15 @@ + cfs_rq = task_cfs_rq(current); + curr = cfs_rq->curr; + +- if (unlikely(task_cpu(p) != this_cpu)) { +- rcu_read_lock(); +- __set_task_cpu(p, this_cpu); +- rcu_read_unlock(); +- } ++ /* ++ * Not only the cpu but also the task_group of the parent might have ++ * been changed after parent->se.parent,cfs_rq were copied to ++ * child->se.parent,cfs_rq. So call __set_task_cpu() to make those ++ * of child point to valid ones. ++ */ ++ rcu_read_lock(); ++ __set_task_cpu(p, this_cpu); ++ rcu_read_unlock(); + + update_curr(cfs_rq); + +Index: linux-3.10-3.10.11/dummy/rpi_1165_51f5294797f14185f9b25ad0972a4abbbeff70c6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1165_51f5294797f14185f9b25ad0972a4abbbeff70c6.txt 2014-05-05 12:45:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1166_791abfbee86161ad63bddc6af88c0391ef7332bd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1166_791abfbee86161ad63bddc6af88c0391ef7332bd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1166_791abfbee86161ad63bddc6af88c0391ef7332bd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1166_791abfbee86161ad63bddc6af88c0391ef7332bd.patch 2014-05-05 12:45:27.000000000 +0000 @@ -0,0 +1,108 @@ +commit 791abfbee86161ad63bddc6af88c0391ef7332bd +Author: Kees Cook +Date: Wed Sep 11 21:56:50 2013 +0200 + + HID: provide a helper for validating hid reports + + commit 331415ff16a12147d57d5c953f3a961b7ede348b upstream. + + Many drivers need to validate the characteristics of their HID report + during initialization to avoid misusing the reports. This adds a common + helper to perform validation of the report exisitng, the field existing, + and the expected number of values within the field. + + Signed-off-by: Kees Cook + Reviewed-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-core.c 2014-05-05 12:44:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-core.c 2014-05-05 12:45:26.000000000 +0000 +@@ -759,6 +759,64 @@ + } + EXPORT_SYMBOL_GPL(hid_parse_report); + ++static const char * const hid_report_names[] = { ++ "HID_INPUT_REPORT", ++ "HID_OUTPUT_REPORT", ++ "HID_FEATURE_REPORT", ++}; ++/** ++ * hid_validate_values - validate existing device report's value indexes ++ * ++ * @device: hid device ++ * @type: which report type to examine ++ * @id: which report ID to examine (0 for first) ++ * @field_index: which report field to examine ++ * @report_counts: expected number of values ++ * ++ * Validate the number of values in a given field of a given report, after ++ * parsing. ++ */ ++struct hid_report *hid_validate_values(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int field_index, ++ unsigned int report_counts) ++{ ++ struct hid_report *report; ++ ++ if (type > HID_FEATURE_REPORT) { ++ hid_err(hid, "invalid HID report type %u\n", type); ++ return NULL; ++ } ++ ++ if (id >= HID_MAX_IDS) { ++ hid_err(hid, "invalid HID report id %u\n", id); ++ return NULL; ++ } ++ ++ /* ++ * Explicitly not using hid_get_report() here since it depends on ++ * ->numbered being checked, which may not always be the case when ++ * drivers go to access report values. ++ */ ++ report = hid->report_enum[type].report_id_hash[id]; ++ if (!report) { ++ hid_err(hid, "missing %s %u\n", hid_report_names[type], id); ++ return NULL; ++ } ++ if (report->maxfield <= field_index) { ++ hid_err(hid, "not enough fields in %s %u\n", ++ hid_report_names[type], id); ++ return NULL; ++ } ++ if (report->field[field_index]->report_count < report_counts) { ++ hid_err(hid, "not enough values in %s %u field %u\n", ++ hid_report_names[type], id, field_index); ++ return NULL; ++ } ++ return report; ++} ++EXPORT_SYMBOL_GPL(hid_validate_values); ++ + /** + * hid_open_report - open a driver-specific device report + * +Index: linux-3.10-3.10.11/include/linux/hid.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/hid.h 2014-05-05 12:44:38.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/hid.h 2014-05-05 12:45:26.000000000 +0000 +@@ -749,6 +749,10 @@ + struct hid_device *hid_allocate_device(void); + struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); + int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); ++struct hid_report *hid_validate_values(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int field_index, ++ unsigned int report_counts); + int hid_open_report(struct hid_device *device); + int hid_check_keys_pressed(struct hid_device *hid); + int hid_connect(struct hid_device *hid, unsigned int connect_mask); +Index: linux-3.10-3.10.11/dummy/rpi_1166_791abfbee86161ad63bddc6af88c0391ef7332bd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1166_791abfbee86161ad63bddc6af88c0391ef7332bd.txt 2014-05-05 12:45:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1167_ae5c98a48258dbdb742be23eadf9261b70d642c3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1167_ae5c98a48258dbdb742be23eadf9261b70d642c3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1167_ae5c98a48258dbdb742be23eadf9261b70d642c3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1167_ae5c98a48258dbdb742be23eadf9261b70d642c3.patch 2014-05-05 12:45:27.000000000 +0000 @@ -0,0 +1,138 @@ +commit ae5c98a48258dbdb742be23eadf9261b70d642c3 +Author: Benjamin Tissoires +Date: Wed Sep 11 21:56:57 2013 +0200 + + HID: validate feature and input report details + + commit cc6b54aa54bf40b762cab45a9fc8aa81653146eb upstream. + + When dealing with usage_index, be sure to properly use unsigned instead of + int to avoid overflows. + + When working on report fields, always validate that their report_counts are + in bounds. + Without this, a HID device could report a malicious feature report that + could trick the driver into a heap overflow: + + [ 634.885003] usb 1-1: New USB device found, idVendor=0596, idProduct=0500 + ... + [ 676.469629] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten + + CVE-2013-2897 + + Signed-off-by: Benjamin Tissoires + Acked-by: Kees Cook + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-core.c 2014-05-05 12:45:26.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-core.c 2014-05-05 12:45:27.000000000 +0000 +@@ -94,7 +94,6 @@ + static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) + { + struct hid_field *field; +- int i; + + if (report->maxfield == HID_MAX_FIELDS) { + hid_err(report->device, "too many fields in report\n"); +@@ -113,9 +112,6 @@ + field->value = (s32 *)(field->usage + usages); + field->report = report; + +- for (i = 0; i < usages; i++) +- field->usage[i].usage_index = i; +- + return field; + } + +@@ -226,9 +222,9 @@ + { + struct hid_report *report; + struct hid_field *field; +- int usages; ++ unsigned usages; + unsigned offset; +- int i; ++ unsigned i; + + report = hid_register_report(parser->device, report_type, parser->global.report_id); + if (!report) { +@@ -255,7 +251,8 @@ + if (!parser->local.usage_index) /* Ignore padding fields */ + return 0; + +- usages = max_t(int, parser->local.usage_index, parser->global.report_count); ++ usages = max_t(unsigned, parser->local.usage_index, ++ parser->global.report_count); + + field = hid_register_field(report, usages, parser->global.report_count); + if (!field) +@@ -266,13 +263,14 @@ + field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); + + for (i = 0; i < usages; i++) { +- int j = i; ++ unsigned j = i; + /* Duplicate the last usage we parsed if we have excess values */ + if (i >= parser->local.usage_index) + j = parser->local.usage_index - 1; + field->usage[i].hid = parser->local.usage[j]; + field->usage[i].collection_index = + parser->local.collection_index[j]; ++ field->usage[i].usage_index = i; + } + + field->maxusage = usages; +@@ -1295,7 +1293,7 @@ + goto out; + } + +- if (hid->claimed != HID_CLAIMED_HIDRAW) { ++ if (hid->claimed != HID_CLAIMED_HIDRAW && report->maxfield) { + for (a = 0; a < report->maxfield; a++) + hid_input_field(hid, report->field[a], cdata, interrupt); + hdrv = hid->driver; +Index: linux-3.10-3.10.11/drivers/hid/hid-input.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-input.c 2014-05-05 12:44:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-input.c 2014-05-05 12:45:27.000000000 +0000 +@@ -485,6 +485,10 @@ + if (field->flags & HID_MAIN_ITEM_CONSTANT) + goto ignore; + ++ /* Ignore if report count is out of bounds. */ ++ if (field->report_count < 1) ++ goto ignore; ++ + /* only LED usages are supported in output fields */ + if (field->report_type == HID_OUTPUT_REPORT && + (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { +@@ -1163,7 +1167,11 @@ + + rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; + list_for_each_entry(rep, &rep_enum->report_list, list) +- for (i = 0; i < rep->maxfield; i++) ++ for (i = 0; i < rep->maxfield; i++) { ++ /* Ignore if report count is out of bounds. */ ++ if (rep->field[i]->report_count < 1) ++ continue; ++ + for (j = 0; j < rep->field[i]->maxusage; j++) { + /* Verify if Battery Strength feature is available */ + hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]); +@@ -1172,6 +1180,7 @@ + drv->feature_mapping(hid, rep->field[i], + rep->field[i]->usage + j); + } ++ } + } + + static struct hid_input *hidinput_allocate(struct hid_device *hid) +Index: linux-3.10-3.10.11/dummy/rpi_1167_ae5c98a48258dbdb742be23eadf9261b70d642c3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1167_ae5c98a48258dbdb742be23eadf9261b70d642c3.txt 2014-05-05 12:45:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1168_9f3383881d9b8f2ea3a1e8453e4e62a57b4af9ab.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1168_9f3383881d9b8f2ea3a1e8453e4e62a57b4af9ab.patch --- linux-3.10.11/debian/patches/rpi/rpi_1168_9f3383881d9b8f2ea3a1e8453e4e62a57b4af9ab.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1168_9f3383881d9b8f2ea3a1e8453e4e62a57b4af9ab.patch 2014-05-05 12:45:28.000000000 +0000 @@ -0,0 +1,88 @@ +commit 9f3383881d9b8f2ea3a1e8453e4e62a57b4af9ab +Author: Benjamin Tissoires +Date: Wed Sep 11 21:56:58 2013 +0200 + + HID: multitouch: validate indexes details + + commit 8821f5dc187bdf16cfb32ef5aa8c3035273fa79a upstream. + + When working on report indexes, always validate that they are in bounds. + Without this, a HID device could report a malicious feature report that + could trick the driver into a heap overflow: + + [ 634.885003] usb 1-1: New USB device found, idVendor=0596, idProduct=0500 + ... + [ 676.469629] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten + + Note that we need to change the indexes from s8 to s16 as they can + be between -1 and 255. + + CVE-2013-2897 + + Signed-off-by: Benjamin Tissoires + Acked-by: Kees Cook + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-multitouch.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-multitouch.c 2014-05-05 11:51:04.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-multitouch.c 2014-05-05 12:45:28.000000000 +0000 +@@ -101,9 +101,9 @@ + unsigned last_slot_field; /* the last field of a slot */ + unsigned mt_report_id; /* the report ID of the multitouch device */ + unsigned pen_report_id; /* the report ID of the pen device */ +- __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ +- __s8 inputmode_index; /* InputMode HID feature index in the report */ +- __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, ++ __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ ++ __s16 inputmode_index; /* InputMode HID feature index in the report */ ++ __s16 maxcontact_report_id; /* Maximum Contact Number HID feature, + -1 if non-existent */ + __u8 num_received; /* how many contacts we received */ + __u8 num_expected; /* expected last contact index */ +@@ -317,20 +317,18 @@ + struct hid_field *field, struct hid_usage *usage) + { + struct mt_device *td = hid_get_drvdata(hdev); +- int i; + + switch (usage->hid) { + case HID_DG_INPUTMODE: +- td->inputmode = field->report->id; +- td->inputmode_index = 0; /* has to be updated below */ +- +- for (i=0; i < field->maxusage; i++) { +- if (field->usage[i].hid == usage->hid) { +- td->inputmode_index = i; +- break; +- } ++ /* Ignore if value index is out of bounds. */ ++ if (usage->usage_index >= field->report_count) { ++ dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n"); ++ break; + } + ++ td->inputmode = field->report->id; ++ td->inputmode_index = usage->usage_index; ++ + break; + case HID_DG_CONTACTMAX: + td->maxcontact_report_id = field->report->id; +@@ -536,6 +534,10 @@ + mt_store_field(usage, td, hi); + return 1; + case HID_DG_CONTACTCOUNT: ++ /* Ignore if indexes are out of bounds. */ ++ if (field->index >= field->report->maxfield || ++ usage->usage_index >= field->report_count) ++ return 1; + td->cc_index = field->index; + td->cc_value_index = usage->usage_index; + return 1; +Index: linux-3.10-3.10.11/dummy/rpi_1168_9f3383881d9b8f2ea3a1e8453e4e62a57b4af9ab.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1168_9f3383881d9b8f2ea3a1e8453e4e62a57b4af9ab.txt 2014-05-05 12:45:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1169_2ec96f1b2beb4f755a61ee961ae2dbd7ad922a35.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1169_2ec96f1b2beb4f755a61ee961ae2dbd7ad922a35.patch --- linux-3.10.11/debian/patches/rpi/rpi_1169_2ec96f1b2beb4f755a61ee961ae2dbd7ad922a35.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1169_2ec96f1b2beb4f755a61ee961ae2dbd7ad922a35.patch 2014-05-05 12:45:29.000000000 +0000 @@ -0,0 +1,194 @@ +commit 2ec96f1b2beb4f755a61ee961ae2dbd7ad922a35 +Author: Kees Cook +Date: Wed Sep 11 21:56:54 2013 +0200 + + HID: LG: validate HID output report details + + commit 0fb6bd06e06792469acc15bbe427361b56ada528 upstream. + + A HID device could send a malicious output report that would cause the + lg, lg3, and lg4 HID drivers to write beyond the output report allocation + during an event, causing a heap overflow: + + [ 325.245240] usb 1-1: New USB device found, idVendor=046d, idProduct=c287 + ... + [ 414.518960] BUG kmalloc-4096 (Not tainted): Redzone overwritten + + Additionally, while lg2 did correctly validate the report details, it was + cleaned up and shortened. + + CVE-2013-2893 + + Signed-off-by: Kees Cook + Reviewed-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-lg2ff.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-lg2ff.c 2014-05-05 11:51:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-lg2ff.c 2014-05-05 12:45:29.000000000 +0000 +@@ -64,26 +64,13 @@ + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; + int error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); ++ /* Check that the report looks ok */ ++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); ++ if (!report) + return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 1) { +- hid_err(hid, "output report is empty\n"); +- return -ENODEV; +- } +- if (report->field[0]->report_count < 7) { +- hid_err(hid, "not enough values in the field\n"); +- return -ENODEV; +- } + + lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); + if (!lg2ff) +Index: linux-3.10-3.10.11/drivers/hid/hid-lg3ff.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-lg3ff.c 2014-05-05 11:51:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-lg3ff.c 2014-05-05 12:45:29.000000000 +0000 +@@ -66,10 +66,11 @@ + int x, y; + + /* +- * Maxusage should always be 63 (maximum fields) +- * likely a better way to ensure this data is clean ++ * Available values in the field should always be 63, but we only use up to ++ * 35. Instead, clear the entire area, however big it is. + */ +- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage); ++ memset(report->field[0]->value, 0, ++ sizeof(__s32) * report->field[0]->report_count); + + switch (effect->type) { + case FF_CONSTANT: +@@ -129,32 +130,14 @@ + int lg3ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff3_joystick_ac; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); +- return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) ++ return -ENODEV; + + /* Assume single fixed device G940 */ + for (i = 0; ff_bits[i] >= 0; i++) +Index: linux-3.10-3.10.11/drivers/hid/hid-lg4ff.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-lg4ff.c 2014-05-05 11:51:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-lg4ff.c 2014-05-05 12:45:29.000000000 +0000 +@@ -484,34 +484,16 @@ + int lg4ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + struct lg4ff_device_entry *entry; + struct lg_drv_data *drv_data; + struct usb_device_descriptor *udesc; + int error, i, j; + __u16 bcdDevice, rev_maj, rev_min; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); +- return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) + return -1; +- } + + /* Check what wheel has been connected */ + for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) { +Index: linux-3.10-3.10.11/drivers/hid/hid-lgff.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-lgff.c 2014-05-05 11:51:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-lgff.c 2014-05-05 12:45:29.000000000 +0000 +@@ -128,27 +128,14 @@ + int lgff_init(struct hid_device* hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff_joystick; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) ++ return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(devices); i++) { + if (dev->id.vendor == devices[i].idVendor && +Index: linux-3.10-3.10.11/dummy/rpi_1169_2ec96f1b2beb4f755a61ee961ae2dbd7ad922a35.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1169_2ec96f1b2beb4f755a61ee961ae2dbd7ad922a35.txt 2014-05-05 12:45:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1170_be3cdbf50f4f72325d145318d6ce02acad478925.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1170_be3cdbf50f4f72325d145318d6ce02acad478925.patch --- linux-3.10.11/debian/patches/rpi/rpi_1170_be3cdbf50f4f72325d145318d6ce02acad478925.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1170_be3cdbf50f4f72325d145318d6ce02acad478925.patch 2014-05-05 12:45:30.000000000 +0000 @@ -0,0 +1,61 @@ +commit be3cdbf50f4f72325d145318d6ce02acad478925 +Author: Kees Cook +Date: Wed Sep 11 21:56:51 2013 +0200 + + HID: zeroplus: validate output report details + + commit 78214e81a1bf43740ce89bb5efda78eac2f8ef83 upstream. + + The zeroplus HID driver was not checking the size of allocated values + in fields it used. A HID device could send a malicious output report + that would cause the driver to write beyond the output report allocation + during initialization, causing a heap overflow: + + [ 1442.728680] usb 1-1: New USB device found, idVendor=0c12, idProduct=0005 + ... + [ 1466.243173] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten + + CVE-2013-2889 + + Signed-off-by: Kees Cook + Reviewed-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-zpff.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-zpff.c 2014-05-05 11:51:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-zpff.c 2014-05-05 12:45:30.000000000 +0000 +@@ -68,21 +68,13 @@ + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- int error; ++ int i, error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); +- return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 4) { +- hid_err(hid, "not enough fields in report\n"); +- return -ENODEV; ++ for (i = 0; i < 4; i++) { ++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); ++ if (!report) ++ return -ENODEV; + } + + zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); +Index: linux-3.10-3.10.11/dummy/rpi_1170_be3cdbf50f4f72325d145318d6ce02acad478925.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1170_be3cdbf50f4f72325d145318d6ce02acad478925.txt 2014-05-05 12:45:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1171_30c1e32f6fb5b48d6fd1625858c25b38af9ee91f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1171_30c1e32f6fb5b48d6fd1625858c25b38af9ee91f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1171_30c1e32f6fb5b48d6fd1625858c25b38af9ee91f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1171_30c1e32f6fb5b48d6fd1625858c25b38af9ee91f.patch 2014-05-05 12:45:31.000000000 +0000 @@ -0,0 +1,61 @@ +commit 30c1e32f6fb5b48d6fd1625858c25b38af9ee91f +Author: Benjamin Tissoires +Date: Wed Sep 11 21:56:59 2013 +0200 + + HID: lenovo-tpkbd: fix leak if tpkbd_probe_tp fails + + commit 0ccdd9e7476680c16113131264ad6597bd10299d upstream. + + If tpkbd_probe_tp() bails out, the probe() function return an error, + but hid_hw_stop() is never called. + + fixes: + https://bugzilla.redhat.com/show_bug.cgi?id=1003998 + + Signed-off-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-lenovo-tpkbd.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-lenovo-tpkbd.c 2014-05-05 11:51:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-lenovo-tpkbd.c 2014-05-05 12:45:30.000000000 +0000 +@@ -406,22 +406,27 @@ + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "hid_parse failed\n"); +- goto err_free; ++ goto err; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hid_hw_start failed\n"); +- goto err_free; ++ goto err; + } + + uhdev = (struct usbhid_device *) hdev->driver_data; + +- if (uhdev->ifnum == 1) +- return tpkbd_probe_tp(hdev); ++ if (uhdev->ifnum == 1) { ++ ret = tpkbd_probe_tp(hdev); ++ if (ret) ++ goto err_hid; ++ } + + return 0; +-err_free: ++err_hid: ++ hid_hw_stop(hdev); ++err: + return ret; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1171_30c1e32f6fb5b48d6fd1625858c25b38af9ee91f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1171_30c1e32f6fb5b48d6fd1625858c25b38af9ee91f.txt 2014-05-05 12:45:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1172_dcfd5f582c316c3e595c3bb28473efb30f4c2e6c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1172_dcfd5f582c316c3e595c3bb28473efb30f4c2e6c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1172_dcfd5f582c316c3e595c3bb28473efb30f4c2e6c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1172_dcfd5f582c316c3e595c3bb28473efb30f4c2e6c.patch 2014-05-05 12:45:32.000000000 +0000 @@ -0,0 +1,45 @@ +commit dcfd5f582c316c3e595c3bb28473efb30f4c2e6c +Author: Kees Cook +Date: Wed Sep 11 21:56:53 2013 +0200 + + HID: steelseries: validate output report details + + commit 41df7f6d43723deb7364340b44bc5d94bf717456 upstream. + + A HID device could send a malicious output report that would cause the + steelseries HID driver to write beyond the output report allocation + during initialization, causing a heap overflow: + + [ 167.981534] usb 1-1: New USB device found, idVendor=1038, idProduct=1410 + ... + [ 182.050547] BUG kmalloc-256 (Tainted: G W ): Redzone overwritten + + CVE-2013-2891 + + Signed-off-by: Kees Cook + Reviewed-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-steelseries.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-steelseries.c 2014-05-05 11:51:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-steelseries.c 2014-05-05 12:45:31.000000000 +0000 +@@ -249,6 +249,11 @@ + goto err_free; + } + ++ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 16)) { ++ ret = -ENODEV; ++ goto err_free; ++ } ++ + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed\n"); +Index: linux-3.10-3.10.11/dummy/rpi_1172_dcfd5f582c316c3e595c3bb28473efb30f4c2e6c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1172_dcfd5f582c316c3e595c3bb28473efb30f4c2e6c.txt 2014-05-05 12:45:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1173_855f21e01243b09e5166b10e9c9e88585fc8e0c5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1173_855f21e01243b09e5166b10e9c9e88585fc8e0c5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1173_855f21e01243b09e5166b10e9c9e88585fc8e0c5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1173_855f21e01243b09e5166b10e9c9e88585fc8e0c5.patch 2014-05-05 12:45:32.000000000 +0000 @@ -0,0 +1,50 @@ +commit 855f21e01243b09e5166b10e9c9e88585fc8e0c5 +Author: Kees Cook +Date: Wed Sep 11 21:56:55 2013 +0200 + + HID: lenovo-tpkbd: validate output report details + + commit 0a9cd0a80ac559357c6a90d26c55270ed752aa26 upstream. + + A HID device could send a malicious output report that would cause the + lenovo-tpkbd HID driver to write just beyond the output report allocation + during initialization, causing a heap overflow: + + [ 76.109807] usb 1-1: New USB device found, idVendor=17ef, idProduct=6009 + ... + [ 80.462540] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten + + CVE-2013-2894 + + Signed-off-by: Kees Cook + Signed-off-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-lenovo-tpkbd.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-lenovo-tpkbd.c 2014-05-05 12:45:30.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-lenovo-tpkbd.c 2014-05-05 12:45:32.000000000 +0000 +@@ -339,7 +339,15 @@ + struct tpkbd_data_pointer *data_pointer; + size_t name_sz = strlen(dev_name(dev)) + 16; + char *name_mute, *name_micmute; +- int ret; ++ int i, ret; ++ ++ /* Validate required reports. */ ++ for (i = 0; i < 4; i++) { ++ if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1)) ++ return -ENODEV; ++ } ++ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2)) ++ return -ENODEV; + + if (sysfs_create_group(&hdev->dev.kobj, + &tpkbd_attr_group_pointer)) { +Index: linux-3.10-3.10.11/dummy/rpi_1173_855f21e01243b09e5166b10e9c9e88585fc8e0c5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1173_855f21e01243b09e5166b10e9c9e88585fc8e0c5.txt 2014-05-05 12:45:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1174_7661107379d11e11736e3c3210a95eb421a1ad3d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1174_7661107379d11e11736e3c3210a95eb421a1ad3d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1174_7661107379d11e11736e3c3210a95eb421a1ad3d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1174_7661107379d11e11736e3c3210a95eb421a1ad3d.patch 2014-05-05 12:45:33.000000000 +0000 @@ -0,0 +1,65 @@ +commit 7661107379d11e11736e3c3210a95eb421a1ad3d +Author: Kees Cook +Date: Wed Sep 11 21:56:56 2013 +0200 + + HID: logitech-dj: validate output report details + + commit 297502abb32e225fb23801fcdb0e4f6f8e17099a upstream. + + A HID device could send a malicious output report that would cause the + logitech-dj HID driver to leak kernel memory contents to the device, or + trigger a NULL dereference during initialization: + + [ 304.424553] usb 1-1: New USB device found, idVendor=046d, idProduct=c52b + ... + [ 304.780467] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 + [ 304.781409] IP: [] logi_dj_recv_send_report.isra.11+0x1a/0x90 + + CVE-2013-2895 + + Signed-off-by: Kees Cook + Signed-off-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-logitech-dj.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-logitech-dj.c 2014-05-05 11:51:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-logitech-dj.c 2014-05-05 12:45:33.000000000 +0000 +@@ -421,7 +421,7 @@ + struct hid_report *report; + struct hid_report_enum *output_report_enum; + u8 *data = (u8 *)(&dj_report->device_index); +- int i; ++ unsigned int i; + + output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; + report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; +@@ -431,7 +431,7 @@ + return -ENODEV; + } + +- for (i = 0; i < report->field[0]->report_count; i++) ++ for (i = 0; i < DJREPORT_SHORT_LENGTH - 1; i++) + report->field[0]->value[i] = data[i]; + + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); +@@ -738,6 +738,12 @@ + goto hid_parse_fail; + } + ++ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT, ++ 0, DJREPORT_SHORT_LENGTH - 1)) { ++ retval = -ENODEV; ++ goto hid_parse_fail; ++ } ++ + /* Starts the usb device and connects to upper interfaces hiddev and + * hidraw */ + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +Index: linux-3.10-3.10.11/dummy/rpi_1174_7661107379d11e11736e3c3210a95eb421a1ad3d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1174_7661107379d11e11736e3c3210a95eb421a1ad3d.txt 2014-05-05 12:45:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1175_45f785a21a8a8a782ceb920487b2c3da78ee77b8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1175_45f785a21a8a8a782ceb920487b2c3da78ee77b8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1175_45f785a21a8a8a782ceb920487b2c3da78ee77b8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1175_45f785a21a8a8a782ceb920487b2c3da78ee77b8.patch 2014-05-05 12:45:34.000000000 +0000 @@ -0,0 +1,57 @@ +commit 45f785a21a8a8a782ceb920487b2c3da78ee77b8 +Author: Alan Stern +Date: Tue Jul 30 15:18:15 2013 -0400 + + usb: gadget: fix a bug and a WARN_ON in dummy-hcd + + commit 5f5610f69be3a925b1f79af27150bb7377bc9ad6 upstream. + + This patch fixes a NULL pointer dereference and a WARN_ON in + dummy-hcd. These things were the result of moving to the UDC core + framework, and possibly of changes to that framework. + + Now unloading a gadget driver causes the UDC to be stopped after the + gadget driver is unbound, not before. Therefore the "driver" argument + to dummy_udc_stop() can be NULL, so we must not try to print the + driver's name without checking first. + + Also, the UDC framework automatically unregisters the gadget when the + UDC is deleted. Therefore a sysfs attribute file attached to the + gadget must be removed before the UDC is deleted, not after. + + Signed-off-by: Alan Stern + Signed-off-by: Felipe Balbi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/gadget/dummy_hcd.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/gadget/dummy_hcd.c 2014-05-05 11:51:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/gadget/dummy_hcd.c 2014-05-05 12:45:33.000000000 +0000 +@@ -923,8 +923,9 @@ + struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); + struct dummy *dum = dum_hcd->dum; + +- dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", +- driver->driver.name); ++ if (driver) ++ dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", ++ driver->driver.name); + + dum->driver = NULL; + +@@ -1000,8 +1001,8 @@ + { + struct dummy *dum = platform_get_drvdata(pdev); + +- usb_del_gadget_udc(&dum->gadget); + device_remove_file(&dum->gadget.dev, &dev_attr_function); ++ usb_del_gadget_udc(&dum->gadget); + return 0; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1175_45f785a21a8a8a782ceb920487b2c3da78ee77b8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1175_45f785a21a8a8a782ceb920487b2c3da78ee77b8.txt 2014-05-05 12:45:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1176_d553bc6d55ec6e27cb46e6d2dd3e7e4e1f33d04b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1176_d553bc6d55ec6e27cb46e6d2dd3e7e4e1f33d04b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1176_d553bc6d55ec6e27cb46e6d2dd3e7e4e1f33d04b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1176_d553bc6d55ec6e27cb46e6d2dd3e7e4e1f33d04b.patch 2014-05-05 12:45:35.000000000 +0000 @@ -0,0 +1,125 @@ +commit d553bc6d55ec6e27cb46e6d2dd3e7e4e1f33d04b +Author: Daniel Vetter +Date: Wed Sep 4 17:36:14 2013 +0200 + + drm/i915: fix gpu hang vs. flip stall deadlocks + + commit 122f46badaafbe651f05c2c0f24cadee692f761b upstream. + + Since we've started to clean up pending flips when the gpu hangs in + + commit 96a02917a0131e52efefde49c2784c0421d6c439 + Author: Ville Syrjälä + Date: Mon Feb 18 19:08:49 2013 +0200 + + drm/i915: Finish page flips and update primary planes after a GPU reset + + the gpu reset work now also grabs modeset locks. But since work items + on our private work queue are not allowed to do that due to the + flush_workqueue from the pageflip code this results in a neat + deadlock: + + INFO: task kms_flip:14676 blocked for more than 120 seconds. + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + kms_flip D ffff88019283a5c0 0 14676 13344 0x00000004 + ffff88018e62dbf8 0000000000000046 ffff88013bdb12e0 ffff88018e62dfd8 + ffff88018e62dfd8 00000000001d3b00 ffff88019283a5c0 ffff88018ec21000 + ffff88018f693f00 ffff88018eece000 ffff88018e62dd60 ffff88018eece898 + Call Trace: + [] schedule+0x60/0x62 + [] intel_crtc_wait_for_pending_flips+0xb2/0x114 [i915] + [] ? finish_wait+0x60/0x60 + [] intel_crtc_set_config+0x7f3/0x81e [i915] + [] drm_mode_set_config_internal+0x4f/0xc6 [drm] + [] drm_mode_setcrtc+0x44d/0x4f9 [drm] + [] ? might_fault+0x38/0x86 + [] drm_ioctl+0x2f9/0x447 [drm] + [] ? trace_hardirqs_off+0xd/0xf + [] ? drm_mode_setplane+0x343/0x343 [drm] + [] ? mntput_no_expire+0x3e/0x13d + [] vfs_ioctl+0x18/0x34 + [] do_vfs_ioctl+0x396/0x454 + [] ? sysret_check+0x1b/0x56 + [] SyS_ioctl+0x52/0x7d + [] system_call_fastpath+0x16/0x1b + 2 locks held by kms_flip/14676: + #0: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x22/0x59 [drm] + #1: (&crtc->mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x48/0x59 [drm] + INFO: task kworker/u8:4:175 blocked for more than 120 seconds. + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + kworker/u8:4 D ffff88018de9a5c0 0 175 2 0x00000000 + Workqueue: i915 i915_error_work_func [i915] + ffff88018e37dc30 0000000000000046 ffff8801938ab8a0 ffff88018e37dfd8 + ffff88018e37dfd8 00000000001d3b00 ffff88018de9a5c0 ffff88018ec21018 + 0000000000000246 ffff88018e37dca0 000000005a865a86 ffff88018de9a5c0 + Call Trace: + [] schedule+0x60/0x62 + [] schedule_preempt_disabled+0x9/0xb + [] mutex_lock_nested+0x205/0x3b1 + [] ? intel_display_handle_reset+0x7e/0xbd [i915] + [] ? intel_display_handle_reset+0x7e/0xbd [i915] + [] intel_display_handle_reset+0x7e/0xbd [i915] + [] i915_error_work_func+0x128/0x147 [i915] + [] process_one_work+0x1d4/0x35a + [] ? process_one_work+0x15b/0x35a + [] worker_thread+0x144/0x1f0 + [] ? rescuer_thread+0x275/0x275 + [] kthread+0xac/0xb4 + [] ? finish_task_switch+0x3b/0xc0 + [] ? __kthread_parkme+0x60/0x60 + [] ret_from_fork+0x7c/0xb0 + [] ? __kthread_parkme+0x60/0x60 + 3 locks held by kworker/u8:4/175: + #0: (i915){.+.+.+}, at: [] process_one_work+0x15b/0x35a + #1: ((&dev_priv->gpu_error.work)){+.+.+.}, at: [] process_one_work+0x15b/0x35a + #2: (&crtc->mutex){+.+.+.}, at: [] intel_display_handle_reset+0x7e/0xbd [i915] + + This blew up while running kms_flip/flip-vs-panning-vs-hang-interruptible + on one of my older machines. + + Unfortunately (despite the proper lockdep annotations for + flush_workqueue) lockdep still doesn't detect this correctly, so we + need to rely on chance to discover these bugs. + + Apply the usual bugfix and schedule the reset work on the system + workqueue to keep our own driver workqueue free of any modeset lock + grabbing. + + Note that this is not a terribly serious regression since before the + offending commit we'd simply have stalled userspace forever due to + failing to abort all outstanding pageflips. + + v2: Add a comment as requested by Chris. + + Cc: Thomas Gleixner + Cc: Ville Syrjälä + Cc: Chris Wilson + Reviewed-by: Chris Wilson + Signed-off-by: Daniel Vetter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/i915/i915_irq.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/i915/i915_irq.c 2014-05-05 11:51:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/i915/i915_irq.c 2014-05-05 12:45:34.000000000 +0000 +@@ -1727,7 +1727,13 @@ + wake_up_all(&ring->irq_queue); + } + +- queue_work(dev_priv->wq, &dev_priv->gpu_error.work); ++ /* ++ * Our reset work can grab modeset locks (since it needs to reset the ++ * state of outstanding pagelips). Hence it must not be run on our own ++ * dev-priv->wq work queue for otherwise the flush_work in the pageflip ++ * code will deadlock. ++ */ ++ schedule_work(&dev_priv->gpu_error.work); + } + + static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe) +Index: linux-3.10-3.10.11/dummy/rpi_1176_d553bc6d55ec6e27cb46e6d2dd3e7e4e1f33d04b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1176_d553bc6d55ec6e27cb46e6d2dd3e7e4e1f33d04b.txt 2014-05-05 12:45:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1177_590f5c013918d7d9724f048fa9d0c09e36446e20.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1177_590f5c013918d7d9724f048fa9d0c09e36446e20.patch --- linux-3.10.11/debian/patches/rpi/rpi_1177_590f5c013918d7d9724f048fa9d0c09e36446e20.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1177_590f5c013918d7d9724f048fa9d0c09e36446e20.patch 2014-05-05 12:45:36.000000000 +0000 @@ -0,0 +1,199 @@ +commit 590f5c013918d7d9724f048fa9d0c09e36446e20 +Author: Daniel Vetter +Date: Sun Sep 8 21:57:13 2013 +0200 + + drm/i915: fix wait_for_pending_flips vs gpu hang deadlock + + commit 17e1df07df0fbc77696a1e1b6ccf9f2e5af70e40 upstream. + + My g33 here seems to be shockingly good at hitting them all. This time + around kms_flip/flip-vs-panning-vs-hang blows up: + + intel_crtc_wait_for_pending_flips correctly checks for gpu hangs and + if a gpu hang is pending aborts the wait for outstanding flips so that + the setcrtc call will succeed and release the crtc mutex. And the gpu + hang handler needs that lock in intel_display_handle_reset to be able + to complete outstanding flips. + + The problem is that we can race in two ways: + - Waiters on the dev_priv->pending_flip_queue aren't woken up after + we've the reset as pending, but before we actually start the reset + work. This means that the waiter doesn't notice the pending reset + and hence will keep on hogging the locks. + + Like with dev->struct_mutex and the ring->irq_queue wait queues we + there need to wake up everyone that potentially holds a lock which + the reset handler needs. + + - intel_display_handle_reset was called _after_ we've already + signalled the completion of the reset work. Which means a waiter + could sneak in, grab the lock and never release it (since the + pageflips won't ever get released). + + Similar to resetting the gem state all the reset work must complete + before we update the reset counter. Contrary to the gem reset we + don't need to have a second explicit wake up call since that will + have happened already when completing the pageflips. We also don't + have any issues that the completion happens while the reset state is + still pending - wait_for_pending_flips is only there to ensure we + display the right frame. After a gpu hang&reset events such + guarantees are out the window anyway. This is in contrast to the gem + code where too-early wake-up would result in unnecessary restarting + of ioctls. + + Also, since we've gotten these various deadlocks and ordering + constraints wrong so often throw copious amounts of comments at the + code. + + This deadlock regression has been introduced in the commit which added + the pageflip reset logic to the gpu hang work: + + commit 96a02917a0131e52efefde49c2784c0421d6c439 + Author: Ville Syrjälä + Date: Mon Feb 18 19:08:49 2013 +0200 + + drm/i915: Finish page flips and update primary planes after a GPU reset + + v2: + - Add comments to explain how the wake_up serves as memory barriers + for the atomic_t reset counter. + - Improve the comments a bit as suggested by Chris Wilson. + - Extract the wake_up calls before/after the reset into a little + i915_error_wake_up and unconditionally wake up the + pending_flip_queue waiters, again as suggested by Chris Wilson. + + v3: Throw copious amounts of comments at i915_error_wake_up as + suggested by Chris Wilson. + + Cc: Ville Syrjälä + Cc: Chris Wilson + Reviewed-by: Chris Wilson + Signed-off-by: Daniel Vetter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/i915/i915_irq.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/i915/i915_irq.c 2014-05-05 12:45:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/i915/i915_irq.c 2014-05-05 12:45:35.000000000 +0000 +@@ -1009,6 +1009,34 @@ + return ret; + } + ++static void i915_error_wake_up(struct drm_i915_private *dev_priv, ++ bool reset_completed) ++{ ++ struct intel_ring_buffer *ring; ++ int i; ++ ++ /* ++ * Notify all waiters for GPU completion events that reset state has ++ * been changed, and that they need to restart their wait after ++ * checking for potential errors (and bail out to drop locks if there is ++ * a gpu reset pending so that i915_error_work_func can acquire them). ++ */ ++ ++ /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */ ++ for_each_ring(ring, dev_priv, i) ++ wake_up_all(&ring->irq_queue); ++ ++ /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */ ++ wake_up_all(&dev_priv->pending_flip_queue); ++ ++ /* ++ * Signal tasks blocked in i915_gem_wait_for_error that the pending ++ * reset state is cleared. ++ */ ++ if (reset_completed) ++ wake_up_all(&dev_priv->gpu_error.reset_queue); ++} ++ + /** + * i915_error_work_func - do process context error handling work + * @work: work struct +@@ -1023,11 +1051,10 @@ + drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t, + gpu_error); + struct drm_device *dev = dev_priv->dev; +- struct intel_ring_buffer *ring; + char *error_event[] = { "ERROR=1", NULL }; + char *reset_event[] = { "RESET=1", NULL }; + char *reset_done_event[] = { "ERROR=0", NULL }; +- int i, ret; ++ int ret; + + kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); + +@@ -1046,8 +1073,16 @@ + kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, + reset_event); + ++ /* ++ * All state reset _must_ be completed before we update the ++ * reset counter, for otherwise waiters might miss the reset ++ * pending state and not properly drop locks, resulting in ++ * deadlocks with the reset work. ++ */ + ret = i915_reset(dev); + ++ intel_display_handle_reset(dev); ++ + if (ret == 0) { + /* + * After all the gem state is reset, increment the reset +@@ -1068,12 +1103,11 @@ + atomic_set(&error->reset_counter, I915_WEDGED); + } + +- for_each_ring(ring, dev_priv, i) +- wake_up_all(&ring->irq_queue); +- +- intel_display_handle_reset(dev); +- +- wake_up_all(&dev_priv->gpu_error.reset_queue); ++ /* ++ * Note: The wake_up also serves as a memory barrier so that ++ * waiters see the update value of the reset counter atomic_t. ++ */ ++ i915_error_wake_up(dev_priv, true); + } + } + +@@ -1709,8 +1743,6 @@ + void i915_handle_error(struct drm_device *dev, bool wedged) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_ring_buffer *ring; +- int i; + + i915_capture_error_state(dev); + i915_report_and_clear_eir(dev); +@@ -1720,11 +1752,19 @@ + &dev_priv->gpu_error.reset_counter); + + /* +- * Wakeup waiting processes so that the reset work item +- * doesn't deadlock trying to grab various locks. ++ * Wakeup waiting processes so that the reset work function ++ * i915_error_work_func doesn't deadlock trying to grab various ++ * locks. By bumping the reset counter first, the woken ++ * processes will see a reset in progress and back off, ++ * releasing their locks and then wait for the reset completion. ++ * We must do this for _all_ gpu waiters that might hold locks ++ * that the reset work needs to acquire. ++ * ++ * Note: The wake_up serves as the required memory barrier to ++ * ensure that the waiters see the updated value of the reset ++ * counter atomic_t. + */ +- for_each_ring(ring, dev_priv, i) +- wake_up_all(&ring->irq_queue); ++ i915_error_wake_up(dev_priv, false); + } + + /* +Index: linux-3.10-3.10.11/dummy/rpi_1177_590f5c013918d7d9724f048fa9d0c09e36446e20.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1177_590f5c013918d7d9724f048fa9d0c09e36446e20.txt 2014-05-05 12:45:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1178_b61d2139fb615a89d30d144907aefa5e66e3348f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1178_b61d2139fb615a89d30d144907aefa5e66e3348f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1178_b61d2139fb615a89d30d144907aefa5e66e3348f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1178_b61d2139fb615a89d30d144907aefa5e66e3348f.patch 2014-05-05 12:45:36.000000000 +0000 @@ -0,0 +1,78 @@ +commit b61d2139fb615a89d30d144907aefa5e66e3348f +Author: David Herrmann +Date: Mon Aug 26 15:16:49 2013 +0200 + + drm: fix DRM_IOCTL_MODE_GETFB handle-leak + + commit 101b96f32956ee99bf1468afaf572b88cda9f88b upstream. + + DRM_IOCTL_MODE_GETFB is used to retrieve information about a given + framebuffer ID. It is a read-only helper and was thus declassified for + unprivileged access in: + + commit a14b1b42477c5ef089fcda88cbaae50d979eb8f9 + Author: Mandeep Singh Baines + Date: Fri Jan 20 12:11:16 2012 -0800 + + drm: remove master fd restriction on mode setting getters + + However, alongside width, height and stride information, + DRM_IOCTL_MODE_GETFB also passes back a handle to the underlying buffer of + the framebuffer. This handle allows users to mmap() it and read or write + into it. Obviously, this should be restricted to DRM-Master. + + With the current setup, *any* process with access to /dev/dri/card0 (which + means any process with access to hardware-accelerated rendering) can + access the current screen framebuffer and modify it ad libitum. + + For backwards-compatibility reasons we want to keep the + DRM_IOCTL_MODE_GETFB call unprivileged. Besides, it provides quite useful + information regarding screen setup. So we simply test whether the caller + is the current DRM-Master and if not, we return 0 as handle, which is + always invalid. A following DRM_IOCTL_GEM_CLOSE on this handle will fail + with EINVAL, but we accept this. Users shouldn't test for errors during + GEM_CLOSE, anyway. And it is still better as a failing MODE_GETFB call. + + v2: add capable(CAP_SYS_ADMIN) check for compatibility with i-g-t + + Signed-off-by: David Herrmann + Reviewed-by: Chris Wilson + Signed-off-by: Dave Airlie + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/drm_crtc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/drm_crtc.c 2014-05-05 11:51:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/drm_crtc.c 2014-05-05 12:45:36.000000000 +0000 +@@ -2501,10 +2501,22 @@ + r->depth = fb->depth; + r->bpp = fb->bits_per_pixel; + r->pitch = fb->pitches[0]; +- if (fb->funcs->create_handle) +- ret = fb->funcs->create_handle(fb, file_priv, &r->handle); +- else ++ if (fb->funcs->create_handle) { ++ if (file_priv->is_master || capable(CAP_SYS_ADMIN)) { ++ ret = fb->funcs->create_handle(fb, file_priv, ++ &r->handle); ++ } else { ++ /* GET_FB() is an unprivileged ioctl so we must not ++ * return a buffer-handle to non-master processes! For ++ * backwards-compatibility reasons, we cannot make ++ * GET_FB() privileged, so just return an invalid handle ++ * for non-masters. */ ++ r->handle = 0; ++ ret = 0; ++ } ++ } else { + ret = -ENODEV; ++ } + + drm_framebuffer_unreference(fb); + +Index: linux-3.10-3.10.11/dummy/rpi_1178_b61d2139fb615a89d30d144907aefa5e66e3348f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1178_b61d2139fb615a89d30d144907aefa5e66e3348f.txt 2014-05-05 12:45:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1179_2781ca89611907abc45110fd992dc5e9d21924d9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1179_2781ca89611907abc45110fd992dc5e9d21924d9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1179_2781ca89611907abc45110fd992dc5e9d21924d9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1179_2781ca89611907abc45110fd992dc5e9d21924d9.patch 2014-05-05 12:45:37.000000000 +0000 @@ -0,0 +1,34 @@ +commit 2781ca89611907abc45110fd992dc5e9d21924d9 +Author: Dave Airlie +Date: Thu Sep 12 15:31:04 2013 +1000 + + drm/ast: fix the ast open key function + + commit 2e8378136f28bea960cec643d3fa5d843c9049ec upstream. + + When porting from UMS I mistyped this from the wrong place, AST noticed + and pointed it out, so we should fix it to be like the X.org driver. + + Reported-by: Y.C. Chen + Signed-off-by: Dave Airlie + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/ast/ast_drv.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/ast/ast_drv.h 2014-05-05 11:51:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/ast/ast_drv.h 2014-05-05 12:45:37.000000000 +0000 +@@ -177,7 +177,7 @@ + + static inline void ast_open_key(struct ast_private *ast) + { +- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xA1, 0xFF, 0x04); ++ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8); + } + + #define AST_VIDMEM_SIZE_8M 0x00800000 +Index: linux-3.10-3.10.11/dummy/rpi_1179_2781ca89611907abc45110fd992dc5e9d21924d9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1179_2781ca89611907abc45110fd992dc5e9d21924d9.txt 2014-05-05 12:45:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1180_3614efdf382ea9da5c04ae1f312c441b78a9fafc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1180_3614efdf382ea9da5c04ae1f312c441b78a9fafc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1180_3614efdf382ea9da5c04ae1f312c441b78a9fafc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1180_3614efdf382ea9da5c04ae1f312c441b78a9fafc.patch 2014-05-05 12:45:38.000000000 +0000 @@ -0,0 +1,46 @@ +commit 3614efdf382ea9da5c04ae1f312c441b78a9fafc +Author: Ben Skeggs +Date: Tue Sep 17 14:21:15 2013 +1000 + + drm/ttm: fix the tt_populated check in ttm_tt_destroy() + + commit 182b17c8dc4e83aab000ce86587b6810e515da87 upstream. + + After a vmalloc failure in ttm_dma_tt_alloc_page_directory(), + ttm_dma_tt_init() will call ttm_tt_destroy() to cleanup, and end up + inside the driver's unpopulate() hook when populate() has never yet + been called. + + On nouveau, the first issue to be hit because of this is that + dma_address[] may be a NULL pointer. After working around this, + ttm_pool_unpopulate() may potentially hit the same issue with + the pages[] array. + + It seems to make more sense to avoid calling unpopulate on already + unpopulated TTMs than to add checks to all the implementations. + + Signed-off-by: Ben Skeggs + Reviewed-by: Thomas Hellstrom + Cc: Jerome Glisse + Signed-off-by: Dave Airlie + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/ttm/ttm_tt.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/ttm/ttm_tt.c 2014-05-05 11:51:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/ttm/ttm_tt.c 2014-05-05 12:45:38.000000000 +0000 +@@ -170,7 +170,7 @@ + ttm_tt_unbind(ttm); + } + +- if (likely(ttm->pages != NULL)) { ++ if (ttm->state == tt_unbound) { + ttm->bdev->driver->ttm_tt_unpopulate(ttm); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1180_3614efdf382ea9da5c04ae1f312c441b78a9fafc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1180_3614efdf382ea9da5c04ae1f312c441b78a9fafc.txt 2014-05-05 12:45:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1181_262246999a59ac0aab5c4dd586b16d191ffe386b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1181_262246999a59ac0aab5c4dd586b16d191ffe386b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1181_262246999a59ac0aab5c4dd586b16d191ffe386b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1181_262246999a59ac0aab5c4dd586b16d191ffe386b.patch 2014-05-05 12:45:39.000000000 +0000 @@ -0,0 +1,61 @@ +commit 262246999a59ac0aab5c4dd586b16d191ffe386b +Author: Emil Velikov +Date: Fri Aug 23 18:43:42 2013 +0100 + + drm/nv50/disp: prevent false output detection on the original nv50 + + commit 5087f51da805f53cba7366f70d596e7bde2a5486 upstream. + + Commit ea9197cc323839ef3d5280c0453b2c622caa6bc7 effectively enabled the + use of an improved DAC detection code, but introduced a regression on + the original nv50 chipset, causing a ghost monitor to be detected. + + v2 (Ben Skeggs): the offending line was likely a thinko, removed it for + all chipsets (tested nv50 and nve6 to cover entire range) and added + some additional debugging. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67382 + Tested-by: Martin Peres + Signed-off-by: Emil Velikov + Signed-off-by: Ben Skeggs + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c 2014-05-05 11:50:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c 2014-05-05 12:45:38.000000000 +0000 +@@ -49,18 +49,23 @@ + nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) + { + const u32 doff = (or * 0x800); +- int load = -EINVAL; ++ + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); ++ + nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); + mdelay(9); + udelay(500); +- nv_wr32(priv, 0x61a00c + doff, 0x80000000); +- load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; +- nv_wr32(priv, 0x61a00c + doff, 0x00000000); ++ loadval = nv_mask(priv, 0x61a00c + doff, 0xffffffff, 0x00000000); ++ + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); +- return load; ++ ++ nv_debug(priv, "DAC%d sense: 0x%08x\n", or, loadval); ++ if (!(loadval & 0x80000000)) ++ return -ETIMEDOUT; ++ ++ return (loadval & 0x38000000) >> 27; + } + + int +Index: linux-3.10-3.10.11/dummy/rpi_1181_262246999a59ac0aab5c4dd586b16d191ffe386b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1181_262246999a59ac0aab5c4dd586b16d191ffe386b.txt 2014-05-05 12:45:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1182_6d90714d9a0d4b9c5c17952cb5affe7a1e3b6fb3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1182_6d90714d9a0d4b9c5c17952cb5affe7a1e3b6fb3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1182_6d90714d9a0d4b9c5c17952cb5affe7a1e3b6fb3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1182_6d90714d9a0d4b9c5c17952cb5affe7a1e3b6fb3.patch 2014-05-05 12:45:40.000000000 +0000 @@ -0,0 +1,37 @@ +commit 6d90714d9a0d4b9c5c17952cb5affe7a1e3b6fb3 +Author: Alex Deucher +Date: Tue Aug 20 14:59:01 2013 -0400 + + drm/radeon: fix LCD record parsing + + commit 95663948ba22a4be8b99acd67fbf83e86ddffba4 upstream. + + If the LCD table contains an EDID record, properly account + for the edid size when walking through the records. + + This should fix error messages about unknown LCD records. + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_atombios.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_atombios.c 2014-05-05 11:50:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_atombios.c 2014-05-05 12:45:39.000000000 +0000 +@@ -1651,7 +1651,9 @@ + kfree(edid); + } + } +- record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); ++ record += fake_edid_record->ucFakeEDIDLength ? ++ fake_edid_record->ucFakeEDIDLength + 2 : ++ sizeof(ATOM_FAKE_EDID_PATCH_RECORD); + break; + case LCD_PANEL_RESOLUTION_RECORD_TYPE: + panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; +Index: linux-3.10-3.10.11/dummy/rpi_1182_6d90714d9a0d4b9c5c17952cb5affe7a1e3b6fb3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1182_6d90714d9a0d4b9c5c17952cb5affe7a1e3b6fb3.txt 2014-05-05 12:45:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1183_5c6ece5d3786f287d61bc0ffd1ab372f47df2b81.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1183_5c6ece5d3786f287d61bc0ffd1ab372f47df2b81.patch --- linux-3.10.11/debian/patches/rpi/rpi_1183_5c6ece5d3786f287d61bc0ffd1ab372f47df2b81.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1183_5c6ece5d3786f287d61bc0ffd1ab372f47df2b81.patch 2014-05-05 12:45:41.000000000 +0000 @@ -0,0 +1,74 @@ +commit 5c6ece5d3786f287d61bc0ffd1ab372f47df2b81 +Author: Alex Deucher +Date: Wed Aug 7 19:34:53 2013 -0400 + + drm/radeon: fix endian bugs in hw i2c atom routines + + commit 4543eda52113d1e2cc0e9bf416f79597e6ef1ec7 upstream. + + Need to swap the data fetched over i2c properly. This + is the same fix as the endian fix for aux channel + transactions. + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_dp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/atombios_dp.c 2014-05-05 11:50:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_dp.c 2014-05-05 12:45:40.000000000 +0000 +@@ -50,7 +50,7 @@ + * or from atom. Note that atom operates on + * dw units. + */ +-static void radeon_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) ++void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) + { + #ifdef __BIG_ENDIAN + u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ +@@ -100,7 +100,7 @@ + + base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); + +- radeon_copy_swap(base, send, send_bytes, true); ++ radeon_atom_copy_swap(base, send, send_bytes, true); + + args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4)); + args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4)); +@@ -137,7 +137,7 @@ + recv_bytes = recv_size; + + if (recv && recv_size) +- radeon_copy_swap(recv, base + 16, recv_bytes, false); ++ radeon_atom_copy_swap(recv, base + 16, recv_bytes, false); + + return recv_bytes; + } +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_i2c.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/atombios_i2c.c 2014-05-05 11:50:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_i2c.c 2014-05-05 12:45:40.000000000 +0000 +@@ -27,6 +27,8 @@ + #include "radeon.h" + #include "atom.h" + ++extern void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le); ++ + #define TARGET_HW_I2C_CLOCK 50 + + /* these are a limitation of ProcessI2cChannelTransaction not the hw */ +@@ -77,7 +79,7 @@ + } + + if (!(flags & HW_I2C_WRITE)) +- memcpy(buf, base, num); ++ radeon_atom_copy_swap(buf, base, num, false); + + return 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1183_5c6ece5d3786f287d61bc0ffd1ab372f47df2b81.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1183_5c6ece5d3786f287d61bc0ffd1ab372f47df2b81.txt 2014-05-05 12:45:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1184_c7384791a785d8f356aa9de8038596cfd2ea87d3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1184_c7384791a785d8f356aa9de8038596cfd2ea87d3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1184_c7384791a785d8f356aa9de8038596cfd2ea87d3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1184_c7384791a785d8f356aa9de8038596cfd2ea87d3.patch 2014-05-05 12:45:42.000000000 +0000 @@ -0,0 +1,206 @@ +commit c7384791a785d8f356aa9de8038596cfd2ea87d3 +Author: Tom Stellard +Date: Fri Aug 16 17:47:39 2013 -0400 + + drm/radeon/si: Add support for CP DMA to CS checker for compute v2 + + commit e5b9e7503eb1f4884efa3b321d3cc47806779202 upstream. + + Also add a new RADEON_INFO query to check that CP DMA packets are + supported on the compute ring. + + CP DMA has been supported since the 3.8 kernel, but due to an oversight + we forgot to teach the CS checker that the CP DMA packet was legal for + the compute ring on Southern Islands GPUs. + + This patch fixes a bug where the radeon driver will incorrectly reject a legal + CP DMA packet from user space. I would like to have the patch + backported to stable so that we don't have to require Mesa users to use a + bleeding edge kernel in order to take advantage of this feature which + is already present in the stable kernels (3.8 and newer). + + v2: + - Don't bump kms version, so this patch can be backported to stable + kernels. + + Signed-off-by: Tom Stellard + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_kms.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_kms.c 2014-05-05 11:50:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_kms.c 2014-05-05 12:45:41.000000000 +0000 +@@ -414,6 +414,9 @@ + value = rdev->config.si.tile_mode_array; + value_size = sizeof(uint32_t)*32; + break; ++ case RADEON_INFO_SI_CP_DMA_COMPUTE: ++ *value = 1; ++ break; + default: + DRM_DEBUG_KMS("Invalid request %d\n", info->request); + return -EINVAL; +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/si.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/si.c 2014-05-05 11:50:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/si.c 2014-05-05 12:45:41.000000000 +0000 +@@ -3796,13 +3796,64 @@ + return 0; + } + ++static int si_vm_packet3_cp_dma_check(u32 *ib, u32 idx) ++{ ++ u32 start_reg, reg, i; ++ u32 command = ib[idx + 4]; ++ u32 info = ib[idx + 1]; ++ u32 idx_value = ib[idx]; ++ if (command & PACKET3_CP_DMA_CMD_SAS) { ++ /* src address space is register */ ++ if (((info & 0x60000000) >> 29) == 0) { ++ start_reg = idx_value << 2; ++ if (command & PACKET3_CP_DMA_CMD_SAIC) { ++ reg = start_reg; ++ if (!si_vm_reg_valid(reg)) { ++ DRM_ERROR("CP DMA Bad SRC register\n"); ++ return -EINVAL; ++ } ++ } else { ++ for (i = 0; i < (command & 0x1fffff); i++) { ++ reg = start_reg + (4 * i); ++ if (!si_vm_reg_valid(reg)) { ++ DRM_ERROR("CP DMA Bad SRC register\n"); ++ return -EINVAL; ++ } ++ } ++ } ++ } ++ } ++ if (command & PACKET3_CP_DMA_CMD_DAS) { ++ /* dst address space is register */ ++ if (((info & 0x00300000) >> 20) == 0) { ++ start_reg = ib[idx + 2]; ++ if (command & PACKET3_CP_DMA_CMD_DAIC) { ++ reg = start_reg; ++ if (!si_vm_reg_valid(reg)) { ++ DRM_ERROR("CP DMA Bad DST register\n"); ++ return -EINVAL; ++ } ++ } else { ++ for (i = 0; i < (command & 0x1fffff); i++) { ++ reg = start_reg + (4 * i); ++ if (!si_vm_reg_valid(reg)) { ++ DRM_ERROR("CP DMA Bad DST register\n"); ++ return -EINVAL; ++ } ++ } ++ } ++ } ++ } ++ return 0; ++} ++ + static int si_vm_packet3_gfx_check(struct radeon_device *rdev, + u32 *ib, struct radeon_cs_packet *pkt) + { ++ int r; + u32 idx = pkt->idx + 1; + u32 idx_value = ib[idx]; + u32 start_reg, end_reg, reg, i; +- u32 command, info; + + switch (pkt->opcode) { + case PACKET3_NOP: +@@ -3903,50 +3954,9 @@ + } + break; + case PACKET3_CP_DMA: +- command = ib[idx + 4]; +- info = ib[idx + 1]; +- if (command & PACKET3_CP_DMA_CMD_SAS) { +- /* src address space is register */ +- if (((info & 0x60000000) >> 29) == 0) { +- start_reg = idx_value << 2; +- if (command & PACKET3_CP_DMA_CMD_SAIC) { +- reg = start_reg; +- if (!si_vm_reg_valid(reg)) { +- DRM_ERROR("CP DMA Bad SRC register\n"); +- return -EINVAL; +- } +- } else { +- for (i = 0; i < (command & 0x1fffff); i++) { +- reg = start_reg + (4 * i); +- if (!si_vm_reg_valid(reg)) { +- DRM_ERROR("CP DMA Bad SRC register\n"); +- return -EINVAL; +- } +- } +- } +- } +- } +- if (command & PACKET3_CP_DMA_CMD_DAS) { +- /* dst address space is register */ +- if (((info & 0x00300000) >> 20) == 0) { +- start_reg = ib[idx + 2]; +- if (command & PACKET3_CP_DMA_CMD_DAIC) { +- reg = start_reg; +- if (!si_vm_reg_valid(reg)) { +- DRM_ERROR("CP DMA Bad DST register\n"); +- return -EINVAL; +- } +- } else { +- for (i = 0; i < (command & 0x1fffff); i++) { +- reg = start_reg + (4 * i); +- if (!si_vm_reg_valid(reg)) { +- DRM_ERROR("CP DMA Bad DST register\n"); +- return -EINVAL; +- } +- } +- } +- } +- } ++ r = si_vm_packet3_cp_dma_check(ib, idx); ++ if (r) ++ return r; + break; + default: + DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode); +@@ -3958,6 +3968,7 @@ + static int si_vm_packet3_compute_check(struct radeon_device *rdev, + u32 *ib, struct radeon_cs_packet *pkt) + { ++ int r; + u32 idx = pkt->idx + 1; + u32 idx_value = ib[idx]; + u32 start_reg, reg, i; +@@ -4030,6 +4041,11 @@ + return -EINVAL; + } + break; ++ case PACKET3_CP_DMA: ++ r = si_vm_packet3_cp_dma_check(ib, idx); ++ if (r) ++ return r; ++ break; + default: + DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode); + return -EINVAL; +Index: linux-3.10-3.10.11/include/uapi/drm/radeon_drm.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/uapi/drm/radeon_drm.h 2014-05-05 11:50:59.000000000 +0000 ++++ linux-3.10-3.10.11/include/uapi/drm/radeon_drm.h 2014-05-05 12:45:41.000000000 +0000 +@@ -979,6 +979,8 @@ + #define RADEON_INFO_RING_WORKING 0x15 + /* SI tile mode array */ + #define RADEON_INFO_SI_TILE_MODE_ARRAY 0x16 ++/* query if CP DMA is supported on the compute ring */ ++#define RADEON_INFO_SI_CP_DMA_COMPUTE 0x17 + + + struct drm_radeon_info { +Index: linux-3.10-3.10.11/dummy/rpi_1184_c7384791a785d8f356aa9de8038596cfd2ea87d3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1184_c7384791a785d8f356aa9de8038596cfd2ea87d3.txt 2014-05-05 12:45:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1185_410653c1e46c54436a66ccf1216ffc7e8b3bd4dd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1185_410653c1e46c54436a66ccf1216ffc7e8b3bd4dd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1185_410653c1e46c54436a66ccf1216ffc7e8b3bd4dd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1185_410653c1e46c54436a66ccf1216ffc7e8b3bd4dd.patch 2014-05-05 12:45:43.000000000 +0000 @@ -0,0 +1,92 @@ +commit 410653c1e46c54436a66ccf1216ffc7e8b3bd4dd +Author: Alex Deucher +Date: Mon Aug 19 11:06:50 2013 -0400 + + drm/radeon: update line buffer allocation for dce4.1/5 + + commit 0b31e02363b0db4e7931561bc6c141436e729d9f upstream. + + We need to allocate line buffer to each display when + setting up the watermarks. Failure to do so can lead + to a blank screen. This fixes blank screen problems + on dce4.1/5 asics. + + Based on an initial fix from: + Jay Cornwall + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreen.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/evergreen.c 2014-05-05 11:50:58.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreen.c 2014-05-05 12:45:42.000000000 +0000 +@@ -1718,7 +1718,8 @@ + struct drm_display_mode *mode, + struct drm_display_mode *other_mode) + { +- u32 tmp; ++ u32 tmp, buffer_alloc, i; ++ u32 pipe_offset = radeon_crtc->crtc_id * 0x20; + /* + * Line Buffer Setup + * There are 3 line buffers, each one shared by 2 display controllers. +@@ -1741,18 +1742,34 @@ + * non-linked crtcs for maximum line buffer allocation. + */ + if (radeon_crtc->base.enabled && mode) { +- if (other_mode) ++ if (other_mode) { + tmp = 0; /* 1/2 */ +- else ++ buffer_alloc = 1; ++ } else { + tmp = 2; /* whole */ +- } else ++ buffer_alloc = 2; ++ } ++ } else { + tmp = 0; ++ buffer_alloc = 0; ++ } + + /* second controller of the pair uses second half of the lb */ + if (radeon_crtc->crtc_id % 2) + tmp += 4; + WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); + ++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { ++ WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, ++ DMIF_BUFFERS_ALLOCATED(buffer_alloc)); ++ for (i = 0; i < rdev->usec_timeout; i++) { ++ if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & ++ DMIF_BUFFERS_ALLOCATED_COMPLETED) ++ break; ++ udelay(1); ++ } ++ } ++ + if (radeon_crtc->base.enabled && mode) { + switch (tmp) { + case 0: +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreend.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/evergreend.h 2014-05-05 11:50:58.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreend.h 2014-05-05 12:45:42.000000000 +0000 +@@ -810,6 +810,10 @@ + # define LATENCY_LOW_WATERMARK(x) ((x) << 0) + # define LATENCY_HIGH_WATERMARK(x) ((x) << 16) + ++#define PIPE0_DMIF_BUFFER_CONTROL 0x0ca0 ++# define DMIF_BUFFERS_ALLOCATED(x) ((x) << 0) ++# define DMIF_BUFFERS_ALLOCATED_COMPLETED (1 << 4) ++ + #define IH_RB_CNTL 0x3e00 + # define IH_RB_ENABLE (1 << 0) + # define IH_IB_SIZE(x) ((x) << 1) /* log2 */ +Index: linux-3.10-3.10.11/dummy/rpi_1185_410653c1e46c54436a66ccf1216ffc7e8b3bd4dd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1185_410653c1e46c54436a66ccf1216ffc7e8b3bd4dd.txt 2014-05-05 12:45:42.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1186_c74a65651ddcef3f06e10364809452191ac6cba6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1186_c74a65651ddcef3f06e10364809452191ac6cba6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1186_c74a65651ddcef3f06e10364809452191ac6cba6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1186_c74a65651ddcef3f06e10364809452191ac6cba6.patch 2014-05-05 12:45:44.000000000 +0000 @@ -0,0 +1,91 @@ +commit c74a65651ddcef3f06e10364809452191ac6cba6 +Author: Alex Deucher +Date: Mon Aug 19 11:15:43 2013 -0400 + + drm/radeon: update line buffer allocation for dce6 + + commit 290d24576ccf1aa0373d2185cedfe262d0d4952a upstream. + + We need to allocate line buffer to each display when + setting up the watermarks. Failure to do so can lead + to a blank screen. This fixes blank screen problems + on dce6 asics. + + Fixes: + https://bugs.freedesktop.org/show_bug.cgi?id=64850 + + Based on an initial fix from: + Jay Cornwall + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/si.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/si.c 2014-05-05 12:45:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/si.c 2014-05-05 12:45:43.000000000 +0000 +@@ -1467,7 +1467,8 @@ + struct drm_display_mode *mode, + struct drm_display_mode *other_mode) + { +- u32 tmp; ++ u32 tmp, buffer_alloc, i; ++ u32 pipe_offset = radeon_crtc->crtc_id * 0x20; + /* + * Line Buffer Setup + * There are 3 line buffers, each one shared by 2 display controllers. +@@ -1482,16 +1483,30 @@ + * non-linked crtcs for maximum line buffer allocation. + */ + if (radeon_crtc->base.enabled && mode) { +- if (other_mode) ++ if (other_mode) { + tmp = 0; /* 1/2 */ +- else ++ buffer_alloc = 1; ++ } else { + tmp = 2; /* whole */ +- } else ++ buffer_alloc = 2; ++ } ++ } else { + tmp = 0; ++ buffer_alloc = 0; ++ } + + WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, + DC_LB_MEMORY_CONFIG(tmp)); + ++ WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, ++ DMIF_BUFFERS_ALLOCATED(buffer_alloc)); ++ for (i = 0; i < rdev->usec_timeout; i++) { ++ if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & ++ DMIF_BUFFERS_ALLOCATED_COMPLETED) ++ break; ++ udelay(1); ++ } ++ + if (radeon_crtc->base.enabled && mode) { + switch (tmp) { + case 0: +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/sid.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/sid.h 2014-05-05 11:50:57.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/sid.h 2014-05-05 12:45:43.000000000 +0000 +@@ -97,6 +97,10 @@ + + #define DMIF_ADDR_CALC 0xC00 + ++#define PIPE0_DMIF_BUFFER_CONTROL 0x0ca0 ++# define DMIF_BUFFERS_ALLOCATED(x) ((x) << 0) ++# define DMIF_BUFFERS_ALLOCATED_COMPLETED (1 << 4) ++ + #define SRBM_STATUS 0xE50 + #define GRBM_RQ_PENDING (1 << 5) + #define VMC_BUSY (1 << 8) +Index: linux-3.10-3.10.11/dummy/rpi_1186_c74a65651ddcef3f06e10364809452191ac6cba6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1186_c74a65651ddcef3f06e10364809452191ac6cba6.txt 2014-05-05 12:45:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1187_a7b153243b75dc0633a0ef85f1598d719a6624e6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1187_a7b153243b75dc0633a0ef85f1598d719a6624e6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1187_a7b153243b75dc0633a0ef85f1598d719a6624e6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1187_a7b153243b75dc0633a0ef85f1598d719a6624e6.patch 2014-05-05 12:45:44.000000000 +0000 @@ -0,0 +1,51 @@ +commit a7b153243b75dc0633a0ef85f1598d719a6624e6 +Author: Alex Deucher +Date: Mon Aug 26 17:52:12 2013 -0400 + + drm/radeon: fix resume on some rs4xx boards (v2) + + commit acf88deb8ddbb73acd1c3fa32fde51af9153227f upstream. + + Setting MC_MISC_CNTL.GART_INDEX_REG_EN causes hangs on + some boards on resume. The systems seem to work fine + without touching this bit so leave it as is. + + v2: read-modify-write the GART_INDEX_REG_EN bit. + I suspect the problem is that we are losing the other + settings in the register. + + fixes: + https://bugs.freedesktop.org/show_bug.cgi?id=52952 + + Reported-by: Ondrej Zary + Tested-by: Daniel Tobias + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/rs400.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/rs400.c 2014-05-05 11:50:57.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/rs400.c 2014-05-05 12:45:44.000000000 +0000 +@@ -174,10 +174,13 @@ + /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0, + * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */ + if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { +- WREG32_MC(RS480_MC_MISC_CNTL, +- (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN)); ++ tmp = RREG32_MC(RS480_MC_MISC_CNTL); ++ tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN; ++ WREG32_MC(RS480_MC_MISC_CNTL, tmp); + } else { +- WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); ++ tmp = RREG32_MC(RS480_MC_MISC_CNTL); ++ tmp |= RS480_GART_INDEX_REG_EN; ++ WREG32_MC(RS480_MC_MISC_CNTL, tmp); + } + /* Enable gart */ + WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg)); +Index: linux-3.10-3.10.11/dummy/rpi_1187_a7b153243b75dc0633a0ef85f1598d719a6624e6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1187_a7b153243b75dc0633a0ef85f1598d719a6624e6.txt 2014-05-05 12:45:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1188_911181cc6e98ee814b4f1616d1b59a54b6bb8e6f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1188_911181cc6e98ee814b4f1616d1b59a54b6bb8e6f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1188_911181cc6e98ee814b4f1616d1b59a54b6bb8e6f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1188_911181cc6e98ee814b4f1616d1b59a54b6bb8e6f.patch 2014-05-05 12:45:45.000000000 +0000 @@ -0,0 +1,55 @@ +commit 911181cc6e98ee814b4f1616d1b59a54b6bb8e6f +Author: Alex Deucher +Date: Tue Aug 27 12:36:01 2013 -0400 + + drm/radeon: fix handling of variable sized arrays for router objects + + commit fb93df1c2d8b3b1fb16d6ee9e32554e0c038815d upstream. + + The table has the following format: + + typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset pointing to this structure + { + UCHAR ucNumberOfSrc; + USHORT usSrcObjectID[1]; + UCHAR ucNumberOfDst; + USHORT usDstObjectID[1]; + }ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT; + + usSrcObjectID[] and usDstObjectID[] are variably sized, so we + can't access them directly. Use pointers and update the offset + appropriately when accessing the Dst members. + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_atombios.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_atombios.c 2014-05-05 12:45:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_atombios.c 2014-05-05 12:45:45.000000000 +0000 +@@ -715,13 +715,16 @@ + (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) + (ctx->bios + data_offset + + le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset)); ++ u8 *num_dst_objs = (u8 *) ++ ((u8 *)router_src_dst_table + 1 + ++ (router_src_dst_table->ucNumberOfSrc * 2)); ++ u16 *dst_objs = (u16 *)(num_dst_objs + 1); + int enum_id; + + router.router_id = router_obj_id; +- for (enum_id = 0; enum_id < router_src_dst_table->ucNumberOfDst; +- enum_id++) { ++ for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) { + if (le16_to_cpu(path->usConnObjectId) == +- le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id])) ++ le16_to_cpu(dst_objs[enum_id])) + break; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1188_911181cc6e98ee814b4f1616d1b59a54b6bb8e6f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1188_911181cc6e98ee814b4f1616d1b59a54b6bb8e6f.txt 2014-05-05 12:45:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1189_39bad38d5dddaaf1296a1e3f0bd75ee952521afc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1189_39bad38d5dddaaf1296a1e3f0bd75ee952521afc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1189_39bad38d5dddaaf1296a1e3f0bd75ee952521afc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1189_39bad38d5dddaaf1296a1e3f0bd75ee952521afc.patch 2014-05-05 12:45:46.000000000 +0000 @@ -0,0 +1,88 @@ +commit 39bad38d5dddaaf1296a1e3f0bd75ee952521afc +Author: Stanislaw Gruszka +Date: Mon Sep 9 12:37:37 2013 +0200 + + rt2800: change initialization sequence to fix system freeze + + commit f4e1a4d3ecbb9e42bdf8e7869ee8a4ebfa27fb20 upstream. + + My commit + + commit c630ccf1a127578421a928489d51e99c05037054 + Author: Stanislaw Gruszka + Date: Sat Mar 16 19:19:46 2013 +0100 + + rt2800: rearrange bbp/rfcsr initialization + + make Maxim machine freeze when try to start wireless device. + + Initialization order and sending MCU_BOOT_SIGNAL request, changed in + above commit, is important. Doing things incorrectly make PCIe bus + problems, which can froze the machine. + + This patch change initialization sequence like vendor driver do: + function NICInitializeAsic() from + 2011_1007_RT5390_RT5392_Linux_STA_V2.5.0.3_DPO (PCI devices) and + DPO_RT5572_LinuxSTA_2.6.1.3_20121022 (according Mediatek, latest driver + for RT8070/RT3070/RT3370/RT3572/RT5370/RT5372/RT5572 USB devices). + It fixes freezes on Maxim system. + + Resolve: + https://bugzilla.redhat.com/show_bug.cgi?id=1000679 + + Reported-and-tested-by: Maxim Polyakov + Bisected-by: Igor Gnatenko + Cc: stable@vger.kernel.org # 3.10+ + Signed-off-by: Stanislaw Gruszka + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/rt2x00/rt2800lib.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/rt2x00/rt2800lib.c 2014-05-05 12:45:23.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/rt2x00/rt2800lib.c 2014-05-05 12:45:45.000000000 +0000 +@@ -4048,10 +4048,6 @@ + u8 reg_id; + u8 value; + +- if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) || +- rt2800_wait_bbp_ready(rt2x00dev))) +- return -EACCES; +- + if (rt2x00_rt(rt2x00dev, RT5592)) { + rt2800_init_bbp_5592(rt2x00dev); + return 0; +@@ -5192,20 +5188,23 @@ + rt2800_init_registers(rt2x00dev))) + return -EIO; + ++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev))) ++ return -EIO; ++ + /* + * Send signal to firmware during boot time. + */ + rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); + rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); +- if (rt2x00_is_usb(rt2x00dev)) { ++ if (rt2x00_is_usb(rt2x00dev)) + rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); +- rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); +- } ++ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); + msleep(1); + +- if (unlikely(rt2800_init_bbp(rt2x00dev))) ++ if (unlikely(rt2800_wait_bbp_ready(rt2x00dev))) + return -EIO; + ++ rt2800_init_bbp(rt2x00dev); + rt2800_init_rfcsr(rt2x00dev); + + if (rt2x00_is_usb(rt2x00dev) && +Index: linux-3.10-3.10.11/dummy/rpi_1189_39bad38d5dddaaf1296a1e3f0bd75ee952521afc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1189_39bad38d5dddaaf1296a1e3f0bd75ee952521afc.txt 2014-05-05 12:45:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1190_abc1e807c2bd7cd5b1aeedca2c4bb41eb786828c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1190_abc1e807c2bd7cd5b1aeedca2c4bb41eb786828c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1190_abc1e807c2bd7cd5b1aeedca2c4bb41eb786828c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1190_abc1e807c2bd7cd5b1aeedca2c4bb41eb786828c.patch 2014-05-05 12:45:47.000000000 +0000 @@ -0,0 +1,54 @@ +commit abc1e807c2bd7cd5b1aeedca2c4bb41eb786828c +Author: Alex Deucher +Date: Mon Sep 9 10:54:22 2013 -0400 + + drm/radeon/atom: workaround vbios bug in transmitter table on rs880 (v2) + + commit 91f3a6aaf280294b07c05dfe606e6c27b7ba3c72 upstream. + + The OUTPUT_ENABLE action jumps past the point in the coder where + the data_offset is set on certain rs780 cards. This worked + previously because the OUTPUT_ENABLE action is always called + immediately after the ENABLE action so the data_offset remained + set. In 6f8bbaf568c7f2c497558bfd04654c0b9841ad57 + (drm/radeon/atom: initialize more atom interpretor elements to 0), + we explictly reset data_offset to 0 between atom calls which then + caused this to fail. The fix is to just skip calling the + OUTPUT_ENABLE action on the problematic chipsets. The ENABLE + action does the same thing and more. Ultimately, we could + probably drop the OUTPUT_ENABLE action all together on DCE3 + asics. + + fixes: + https://bugzilla.kernel.org/show_bug.cgi?id=60791 + + v2: only rs880 seems to be affected + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_encoders.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/atombios_encoders.c 2014-05-05 11:50:56.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_encoders.c 2014-05-05 12:45:46.000000000 +0000 +@@ -1636,8 +1636,12 @@ + atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); +- /* some early dce3.2 boards have a bug in their transmitter control table */ +- if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) ++ /* some dce3.x boards have a bug in their transmitter control table. ++ * ACTION_ENABLE_OUTPUT can probably be dropped since ACTION_ENABLE ++ * does the same thing and more. ++ */ ++ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) && ++ (rdev->family != CHIP_RS880)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + } + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { +Index: linux-3.10-3.10.11/dummy/rpi_1190_abc1e807c2bd7cd5b1aeedca2c4bb41eb786828c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1190_abc1e807c2bd7cd5b1aeedca2c4bb41eb786828c.txt 2014-05-05 12:45:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1191_85faca8521551b799955359334969b2b58cdd2fa.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1191_85faca8521551b799955359334969b2b58cdd2fa.patch --- linux-3.10.11/debian/patches/rpi/rpi_1191_85faca8521551b799955359334969b2b58cdd2fa.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1191_85faca8521551b799955359334969b2b58cdd2fa.patch 2014-05-05 12:45:48.000000000 +0000 @@ -0,0 +1,101 @@ +commit 85faca8521551b799955359334969b2b58cdd2fa +Author: Alex Deucher +Date: Fri Sep 13 18:33:16 2013 -0400 + + drm/radeon: fix panel scaling with eDP and LVDS bridges + + commit 855f5f1d882a34e4e9dd27b299737cd3508a5624 upstream. + + We were using the wrong set_properly callback so we always + ended up with Full scaling even if something else (Center or + Full aspect) was selected. + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_connectors.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_connectors.c 2014-05-05 11:50:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_connectors.c 2014-05-05 12:45:47.000000000 +0000 +@@ -1489,6 +1489,24 @@ + .force = radeon_dvi_force, + }; + ++static const struct drm_connector_funcs radeon_edp_connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = radeon_dp_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = radeon_lvds_set_property, ++ .destroy = radeon_dp_connector_destroy, ++ .force = radeon_dvi_force, ++}; ++ ++static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = radeon_dp_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = radeon_lvds_set_property, ++ .destroy = radeon_dp_connector_destroy, ++ .force = radeon_dvi_force, ++}; ++ + void + radeon_add_atom_connector(struct drm_device *dev, + uint32_t connector_id, +@@ -1580,8 +1598,6 @@ + goto failed; + radeon_dig_connector->igp_lane_info = igp_lane_info; + radeon_connector->con_priv = radeon_dig_connector; +- drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); +- drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); + if (i2c_bus->valid) { + /* add DP i2c bus */ + if (connector_type == DRM_MODE_CONNECTOR_eDP) +@@ -1598,6 +1614,10 @@ + case DRM_MODE_CONNECTOR_VGA: + case DRM_MODE_CONNECTOR_DVIA: + default: ++ drm_connector_init(dev, &radeon_connector->base, ++ &radeon_dp_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, ++ &radeon_dp_connector_helper_funcs); + connector->interlace_allowed = true; + connector->doublescan_allowed = true; + radeon_connector->dac_load_detect = true; +@@ -1610,6 +1630,10 @@ + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + case DRM_MODE_CONNECTOR_DisplayPort: ++ drm_connector_init(dev, &radeon_connector->base, ++ &radeon_dp_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, ++ &radeon_dp_connector_helper_funcs); + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.underscan_property, + UNDERSCAN_OFF); +@@ -1634,6 +1658,10 @@ + break; + case DRM_MODE_CONNECTOR_LVDS: + case DRM_MODE_CONNECTOR_eDP: ++ drm_connector_init(dev, &radeon_connector->base, ++ &radeon_lvds_bridge_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, ++ &radeon_dp_connector_helper_funcs); + drm_object_attach_property(&radeon_connector->base.base, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_FULLSCREEN); +@@ -1797,7 +1825,7 @@ + goto failed; + radeon_dig_connector->igp_lane_info = igp_lane_info; + radeon_connector->con_priv = radeon_dig_connector; +- drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); ++ drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type); + drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); + if (i2c_bus->valid) { + /* add DP i2c bus */ +Index: linux-3.10-3.10.11/dummy/rpi_1191_85faca8521551b799955359334969b2b58cdd2fa.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1191_85faca8521551b799955359334969b2b58cdd2fa.txt 2014-05-05 12:45:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1192_075bf1f91aba3d3c689fa370850a6b89aa31cfe5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1192_075bf1f91aba3d3c689fa370850a6b89aa31cfe5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1192_075bf1f91aba3d3c689fa370850a6b89aa31cfe5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1192_075bf1f91aba3d3c689fa370850a6b89aa31cfe5.patch 2014-05-05 12:45:48.000000000 +0000 @@ -0,0 +1,39 @@ +commit 075bf1f91aba3d3c689fa370850a6b89aa31cfe5 +Author: Christian König +Date: Sun Sep 15 13:31:28 2013 +0200 + + drm/radeon: avoid UVD corruptions on AGP cards + + commit 4f66c59922cbcda14c9e103e6c7f4ee616360d43 upstream. + + Putting everything into VRAM seems to help. + + Signed-off-by: Christian König + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_cs.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_cs.c 2014-05-05 11:50:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_cs.c 2014-05-05 12:45:48.000000000 +0000 +@@ -80,9 +80,11 @@ + p->relocs[i].lobj.bo = p->relocs[i].robj; + p->relocs[i].lobj.written = !!r->write_domain; + +- /* the first reloc of an UVD job is the +- msg and that must be in VRAM */ +- if (p->ring == R600_RING_TYPE_UVD_INDEX && i == 0) { ++ /* the first reloc of an UVD job is the msg and that must be in ++ VRAM, also but everything into VRAM on AGP cards to avoid ++ image corruptions */ ++ if (p->ring == R600_RING_TYPE_UVD_INDEX && ++ (i == 0 || p->rdev->flags & RADEON_IS_AGP)) { + /* TODO: is this still needed for NI+ ? */ + p->relocs[i].lobj.domain = + RADEON_GEM_DOMAIN_VRAM; +Index: linux-3.10-3.10.11/dummy/rpi_1192_075bf1f91aba3d3c689fa370850a6b89aa31cfe5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1192_075bf1f91aba3d3c689fa370850a6b89aa31cfe5.txt 2014-05-05 12:45:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1193_3db27a31a8b1c89bd6a0736559ee58550efe6278.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1193_3db27a31a8b1c89bd6a0736559ee58550efe6278.patch --- linux-3.10.11/debian/patches/rpi/rpi_1193_3db27a31a8b1c89bd6a0736559ee58550efe6278.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1193_3db27a31a8b1c89bd6a0736559ee58550efe6278.patch 2014-05-05 12:45:49.000000000 +0000 @@ -0,0 +1,141 @@ +commit 3db27a31a8b1c89bd6a0736559ee58550efe6278 +Author: Randy Dunlap +Date: Wed May 8 17:28:13 2013 -0300 + + media: media/usb: fix kconfig dependencies + + commit a0f9354b1a319cb29c331bfd2e5a15d7f9b87fa4 upstream. + + (a.k.a. Kconfig bool depending on a tristate considered harmful) + Fix various build errors when CONFIG_USB=m and media USB drivers + are builtin. In this case, CONFIG_USB_ZR364XX=y, + CONFIG_VIDEO_PVRUSB2=y, and CONFIG_VIDEO_STK1160=y. + This is caused by (from drivers/media/usb/Kconfig): + menuconfig MEDIA_USB_SUPPORT + bool "Media USB Adapters" + depends on USB && MEDIA_SUPPORT + =m =y + so MEDIA_USB_SUPPORT=y and all following Kconfig 'source' lines + are included. By adding an "if USB" guard around most of this file, + the needed dependencies are enforced. + drivers/built-in.o: In function `zr364xx_start_readpipe': + zr364xx.c:(.text+0xc726a): undefined reference to `usb_alloc_urb' + zr364xx.c:(.text+0xc72bb): undefined reference to `usb_submit_urb' + drivers/built-in.o: In function `zr364xx_stop_readpipe': + zr364xx.c:(.text+0xc72fd): undefined reference to `usb_kill_urb' + zr364xx.c:(.text+0xc7309): undefined reference to `usb_free_urb' + drivers/built-in.o: In function `read_pipe_completion': + zr364xx.c:(.text+0xc7acc): undefined reference to `usb_submit_urb' + drivers/built-in.o: In function `send_control_msg.constprop.12': + zr364xx.c:(.text+0xc7d2f): undefined reference to `usb_control_msg' + drivers/built-in.o: In function `pvr2_ctl_timeout': + pvrusb2-hdw.c:(.text+0xcadb6): undefined reference to `usb_unlink_urb' + pvrusb2-hdw.c:(.text+0xcadcb): undefined reference to `usb_unlink_urb' + drivers/built-in.o: In function `pvr2_hdw_create': + (.text+0xcc42c): undefined reference to `usb_alloc_urb' + drivers/built-in.o: In function `pvr2_hdw_create': + (.text+0xcc448): undefined reference to `usb_alloc_urb' + drivers/built-in.o: In function `pvr2_hdw_create': + (.text+0xcc5f9): undefined reference to `usb_set_interface' + drivers/built-in.o: In function `pvr2_hdw_create': + (.text+0xcc65a): undefined reference to `usb_free_urb' + drivers/built-in.o: In function `pvr2_hdw_create': + (.text+0xcc666): undefined reference to `usb_free_urb' + drivers/built-in.o: In function `pvr2_send_request_ex.part.22': + pvrusb2-hdw.c:(.text+0xccbe3): undefined reference to `usb_submit_urb' + pvrusb2-hdw.c:(.text+0xccc83): undefined reference to `usb_submit_urb' + drivers/built-in.o: In function `pvr2_hdw_remove_usb_stuff.part.25': + pvrusb2-hdw.c:(.text+0xcd3f9): undefined reference to `usb_kill_urb' + pvrusb2-hdw.c:(.text+0xcd405): undefined reference to `usb_free_urb' + pvrusb2-hdw.c:(.text+0xcd421): undefined reference to `usb_kill_urb' + pvrusb2-hdw.c:(.text+0xcd42d): undefined reference to `usb_free_urb' + drivers/built-in.o: In function `pvr2_hdw_device_reset': + (.text+0xcd658): undefined reference to `usb_lock_device_for_reset' + drivers/built-in.o: In function `pvr2_hdw_device_reset': + (.text+0xcd664): undefined reference to `usb_reset_device' + drivers/built-in.o: In function `pvr2_hdw_cpureset_assert': + (.text+0xcd6f9): undefined reference to `usb_control_msg' + drivers/built-in.o: In function `pvr2_hdw_cpufw_set_enabled': + (.text+0xcd84e): undefined reference to `usb_control_msg' + drivers/built-in.o: In function `pvr2_upload_firmware1': + pvrusb2-hdw.c:(.text+0xcda47): undefined reference to `usb_clear_halt' + pvrusb2-hdw.c:(.text+0xcdb04): undefined reference to `usb_control_msg' + drivers/built-in.o: In function `pvr2_upload_firmware2': + (.text+0xce7dc): undefined reference to `usb_bulk_msg' + drivers/built-in.o: In function `pvr2_stream_buffer_count': + pvrusb2-io.c:(.text+0xd2e05): undefined reference to `usb_alloc_urb' + pvrusb2-io.c:(.text+0xd2e5b): undefined reference to `usb_kill_urb' + pvrusb2-io.c:(.text+0xd2e9f): undefined reference to `usb_free_urb' + drivers/built-in.o: In function `pvr2_stream_internal_flush': + pvrusb2-io.c:(.text+0xd2f9b): undefined reference to `usb_kill_urb' + drivers/built-in.o: In function `pvr2_buffer_queue': + (.text+0xd3328): undefined reference to `usb_kill_urb' + drivers/built-in.o: In function `pvr2_buffer_queue': + (.text+0xd33ea): undefined reference to `usb_submit_urb' + drivers/built-in.o: In function `stk1160_read_reg': + (.text+0xd3efa): undefined reference to `usb_control_msg' + drivers/built-in.o: In function `stk1160_write_reg': + (.text+0xd3f4f): undefined reference to `usb_control_msg' + drivers/built-in.o: In function `stop_streaming': + stk1160-v4l.c:(.text+0xd4997): undefined reference to `usb_set_interface' + drivers/built-in.o: In function `start_streaming': + stk1160-v4l.c:(.text+0xd4a9f): undefined reference to `usb_set_interface' + stk1160-v4l.c:(.text+0xd4afa): undefined reference to `usb_submit_urb' + stk1160-v4l.c:(.text+0xd4ba3): undefined reference to `usb_set_interface' + drivers/built-in.o: In function `stk1160_isoc_irq': + stk1160-video.c:(.text+0xd509b): undefined reference to `usb_submit_urb' + drivers/built-in.o: In function `stk1160_cancel_isoc': + (.text+0xd50ef): undefined reference to `usb_kill_urb' + drivers/built-in.o: In function `stk1160_free_isoc': + (.text+0xd5155): undefined reference to `usb_free_coherent' + drivers/built-in.o: In function `stk1160_free_isoc': + (.text+0xd515d): undefined reference to `usb_free_urb' + drivers/built-in.o: In function `stk1160_alloc_isoc': + (.text+0xd5278): undefined reference to `usb_alloc_urb' + drivers/built-in.o: In function `stk1160_alloc_isoc': + (.text+0xd52c2): undefined reference to `usb_alloc_coherent' + drivers/built-in.o: In function `stk1160_alloc_isoc': + (.text+0xd53c4): undefined reference to `usb_free_urb' + drivers/built-in.o: In function `zr364xx_driver_init': + zr364xx.c:(.init.text+0x463e): undefined reference to `usb_register_driver' + drivers/built-in.o: In function `pvr_init': + pvrusb2-main.c:(.init.text+0x4662): undefined reference to `usb_register_driver' + drivers/built-in.o: In function `stk1160_usb_driver_init': + stk1160-core.c:(.init.text+0x467d): undefined reference to `usb_register_driver' + drivers/built-in.o: In function `zr364xx_driver_exit': + zr364xx.c:(.exit.text+0x1377): undefined reference to `usb_deregister' + drivers/built-in.o: In function `pvr_exit': + pvrusb2-main.c:(.exit.text+0x1389): undefined reference to `usb_deregister' + drivers/built-in.o: In function `stk1160_usb_driver_exit': + stk1160-core.c:(.exit.text+0x13a0): undefined reference to `usb_deregister' + + Suggested-by: "Yann E. MORIN" + Signed-off-by: Randy Dunlap + Signed-off-by: Mauro Carvalho Chehab + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/usb/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/Kconfig 2014-05-05 11:50:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/Kconfig 2014-05-05 12:45:49.000000000 +0000 +@@ -1,6 +1,8 @@ ++if USB ++ + menuconfig MEDIA_USB_SUPPORT + bool "Media USB Adapters" +- depends on USB && MEDIA_SUPPORT ++ depends on MEDIA_SUPPORT + help + Enable media drivers for USB bus. + If you have such devices, say Y. +@@ -52,3 +54,4 @@ + endif + + endif #MEDIA_USB_SUPPORT ++endif #USB +Index: linux-3.10-3.10.11/dummy/rpi_1193_3db27a31a8b1c89bd6a0736559ee58550efe6278.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1193_3db27a31a8b1c89bd6a0736559ee58550efe6278.txt 2014-05-05 12:45:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1194_7b7b9915f77d3c5db399866080751e9dafc9136f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1194_7b7b9915f77d3c5db399866080751e9dafc9136f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1194_7b7b9915f77d3c5db399866080751e9dafc9136f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1194_7b7b9915f77d3c5db399866080751e9dafc9136f.patch 2014-05-05 12:45:50.000000000 +0000 @@ -0,0 +1,58 @@ +commit 7b7b9915f77d3c5db399866080751e9dafc9136f +Author: Mauro Carvalho Chehab +Date: Wed May 22 11:25:52 2013 -0300 + + Properly handle tristate dependencies on USB/PCI menus + + commit 5077ac3b8108007f4a2b4589f2d373cf55453206 upstream. + + As USB/PCI/MEDIA_SUPPORT dependencies can be tristate, we can't + simply make the bool menu to be dependent on it. Everything below + the menu should also depend on it, otherwise, we risk to allow + building them with 'y', while only 'm' would be supported. + + So, add an IF just before everything below, in order to avoid + such risks. + + Signed-off-by: Mauro Carvalho Chehab + Cc: Randy Dunlap + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/media/pci/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/pci/Kconfig 2014-05-05 11:50:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/pci/Kconfig 2014-05-05 12:45:49.000000000 +0000 +@@ -1,6 +1,7 @@ ++if PCI && MEDIA_SUPPORT ++ + menuconfig MEDIA_PCI_SUPPORT + bool "Media PCI Adapters" +- depends on PCI && MEDIA_SUPPORT + help + Enable media drivers for PCI/PCIe bus. + If you have such devices, say Y. +@@ -45,3 +46,4 @@ + endif + + endif #MEDIA_PCI_SUPPORT ++endif #PCI +Index: linux-3.10-3.10.11/drivers/media/usb/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/media/usb/Kconfig 2014-05-05 12:45:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/media/usb/Kconfig 2014-05-05 12:45:49.000000000 +0000 +@@ -1,8 +1,7 @@ +-if USB ++if USB && MEDIA_SUPPORT + + menuconfig MEDIA_USB_SUPPORT + bool "Media USB Adapters" +- depends on MEDIA_SUPPORT + help + Enable media drivers for USB bus. + If you have such devices, say Y. +Index: linux-3.10-3.10.11/dummy/rpi_1194_7b7b9915f77d3c5db399866080751e9dafc9136f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1194_7b7b9915f77d3c5db399866080751e9dafc9136f.txt 2014-05-05 12:45:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1195_66ccf96185266dee7b0b15ae08e9c1359e0e1c47.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1195_66ccf96185266dee7b0b15ae08e9c1359e0e1c47.patch --- linux-3.10.11/debian/patches/rpi/rpi_1195_66ccf96185266dee7b0b15ae08e9c1359e0e1c47.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1195_66ccf96185266dee7b0b15ae08e9c1359e0e1c47.patch 2014-05-05 12:45:51.000000000 +0000 @@ -0,0 +1,734 @@ +commit 66ccf96185266dee7b0b15ae08e9c1359e0e1c47 +Author: Jan Kara +Date: Thu Jul 25 19:10:59 2013 +0200 + + udf: Standardize return values in mount sequence + + commit d759bfa4e7919b89357de50a2e23817079889195 upstream. + + Change all function used in filesystem discovery during mount to user + standard kernel return values - -errno on error, 0 on success instead + of 1 on failure and 0 on success. This allows us to pass error number + (not just failure / success) so we can abort device scanning earlier + in case of errors like EIO or ENOMEM . Also we will be able to return + EROFS in case writeable mount is requested but writing isn't supported. + + Signed-off-by: Jan Kara + Cc: Hui Wang + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/udf/super.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/udf/super.c 2014-05-05 11:50:54.000000000 +0000 ++++ linux-3.10-3.10.11/fs/udf/super.c 2014-05-05 12:45:50.000000000 +0000 +@@ -843,27 +843,38 @@ + return 1; + } + ++/* ++ * Load primary Volume Descriptor Sequence ++ * ++ * Return <0 on error, 0 on success. -EAGAIN is special meaning next sequence ++ * should be tried. ++ */ + static int udf_load_pvoldesc(struct super_block *sb, sector_t block) + { + struct primaryVolDesc *pvoldesc; + struct ustr *instr, *outstr; + struct buffer_head *bh; + uint16_t ident; +- int ret = 1; ++ int ret = -ENOMEM; + + instr = kmalloc(sizeof(struct ustr), GFP_NOFS); + if (!instr) +- return 1; ++ return -ENOMEM; + + outstr = kmalloc(sizeof(struct ustr), GFP_NOFS); + if (!outstr) + goto out1; + + bh = udf_read_tagged(sb, block, block, &ident); +- if (!bh) ++ if (!bh) { ++ ret = -EAGAIN; + goto out2; ++ } + +- BUG_ON(ident != TAG_IDENT_PVD); ++ if (ident != TAG_IDENT_PVD) { ++ ret = -EIO; ++ goto out_bh; ++ } + + pvoldesc = (struct primaryVolDesc *)bh->b_data; + +@@ -889,8 +900,9 @@ + if (udf_CS0toUTF8(outstr, instr)) + udf_debug("volSetIdent[] = '%s'\n", outstr->u_name); + +- brelse(bh); + ret = 0; ++out_bh: ++ brelse(bh); + out2: + kfree(outstr); + out1: +@@ -947,7 +959,7 @@ + + if (mdata->s_mirror_fe == NULL) { + udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n"); +- goto error_exit; ++ return -EIO; + } + } + +@@ -964,23 +976,18 @@ + addr.logicalBlockNum, addr.partitionReferenceNum); + + mdata->s_bitmap_fe = udf_iget(sb, &addr); +- + if (mdata->s_bitmap_fe == NULL) { + if (sb->s_flags & MS_RDONLY) + udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only\n"); + else { + udf_err(sb, "bitmap inode efe not found and attempted read-write mount\n"); +- goto error_exit; ++ return -EIO; + } + } + } + + udf_debug("udf_load_metadata_files Ok\n"); +- + return 0; +- +-error_exit: +- return 1; + } + + static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, +@@ -1069,7 +1076,7 @@ + if (!map->s_uspace.s_table) { + udf_debug("cannot load unallocSpaceTable (part %d)\n", + p_index); +- return 1; ++ return -EIO; + } + map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE; + udf_debug("unallocSpaceTable (part %d) @ %ld\n", +@@ -1079,7 +1086,7 @@ + if (phd->unallocSpaceBitmap.extLength) { + struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); + if (!bitmap) +- return 1; ++ return -ENOMEM; + map->s_uspace.s_bitmap = bitmap; + bitmap->s_extPosition = le32_to_cpu( + phd->unallocSpaceBitmap.extPosition); +@@ -1102,7 +1109,7 @@ + if (!map->s_fspace.s_table) { + udf_debug("cannot load freedSpaceTable (part %d)\n", + p_index); +- return 1; ++ return -EIO; + } + + map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE; +@@ -1113,7 +1120,7 @@ + if (phd->freedSpaceBitmap.extLength) { + struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); + if (!bitmap) +- return 1; ++ return -ENOMEM; + map->s_fspace.s_bitmap = bitmap; + bitmap->s_extPosition = le32_to_cpu( + phd->freedSpaceBitmap.extPosition); +@@ -1165,7 +1172,7 @@ + udf_find_vat_block(sb, p_index, type1_index, blocks - 1); + } + if (!sbi->s_vat_inode) +- return 1; ++ return -EIO; + + if (map->s_partition_type == UDF_VIRTUAL_MAP15) { + map->s_type_specific.s_virtual.s_start_offset = 0; +@@ -1177,7 +1184,7 @@ + pos = udf_block_map(sbi->s_vat_inode, 0); + bh = sb_bread(sb, pos); + if (!bh) +- return 1; ++ return -EIO; + vat20 = (struct virtualAllocationTable20 *)bh->b_data; + } else { + vat20 = (struct virtualAllocationTable20 *) +@@ -1195,6 +1202,12 @@ + return 0; + } + ++/* ++ * Load partition descriptor block ++ * ++ * Returns <0 on error, 0 on success, -EAGAIN is special - try next descriptor ++ * sequence. ++ */ + static int udf_load_partdesc(struct super_block *sb, sector_t block) + { + struct buffer_head *bh; +@@ -1204,13 +1217,15 @@ + int i, type1_idx; + uint16_t partitionNumber; + uint16_t ident; +- int ret = 0; ++ int ret; + + bh = udf_read_tagged(sb, block, block, &ident); + if (!bh) +- return 1; +- if (ident != TAG_IDENT_PD) ++ return -EAGAIN; ++ if (ident != TAG_IDENT_PD) { ++ ret = 0; + goto out_bh; ++ } + + p = (struct partitionDesc *)bh->b_data; + partitionNumber = le16_to_cpu(p->partitionNumber); +@@ -1229,10 +1244,13 @@ + if (i >= sbi->s_partitions) { + udf_debug("Partition (%d) not found in partition map\n", + partitionNumber); ++ ret = 0; + goto out_bh; + } + + ret = udf_fill_partdesc_info(sb, p, i); ++ if (ret < 0) ++ goto out_bh; + + /* + * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and +@@ -1249,23 +1267,25 @@ + break; + } + +- if (i >= sbi->s_partitions) ++ if (i >= sbi->s_partitions) { ++ ret = 0; + goto out_bh; ++ } + + ret = udf_fill_partdesc_info(sb, p, i); +- if (ret) ++ if (ret < 0) + goto out_bh; + + if (map->s_partition_type == UDF_METADATA_MAP25) { + ret = udf_load_metadata_files(sb, i); +- if (ret) { ++ if (ret < 0) { + udf_err(sb, "error loading MetaData partition map %d\n", + i); + goto out_bh; + } + } else { + ret = udf_load_vat(sb, i, type1_idx); +- if (ret) ++ if (ret < 0) + goto out_bh; + /* + * Mark filesystem read-only if we have a partition with +@@ -1275,6 +1295,7 @@ + sb->s_flags |= MS_RDONLY; + pr_notice("Filesystem marked read-only because writing to pseudooverwrite partition is not implemented\n"); + } ++ ret = 0; + out_bh: + /* In case loading failed, we handle cleanup in udf_fill_super */ + brelse(bh); +@@ -1340,11 +1361,11 @@ + uint16_t ident; + struct buffer_head *bh; + unsigned int table_len; +- int ret = 0; ++ int ret; + + bh = udf_read_tagged(sb, block, block, &ident); + if (!bh) +- return 1; ++ return -EAGAIN; + BUG_ON(ident != TAG_IDENT_LVD); + lvd = (struct logicalVolDesc *)bh->b_data; + table_len = le32_to_cpu(lvd->mapTableLength); +@@ -1352,7 +1373,7 @@ + udf_err(sb, "error loading logical volume descriptor: " + "Partition table too long (%u > %lu)\n", table_len, + sb->s_blocksize - sizeof(*lvd)); +- ret = 1; ++ ret = -EIO; + goto out_bh; + } + +@@ -1396,11 +1417,10 @@ + } else if (!strncmp(upm2->partIdent.ident, + UDF_ID_SPARABLE, + strlen(UDF_ID_SPARABLE))) { +- if (udf_load_sparable_map(sb, map, +- (struct sparablePartitionMap *)gpm) < 0) { +- ret = 1; ++ ret = udf_load_sparable_map(sb, map, ++ (struct sparablePartitionMap *)gpm); ++ if (ret < 0) + goto out_bh; +- } + } else if (!strncmp(upm2->partIdent.ident, + UDF_ID_METADATA, + strlen(UDF_ID_METADATA))) { +@@ -1465,7 +1485,7 @@ + } + if (lvd->integritySeqExt.extLength) + udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); +- ++ ret = 0; + out_bh: + brelse(bh); + return ret; +@@ -1503,22 +1523,18 @@ + } + + /* +- * udf_process_sequence +- * +- * PURPOSE +- * Process a main/reserve volume descriptor sequence. ++ * Process a main/reserve volume descriptor sequence. ++ * @block First block of first extent of the sequence. ++ * @lastblock Lastblock of first extent of the sequence. ++ * @fileset There we store extent containing root fileset + * +- * PRE-CONDITIONS +- * sb Pointer to _locked_ superblock. +- * block First block of first extent of the sequence. +- * lastblock Lastblock of first extent of the sequence. +- * +- * HISTORY +- * July 1, 1997 - Andrew E. Mileski +- * Written, tested, and released. ++ * Returns <0 on error, 0 on success. -EAGAIN is special - try next descriptor ++ * sequence + */ +-static noinline int udf_process_sequence(struct super_block *sb, long block, +- long lastblock, struct kernel_lb_addr *fileset) ++static noinline int udf_process_sequence( ++ struct super_block *sb, ++ sector_t block, sector_t lastblock, ++ struct kernel_lb_addr *fileset) + { + struct buffer_head *bh = NULL; + struct udf_vds_record vds[VDS_POS_LENGTH]; +@@ -1529,6 +1545,7 @@ + uint32_t vdsn; + uint16_t ident; + long next_s = 0, next_e = 0; ++ int ret; + + memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); + +@@ -1543,7 +1560,7 @@ + udf_err(sb, + "Block %llu of volume descriptor sequence is corrupted or we could not read it\n", + (unsigned long long)block); +- return 1; ++ return -EAGAIN; + } + + /* Process each descriptor (ISO 13346 3/8.3-8.4) */ +@@ -1616,14 +1633,19 @@ + */ + if (!vds[VDS_POS_PRIMARY_VOL_DESC].block) { + udf_err(sb, "Primary Volume Descriptor not found!\n"); +- return 1; ++ return -EAGAIN; ++ } ++ ret = udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block); ++ if (ret < 0) ++ return ret; ++ ++ if (vds[VDS_POS_LOGICAL_VOL_DESC].block) { ++ ret = udf_load_logicalvol(sb, ++ vds[VDS_POS_LOGICAL_VOL_DESC].block, ++ fileset); ++ if (ret < 0) ++ return ret; + } +- if (udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block)) +- return 1; +- +- if (vds[VDS_POS_LOGICAL_VOL_DESC].block && udf_load_logicalvol(sb, +- vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset)) +- return 1; + + if (vds[VDS_POS_PARTITION_DESC].block) { + /* +@@ -1632,19 +1654,27 @@ + */ + for (block = vds[VDS_POS_PARTITION_DESC].block; + block < vds[VDS_POS_TERMINATING_DESC].block; +- block++) +- if (udf_load_partdesc(sb, block)) +- return 1; ++ block++) { ++ ret = udf_load_partdesc(sb, block); ++ if (ret < 0) ++ return ret; ++ } + } + + return 0; + } + ++/* ++ * Load Volume Descriptor Sequence described by anchor in bh ++ * ++ * Returns <0 on error, 0 on success ++ */ + static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh, + struct kernel_lb_addr *fileset) + { + struct anchorVolDescPtr *anchor; +- long main_s, main_e, reserve_s, reserve_e; ++ sector_t main_s, main_e, reserve_s, reserve_e; ++ int ret; + + anchor = (struct anchorVolDescPtr *)bh->b_data; + +@@ -1662,18 +1692,26 @@ + + /* Process the main & reserve sequences */ + /* responsible for finding the PartitionDesc(s) */ +- if (!udf_process_sequence(sb, main_s, main_e, fileset)) +- return 1; ++ ret = udf_process_sequence(sb, main_s, main_e, fileset); ++ if (ret != -EAGAIN) ++ return ret; + udf_sb_free_partitions(sb); +- if (!udf_process_sequence(sb, reserve_s, reserve_e, fileset)) +- return 1; +- udf_sb_free_partitions(sb); +- return 0; ++ ret = udf_process_sequence(sb, reserve_s, reserve_e, fileset); ++ if (ret < 0) { ++ udf_sb_free_partitions(sb); ++ /* No sequence was OK, return -EIO */ ++ if (ret == -EAGAIN) ++ ret = -EIO; ++ } ++ return ret; + } + + /* + * Check whether there is an anchor block in the given block and + * load Volume Descriptor Sequence if so. ++ * ++ * Returns <0 on error, 0 on success, -EAGAIN is special - try next anchor ++ * block + */ + static int udf_check_anchor_block(struct super_block *sb, sector_t block, + struct kernel_lb_addr *fileset) +@@ -1685,33 +1723,40 @@ + if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && + udf_fixed_to_variable(block) >= + sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) +- return 0; ++ return -EAGAIN; + + bh = udf_read_tagged(sb, block, block, &ident); + if (!bh) +- return 0; ++ return -EAGAIN; + if (ident != TAG_IDENT_AVDP) { + brelse(bh); +- return 0; ++ return -EAGAIN; + } + ret = udf_load_sequence(sb, bh, fileset); + brelse(bh); + return ret; + } + +-/* Search for an anchor volume descriptor pointer */ +-static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock, +- struct kernel_lb_addr *fileset) ++/* ++ * Search for an anchor volume descriptor pointer. ++ * ++ * Returns < 0 on error, 0 on success. -EAGAIN is special - try next set ++ * of anchors. ++ */ ++static int udf_scan_anchors(struct super_block *sb, sector_t *lastblock, ++ struct kernel_lb_addr *fileset) + { + sector_t last[6]; + int i; + struct udf_sb_info *sbi = UDF_SB(sb); + int last_count = 0; ++ int ret; + + /* First try user provided anchor */ + if (sbi->s_anchor) { +- if (udf_check_anchor_block(sb, sbi->s_anchor, fileset)) +- return lastblock; ++ ret = udf_check_anchor_block(sb, sbi->s_anchor, fileset); ++ if (ret != -EAGAIN) ++ return ret; + } + /* + * according to spec, anchor is in either: +@@ -1720,39 +1765,46 @@ + * lastblock + * however, if the disc isn't closed, it could be 512. + */ +- if (udf_check_anchor_block(sb, sbi->s_session + 256, fileset)) +- return lastblock; ++ ret = udf_check_anchor_block(sb, sbi->s_session + 256, fileset); ++ if (ret != -EAGAIN) ++ return ret; + /* + * The trouble is which block is the last one. Drives often misreport + * this so we try various possibilities. + */ +- last[last_count++] = lastblock; +- if (lastblock >= 1) +- last[last_count++] = lastblock - 1; +- last[last_count++] = lastblock + 1; +- if (lastblock >= 2) +- last[last_count++] = lastblock - 2; +- if (lastblock >= 150) +- last[last_count++] = lastblock - 150; +- if (lastblock >= 152) +- last[last_count++] = lastblock - 152; ++ last[last_count++] = *lastblock; ++ if (*lastblock >= 1) ++ last[last_count++] = *lastblock - 1; ++ last[last_count++] = *lastblock + 1; ++ if (*lastblock >= 2) ++ last[last_count++] = *lastblock - 2; ++ if (*lastblock >= 150) ++ last[last_count++] = *lastblock - 150; ++ if (*lastblock >= 152) ++ last[last_count++] = *lastblock - 152; + + for (i = 0; i < last_count; i++) { + if (last[i] >= sb->s_bdev->bd_inode->i_size >> + sb->s_blocksize_bits) + continue; +- if (udf_check_anchor_block(sb, last[i], fileset)) +- return last[i]; ++ ret = udf_check_anchor_block(sb, last[i], fileset); ++ if (ret != -EAGAIN) { ++ if (!ret) ++ *lastblock = last[i]; ++ return ret; ++ } + if (last[i] < 256) + continue; +- if (udf_check_anchor_block(sb, last[i] - 256, fileset)) +- return last[i]; ++ ret = udf_check_anchor_block(sb, last[i] - 256, fileset); ++ if (ret != -EAGAIN) { ++ if (!ret) ++ *lastblock = last[i]; ++ return ret; ++ } + } + + /* Finally try block 512 in case media is open */ +- if (udf_check_anchor_block(sb, sbi->s_session + 512, fileset)) +- return last[0]; +- return 0; ++ return udf_check_anchor_block(sb, sbi->s_session + 512, fileset); + } + + /* +@@ -1760,54 +1812,59 @@ + * area specified by it. The function expects sbi->s_lastblock to be the last + * block on the media. + * +- * Return 1 if ok, 0 if not found. +- * ++ * Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor ++ * was not found. + */ + static int udf_find_anchor(struct super_block *sb, + struct kernel_lb_addr *fileset) + { +- sector_t lastblock; + struct udf_sb_info *sbi = UDF_SB(sb); ++ sector_t lastblock = sbi->s_last_block; ++ int ret; + +- lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset); +- if (lastblock) ++ ret = udf_scan_anchors(sb, &lastblock, fileset); ++ if (ret != -EAGAIN) + goto out; + + /* No anchor found? Try VARCONV conversion of block numbers */ + UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); ++ lastblock = udf_variable_to_fixed(sbi->s_last_block); + /* Firstly, we try to not convert number of the last block */ +- lastblock = udf_scan_anchors(sb, +- udf_variable_to_fixed(sbi->s_last_block), +- fileset); +- if (lastblock) ++ ret = udf_scan_anchors(sb, &lastblock, fileset); ++ if (ret != -EAGAIN) + goto out; + ++ lastblock = sbi->s_last_block; + /* Secondly, we try with converted number of the last block */ +- lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset); +- if (!lastblock) { ++ ret = udf_scan_anchors(sb, &lastblock, fileset); ++ if (ret < 0) { + /* VARCONV didn't help. Clear it. */ + UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); +- return 0; + } + out: +- sbi->s_last_block = lastblock; +- return 1; ++ if (ret == 0) ++ sbi->s_last_block = lastblock; ++ return ret; + } + + /* + * Check Volume Structure Descriptor, find Anchor block and load Volume +- * Descriptor Sequence ++ * Descriptor Sequence. ++ * ++ * Returns < 0 on error, 0 on success. -EAGAIN is special meaning anchor ++ * block was not found. + */ + static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, + int silent, struct kernel_lb_addr *fileset) + { + struct udf_sb_info *sbi = UDF_SB(sb); + loff_t nsr_off; ++ int ret; + + if (!sb_set_blocksize(sb, uopt->blocksize)) { + if (!silent) + udf_warn(sb, "Bad block size\n"); +- return 0; ++ return -EINVAL; + } + sbi->s_last_block = uopt->lastblock; + if (!uopt->novrs) { +@@ -1828,12 +1885,13 @@ + + /* Look for anchor block and load Volume Descriptor Sequence */ + sbi->s_anchor = uopt->anchor; +- if (!udf_find_anchor(sb, fileset)) { +- if (!silent) ++ ret = udf_find_anchor(sb, fileset); ++ if (ret < 0) { ++ if (!silent && ret == -EAGAIN) + udf_warn(sb, "No anchor found\n"); +- return 0; ++ return ret; + } +- return 1; ++ return 0; + } + + static void udf_open_lvid(struct super_block *sb) +@@ -1939,7 +1997,7 @@ + + static int udf_fill_super(struct super_block *sb, void *options, int silent) + { +- int ret; ++ int ret = -EINVAL; + struct inode *inode = NULL; + struct udf_options uopt; + struct kernel_lb_addr rootdir, fileset; +@@ -2011,7 +2069,7 @@ + } else { + uopt.blocksize = bdev_logical_block_size(sb->s_bdev); + ret = udf_load_vrs(sb, &uopt, silent, &fileset); +- if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { ++ if (ret == -EAGAIN && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { + if (!silent) + pr_notice("Rescanning with blocksize %d\n", + UDF_DEFAULT_BLOCKSIZE); +@@ -2021,8 +2079,11 @@ + ret = udf_load_vrs(sb, &uopt, silent, &fileset); + } + } +- if (!ret) { +- udf_warn(sb, "No partition found (1)\n"); ++ if (ret < 0) { ++ if (ret == -EAGAIN) { ++ udf_warn(sb, "No partition found (1)\n"); ++ ret = -EINVAL; ++ } + goto error_out; + } + +@@ -2040,6 +2101,7 @@ + udf_err(sb, "minUDFReadRev=%x (max is %x)\n", + le16_to_cpu(lvidiu->minUDFReadRev), + UDF_MAX_READ_VERSION); ++ ret = -EINVAL; + goto error_out; + } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) + sb->s_flags |= MS_RDONLY; +@@ -2054,6 +2116,7 @@ + + if (!sbi->s_partitions) { + udf_warn(sb, "No partition found (2)\n"); ++ ret = -EINVAL; + goto error_out; + } + +@@ -2065,6 +2128,7 @@ + + if (udf_find_fileset(sb, &fileset, &rootdir)) { + udf_warn(sb, "No fileset found\n"); ++ ret = -EINVAL; + goto error_out; + } + +@@ -2086,6 +2150,7 @@ + if (!inode) { + udf_err(sb, "Error in udf_iget, block=%d, partition=%d\n", + rootdir.logicalBlockNum, rootdir.partitionReferenceNum); ++ ret = -EIO; + goto error_out; + } + +@@ -2093,6 +2158,7 @@ + sb->s_root = d_make_root(inode); + if (!sb->s_root) { + udf_err(sb, "Couldn't allocate root dentry\n"); ++ ret = -ENOMEM; + goto error_out; + } + sb->s_maxbytes = MAX_LFS_FILESIZE; +@@ -2113,7 +2179,7 @@ + kfree(sbi); + sb->s_fs_info = NULL; + +- return -EINVAL; ++ return ret; + } + + void _udf_err(struct super_block *sb, const char *function, +Index: linux-3.10-3.10.11/dummy/rpi_1195_66ccf96185266dee7b0b15ae08e9c1359e0e1c47.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1195_66ccf96185266dee7b0b15ae08e9c1359e0e1c47.txt 2014-05-05 12:45:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1196_39b79aa3f1554bb1e39be3b25d6c12fd429583d4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1196_39b79aa3f1554bb1e39be3b25d6c12fd429583d4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1196_39b79aa3f1554bb1e39be3b25d6c12fd429583d4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1196_39b79aa3f1554bb1e39be3b25d6c12fd429583d4.patch 2014-05-05 12:45:52.000000000 +0000 @@ -0,0 +1,114 @@ +commit 39b79aa3f1554bb1e39be3b25d6c12fd429583d4 +Author: Jan Kara +Date: Thu Jul 25 16:15:16 2013 +0200 + + udf: Refuse RW mount of the filesystem instead of making it RO + + commit e729eac6f65e11c5f03b09adcc84bd5bcb230467 upstream. + + Refuse RW mount of udf filesystem. So far we just silently changed it + to RO mount but when the media is writeable, block layer won't notice + this change and thus will think device is used RW and will block eject + button of the drive. That is unexpected by users because for + non-writeable media eject button works just fine. + + Userspace mount(8) command handles this just fine and retries mounting + with MS_RDONLY set so userspace shouldn't see any regression. Plus any + tool mounting udf is likely confronted with the case of read-only + media where block layer already refuses to mount the filesystem without + MS_RDONLY set so our behavior shouldn't be anything new for it. + + Reported-by: Hui Wang + Signed-off-by: Jan Kara + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/udf/super.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/udf/super.c 2014-05-05 12:45:50.000000000 +0000 ++++ linux-3.10-3.10.11/fs/udf/super.c 2014-05-05 12:45:51.000000000 +0000 +@@ -630,6 +630,12 @@ + struct udf_sb_info *sbi = UDF_SB(sb); + int error = 0; + ++ if (sbi->s_lvid_bh) { ++ int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); ++ if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY)) ++ return -EACCES; ++ } ++ + uopt.flags = sbi->s_flags; + uopt.uid = sbi->s_uid; + uopt.gid = sbi->s_gid; +@@ -649,12 +655,6 @@ + sbi->s_dmode = uopt.dmode; + write_unlock(&sbi->s_cred_lock); + +- if (sbi->s_lvid_bh) { +- int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); +- if (write_rev > UDF_MAX_WRITE_VERSION) +- *flags |= MS_RDONLY; +- } +- + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + goto out_unlock; + +@@ -1284,16 +1284,18 @@ + goto out_bh; + } + } else { ++ /* ++ * If we have a partition with virtual map, we don't handle ++ * writing to it (we overwrite blocks instead of relocating ++ * them). ++ */ ++ if (!(sb->s_flags & MS_RDONLY)) { ++ ret = -EACCES; ++ goto out_bh; ++ } + ret = udf_load_vat(sb, i, type1_idx); + if (ret < 0) + goto out_bh; +- /* +- * Mark filesystem read-only if we have a partition with +- * virtual map since we don't handle writing to it (we +- * overwrite blocks instead of relocating them). +- */ +- sb->s_flags |= MS_RDONLY; +- pr_notice("Filesystem marked read-only because writing to pseudooverwrite partition is not implemented\n"); + } + ret = 0; + out_bh: +@@ -2103,8 +2105,11 @@ + UDF_MAX_READ_VERSION); + ret = -EINVAL; + goto error_out; +- } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) +- sb->s_flags |= MS_RDONLY; ++ } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION && ++ !(sb->s_flags & MS_RDONLY)) { ++ ret = -EACCES; ++ goto error_out; ++ } + + sbi->s_udfrev = minUDFWriteRev; + +@@ -2121,9 +2126,10 @@ + } + + if (sbi->s_partmaps[sbi->s_partition].s_partition_flags & +- UDF_PART_FLAG_READ_ONLY) { +- pr_notice("Partition marked readonly; forcing readonly mount\n"); +- sb->s_flags |= MS_RDONLY; ++ UDF_PART_FLAG_READ_ONLY && ++ !(sb->s_flags & MS_RDONLY)) { ++ ret = -EACCES; ++ goto error_out; + } + + if (udf_find_fileset(sb, &fileset, &rootdir)) { +Index: linux-3.10-3.10.11/dummy/rpi_1196_39b79aa3f1554bb1e39be3b25d6c12fd429583d4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1196_39b79aa3f1554bb1e39be3b25d6c12fd429583d4.txt 2014-05-05 12:45:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1197_3ed3690eac0c839c6216fd7f7ce0add6a1f593b2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1197_3ed3690eac0c839c6216fd7f7ce0add6a1f593b2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1197_3ed3690eac0c839c6216fd7f7ce0add6a1f593b2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1197_3ed3690eac0c839c6216fd7f7ce0add6a1f593b2.patch 2014-05-05 12:45:53.000000000 +0000 @@ -0,0 +1,51 @@ +commit 3ed3690eac0c839c6216fd7f7ce0add6a1f593b2 +Author: Konstantin Khlebnikov +Date: Tue Sep 24 15:27:42 2013 -0700 + + audit: fix endless wait in audit_log_start() + + commit 8ac1c8d5deba65513b6a82c35e89e73996c8e0d6 upstream. + + After commit 829199197a43 ("kernel/audit.c: avoid negative sleep + durations") audit emitters will block forever if userspace daemon cannot + handle backlog. + + After the timeout the waiting loop turns into busy loop and runs until + daemon dies or returns back to work. This is a minimal patch for that + bug. + + Signed-off-by: Konstantin Khlebnikov + Cc: Luiz Capitulino + Cc: Richard Guy Briggs + Cc: Eric Paris + Cc: Chuck Anderson + Cc: Dan Duval + Cc: Dave Kleikamp + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/audit.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/audit.c 2014-05-05 11:50:53.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/audit.c 2014-05-05 12:45:52.000000000 +0000 +@@ -1117,9 +1117,10 @@ + + sleep_time = timeout_start + audit_backlog_wait_time - + jiffies; +- if ((long)sleep_time > 0) ++ if ((long)sleep_time > 0) { + wait_for_auditd(sleep_time); +- continue; ++ continue; ++ } + } + if (audit_rate_check() && printk_ratelimit()) + printk(KERN_WARNING +Index: linux-3.10-3.10.11/dummy/rpi_1197_3ed3690eac0c839c6216fd7f7ce0add6a1f593b2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1197_3ed3690eac0c839c6216fd7f7ce0add6a1f593b2.txt 2014-05-05 12:45:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1198_09642082b35034719f6916ee83b0a6251620ba74.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1198_09642082b35034719f6916ee83b0a6251620ba74.patch --- linux-3.10.11/debian/patches/rpi/rpi_1198_09642082b35034719f6916ee83b0a6251620ba74.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1198_09642082b35034719f6916ee83b0a6251620ba74.patch 2014-05-05 12:45:53.000000000 +0000 @@ -0,0 +1,180 @@ +commit 09642082b35034719f6916ee83b0a6251620ba74 +Author: Khalid Aziz +Date: Wed Sep 11 14:22:20 2013 -0700 + + mm: fix aio performance regression for database caused by THP + + commit 7cb2ef56e6a8b7b368b2e883a0a47d02fed66911 upstream. + + I am working with a tool that simulates oracle database I/O workload. + This tool (orion to be specific - + ) + allocates hugetlbfs pages using shmget() with SHM_HUGETLB flag. It then + does aio into these pages from flash disks using various common block + sizes used by database. I am looking at performance with two of the most + common block sizes - 1M and 64K. aio performance with these two block + sizes plunged after Transparent HugePages was introduced in the kernel. + Here are performance numbers: + + pre-THP 2.6.39 3.11-rc5 + 1M read 8384 MB/s 5629 MB/s 6501 MB/s + 64K read 7867 MB/s 4576 MB/s 4251 MB/s + + I have narrowed the performance impact down to the overheads introduced by + THP in __get_page_tail() and put_compound_page() routines. perf top shows + >40% of cycles being spent in these two routines. Every time direct I/O + to hugetlbfs pages starts, kernel calls get_page() to grab a reference to + the pages and calls put_page() when I/O completes to put the reference + away. THP introduced significant amount of locking overhead to get_page() + and put_page() when dealing with compound pages because hugepages can be + split underneath get_page() and put_page(). It added this overhead + irrespective of whether it is dealing with hugetlbfs pages or transparent + hugepages. This resulted in 20%-45% drop in aio performance when using + hugetlbfs pages. + + Since hugetlbfs pages can not be split, there is no reason to go through + all the locking overhead for these pages from what I can see. I added + code to __get_page_tail() and put_compound_page() to bypass all the + locking code when working with hugetlbfs pages. This improved performance + significantly. Performance numbers with this patch: + + pre-THP 3.11-rc5 3.11-rc5 + Patch + 1M read 8384 MB/s 6501 MB/s 8371 MB/s + 64K read 7867 MB/s 4251 MB/s 6510 MB/s + + Performance with 64K read is still lower than what it was before THP, but + still a 53% improvement. It does mean there is more work to be done but I + will take a 53% improvement for now. + + Please take a look at the following patch and let me know if it looks + reasonable. + + [akpm@linux-foundation.org: tweak comments] + Signed-off-by: Khalid Aziz + Cc: Pravin B Shelar + Cc: Christoph Lameter + Cc: Andrea Arcangeli + Cc: Johannes Weiner + Cc: Mel Gorman + Cc: Rik van Riel + Cc: Minchan Kim + Cc: Andi Kleen + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/swap.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/swap.c 2014-05-05 11:50:53.000000000 +0000 ++++ linux-3.10-3.10.11/mm/swap.c 2014-05-05 12:45:53.000000000 +0000 +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "internal.h" + +@@ -78,6 +79,19 @@ + + static void put_compound_page(struct page *page) + { ++ /* ++ * hugetlbfs pages cannot be split from under us. If this is a ++ * hugetlbfs page, check refcount on head page and release the page if ++ * the refcount becomes zero. ++ */ ++ if (PageHuge(page)) { ++ page = compound_head(page); ++ if (put_page_testzero(page)) ++ __put_compound_page(page); ++ ++ return; ++ } ++ + if (unlikely(PageTail(page))) { + /* __split_huge_page_refcount can run under us */ + struct page *page_head = compound_trans_head(page); +@@ -181,38 +195,51 @@ + * proper PT lock that already serializes against + * split_huge_page(). + */ +- unsigned long flags; + bool got = false; +- struct page *page_head = compound_trans_head(page); ++ struct page *page_head; + +- if (likely(page != page_head && get_page_unless_zero(page_head))) { ++ /* ++ * If this is a hugetlbfs page it cannot be split under us. Simply ++ * increment refcount for the head page. ++ */ ++ if (PageHuge(page)) { ++ page_head = compound_head(page); ++ atomic_inc(&page_head->_count); ++ got = true; ++ } else { ++ unsigned long flags; ++ ++ page_head = compound_trans_head(page); ++ if (likely(page != page_head && ++ get_page_unless_zero(page_head))) { ++ ++ /* Ref to put_compound_page() comment. */ ++ if (PageSlab(page_head)) { ++ if (likely(PageTail(page))) { ++ __get_page_tail_foll(page, false); ++ return true; ++ } else { ++ put_page(page_head); ++ return false; ++ } ++ } + +- /* Ref to put_compound_page() comment. */ +- if (PageSlab(page_head)) { ++ /* ++ * page_head wasn't a dangling pointer but it ++ * may not be a head page anymore by the time ++ * we obtain the lock. That is ok as long as it ++ * can't be freed from under us. ++ */ ++ flags = compound_lock_irqsave(page_head); ++ /* here __split_huge_page_refcount won't run anymore */ + if (likely(PageTail(page))) { + __get_page_tail_foll(page, false); +- return true; +- } else { +- put_page(page_head); +- return false; ++ got = true; + } ++ compound_unlock_irqrestore(page_head, flags); ++ if (unlikely(!got)) ++ put_page(page_head); + } +- +- /* +- * page_head wasn't a dangling pointer but it +- * may not be a head page anymore by the time +- * we obtain the lock. That is ok as long as it +- * can't be freed from under us. +- */ +- flags = compound_lock_irqsave(page_head); +- /* here __split_huge_page_refcount won't run anymore */ +- if (likely(PageTail(page))) { +- __get_page_tail_foll(page, false); +- got = true; +- } +- compound_unlock_irqrestore(page_head, flags); +- if (unlikely(!got)) +- put_page(page_head); + } + return got; + } +Index: linux-3.10-3.10.11/dummy/rpi_1198_09642082b35034719f6916ee83b0a6251620ba74.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1198_09642082b35034719f6916ee83b0a6251620ba74.txt 2014-05-05 12:45:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1199_71828ed93986ea0f89c0daf739e13aadb870a3ef.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1199_71828ed93986ea0f89c0daf739e13aadb870a3ef.patch --- linux-3.10.11/debian/patches/rpi/rpi_1199_71828ed93986ea0f89c0daf739e13aadb870a3ef.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1199_71828ed93986ea0f89c0daf739e13aadb870a3ef.patch 2014-05-05 12:45:54.000000000 +0000 @@ -0,0 +1,36 @@ +commit 71828ed93986ea0f89c0daf739e13aadb870a3ef +Author: Andi Kleen +Date: Wed Apr 24 17:03:02 2013 -0700 + + perf tools: Handle JITed code in shared memory + + commit 89365e6c9ad4c0e090e4c6a4b67a3ce319381d89 upstream. + + Need to check for /dev/zero. + + Most likely more strings are missing too. + + Signed-off-by: Andi Kleen + Link: http://lkml.kernel.org/r/1366848182-30449-1-git-send-email-andi@firstfloor.org + Signed-off-by: Arnaldo Carvalho de Melo + Cc: Vinson Lee + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/tools/perf/util/map.c +=================================================================== +--- linux-3.10-3.10.11.orig/tools/perf/util/map.c 2014-05-05 11:50:52.000000000 +0000 ++++ linux-3.10-3.10.11/tools/perf/util/map.c 2014-05-05 12:45:54.000000000 +0000 +@@ -21,6 +21,7 @@ + static inline int is_anon_memory(const char *filename) + { + return !strcmp(filename, "//anon") || ++ !strcmp(filename, "/dev/zero (deleted)") || + !strcmp(filename, "/anon_hugepage (deleted)"); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1199_71828ed93986ea0f89c0daf739e13aadb870a3ef.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1199_71828ed93986ea0f89c0daf739e13aadb870a3ef.txt 2014-05-05 12:45:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1200_edc96e2c36766db781313a53ba130e52e74d3296.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1200_edc96e2c36766db781313a53ba130e52e74d3296.patch --- linux-3.10.11/debian/patches/rpi/rpi_1200_edc96e2c36766db781313a53ba130e52e74d3296.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1200_edc96e2c36766db781313a53ba130e52e74d3296.patch 2014-05-05 12:45:55.000000000 +0000 @@ -0,0 +1,38 @@ +commit edc96e2c36766db781313a53ba130e52e74d3296 +Author: Bjorn Helgaas +Date: Wed May 29 16:29:55 2013 -0600 + + bio-integrity: Fix use of bs->bio_integrity_pool after free + + commit adbe6991efd36104ac9eaf751993d35eaa7f493a upstream. + + This fixes a copy and paste error introduced by 9f060e2231 + ("block: Convert integrity to bvec_alloc_bs()"). + + Found by Coverity (CID 1020654). + + Signed-off-by: Bjorn Helgaas + Acked-by: Kent Overstreet + Signed-off-by: Jens Axboe + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/bio-integrity.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/bio-integrity.c 2014-05-05 11:50:52.000000000 +0000 ++++ linux-3.10-3.10.11/fs/bio-integrity.c 2014-05-05 12:45:55.000000000 +0000 +@@ -734,7 +734,7 @@ + mempool_destroy(bs->bio_integrity_pool); + + if (bs->bvec_integrity_pool) +- mempool_destroy(bs->bio_integrity_pool); ++ mempool_destroy(bs->bvec_integrity_pool); + } + EXPORT_SYMBOL(bioset_integrity_free); + +Index: linux-3.10-3.10.11/dummy/rpi_1200_edc96e2c36766db781313a53ba130e52e74d3296.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1200_edc96e2c36766db781313a53ba130e52e74d3296.txt 2014-05-05 12:45:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1201_85f58908c038a5e1f51fb9014f0b0954f66be1d4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1201_85f58908c038a5e1f51fb9014f0b0954f66be1d4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1201_85f58908c038a5e1f51fb9014f0b0954f66be1d4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1201_85f58908c038a5e1f51fb9014f0b0954f66be1d4.patch 2014-05-05 12:45:56.000000000 +0000 @@ -0,0 +1,40 @@ +commit 85f58908c038a5e1f51fb9014f0b0954f66be1d4 +Author: Anatol Pomozov +Date: Sun Sep 22 12:43:47 2013 -0600 + + cfq: explicitly use 64bit divide operation for 64bit arguments + + commit f3cff25f05f2ac29b2ee355e611b0657482f6f1d upstream. + + 'samples' is 64bit operant, but do_div() second parameter is 32. + do_div silently truncates high 32 bits and calculated result + is invalid. + + In case if low 32bit of 'samples' are zeros then do_div() produces + kernel crash. + + Signed-off-by: Anatol Pomozov + Acked-by: Tejun Heo + Signed-off-by: Jens Axboe + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/block/cfq-iosched.c +=================================================================== +--- linux-3.10-3.10.11.orig/block/cfq-iosched.c 2014-05-05 11:50:52.000000000 +0000 ++++ linux-3.10-3.10.11/block/cfq-iosched.c 2014-05-05 12:45:55.000000000 +0000 +@@ -1803,7 +1803,7 @@ + + if (samples) { + v = blkg_stat_read(&cfqg->stats.avg_queue_size_sum); +- do_div(v, samples); ++ v = div64_u64(v, samples); + } + __blkg_prfill_u64(sf, pd, v); + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1201_85f58908c038a5e1f51fb9014f0b0954f66be1d4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1201_85f58908c038a5e1f51fb9014f0b0954f66be1d4.txt 2014-05-05 12:45:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1202_d68b9c457e6298e941b8b574f921624c6c648218.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1202_d68b9c457e6298e941b8b574f921624c6c648218.patch --- linux-3.10.11/debian/patches/rpi/rpi_1202_d68b9c457e6298e941b8b574f921624c6c648218.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1202_d68b9c457e6298e941b8b574f921624c6c648218.patch 2014-05-05 12:45:57.000000000 +0000 @@ -0,0 +1,111 @@ +commit d68b9c457e6298e941b8b574f921624c6c648218 +Author: J. Bruce Fields +Date: Wed Aug 21 10:32:52 2013 -0400 + + rpc: clean up decoding of gssproxy linux creds + + commit 778e512bb1d3315c6b55832248cd30c566c081d7 upstream. + + We can use the normal coding infrastructure here. + + Two minor behavior changes: + + - we're assuming no wasted space at the end of the linux cred. + That seems to match gss-proxy's behavior, and I can't see why + it would need to do differently in the future. + + - NGROUPS_MAX check added: note groups_alloc doesn't do this, + this is the caller's responsibility. + + Tested-by: Simo Sorce + Signed-off-by: J. Bruce Fields + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sunrpc/auth_gss/gss_rpc_xdr.c 2014-05-05 11:50:51.000000000 +0000 ++++ linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.c 2014-05-05 12:45:56.000000000 +0000 +@@ -166,14 +166,14 @@ + return 0; + } + +-static int get_s32(void **p, void *max, s32 *res) ++static int get_s32(struct xdr_stream *xdr, s32 *res) + { +- void *base = *p; +- void *next = (void *)((char *)base + sizeof(s32)); +- if (unlikely(next > max || next < base)) ++ __be32 *p; ++ ++ p = xdr_inline_decode(xdr, 4); ++ if (!p) + return -EINVAL; +- memcpy(res, base, sizeof(s32)); +- *p = next; ++ memcpy(res, p, sizeof(s32)); + return 0; + } + +@@ -182,7 +182,6 @@ + { + u32 length; + __be32 *p; +- void *q, *end; + s32 tmp; + int N, i, err; + +@@ -192,33 +191,28 @@ + + length = be32_to_cpup(p); + +- /* FIXME: we do not want to use the scratch buffer for this one +- * may need to use functions that allows us to access an io vector +- * directly */ +- p = xdr_inline_decode(xdr, length); +- if (unlikely(p == NULL)) ++ if (length > (3 + NGROUPS_MAX) * sizeof(u32)) + return -ENOSPC; + +- q = p; +- end = q + length; +- + /* uid */ +- err = get_s32(&q, end, &tmp); ++ err = get_s32(xdr, &tmp); + if (err) + return err; + creds->cr_uid = make_kuid(&init_user_ns, tmp); + + /* gid */ +- err = get_s32(&q, end, &tmp); ++ err = get_s32(xdr, &tmp); + if (err) + return err; + creds->cr_gid = make_kgid(&init_user_ns, tmp); + + /* number of additional gid's */ +- err = get_s32(&q, end, &tmp); ++ err = get_s32(xdr, &tmp); + if (err) + return err; + N = tmp; ++ if ((3 + N) * sizeof(u32) != length) ++ return -EINVAL; + creds->cr_group_info = groups_alloc(N); + if (creds->cr_group_info == NULL) + return -ENOMEM; +@@ -226,7 +220,7 @@ + /* gid's */ + for (i = 0; i < N; i++) { + kgid_t kgid; +- err = get_s32(&q, end, &tmp); ++ err = get_s32(xdr, &tmp); + if (err) + goto out_free_groups; + err = -EINVAL; +Index: linux-3.10-3.10.11/dummy/rpi_1202_d68b9c457e6298e941b8b574f921624c6c648218.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1202_d68b9c457e6298e941b8b574f921624c6c648218.txt 2014-05-05 12:45:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1203_577e9397bcfaa293bb8de0e619fe93f69bf992b9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1203_577e9397bcfaa293bb8de0e619fe93f69bf992b9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1203_577e9397bcfaa293bb8de0e619fe93f69bf992b9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1203_577e9397bcfaa293bb8de0e619fe93f69bf992b9.patch 2014-05-05 12:45:58.000000000 +0000 @@ -0,0 +1,91 @@ +commit 577e9397bcfaa293bb8de0e619fe93f69bf992b9 +Author: J. Bruce Fields +Date: Fri Aug 23 11:17:53 2013 -0400 + + rpc: comment on linux_cred encoding, treat all as unsigned + + commit 6a36978e6931e6601be586eb313375335f2cfaa3 upstream. + + The encoding of linux creds is a bit confusing. + + Also: I think in practice it doesn't really matter whether we treat any + of these things as signed or unsigned, but unsigned seems more + straightforward: uid_t/gid_t are unsigned and it simplifies the ngroups + overflow check. + + Tested-by: Simo Sorce + Signed-off-by: J. Bruce Fields + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sunrpc/auth_gss/gss_rpc_xdr.c 2014-05-05 12:45:56.000000000 +0000 ++++ linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.c 2014-05-05 12:45:57.000000000 +0000 +@@ -166,14 +166,15 @@ + return 0; + } + +-static int get_s32(struct xdr_stream *xdr, s32 *res) ++static int get_host_u32(struct xdr_stream *xdr, u32 *res) + { + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (!p) + return -EINVAL; +- memcpy(res, p, sizeof(s32)); ++ /* Contents of linux creds are all host-endian: */ ++ memcpy(res, p, sizeof(u32)); + return 0; + } + +@@ -182,8 +183,9 @@ + { + u32 length; + __be32 *p; +- s32 tmp; +- int N, i, err; ++ u32 tmp; ++ u32 N; ++ int i, err; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) +@@ -195,19 +197,19 @@ + return -ENOSPC; + + /* uid */ +- err = get_s32(xdr, &tmp); ++ err = get_host_u32(xdr, &tmp); + if (err) + return err; + creds->cr_uid = make_kuid(&init_user_ns, tmp); + + /* gid */ +- err = get_s32(xdr, &tmp); ++ err = get_host_u32(xdr, &tmp); + if (err) + return err; + creds->cr_gid = make_kgid(&init_user_ns, tmp); + + /* number of additional gid's */ +- err = get_s32(xdr, &tmp); ++ err = get_host_u32(xdr, &tmp); + if (err) + return err; + N = tmp; +@@ -220,7 +222,7 @@ + /* gid's */ + for (i = 0; i < N; i++) { + kgid_t kgid; +- err = get_s32(xdr, &tmp); ++ err = get_host_u32(xdr, &tmp); + if (err) + goto out_free_groups; + err = -EINVAL; +Index: linux-3.10-3.10.11/dummy/rpi_1203_577e9397bcfaa293bb8de0e619fe93f69bf992b9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1203_577e9397bcfaa293bb8de0e619fe93f69bf992b9.txt 2014-05-05 12:45:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1204_fea655196e39b35ef0d6c5a6372edb53315031db.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1204_fea655196e39b35ef0d6c5a6372edb53315031db.patch --- linux-3.10.11/debian/patches/rpi/rpi_1204_fea655196e39b35ef0d6c5a6372edb53315031db.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1204_fea655196e39b35ef0d6c5a6372edb53315031db.patch 2014-05-05 12:45:59.000000000 +0000 @@ -0,0 +1,112 @@ +commit fea655196e39b35ef0d6c5a6372edb53315031db +Author: J. Bruce Fields +Date: Tue Aug 20 18:13:27 2013 -0400 + + rpc: fix huge kmalloc's in gss-proxy + + commit 9dfd87da1aeb0fd364167ad199f40fe96a6a87be upstream. + + The reply to a gssproxy can include up to NGROUPS_MAX gid's, which will + take up more than a page. We therefore need to allocate an array of + pages to hold the reply instead of trying to allocate a single huge + buffer. + + Tested-by: Simo Sorce + Signed-off-by: J. Bruce Fields + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_upcall.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sunrpc/auth_gss/gss_rpc_upcall.c 2014-05-05 11:50:51.000000000 +0000 ++++ linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_upcall.c 2014-05-05 12:45:58.000000000 +0000 +@@ -213,6 +213,30 @@ + return status; + } + ++static void gssp_free_receive_pages(struct gssx_arg_accept_sec_context *arg) ++{ ++ int i; ++ ++ for (i = 0; i < arg->npages && arg->pages[i]; i++) ++ __free_page(arg->pages[i]); ++} ++ ++static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) ++{ ++ int i; ++ ++ arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE); ++ arg->pages = kzalloc(arg->npages * sizeof(struct page *), GFP_KERNEL); ++ ++ for (i=0; i < arg->npages; i++) { ++ arg->pages[i] = alloc_page(GFP_KERNEL); ++ if (arg->pages[i] == NULL) { ++ gssp_free_receive_pages(arg); ++ return -ENOMEM; ++ } ++ } ++ return 0; ++} + + /* + * Public functions +@@ -261,10 +285,16 @@ + arg.context_handle = &ctxh; + res.output_token->len = GSSX_max_output_token_sz; + ++ ret = gssp_alloc_receive_pages(&arg); ++ if (ret) ++ return ret; ++ + /* use nfs/ for targ_name ? */ + + ret = gssp_call(net, &msg); + ++ gssp_free_receive_pages(&arg); ++ + /* we need to fetch all data even in case of error so + * that we can free special strctures is they have been allocated */ + data->major_status = res.status.major_status; +Index: linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sunrpc/auth_gss/gss_rpc_xdr.c 2014-05-05 12:45:57.000000000 +0000 ++++ linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.c 2014-05-05 12:45:58.000000000 +0000 +@@ -780,6 +780,9 @@ + /* arg->options */ + err = dummy_enc_opt_array(xdr, &arg->options); + ++ xdr_inline_pages(&req->rq_rcv_buf, ++ PAGE_SIZE/2 /* pretty arbitrary */, ++ arg->pages, 0 /* page base */, arg->npages * PAGE_SIZE); + done: + if (err) + dprintk("RPC: gssx_enc_accept_sec_context: %d\n", err); +Index: linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.h +=================================================================== +--- linux-3.10-3.10.11.orig/net/sunrpc/auth_gss/gss_rpc_xdr.h 2014-05-05 11:50:51.000000000 +0000 ++++ linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_xdr.h 2014-05-05 12:45:58.000000000 +0000 +@@ -147,6 +147,8 @@ + struct gssx_cb *input_cb; + u32 ret_deleg_cred; + struct gssx_option_array options; ++ struct page **pages; ++ unsigned int npages; + }; + + struct gssx_res_accept_sec_context { +@@ -240,7 +242,8 @@ + 2 * GSSX_max_princ_sz + \ + 8 + 8 + 4 + 4 + 4) + #define GSSX_max_output_token_sz 1024 +-#define GSSX_max_creds_sz (4 + 4 + 4 + NGROUPS_MAX * 4) ++/* grouplist not included; we allocate separate pages for that: */ ++#define GSSX_max_creds_sz (4 + 4 + 4 /* + NGROUPS_MAX*4 */) + #define GSSX_RES_accept_sec_context_sz (GSSX_default_status_sz + \ + GSSX_default_ctx_sz + \ + GSSX_max_output_token_sz + \ +Index: linux-3.10-3.10.11/dummy/rpi_1204_fea655196e39b35ef0d6c5a6372edb53315031db.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1204_fea655196e39b35ef0d6c5a6372edb53315031db.txt 2014-05-05 12:45:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1205_ab2b9429c40a4083d675e15d79dc34f363096235.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1205_ab2b9429c40a4083d675e15d79dc34f363096235.patch --- linux-3.10.11/debian/patches/rpi/rpi_1205_ab2b9429c40a4083d675e15d79dc34f363096235.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1205_ab2b9429c40a4083d675e15d79dc34f363096235.patch 2014-05-05 12:45:59.000000000 +0000 @@ -0,0 +1,53 @@ +commit ab2b9429c40a4083d675e15d79dc34f363096235 +Author: J. Bruce Fields +Date: Fri Aug 23 17:26:28 2013 -0400 + + rpc: let xdr layer allocate gssproxy receieve pages + + commit d4a516560fc96a9d486a9939bcb567e3fdce8f49 upstream. + + In theory the linux cred in a gssproxy reply can include up to + NGROUPS_MAX data, 256K of data. In the common case we expect it to be + shorter. So do as the nfsv3 ACL code does and let the xdr code allocate + the pages as they come in, instead of allocating a lot of pages that + won't typically be used. + + Tested-by: Simo Sorce + Signed-off-by: J. Bruce Fields + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_upcall.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sunrpc/auth_gss/gss_rpc_upcall.c 2014-05-05 12:45:58.000000000 +0000 ++++ linux-3.10-3.10.11/net/sunrpc/auth_gss/gss_rpc_upcall.c 2014-05-05 12:45:59.000000000 +0000 +@@ -223,18 +223,14 @@ + + static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) + { +- int i; +- + arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE); + arg->pages = kzalloc(arg->npages * sizeof(struct page *), GFP_KERNEL); +- +- for (i=0; i < arg->npages; i++) { +- arg->pages[i] = alloc_page(GFP_KERNEL); +- if (arg->pages[i] == NULL) { +- gssp_free_receive_pages(arg); +- return -ENOMEM; +- } +- } ++ /* ++ * XXX: actual pages are allocated by xdr layer in ++ * xdr_partial_copy_from_skb. ++ */ ++ if (!arg->pages) ++ return -ENOMEM; + return 0; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1205_ab2b9429c40a4083d675e15d79dc34f363096235.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1205_ab2b9429c40a4083d675e15d79dc34f363096235.txt 2014-05-05 12:45:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1206_97d2a12a277626098d6a001db1166447f86998d4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1206_97d2a12a277626098d6a001db1166447f86998d4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1206_97d2a12a277626098d6a001db1166447f86998d4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1206_97d2a12a277626098d6a001db1166447f86998d4.patch 2014-05-05 12:46:00.000000000 +0000 @@ -0,0 +1,76 @@ +commit 97d2a12a277626098d6a001db1166447f86998d4 +Author: Oliver Smith +Date: Mon Sep 16 20:30:57 2013 +0200 + + netfilter: ipset: Fix serious failure in CIDR tracking + + commit 2cf55125c64d64cc106e204d53b107094762dfdf upstream. + + This fixes a serious bug affecting all hash types with a net element - + specifically, if a CIDR value is deleted such that none of the same size + exist any more, all larger (less-specific) values will then fail to + match. Adding back any prefix with a CIDR equal to or more specific than + the one deleted will fix it. + + Steps to reproduce: + ipset -N test hash:net + ipset -A test 1.1.0.0/16 + ipset -A test 2.2.2.0/24 + ipset -T test 1.1.1.1 #1.1.1.1 IS in set + ipset -D test 2.2.2.0/24 + ipset -T test 1.1.1.1 #1.1.1.1 IS NOT in set + + This is due to the fact that the nets counter was unconditionally + decremented prior to the iteration that shifts up the entries. Now, we + first check if there is a proceeding entry and if not, decrement it and + return. Otherwise, we proceed to iterate and then zero the last element, + which, in most cases, will already be zero. + + Signed-off-by: Oliver Smith + Signed-off-by: Jozsef Kadlecsik + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/netfilter/ipset/ip_set_hash_gen.h +=================================================================== +--- linux-3.10-3.10.11.orig/net/netfilter/ipset/ip_set_hash_gen.h 2014-05-05 11:50:50.000000000 +0000 ++++ linux-3.10-3.10.11/net/netfilter/ipset/ip_set_hash_gen.h 2014-05-05 12:46:00.000000000 +0000 +@@ -325,18 +325,22 @@ + static void + mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length) + { +- u8 i, j; ++ u8 i, j, net_end = nets_length - 1; + +- for (i = 0; i < nets_length - 1 && h->nets[i].cidr != cidr; i++) +- ; +- h->nets[i].nets--; +- +- if (h->nets[i].nets != 0) +- return; +- +- for (j = i; j < nets_length - 1 && h->nets[j].nets; j++) { +- h->nets[j].cidr = h->nets[j + 1].cidr; +- h->nets[j].nets = h->nets[j + 1].nets; ++ for (i = 0; i < nets_length; i++) { ++ if (h->nets[i].cidr != cidr) ++ continue; ++ if (h->nets[i].nets > 1 || i == net_end || ++ h->nets[i + 1].nets == 0) { ++ h->nets[i].nets--; ++ return; ++ } ++ for (j = i; j < net_end && h->nets[j].nets; j++) { ++ h->nets[j].cidr = h->nets[j + 1].cidr; ++ h->nets[j].nets = h->nets[j + 1].nets; ++ } ++ h->nets[j].nets = 0; ++ return; + } + } + #endif +Index: linux-3.10-3.10.11/dummy/rpi_1206_97d2a12a277626098d6a001db1166447f86998d4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1206_97d2a12a277626098d6a001db1166447f86998d4.txt 2014-05-05 12:46:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1207_8c15abc94c737f9120d3d4a550abbcbb9be121f6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1207_8c15abc94c737f9120d3d4a550abbcbb9be121f6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1207_8c15abc94c737f9120d3d4a550abbcbb9be121f6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1207_8c15abc94c737f9120d3d4a550abbcbb9be121f6.patch 2014-05-05 12:46:01.000000000 +0000 @@ -0,0 +1,24 @@ +commit 8c15abc94c737f9120d3d4a550abbcbb9be121f6 +Author: Greg Kroah-Hartman +Date: Tue Oct 1 09:18:05 2013 -0700 + + Linux 3.10.14 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:45:19.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:46:00.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 13 ++SUBLEVEL = 14 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1207_8c15abc94c737f9120d3d4a550abbcbb9be121f6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1207_8c15abc94c737f9120d3d4a550abbcbb9be121f6.txt 2014-05-05 12:46:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1208_9204e9dd40ce207074419e60f66922ce47bb1b79.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1208_9204e9dd40ce207074419e60f66922ce47bb1b79.patch --- linux-3.10.11/debian/patches/rpi/rpi_1208_9204e9dd40ce207074419e60f66922ce47bb1b79.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1208_9204e9dd40ce207074419e60f66922ce47bb1b79.patch 2014-05-05 12:46:02.000000000 +0000 @@ -0,0 +1,37 @@ +commit 9204e9dd40ce207074419e60f66922ce47bb1b79 +Author: Kent Overstreet +Date: Mon Sep 23 23:17:26 2013 -0700 + + block: Fix bio_copy_data() + + commit 2f6cf0de0281d210061ce976f2d42d246adc75bb upstream. + + The memcpy() in bio_copy_data() was using the wrong offset vars, leading + to data corruption in weird unusual setups. + + Signed-off-by: Kent Overstreet + Cc: Jens Axboe + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/bio.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/bio.c 2014-05-05 11:50:49.000000000 +0000 ++++ linux-3.10-3.10.11/fs/bio.c 2014-05-05 12:46:01.000000000 +0000 +@@ -917,8 +917,8 @@ + src_p = kmap_atomic(src_bv->bv_page); + dst_p = kmap_atomic(dst_bv->bv_page); + +- memcpy(dst_p + dst_bv->bv_offset, +- src_p + src_bv->bv_offset, ++ memcpy(dst_p + dst_offset, ++ src_p + src_offset, + bytes); + + kunmap_atomic(dst_p); +Index: linux-3.10-3.10.11/dummy/rpi_1208_9204e9dd40ce207074419e60f66922ce47bb1b79.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1208_9204e9dd40ce207074419e60f66922ce47bb1b79.txt 2014-05-05 12:46:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1209_d8a1cf0bdbf668951b3ad4dfea4cde19c3fbe432.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1209_d8a1cf0bdbf668951b3ad4dfea4cde19c3fbe432.patch --- linux-3.10.11/debian/patches/rpi/rpi_1209_d8a1cf0bdbf668951b3ad4dfea4cde19c3fbe432.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1209_d8a1cf0bdbf668951b3ad4dfea4cde19c3fbe432.patch 2014-05-05 12:46:03.000000000 +0000 @@ -0,0 +1,35 @@ +commit d8a1cf0bdbf668951b3ad4dfea4cde19c3fbe432 +Author: Lubomir Rintel +Date: Wed Sep 18 12:39:16 2013 +0200 + + sysv: Add forgotten superblock lock init for v7 fs + + commit 49475555848d396a0c78fb2f8ecceb3f3f263ef1 upstream. + + Superblock lock was replaced with (un)lock_super() removal, but left + uninitialized for Seventh Edition UNIX filesystem in the following commit (3.7): + c07cb01 sysv: drop lock/unlock super + + Signed-off-by: Lubomir Rintel + Signed-off-by: Christoph Hellwig + Signed-off-by: Al Viro + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/sysv/super.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/sysv/super.c 2014-05-05 11:50:49.000000000 +0000 ++++ linux-3.10-3.10.11/fs/sysv/super.c 2014-05-05 12:46:02.000000000 +0000 +@@ -487,6 +487,7 @@ + sbi->s_sb = sb; + sbi->s_block_base = 0; + sbi->s_type = FSTYPE_V7; ++ mutex_init(&sbi->s_lock); + sb->s_fs_info = sbi; + + sb_set_blocksize(sb, 512); +Index: linux-3.10-3.10.11/dummy/rpi_1209_d8a1cf0bdbf668951b3ad4dfea4cde19c3fbe432.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1209_d8a1cf0bdbf668951b3ad4dfea4cde19c3fbe432.txt 2014-05-05 12:46:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1210_0a22f485eee6ae8da77c3e37c8856e025678cdb0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1210_0a22f485eee6ae8da77c3e37c8856e025678cdb0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1210_0a22f485eee6ae8da77c3e37c8856e025678cdb0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1210_0a22f485eee6ae8da77c3e37c8856e025678cdb0.patch 2014-05-05 12:46:03.000000000 +0000 @@ -0,0 +1,34 @@ +commit 0a22f485eee6ae8da77c3e37c8856e025678cdb0 +Author: Kent Overstreet +Date: Mon Sep 23 23:17:27 2013 -0700 + + bcache: Fix a dumb journal discard bug + + commit 6d9d21e35fbfa2934339e96934f862d118abac23 upstream. + + That switch statement was obviously wrong, leading to some sort of weird + spinning on rare occasion with discards enabled... + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/journal.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/journal.c 2014-05-05 11:50:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/journal.c 2014-05-05 12:46:03.000000000 +0000 +@@ -425,7 +425,7 @@ + return; + } + +- switch (atomic_read(&ja->discard_in_flight) == DISCARD_IN_FLIGHT) { ++ switch (atomic_read(&ja->discard_in_flight)) { + case DISCARD_IN_FLIGHT: + return; + +Index: linux-3.10-3.10.11/dummy/rpi_1210_0a22f485eee6ae8da77c3e37c8856e025678cdb0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1210_0a22f485eee6ae8da77c3e37c8856e025678cdb0.txt 2014-05-05 12:46:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1211_bb343115253500dcee63ea78d765e4c2f2a57fc4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1211_bb343115253500dcee63ea78d765e4c2f2a57fc4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1211_bb343115253500dcee63ea78d765e4c2f2a57fc4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1211_bb343115253500dcee63ea78d765e4c2f2a57fc4.patch 2014-05-05 12:46:04.000000000 +0000 @@ -0,0 +1,43 @@ +commit bb343115253500dcee63ea78d765e4c2f2a57fc4 +Author: Gabriel de Perthuis +Date: Mon Sep 23 23:17:28 2013 -0700 + + bcache: Strip endline when writing the label through sysfs + + commit aee6f1cfff3ce240eb4b43b41ca466b907acbd2e upstream. + + sysfs attributes with unusual characters have crappy failure modes + in Squeeze (udev 164); later versions of udev are unaffected. + + This should make these characters more unusual. + + Signed-off-by: Gabriel de Perthuis + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/sysfs.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/sysfs.c 2014-05-05 11:50:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/sysfs.c 2014-05-05 12:46:04.000000000 +0000 +@@ -214,7 +214,13 @@ + } + + if (attr == &sysfs_label) { +- memcpy(dc->sb.label, buf, SB_LABEL_SIZE); ++ if (size > SB_LABEL_SIZE) ++ return -EINVAL; ++ memcpy(dc->sb.label, buf, size); ++ if (size < SB_LABEL_SIZE) ++ dc->sb.label[size] = '\0'; ++ if (size && dc->sb.label[size - 1] == '\n') ++ dc->sb.label[size - 1] = '\0'; + bch_write_bdev_super(dc, NULL); + if (dc->disk.c) { + memcpy(dc->disk.c->uuids[dc->disk.id].label, +Index: linux-3.10-3.10.11/dummy/rpi_1211_bb343115253500dcee63ea78d765e4c2f2a57fc4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1211_bb343115253500dcee63ea78d765e4c2f2a57fc4.txt 2014-05-05 12:46:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1212_808eea9d2912e4a3fb8cd45e3e3da94d114757fb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1212_808eea9d2912e4a3fb8cd45e3e3da94d114757fb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1212_808eea9d2912e4a3fb8cd45e3e3da94d114757fb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1212_808eea9d2912e4a3fb8cd45e3e3da94d114757fb.patch 2014-05-05 12:46:05.000000000 +0000 @@ -0,0 +1,91 @@ +commit 808eea9d2912e4a3fb8cd45e3e3da94d114757fb +Author: Kent Overstreet +Date: Mon Sep 23 23:17:29 2013 -0700 + + bcache: Fix for when no journal entries are found + + commit c426c4fd46f709ade2bddd51c5738729c7ae1db5 upstream. + + The journal replay code didn't handle this case, causing it to go into + an infinite loop... + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/journal.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/journal.c 2014-05-05 12:46:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/journal.c 2014-05-05 12:46:04.000000000 +0000 +@@ -151,7 +151,8 @@ + bitmap_zero(bitmap, SB_JOURNAL_BUCKETS); + pr_debug("%u journal buckets", ca->sb.njournal_buckets); + +- /* Read journal buckets ordered by golden ratio hash to quickly ++ /* ++ * Read journal buckets ordered by golden ratio hash to quickly + * find a sequence of buckets with valid journal entries + */ + for (i = 0; i < ca->sb.njournal_buckets; i++) { +@@ -164,18 +165,20 @@ + goto bsearch; + } + +- /* If that fails, check all the buckets we haven't checked ++ /* ++ * If that fails, check all the buckets we haven't checked + * already + */ + pr_debug("falling back to linear search"); + +- for (l = 0; l < ca->sb.njournal_buckets; l++) { +- if (test_bit(l, bitmap)) +- continue; +- ++ for (l = find_first_zero_bit(bitmap, ca->sb.njournal_buckets); ++ l < ca->sb.njournal_buckets; ++ l = find_next_zero_bit(bitmap, ca->sb.njournal_buckets, l + 1)) + if (read_bucket(l)) + goto bsearch; +- } ++ ++ if (list_empty(list)) ++ continue; + bsearch: + /* Binary search */ + m = r = find_next_bit(bitmap, ca->sb.njournal_buckets, l + 1); +@@ -195,10 +198,12 @@ + r = m; + } + +- /* Read buckets in reverse order until we stop finding more ++ /* ++ * Read buckets in reverse order until we stop finding more + * journal entries + */ +- pr_debug("finishing up"); ++ pr_debug("finishing up: m %u njournal_buckets %u", ++ m, ca->sb.njournal_buckets); + l = m; + + while (1) { +@@ -226,9 +231,10 @@ + } + } + +- c->journal.seq = list_entry(list->prev, +- struct journal_replay, +- list)->j.seq; ++ if (!list_empty(list)) ++ c->journal.seq = list_entry(list->prev, ++ struct journal_replay, ++ list)->j.seq; + + return 0; + #undef read_bucket +Index: linux-3.10-3.10.11/dummy/rpi_1212_808eea9d2912e4a3fb8cd45e3e3da94d114757fb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1212_808eea9d2912e4a3fb8cd45e3e3da94d114757fb.txt 2014-05-05 12:46:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1213_48c4100e10b75152098675d534d8a6109b28f1bf.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1213_48c4100e10b75152098675d534d8a6109b28f1bf.patch --- linux-3.10.11/debian/patches/rpi/rpi_1213_48c4100e10b75152098675d534d8a6109b28f1bf.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1213_48c4100e10b75152098675d534d8a6109b28f1bf.patch 2014-05-05 12:46:06.000000000 +0000 @@ -0,0 +1,228 @@ +commit 48c4100e10b75152098675d534d8a6109b28f1bf +Author: Kent Overstreet +Date: Mon Sep 23 23:17:31 2013 -0700 + + bcache: Fix a writeback performance regression + + commit c2a4f3183a1248f615a695fbd8905da55ad11bba upstream. + + Background writeback works by scanning the btree for dirty data and + adding those keys into a fixed size buffer, then for each dirty key in + the keybuf writing it to the backing device. + + When read_dirty() finishes and it's time to scan for more dirty data, we + need to wait for the outstanding writeback IO to finish - they still + take up slots in the keybuf (so that foreground writes can check for + them to avoid races) - without that wait, we'll continually rescan when + we'll be able to add at most a key or two to the keybuf, and that takes + locks that starves foreground IO. Doh. + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/bcache.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/bcache.h 2014-05-05 11:50:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/bcache.h 2014-05-05 12:46:05.000000000 +0000 +@@ -499,7 +499,7 @@ + */ + atomic_t has_dirty; + +- struct ratelimit writeback_rate; ++ struct bch_ratelimit writeback_rate; + struct delayed_work writeback_rate_update; + + /* +@@ -508,10 +508,9 @@ + */ + sector_t last_read; + +- /* Number of writeback bios in flight */ +- atomic_t in_flight; ++ /* Limit number of writeback bios in flight */ ++ struct semaphore in_flight; + struct closure_with_timer writeback; +- struct closure_waitlist writeback_wait; + + struct keybuf writeback_keys; + +Index: linux-3.10-3.10.11/drivers/md/bcache/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/util.c 2014-05-05 11:50:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/util.c 2014-05-05 12:46:05.000000000 +0000 +@@ -190,7 +190,16 @@ + stats->last = now ?: 1; + } + +-unsigned bch_next_delay(struct ratelimit *d, uint64_t done) ++/** ++ * bch_next_delay() - increment @d by the amount of work done, and return how ++ * long to delay until the next time to do some work. ++ * ++ * @d - the struct bch_ratelimit to update ++ * @done - the amount of work done, in arbitrary units ++ * ++ * Returns the amount of time to delay by, in jiffies ++ */ ++uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done) + { + uint64_t now = local_clock(); + +Index: linux-3.10-3.10.11/drivers/md/bcache/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/util.h 2014-05-05 11:50:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/util.h 2014-05-05 12:46:05.000000000 +0000 +@@ -452,17 +452,23 @@ + (ewma) >> factor; \ + }) + +-struct ratelimit { ++struct bch_ratelimit { ++ /* Next time we want to do some work, in nanoseconds */ + uint64_t next; ++ ++ /* ++ * Rate at which we want to do work, in units per nanosecond ++ * The units here correspond to the units passed to bch_next_delay() ++ */ + unsigned rate; + }; + +-static inline void ratelimit_reset(struct ratelimit *d) ++static inline void bch_ratelimit_reset(struct bch_ratelimit *d) + { + d->next = local_clock(); + } + +-unsigned bch_next_delay(struct ratelimit *d, uint64_t done); ++uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done); + + #define __DIV_SAFE(n, d, zero) \ + ({ \ +Index: linux-3.10-3.10.11/drivers/md/bcache/writeback.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/writeback.c 2014-05-05 11:50:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/writeback.c 2014-05-05 12:46:05.000000000 +0000 +@@ -91,11 +91,15 @@ + + static unsigned writeback_delay(struct cached_dev *dc, unsigned sectors) + { ++ uint64_t ret; ++ + if (atomic_read(&dc->disk.detaching) || + !dc->writeback_percent) + return 0; + +- return bch_next_delay(&dc->writeback_rate, sectors * 10000000ULL); ++ ret = bch_next_delay(&dc->writeback_rate, sectors * 10000000ULL); ++ ++ return min_t(uint64_t, ret, HZ); + } + + /* Background writeback */ +@@ -165,7 +169,7 @@ + + up_write(&dc->writeback_lock); + +- ratelimit_reset(&dc->writeback_rate); ++ bch_ratelimit_reset(&dc->writeback_rate); + + /* Punt to workqueue only so we don't recurse and blow the stack */ + continue_at(cl, read_dirty, dirty_wq); +@@ -246,9 +250,7 @@ + } + + bch_keybuf_del(&dc->writeback_keys, w); +- atomic_dec_bug(&dc->in_flight); +- +- closure_wake_up(&dc->writeback_wait); ++ up(&dc->in_flight); + + closure_return_with_destructor(cl, dirty_io_destructor); + } +@@ -278,7 +280,7 @@ + trace_bcache_write_dirty(&io->bio); + closure_bio_submit(&io->bio, cl, &io->dc->disk); + +- continue_at(cl, write_dirty_finish, dirty_wq); ++ continue_at(cl, write_dirty_finish, system_wq); + } + + static void read_dirty_endio(struct bio *bio, int error) +@@ -299,7 +301,7 @@ + trace_bcache_read_dirty(&io->bio); + closure_bio_submit(&io->bio, cl, &io->dc->disk); + +- continue_at(cl, write_dirty, dirty_wq); ++ continue_at(cl, write_dirty, system_wq); + } + + static void read_dirty(struct closure *cl) +@@ -324,12 +326,9 @@ + + if (delay > 0 && + (KEY_START(&w->key) != dc->last_read || +- jiffies_to_msecs(delay) > 50)) { +- w->private = NULL; +- +- closure_delay(&dc->writeback, delay); +- continue_at(cl, read_dirty, dirty_wq); +- } ++ jiffies_to_msecs(delay) > 50)) ++ while (delay) ++ delay = schedule_timeout(delay); + + dc->last_read = KEY_OFFSET(&w->key); + +@@ -354,15 +353,10 @@ + + pr_debug("%s", pkey(&w->key)); + +- closure_call(&io->cl, read_dirty_submit, NULL, &dc->disk.cl); ++ down(&dc->in_flight); ++ closure_call(&io->cl, read_dirty_submit, NULL, cl); + + delay = writeback_delay(dc, KEY_SIZE(&w->key)); +- +- atomic_inc(&dc->in_flight); +- +- if (!closure_wait_event(&dc->writeback_wait, cl, +- atomic_read(&dc->in_flight) < 64)) +- continue_at(cl, read_dirty, dirty_wq); + } + + if (0) { +@@ -372,11 +366,16 @@ + bch_keybuf_del(&dc->writeback_keys, w); + } + +- refill_dirty(cl); ++ /* ++ * Wait for outstanding writeback IOs to finish (and keybuf slots to be ++ * freed) before refilling again ++ */ ++ continue_at(cl, refill_dirty, dirty_wq); + } + + void bch_cached_dev_writeback_init(struct cached_dev *dc) + { ++ sema_init(&dc->in_flight, 64); + closure_init_unlocked(&dc->writeback); + init_rwsem(&dc->writeback_lock); + +@@ -406,7 +405,7 @@ + + int __init bch_writeback_init(void) + { +- dirty_wq = create_singlethread_workqueue("bcache_writeback"); ++ dirty_wq = create_workqueue("bcache_writeback"); + if (!dirty_wq) + return -ENOMEM; + +Index: linux-3.10-3.10.11/dummy/rpi_1213_48c4100e10b75152098675d534d8a6109b28f1bf.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1213_48c4100e10b75152098675d534d8a6109b28f1bf.txt 2014-05-05 12:46:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1214_77dbabefd61a7db6dad630d59823dd610ac6692d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1214_77dbabefd61a7db6dad630d59823dd610ac6692d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1214_77dbabefd61a7db6dad630d59823dd610ac6692d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1214_77dbabefd61a7db6dad630d59823dd610ac6692d.patch 2014-05-05 12:46:07.000000000 +0000 @@ -0,0 +1,35 @@ +commit 77dbabefd61a7db6dad630d59823dd610ac6692d +Author: Kent Overstreet +Date: Mon Sep 23 23:17:32 2013 -0700 + + bcache: Fix a flush/fua performance bug + + commit 1394d6761b6e9e15ee7c632a6d48791188727b40 upstream. + + bch_journal_meta() was missing the flush to make the journal write + actually go down (instead of waiting up to journal_delay_ms)... + + Whoops + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/journal.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/journal.c 2014-05-05 12:46:04.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/journal.c 2014-05-05 12:46:06.000000000 +0000 +@@ -692,6 +692,7 @@ + if (cl) + BUG_ON(!closure_wait(&w->wait, cl)); + ++ closure_flush(&c->journal.io); + __journal_try_write(c, true); + } + } +Index: linux-3.10-3.10.11/dummy/rpi_1214_77dbabefd61a7db6dad630d59823dd610ac6692d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1214_77dbabefd61a7db6dad630d59823dd610ac6692d.txt 2014-05-05 12:46:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1215_ff1a51b9bf5808f2d40b8e605ff7f7cdc7973b3e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1215_ff1a51b9bf5808f2d40b8e605ff7f7cdc7973b3e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1215_ff1a51b9bf5808f2d40b8e605ff7f7cdc7973b3e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1215_ff1a51b9bf5808f2d40b8e605ff7f7cdc7973b3e.patch 2014-05-05 12:46:08.000000000 +0000 @@ -0,0 +1,34 @@ +commit ff1a51b9bf5808f2d40b8e605ff7f7cdc7973b3e +Author: Kent Overstreet +Date: Mon Sep 23 23:17:33 2013 -0700 + + bcache: Fix a dumb CPU spinning bug in writeback + + commit 79e3dab90d9f826ceca67c7890e048ac9169de49 upstream. + + schedule_timeout() != schedule_timeout_uninterruptible() + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/writeback.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/writeback.c 2014-05-05 12:46:05.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/writeback.c 2014-05-05 12:46:07.000000000 +0000 +@@ -327,8 +327,7 @@ + if (delay > 0 && + (KEY_START(&w->key) != dc->last_read || + jiffies_to_msecs(delay) > 50)) +- while (delay) +- delay = schedule_timeout(delay); ++ delay = schedule_timeout_uninterruptible(delay); + + dc->last_read = KEY_OFFSET(&w->key); + +Index: linux-3.10-3.10.11/dummy/rpi_1215_ff1a51b9bf5808f2d40b8e605ff7f7cdc7973b3e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1215_ff1a51b9bf5808f2d40b8e605ff7f7cdc7973b3e.txt 2014-05-05 12:46:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1216_7866bece346caecd88c53c6603e178ce4ebda87b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1216_7866bece346caecd88c53c6603e178ce4ebda87b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1216_7866bece346caecd88c53c6603e178ce4ebda87b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1216_7866bece346caecd88c53c6603e178ce4ebda87b.patch 2014-05-05 12:46:09.000000000 +0000 @@ -0,0 +1,35 @@ +commit 7866bece346caecd88c53c6603e178ce4ebda87b +Author: Kent Overstreet +Date: Mon Sep 23 23:17:34 2013 -0700 + + bcache: Fix a shrinker deadlock + + commit a698e08c82dfb9771e0bac12c7337c706d729b6d upstream. + + GFP_NOIO means we could be getting called recursively - mca_alloc() -> + mca_data_alloc() - definitely can't use mutex_lock(bucket_lock) then. + Whoops. + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/btree.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/btree.c 2014-05-05 11:50:47.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/btree.c 2014-05-05 12:46:08.000000000 +0000 +@@ -633,7 +633,7 @@ + return mca_can_free(c) * c->btree_pages; + + /* Return -1 if we can't do anything right now */ +- if (sc->gfp_mask & __GFP_WAIT) ++ if (sc->gfp_mask & __GFP_IO) + mutex_lock(&c->bucket_lock); + else if (!mutex_trylock(&c->bucket_lock)) + return -1; +Index: linux-3.10-3.10.11/dummy/rpi_1216_7866bece346caecd88c53c6603e178ce4ebda87b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1216_7866bece346caecd88c53c6603e178ce4ebda87b.txt 2014-05-05 12:46:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1217_df8b0d944cae63df86dba0edaa8fa8f5efaa7e03.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1217_df8b0d944cae63df86dba0edaa8fa8f5efaa7e03.patch --- linux-3.10.11/debian/patches/rpi/rpi_1217_df8b0d944cae63df86dba0edaa8fa8f5efaa7e03.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1217_df8b0d944cae63df86dba0edaa8fa8f5efaa7e03.patch 2014-05-05 12:46:09.000000000 +0000 @@ -0,0 +1,86 @@ +commit df8b0d944cae63df86dba0edaa8fa8f5efaa7e03 +Author: Kent Overstreet +Date: Mon Sep 23 23:17:35 2013 -0700 + + bcache: Fix for handling overlapping extents when reading in a btree node + + commit 84786438ed17978d72eeced580ab757e4da8830b upstream. + + btree_sort_fixup() was overly clever, because it was trying to avoid + pulling a key off the btree iterator in more than one place. + + This led to a really obscure bug where we'd break early from the loop in + btree_sort_fixup() if the current key overlapped with keys in more than + one older set, and the next key it overlapped with was zero size. + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/bset.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/bset.c 2014-05-05 11:50:47.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/bset.c 2014-05-05 12:46:09.000000000 +0000 +@@ -918,28 +918,45 @@ + + /* Mergesort */ + ++static void sort_key_next(struct btree_iter *iter, ++ struct btree_iter_set *i) ++{ ++ i->k = bkey_next(i->k); ++ ++ if (i->k == i->end) ++ *i = iter->data[--iter->used]; ++} ++ + static void btree_sort_fixup(struct btree_iter *iter) + { + while (iter->used > 1) { + struct btree_iter_set *top = iter->data, *i = top + 1; +- struct bkey *k; + + if (iter->used > 2 && + btree_iter_cmp(i[0], i[1])) + i++; + +- for (k = i->k; +- k != i->end && bkey_cmp(top->k, &START_KEY(k)) > 0; +- k = bkey_next(k)) +- if (top->k > i->k) +- __bch_cut_front(top->k, k); +- else if (KEY_SIZE(k)) +- bch_cut_back(&START_KEY(k), top->k); +- +- if (top->k < i->k || k == i->k) ++ if (bkey_cmp(top->k, &START_KEY(i->k)) <= 0) + break; + +- heap_sift(iter, i - top, btree_iter_cmp); ++ if (!KEY_SIZE(i->k)) { ++ sort_key_next(iter, i); ++ heap_sift(iter, i - top, btree_iter_cmp); ++ continue; ++ } ++ ++ if (top->k > i->k) { ++ if (bkey_cmp(top->k, i->k) >= 0) ++ sort_key_next(iter, i); ++ else ++ bch_cut_front(top->k, i->k); ++ ++ heap_sift(iter, i - top, btree_iter_cmp); ++ } else { ++ /* can't happen because of comparison func */ ++ BUG_ON(!bkey_cmp(&START_KEY(top->k), &START_KEY(i->k))); ++ bch_cut_back(&START_KEY(i->k), top->k); ++ } + } + } + +Index: linux-3.10-3.10.11/dummy/rpi_1217_df8b0d944cae63df86dba0edaa8fa8f5efaa7e03.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1217_df8b0d944cae63df86dba0edaa8fa8f5efaa7e03.txt 2014-05-05 12:46:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1218_30d0e7953b17462b8e42ad374ace70c76e31d410.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1218_30d0e7953b17462b8e42ad374ace70c76e31d410.patch --- linux-3.10.11/debian/patches/rpi/rpi_1218_30d0e7953b17462b8e42ad374ace70c76e31d410.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1218_30d0e7953b17462b8e42ad374ace70c76e31d410.patch 2014-05-05 12:46:10.000000000 +0000 @@ -0,0 +1,57 @@ +commit 30d0e7953b17462b8e42ad374ace70c76e31d410 +Author: Kent Overstreet +Date: Mon Sep 23 23:17:36 2013 -0700 + + bcache: Fix flushes in writeback mode + + commit c0f04d88e46d14de51f4baebb6efafb7d59e9f96 upstream. + + In writeback mode, when we get a cache flush we need to make sure we + issue a flush to the backing device. + + The code for sending down an extra flush was wrong - by cloning the bio + we were probably getting flags that didn't make sense for a bare flush, + and also the old code was firing for FUA bios, for which we don't need + to send a flush to the backing device. + + This was causing data corruption somehow - the mechanism was never + determined, but this patch fixes it for the users that were seeing it. + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/request.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/request.c 2014-05-05 11:50:46.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/request.c 2014-05-05 12:46:10.000000000 +0000 +@@ -1056,14 +1056,17 @@ + trace_bcache_writeback(s->orig_bio); + bch_writeback_add(dc, bio_sectors(bio)); + +- if (s->op.flush_journal) { ++ if (bio->bi_rw & REQ_FLUSH) { + /* Also need to send a flush to the backing device */ +- s->op.cache_bio = bio_clone_bioset(bio, GFP_NOIO, +- dc->disk.bio_split); ++ struct bio *flush = bio_alloc_bioset(0, GFP_NOIO, ++ dc->disk.bio_split); + +- bio->bi_size = 0; +- bio->bi_vcnt = 0; +- closure_bio_submit(bio, cl, s->d); ++ flush->bi_rw = WRITE_FLUSH; ++ flush->bi_bdev = bio->bi_bdev; ++ flush->bi_end_io = request_endio; ++ flush->bi_private = cl; ++ ++ closure_bio_submit(flush, cl, s->d); + } else { + s->op.cache_bio = bio; + } +Index: linux-3.10-3.10.11/dummy/rpi_1218_30d0e7953b17462b8e42ad374ace70c76e31d410.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1218_30d0e7953b17462b8e42ad374ace70c76e31d410.txt 2014-05-05 12:46:10.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1219_fdc43786ed80ac4d85fb82ed3e37a5143721b50b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1219_fdc43786ed80ac4d85fb82ed3e37a5143721b50b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1219_fdc43786ed80ac4d85fb82ed3e37a5143721b50b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1219_fdc43786ed80ac4d85fb82ed3e37a5143721b50b.patch 2014-05-05 12:46:11.000000000 +0000 @@ -0,0 +1,52 @@ +commit fdc43786ed80ac4d85fb82ed3e37a5143721b50b +Author: Masoud Sharbiani +Date: Fri Sep 20 15:59:07 2013 -0700 + + x86/reboot: Add quirk to make Dell C6100 use reboot=pci automatically + + commit 4f0acd31c31f03ba42494c8baf6c0465150e2621 upstream. + + Dell PowerEdge C6100 machines fail to completely reboot about 20% of the time. + + Signed-off-by: Masoud Sharbiani + Signed-off-by: Vinson Lee + Cc: Robin Holt + Cc: Russell King + Cc: Guan Xuetao + Link: http://lkml.kernel.org/r/1379717947-18042-1-git-send-email-vlee@freedesktop.org + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/kernel/reboot.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/reboot.c 2014-05-05 11:50:46.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/reboot.c 2014-05-05 12:46:11.000000000 +0000 +@@ -447,6 +447,22 @@ + DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), + }, + }, ++ { /* Handle problems with rebooting on the Dell PowerEdge C6100. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell PowerEdge C6100", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), ++ }, ++ }, ++ { /* Some C6100 machines were shipped with vendor being 'Dell'. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell PowerEdge C6100", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), ++ }, ++ }, + { } + }; + +Index: linux-3.10-3.10.11/dummy/rpi_1219_fdc43786ed80ac4d85fb82ed3e37a5143721b50b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1219_fdc43786ed80ac4d85fb82ed3e37a5143721b50b.txt 2014-05-05 12:46:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1220_655325c7e4f62ece9bea61e5b24d8118d6e09ef1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1220_655325c7e4f62ece9bea61e5b24d8118d6e09ef1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1220_655325c7e4f62ece9bea61e5b24d8118d6e09ef1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1220_655325c7e4f62ece9bea61e5b24d8118d6e09ef1.patch 2014-05-05 12:46:12.000000000 +0000 @@ -0,0 +1,58 @@ +commit 655325c7e4f62ece9bea61e5b24d8118d6e09ef1 +Author: Vinson Lee +Date: Wed Sep 18 16:16:40 2013 -0700 + + tools lib lk: Uninclude linux/magic.h in debugfs.c + + commit ce7eebe5c3deef8e19c177c24ee75843256e69ca upstream. + + The compilation only looks for linux/magic.h from the default include + paths, which does not include the source tree. This results in a build + error if linux/magic.h is not available or not installed. + + For example, this build error occurs on CentOS 5. + + $ make -C tools/lib/lk V=1 + [...] + gcc -o debugfs.o -c -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 + -D_FORTIFY_SOURCE=2 -Wbad-function-cast -Wdeclaration-after-statement + -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations + -Wmissing-prototypes -Wnested-externs -Wno-system-headers + -Wold-style-definition -Wpacked -Wredundant-decls -Wshadow + -Wstrict-aliasing=3 -Wstrict-prototypes -Wswitch-default -Wswitch-enum + -Wundef -Wwrite-strings -Wformat -fPIC -D_LARGEFILE64_SOURCE + -D_FILE_OFFSET_BITS=64 debugfs.c + debugfs.c:8:25: error: linux/magic.h: No such file or directory + + The only symbol from linux/magic.h needed by debugfs.c is DEBUGFS_MAGIC, + and that is already defined in debugfs.h. linux/magic.h isn't providing + any extra symbols and can unincluded. This is similar to the approach by + perf, which has its own magic.h wrapper at + tools/perf/util/include/linux/magic.h + + Signed-off-by: Vinson Lee + Acked-by: Borislav Petkov + Cc: Borislav Petkov + Cc: Vinson Lee + Link: http://lkml.kernel.org/r/1379546200-17028-1-git-send-email-vlee@freedesktop.org + Signed-off-by: Arnaldo Carvalho de Melo + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/tools/lib/lk/debugfs.c +=================================================================== +--- linux-3.10-3.10.11.orig/tools/lib/lk/debugfs.c 2014-05-05 11:50:46.000000000 +0000 ++++ linux-3.10-3.10.11/tools/lib/lk/debugfs.c 2014-05-05 12:46:12.000000000 +0000 +@@ -5,7 +5,6 @@ + #include + #include + #include +-#include + #include + + #include "debugfs.h" +Index: linux-3.10-3.10.11/dummy/rpi_1220_655325c7e4f62ece9bea61e5b24d8118d6e09ef1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1220_655325c7e4f62ece9bea61e5b24d8118d6e09ef1.txt 2014-05-05 12:46:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1221_81fbb94d1fbdad184ca4091da4cae87a92dbf3c7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1221_81fbb94d1fbdad184ca4091da4cae87a92dbf3c7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1221_81fbb94d1fbdad184ca4091da4cae87a92dbf3c7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1221_81fbb94d1fbdad184ca4091da4cae87a92dbf3c7.patch 2014-05-05 12:46:13.000000000 +0000 @@ -0,0 +1,91 @@ +commit 81fbb94d1fbdad184ca4091da4cae87a92dbf3c7 +Author: Josh Boyer +Date: Thu Apr 18 07:51:34 2013 -0700 + + x86, efi: Don't map Boot Services on i386 + + commit 700870119f49084da004ab588ea2b799689efaf7 upstream. + + Add patch to fix 32bit EFI service mapping (rhbz 726701) + + Multiple people are reporting hitting the following WARNING on i386, + + WARNING: at arch/x86/mm/ioremap.c:102 __ioremap_caller+0x3d3/0x440() + Modules linked in: + Pid: 0, comm: swapper Not tainted 3.9.0-rc7+ #95 + Call Trace: + [] warn_slowpath_common+0x5f/0x80 + [] ? __ioremap_caller+0x3d3/0x440 + [] ? __ioremap_caller+0x3d3/0x440 + [] warn_slowpath_null+0x1d/0x20 + [] __ioremap_caller+0x3d3/0x440 + [] ? get_usage_chars+0xfb/0x110 + [] ? vprintk_emit+0x147/0x480 + [] ? efi_enter_virtual_mode+0x1e4/0x3de + [] ioremap_cache+0x1a/0x20 + [] ? efi_enter_virtual_mode+0x1e4/0x3de + [] efi_enter_virtual_mode+0x1e4/0x3de + [] start_kernel+0x286/0x2f4 + [] ? repair_env_string+0x51/0x51 + [] i386_start_kernel+0x12c/0x12f + + Due to the workaround described in commit 916f676f8 ("x86, efi: Retain + boot service code until after switching to virtual mode") EFI Boot + Service regions are mapped for a period during boot. Unfortunately, with + the limited size of the i386 direct kernel map it's possible that some + of the Boot Service regions will not be directly accessible, which + causes them to be ioremap()'d, triggering the above warning as the + regions are marked as E820_RAM in the e820 memmap. + + There are currently only two situations where we need to map EFI Boot + Service regions, + + 1. To workaround the firmware bug described in 916f676f8 + 2. To access the ACPI BGRT image + + but since we haven't seen an i386 implementation that requires either, + this simple fix should suffice for now. + + [ Added to changelog - Matt ] + + Reported-by: Bryan O'Donoghue + Acked-by: Tom Zanussi + Acked-by: Darren Hart + Cc: Josh Triplett + Cc: Matthew Garrett + Cc: H. Peter Anvin + Cc: Ingo Molnar + Cc: Thomas Gleixner + Cc: Greg Kroah-Hartman + Signed-off-by: Josh Boyer + Signed-off-by: Matt Fleming + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/platform/efi/efi.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/platform/efi/efi.c 2014-05-05 12:42:51.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/platform/efi/efi.c 2014-05-05 12:46:12.000000000 +0000 +@@ -925,10 +925,13 @@ + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; +- if (!(md->attribute & EFI_MEMORY_RUNTIME) && +- md->type != EFI_BOOT_SERVICES_CODE && +- md->type != EFI_BOOT_SERVICES_DATA) +- continue; ++ if (!(md->attribute & EFI_MEMORY_RUNTIME)) { ++#ifdef CONFIG_X86_64 ++ if (md->type != EFI_BOOT_SERVICES_CODE && ++ md->type != EFI_BOOT_SERVICES_DATA) ++#endif ++ continue; ++ } + + size = md->num_pages << EFI_PAGE_SHIFT; + end = md->phys_addr + size; +Index: linux-3.10-3.10.11/dummy/rpi_1221_81fbb94d1fbdad184ca4091da4cae87a92dbf3c7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1221_81fbb94d1fbdad184ca4091da4cae87a92dbf3c7.txt 2014-05-05 12:46:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1222_cb4af713f95f049056c25e0c18f652c3338c2bc7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1222_cb4af713f95f049056c25e0c18f652c3338c2bc7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1222_cb4af713f95f049056c25e0c18f652c3338c2bc7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1222_cb4af713f95f049056c25e0c18f652c3338c2bc7.patch 2014-05-05 12:46:14.000000000 +0000 @@ -0,0 +1,80 @@ +commit cb4af713f95f049056c25e0c18f652c3338c2bc7 +Author: Tomas Winkler +Date: Mon Sep 2 13:29:45 2013 +0300 + + mei: make me client counters less error prone + + commit 1aee351a739153529fbb98ee461777b2abd5e1c9 upstream. + + 1. u8 counters are prone to hard to detect overflow: + make them unsigned long to match bit_ functions argument type + + 2. don't check me_clients_num for negativity, it is unsigned. + + 3. init all the me client counters from one place + + Signed-off-by: Tomas Winkler + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/misc/mei/hbm.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/mei/hbm.c 2014-05-05 11:50:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/mei/hbm.c 2014-05-05 12:46:13.000000000 +0000 +@@ -35,11 +35,15 @@ + struct mei_me_client *clients; + int b; + ++ dev->me_clients_num = 0; ++ dev->me_client_presentation_num = 0; ++ dev->me_client_index = 0; ++ + /* count how many ME clients we have */ + for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) + dev->me_clients_num++; + +- if (dev->me_clients_num <= 0) ++ if (dev->me_clients_num == 0) + return; + + kfree(dev->me_clients); +@@ -221,7 +225,7 @@ + struct hbm_props_request *prop_req; + const size_t len = sizeof(struct hbm_props_request); + unsigned long next_client_index; +- u8 client_num; ++ unsigned long client_num; + + + client_num = dev->me_client_presentation_num; +@@ -650,8 +654,6 @@ + if (dev->dev_state == MEI_DEV_INIT_CLIENTS && + dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { + dev->init_clients_timer = 0; +- dev->me_client_presentation_num = 0; +- dev->me_client_index = 0; + mei_hbm_me_cl_allocate(dev); + dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; + +Index: linux-3.10-3.10.11/drivers/misc/mei/mei_dev.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/mei/mei_dev.h 2014-05-05 11:50:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/mei/mei_dev.h 2014-05-05 12:46:13.000000000 +0000 +@@ -402,9 +402,9 @@ + struct mei_me_client *me_clients; /* Note: memory has to be allocated */ + DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); + DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); +- u8 me_clients_num; +- u8 me_client_presentation_num; +- u8 me_client_index; ++ unsigned long me_clients_num; ++ unsigned long me_client_presentation_num; ++ unsigned long me_client_index; + + struct mei_cl wd_cl; + enum mei_wd_states wd_state; +Index: linux-3.10-3.10.11/dummy/rpi_1222_cb4af713f95f049056c25e0c18f652c3338c2bc7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1222_cb4af713f95f049056c25e0c18f652c3338c2bc7.txt 2014-05-05 12:46:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1223_18f48d9e784339c954eb1641fef600e00c7a53c0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1223_18f48d9e784339c954eb1641fef600e00c7a53c0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1223_18f48d9e784339c954eb1641fef600e00c7a53c0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1223_18f48d9e784339c954eb1641fef600e00c7a53c0.patch 2014-05-05 12:46:15.000000000 +0000 @@ -0,0 +1,89 @@ +commit 18f48d9e784339c954eb1641fef600e00c7a53c0 +Author: Tomas Winkler +Date: Mon Sep 2 13:29:46 2013 +0300 + + mei: bus: stop wait for read during cl state transition + + commit e2b31644e999e8bfe3efce880fb32840299abf41 upstream. + + Bus layer omitted check for client state transition while waiting + for read completion + The client state transition may occur for example as result + of firmware initiated reset + + Add mei_cl_is_transitioning wrapper to reduce the code + repetition.: + + Signed-off-by: Tomas Winkler + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/misc/mei/bus.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/mei/bus.c 2014-05-05 11:50:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/mei/bus.c 2014-05-05 12:46:14.000000000 +0000 +@@ -295,10 +295,13 @@ + + if (cl->reading_state != MEI_READ_COMPLETE && + !waitqueue_active(&cl->rx_wait)) { ++ + mutex_unlock(&dev->device_lock); + + if (wait_event_interruptible(cl->rx_wait, +- (MEI_READ_COMPLETE == cl->reading_state))) { ++ cl->reading_state == MEI_READ_COMPLETE || ++ mei_cl_is_transitioning(cl))) { ++ + if (signal_pending(current)) + return -EINTR; + return -ERESTARTSYS; +Index: linux-3.10-3.10.11/drivers/misc/mei/client.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/mei/client.h 2014-05-05 11:50:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/mei/client.h 2014-05-05 12:46:14.000000000 +0000 +@@ -76,6 +76,12 @@ + (cl1->host_client_id == cl2->host_client_id) && + (cl1->me_client_id == cl2->me_client_id); + } ++static inline bool mei_cl_is_transitioning(struct mei_cl *cl) ++{ ++ return (MEI_FILE_INITIALIZING == cl->state || ++ MEI_FILE_DISCONNECTED == cl->state || ++ MEI_FILE_DISCONNECTING == cl->state); ++} + + + int mei_cl_flow_ctrl_creds(struct mei_cl *cl); +Index: linux-3.10-3.10.11/drivers/misc/mei/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/mei/main.c 2014-05-05 11:50:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/mei/main.c 2014-05-05 12:46:14.000000000 +0000 +@@ -262,19 +262,16 @@ + mutex_unlock(&dev->device_lock); + + if (wait_event_interruptible(cl->rx_wait, +- (MEI_READ_COMPLETE == cl->reading_state || +- MEI_FILE_INITIALIZING == cl->state || +- MEI_FILE_DISCONNECTED == cl->state || +- MEI_FILE_DISCONNECTING == cl->state))) { ++ MEI_READ_COMPLETE == cl->reading_state || ++ mei_cl_is_transitioning(cl))) { ++ + if (signal_pending(current)) + return -EINTR; + return -ERESTARTSYS; + } + + mutex_lock(&dev->device_lock); +- if (MEI_FILE_INITIALIZING == cl->state || +- MEI_FILE_DISCONNECTED == cl->state || +- MEI_FILE_DISCONNECTING == cl->state) { ++ if (mei_cl_is_transitioning(cl)) { + rets = -EBUSY; + goto out; + } +Index: linux-3.10-3.10.11/dummy/rpi_1223_18f48d9e784339c954eb1641fef600e00c7a53c0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1223_18f48d9e784339c954eb1641fef600e00c7a53c0.txt 2014-05-05 12:46:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1224_51d4e0771c3c69bb021d3052433e49effa6e4f65.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1224_51d4e0771c3c69bb021d3052433e49effa6e4f65.patch --- linux-3.10.11/debian/patches/rpi/rpi_1224_51d4e0771c3c69bb021d3052433e49effa6e4f65.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1224_51d4e0771c3c69bb021d3052433e49effa6e4f65.patch 2014-05-05 12:46:16.000000000 +0000 @@ -0,0 +1,48 @@ +commit 51d4e0771c3c69bb021d3052433e49effa6e4f65 +Author: Alexander Usyskin +Date: Mon Sep 2 13:29:47 2013 +0300 + + mei: cancel stall timers in mei_reset + + commit 4a704575cc1afb3b848f096778fa9b8d7b3d5813 upstream. + + Unset init_clients_timer and amthif_stall_timers + in mei_reset in order to cancel timer ticking and hence + avoid recursive reset calls. + + Signed-off-by: Alexander Usyskin + Signed-off-by: Tomas Winkler + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/misc/mei/amthif.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/mei/amthif.c 2014-05-05 11:50:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/mei/amthif.c 2014-05-05 12:46:15.000000000 +0000 +@@ -57,6 +57,7 @@ + dev->iamthif_ioctl = false; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + dev->iamthif_timer = 0; ++ dev->iamthif_stall_timer = 0; + } + + /** +Index: linux-3.10-3.10.11/drivers/misc/mei/init.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/mei/init.c 2014-05-05 11:50:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/mei/init.c 2014-05-05 12:46:15.000000000 +0000 +@@ -164,6 +164,9 @@ + memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); + } + ++ /* we're already in reset, cancel the init timer */ ++ dev->init_clients_timer = 0; ++ + dev->me_clients_num = 0; + dev->rd_msg_hdr = 0; + dev->wd_pending = false; +Index: linux-3.10-3.10.11/dummy/rpi_1224_51d4e0771c3c69bb021d3052433e49effa6e4f65.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1224_51d4e0771c3c69bb021d3052433e49effa6e4f65.txt 2014-05-05 12:46:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1225_fe0da74501e9eb204dc1b8167708bd9273f4277f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1225_fe0da74501e9eb204dc1b8167708bd9273f4277f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1225_fe0da74501e9eb204dc1b8167708bd9273f4277f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1225_fe0da74501e9eb204dc1b8167708bd9273f4277f.patch 2014-05-05 12:46:17.000000000 +0000 @@ -0,0 +1,40 @@ +commit fe0da74501e9eb204dc1b8167708bd9273f4277f +Author: Peter Hurley +Date: Wed Sep 25 20:13:04 2013 -0400 + + tty: Fix SIGTTOU not sent with tcflush() + + commit 5cec7bf699c61d14f0538345076480bb8c8ebfbb upstream. + + Commit 'e7f3880cd9b98c5bf9391ae7acdec82b75403776' + tty: Fix recursive deadlock in tty_perform_flush() + introduced a regression where tcflush() does not generate + SIGTTOU for background process groups. + + Make sure ioctl(TCFLSH) calls tty_check_change() when + invoked from the line discipline. + + Reported-by: Oleg Nesterov + Signed-off-by: Peter Hurley + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/tty/tty_ioctl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/tty_ioctl.c 2014-05-05 11:50:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/tty_ioctl.c 2014-05-05 12:46:16.000000000 +0000 +@@ -1201,6 +1201,9 @@ + } + return 0; + case TCFLSH: ++ retval = tty_check_change(tty); ++ if (retval) ++ return retval; + return __tty_perform_flush(tty, arg); + default: + /* Try the mode commands */ +Index: linux-3.10-3.10.11/dummy/rpi_1225_fe0da74501e9eb204dc1b8167708bd9273f4277f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1225_fe0da74501e9eb204dc1b8167708bd9273f4277f.txt 2014-05-05 12:46:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1226_64dc8de491ef490e979fe65d83daaadf32c83633.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1226_64dc8de491ef490e979fe65d83daaadf32c83633.patch --- linux-3.10.11/debian/patches/rpi/rpi_1226_64dc8de491ef490e979fe65d83daaadf32c83633.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1226_64dc8de491ef490e979fe65d83daaadf32c83633.patch 2014-05-05 12:46:17.000000000 +0000 @@ -0,0 +1,42 @@ +commit 64dc8de491ef490e979fe65d83daaadf32c83633 +Author: Johan Hovold +Date: Tue Sep 10 12:50:48 2013 +0200 + + serial: tegra: fix tty-kref leak + + commit cfd29aa0e81b791985e8428e6507e80e074e6730 upstream. + + Fix potential tty-kref leak in stop_rx path. + + Signed-off-by: Johan Hovold + Tested-by: Stephen Warren + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/tty/serial/serial-tegra.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/serial/serial-tegra.c 2014-05-05 11:50:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/serial/serial-tegra.c 2014-05-05 12:46:17.000000000 +0000 +@@ -726,7 +726,7 @@ + static void tegra_uart_stop_rx(struct uart_port *u) + { + struct tegra_uart_port *tup = to_tegra_uport(u); +- struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); ++ struct tty_struct *tty; + struct tty_port *port = &u->state->port; + struct dma_tx_state state; + unsigned long ier; +@@ -738,6 +738,8 @@ + if (!tup->rx_in_progress) + return; + ++ tty = tty_port_tty_get(&tup->uport.state->port); ++ + tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ + + ier = tup->ier_shadow; +Index: linux-3.10-3.10.11/dummy/rpi_1226_64dc8de491ef490e979fe65d83daaadf32c83633.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1226_64dc8de491ef490e979fe65d83daaadf32c83633.txt 2014-05-05 12:46:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1227_b0a382b5a35e306362cde912bff18a42cc00b0f5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1227_b0a382b5a35e306362cde912bff18a42cc00b0f5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1227_b0a382b5a35e306362cde912bff18a42cc00b0f5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1227_b0a382b5a35e306362cde912bff18a42cc00b0f5.patch 2014-05-05 12:46:18.000000000 +0000 @@ -0,0 +1,33 @@ +commit b0a382b5a35e306362cde912bff18a42cc00b0f5 +Author: Johan Hovold +Date: Tue Sep 10 12:50:49 2013 +0200 + + serial: pch_uart: fix tty-kref leak in rx-error path + + commit fc0919c68cb2f75bb1af759315f9d7e2a9443c28 upstream. + + Fix tty-kref leak introduced by commit 384e301e ("pch_uart: fix a + deadlock when pch_uart as console") which never put its tty reference. + + Signed-off-by: Johan Hovold + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/tty/serial/pch_uart.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/serial/pch_uart.c 2014-05-05 11:50:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/serial/pch_uart.c 2014-05-05 12:46:18.000000000 +0000 +@@ -1071,6 +1071,8 @@ + if (tty == NULL) { + for (i = 0; error_msg[i] != NULL; i++) + dev_err(&priv->pdev->dev, error_msg[i]); ++ } else { ++ tty_kref_put(tty); + } + } + +Index: linux-3.10-3.10.11/dummy/rpi_1227_b0a382b5a35e306362cde912bff18a42cc00b0f5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1227_b0a382b5a35e306362cde912bff18a42cc00b0f5.txt 2014-05-05 12:46:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1228_20d7e144c93a9f06224fc983cb5b248bb5bc87fb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1228_20d7e144c93a9f06224fc983cb5b248bb5bc87fb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1228_20d7e144c93a9f06224fc983cb5b248bb5bc87fb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1228_20d7e144c93a9f06224fc983cb5b248bb5bc87fb.patch 2014-05-05 12:46:19.000000000 +0000 @@ -0,0 +1,41 @@ +commit 20d7e144c93a9f06224fc983cb5b248bb5bc87fb +Author: Johan Hovold +Date: Tue Sep 10 12:50:50 2013 +0200 + + serial: pch_uart: fix tty-kref leak in dma-rx path + + commit 19b85cfb190eb9980eaf416bff96aef4159a430e upstream. + + Fix tty_kref leak when tty_buffer_request room fails in dma-rx path. + + Note that the tty ref isn't really needed anymore, but as the leak has + always been there, fixing it before removing should makes it easier to + backport the fix. + + Signed-off-by: Johan Hovold + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/tty/serial/pch_uart.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/serial/pch_uart.c 2014-05-05 12:46:18.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/serial/pch_uart.c 2014-05-05 12:46:18.000000000 +0000 +@@ -658,11 +658,12 @@ + dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", + size - room); + if (!room) +- return room; ++ goto out; + + tty_insert_flip_string(tport, sg_virt(&priv->sg_rx), size); + + port->icount.rx += room; ++out: + tty_kref_put(tty); + + return room; +Index: linux-3.10-3.10.11/dummy/rpi_1228_20d7e144c93a9f06224fc983cb5b248bb5bc87fb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1228_20d7e144c93a9f06224fc983cb5b248bb5bc87fb.txt 2014-05-05 12:46:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1229_ace53ef6a91d0afcb4f45fa06d162fe45c7c3b2f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1229_ace53ef6a91d0afcb4f45fa06d162fe45c7c3b2f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1229_ace53ef6a91d0afcb4f45fa06d162fe45c7c3b2f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1229_ace53ef6a91d0afcb4f45fa06d162fe45c7c3b2f.patch 2014-05-05 12:46:20.000000000 +0000 @@ -0,0 +1,56 @@ +commit ace53ef6a91d0afcb4f45fa06d162fe45c7c3b2f +Author: Ard Biesheuvel +Date: Sat Sep 21 11:23:50 2013 +0100 + + ARM: 7837/3: fix Thumb-2 bug in AES assembler code + + commit 40190c85f427dcfdbab5dbef4ffd2510d649da1f upstream. + + Patch 638591c enabled building the AES assembler code in Thumb2 mode. + However, this code used arithmetic involving PC rather than adr{l} + instructions to generate PC-relative references to the lookup tables, + and this needs to take into account the different PC offset when + running in Thumb mode. + + Signed-off-by: Ard Biesheuvel + Acked-by: Nicolas Pitre + Signed-off-by: Russell King + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/crypto/aes-armv4.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/crypto/aes-armv4.S 2014-05-05 11:50:43.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/crypto/aes-armv4.S 2014-05-05 12:46:19.000000000 +0000 +@@ -148,7 +148,7 @@ + @ const AES_KEY *key) { + .align 5 + ENTRY(AES_encrypt) +- sub r3,pc,#8 @ AES_encrypt ++ adr r3,AES_encrypt + stmdb sp!,{r1,r4-r12,lr} + mov r12,r0 @ inp + mov r11,r2 +@@ -381,7 +381,7 @@ + .align 5 + ENTRY(private_AES_set_encrypt_key) + _armv4_AES_set_encrypt_key: +- sub r3,pc,#8 @ AES_set_encrypt_key ++ adr r3,_armv4_AES_set_encrypt_key + teq r0,#0 + moveq r0,#-1 + beq .Labrt +@@ -843,7 +843,7 @@ + @ const AES_KEY *key) { + .align 5 + ENTRY(AES_decrypt) +- sub r3,pc,#8 @ AES_decrypt ++ adr r3,AES_decrypt + stmdb sp!,{r1,r4-r12,lr} + mov r12,r0 @ inp + mov r11,r2 +Index: linux-3.10-3.10.11/dummy/rpi_1229_ace53ef6a91d0afcb4f45fa06d162fe45c7c3b2f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1229_ace53ef6a91d0afcb4f45fa06d162fe45c7c3b2f.txt 2014-05-05 12:46:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1230_d66aed99301eb9dd6a6e71f73081057480369ab4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1230_d66aed99301eb9dd6a6e71f73081057480369ab4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1230_d66aed99301eb9dd6a6e71f73081057480369ab4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1230_d66aed99301eb9dd6a6e71f73081057480369ab4.patch 2014-05-05 12:46:21.000000000 +0000 @@ -0,0 +1,48 @@ +commit d66aed99301eb9dd6a6e71f73081057480369ab4 +Author: Malcolm Priestley +Date: Sun Sep 22 19:48:54 2013 +0100 + + staging: vt6656: [BUG] main_usb.c oops on device_close move flag earlier. + + commit e3eb270fab7734427dd8171a93e4946fe28674bc upstream. + + The vt6656 is prone to resetting on the usb bus. + + It seems there is a race condition and wpa supplicant is + trying to open the device via iw_handlers before its actually + closed at a stage that the buffers are being removed. + + The device is longer considered open when the + buffers are being removed. So move ~DEVICE_FLAGS_OPENED + flag to before freeing the device buffers. + + Signed-off-by: Malcolm Priestley + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/vt6656/main_usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/vt6656/main_usb.c 2014-05-05 11:50:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/vt6656/main_usb.c 2014-05-05 12:46:20.000000000 +0000 +@@ -1099,6 +1099,8 @@ + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + ++ pDevice->flags &= ~DEVICE_FLAGS_OPENED; ++ + device_free_tx_bufs(pDevice); + device_free_rx_bufs(pDevice); + device_free_int_bufs(pDevice); +@@ -1110,7 +1112,6 @@ + usb_free_urb(pDevice->pInterruptURB); + + BSSvClearNodeDBTable(pDevice, 0); +- pDevice->flags &=(~DEVICE_FLAGS_OPENED); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n"); + +Index: linux-3.10-3.10.11/dummy/rpi_1230_d66aed99301eb9dd6a6e71f73081057480369ab4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1230_d66aed99301eb9dd6a6e71f73081057480369ab4.txt 2014-05-05 12:46:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1231_54cff964637d840e7860afa49a369c84c8cfbf61.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1231_54cff964637d840e7860afa49a369c84c8cfbf61.patch --- linux-3.10.11/debian/patches/rpi/rpi_1231_54cff964637d840e7860afa49a369c84c8cfbf61.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1231_54cff964637d840e7860afa49a369c84c8cfbf61.patch 2014-05-05 12:46:21.000000000 +0000 @@ -0,0 +1,36 @@ +commit 54cff964637d840e7860afa49a369c84c8cfbf61 +Author: Malcolm Priestley +Date: Mon Sep 23 20:30:42 2013 +0100 + + staging: vt6656: [BUG] iwctl_siwencodeext return if device not open + + commit 5e8c3d3e41b0bf241e830a1ee0752405adecc050 upstream. + + Don't allow entry to iwctl_siwencodeext if device not open. + + This fixes a race condition where wpa supplicant/network manager + enters the function when the device is already closed. + + Signed-off-by: Malcolm Priestley + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/vt6656/iwctl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/vt6656/iwctl.c 2014-05-05 11:50:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/vt6656/iwctl.c 2014-05-05 12:46:21.000000000 +0000 +@@ -1634,6 +1634,9 @@ + if (pMgmt == NULL) + return -EFAULT; + ++ if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) ++ return -ENODEV; ++ + buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; +Index: linux-3.10-3.10.11/dummy/rpi_1231_54cff964637d840e7860afa49a369c84c8cfbf61.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1231_54cff964637d840e7860afa49a369c84c8cfbf61.txt 2014-05-05 12:46:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1232_4bc8e1356cf9c7c2dbff522671a5d6d33d49c2ba.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1232_4bc8e1356cf9c7c2dbff522671a5d6d33d49c2ba.patch --- linux-3.10.11/debian/patches/rpi/rpi_1232_4bc8e1356cf9c7c2dbff522671a5d6d33d49c2ba.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1232_4bc8e1356cf9c7c2dbff522671a5d6d33d49c2ba.patch 2014-05-05 12:46:22.000000000 +0000 @@ -0,0 +1,66 @@ +commit 4bc8e1356cf9c7c2dbff522671a5d6d33d49c2ba +Author: Daniel Vetter +Date: Tue Sep 10 11:44:30 2013 +0200 + + drm/i915/tv: clear adjusted_mode.flags + + commit 1062b81598bc00e2f6620e6f3788f8f8df2f01e7 upstream. + + The native TV encoder has it's own flags to adjust sync modes and + enabled interlaced modes which are totally irrelevant for the adjusted + mode. This worked out nicely since the input modes used by both the + load detect code and reported in the ->get_modes callbacks all have no + flags set, and we also don't fill out any of them in the ->get_config + callback. + + This changed with the additional sanitation done with + + commit 2960bc9cceecb5d556ce1c07656a6609e2f7e8b0 + Author: Imre Deak + Date: Tue Jul 30 13:36:32 2013 +0300 + + drm/i915: make user mode sync polarity setting explicit + + sinc now the "no flags at all" state wouldn't fit through core code + any more. So fix this up again by explicitly clearing the flags in the + ->compute_config callback. + + Aside: We have zero checking in place to make sure that the requested + mode is indeed the right input mode we want for the selected TV mode. + So we'll happily fall over if userspace tries to pull us. But that's + definitely work for a different patch series. So just add a FIXME + comment for now. + + Reported-by: Knut Petersen + Cc: Knut Petersen + Cc: Imre Deak + Cc: Chris Wilson + Tested-by: Knut Petersen + Signed-off-by: Daniel Vetter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_tv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/i915/intel_tv.c 2014-05-05 11:50:42.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_tv.c 2014-05-05 12:46:22.000000000 +0000 +@@ -921,6 +921,14 @@ + DRM_DEBUG_KMS("forcing bpc to 8 for TV\n"); + pipe_config->pipe_bpp = 8*3; + ++ /* TV has it's own notion of sync and other mode flags, so clear them. */ ++ pipe_config->adjusted_mode.flags = 0; ++ ++ /* ++ * FIXME: We don't check whether the input mode is actually what we want ++ * or whether userspace is doing something stupid. ++ */ ++ + return true; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1232_4bc8e1356cf9c7c2dbff522671a5d6d33d49c2ba.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1232_4bc8e1356cf9c7c2dbff522671a5d6d33d49c2ba.txt 2014-05-05 12:46:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1233_57ad776884c52610af5e00d53e9755f2a8d50bbd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1233_57ad776884c52610af5e00d53e9755f2a8d50bbd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1233_57ad776884c52610af5e00d53e9755f2a8d50bbd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1233_57ad776884c52610af5e00d53e9755f2a8d50bbd.patch 2014-05-05 12:46:23.000000000 +0000 @@ -0,0 +1,150 @@ +commit 57ad776884c52610af5e00d53e9755f2a8d50bbd +Author: Mathias Nyman +Date: Fri Aug 30 18:25:49 2013 +0300 + + xhci: Ensure a command structure points to the correct trb on the command ring + + commit ec7e43e2d98173483866fe2e4e690143626b659c upstream. + + If a command on the command ring needs to be cancelled before it is handled + it can be turned to a no-op operation when the ring is stopped. + We want to store the command ring enqueue pointer in the command structure + when the command in enqueued for the cancellation case. + + Some commands used to store the command ring dequeue pointers instead of enqueue + (these often worked because enqueue happends to equal dequeue quite often) + + Other commands correctly used the enqueue pointer but did not check if it pointed + to a valid trb or a link trb, this caused for example stop endpoint command to timeout in + xhci_stop_device() in about 2% of suspend/resume cases. + + This should also solve some weird behavior happening in command cancellation cases. + + This patch is based on a patch submitted by Sarah Sharp to linux-usb, but + then forgotten: + http://marc.info/?l=linux-usb&m=136269803207465&w=2 + + This patch should be backported to kernels as old as 3.7, that contain + the commit b92cc66c047ff7cf587b318fe377061a353c120f "xHCI: add aborting + command ring function" + + Signed-off-by: Mathias Nyman + Signed-off-by: Sarah Sharp + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/xhci-hub.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci-hub.c 2014-05-05 11:50:42.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci-hub.c 2014-05-05 12:46:22.000000000 +0000 +@@ -286,7 +286,7 @@ + if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) + xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); + } +- cmd->command_trb = xhci->cmd_ring->enqueue; ++ cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); + xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); + xhci_ring_cmd_db(xhci); +Index: linux-3.10-3.10.11/drivers/usb/host/xhci-ring.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci-ring.c 2014-05-05 11:50:42.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci-ring.c 2014-05-05 12:46:23.000000000 +0000 +@@ -122,6 +122,16 @@ + return TRB_TYPE_LINK_LE32(link->control); + } + ++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring) ++{ ++ /* Enqueue pointer can be left pointing to the link TRB, ++ * we must handle that ++ */ ++ if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control)) ++ return ring->enq_seg->next->trbs; ++ return ring->enqueue; ++} ++ + /* Updates trb to point to the next TRB in the ring, and updates seg if the next + * TRB is in a new segment. This does not skip over link TRBs, and it does not + * effect the ring dequeue or enqueue pointers. +Index: linux-3.10-3.10.11/drivers/usb/host/xhci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci.c 2014-05-05 12:44:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci.c 2014-05-05 12:46:23.000000000 +0000 +@@ -2592,15 +2592,7 @@ + if (command) { + cmd_completion = command->completion; + cmd_status = &command->status; +- command->command_trb = xhci->cmd_ring->enqueue; +- +- /* Enqueue pointer can be left pointing to the link TRB, +- * we must handle that +- */ +- if (TRB_TYPE_LINK_LE32(command->command_trb->link.control)) +- command->command_trb = +- xhci->cmd_ring->enq_seg->next->trbs; +- ++ command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + list_add_tail(&command->cmd_list, &virt_dev->cmd_list); + } else { + cmd_completion = &virt_dev->cmd_completion; +@@ -2608,7 +2600,7 @@ + } + init_completion(cmd_completion); + +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + if (!ctx_change) + ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, + udev->slot_id, must_succeed); +@@ -3393,14 +3385,7 @@ + + /* Attempt to submit the Reset Device command to the command ring */ + spin_lock_irqsave(&xhci->lock, flags); +- reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; +- +- /* Enqueue pointer can be left pointing to the link TRB, +- * we must handle that +- */ +- if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control)) +- reset_device_cmd->command_trb = +- xhci->cmd_ring->enq_seg->next->trbs; ++ reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + + list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); + ret = xhci_queue_reset_device(xhci, slot_id); +@@ -3604,7 +3589,7 @@ + union xhci_trb *cmd_trb; + + spin_lock_irqsave(&xhci->lock, flags); +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -3731,7 +3716,7 @@ + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + + spin_lock_irqsave(&xhci->lock, flags); +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, + udev->slot_id); + if (ret) { +Index: linux-3.10-3.10.11/drivers/usb/host/xhci.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci.h 2014-05-05 12:44:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci.h 2014-05-05 12:46:23.000000000 +0000 +@@ -1821,6 +1821,7 @@ + union xhci_trb *cmd_trb); + void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, + unsigned int ep_index, unsigned int stream_id); ++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring); + + /* xHCI roothub code */ + void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, +Index: linux-3.10-3.10.11/dummy/rpi_1233_57ad776884c52610af5e00d53e9755f2a8d50bbd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1233_57ad776884c52610af5e00d53e9755f2a8d50bbd.txt 2014-05-05 12:46:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1234_a9b9047e6dcdfa8472b39d5a3c374d74d89a7f4d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1234_a9b9047e6dcdfa8472b39d5a3c374d74d89a7f4d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1234_a9b9047e6dcdfa8472b39d5a3c374d74d89a7f4d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1234_a9b9047e6dcdfa8472b39d5a3c374d74d89a7f4d.patch 2014-05-05 12:46:24.000000000 +0000 @@ -0,0 +1,48 @@ +commit a9b9047e6dcdfa8472b39d5a3c374d74d89a7f4d +Author: Mathias Nyman +Date: Thu Sep 5 11:01:20 2013 +0300 + + xhci: Fix oops happening after address device timeout + + commit 284d20552461466b04d6bfeafeb1c47a8891b591 upstream. + + When a command times out, the command ring is first aborted, + and then stopped. If the command ring is empty when it is stopped + the stop event will point to next command which is not yet set. + xHCI tries to handle this next event often causing an oops. + + Don't handle command completion events on stopped cmd ring if ring is + empty. + + This patch should be backported to kernels as old as 3.7, that contain + the commit b92cc66c047ff7cf587b318fe377061a353c120f "xHCI: add aborting + command ring function" + + Signed-off-by: Mathias Nyman + Reported-by: Giovanni + Signed-off-by: Sarah Sharp + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/xhci-ring.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci-ring.c 2014-05-05 12:46:23.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci-ring.c 2014-05-05 12:46:23.000000000 +0000 +@@ -1400,6 +1400,12 @@ + inc_deq(xhci, xhci->cmd_ring); + return; + } ++ /* There is no command to handle if we get a stop event when the ++ * command ring is empty, event->cmd_trb points to the next ++ * unset command ++ */ ++ if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) ++ return; + } + + switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) +Index: linux-3.10-3.10.11/dummy/rpi_1234_a9b9047e6dcdfa8472b39d5a3c374d74d89a7f4d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1234_a9b9047e6dcdfa8472b39d5a3c374d74d89a7f4d.txt 2014-05-05 12:46:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1235_c9dd3462b3f99a4a397b7d90265c2e21831ed3a0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1235_c9dd3462b3f99a4a397b7d90265c2e21831ed3a0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1235_c9dd3462b3f99a4a397b7d90265c2e21831ed3a0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1235_c9dd3462b3f99a4a397b7d90265c2e21831ed3a0.patch 2014-05-05 12:46:25.000000000 +0000 @@ -0,0 +1,65 @@ +commit c9dd3462b3f99a4a397b7d90265c2e21831ed3a0 +Author: Alan Stern +Date: Tue Sep 24 15:45:25 2013 -0400 + + USB: fix PM config symbol in uhci-hcd, ehci-hcd, and xhci-hcd + + commit f875fdbf344b9fde207f66b392c40845dd7e5aa6 upstream. + + Since uhci-hcd, ehci-hcd, and xhci-hcd support runtime PM, the .pm + field in their pci_driver structures should be protected by CONFIG_PM + rather than CONFIG_PM_SLEEP. The corresponding change has already + been made for ohci-hcd. + + Without this change, controllers won't do runtime suspend if system + suspend or hibernation isn't enabled. + + Signed-off-by: Alan Stern + CC: Sarah Sharp + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/ehci-pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/ehci-pci.c 2014-05-05 11:50:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/ehci-pci.c 2014-05-05 12:46:24.000000000 +0000 +@@ -403,7 +403,7 @@ + .remove = usb_hcd_pci_remove, + .shutdown = usb_hcd_pci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +Index: linux-3.10-3.10.11/drivers/usb/host/uhci-pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/uhci-pci.c 2014-05-05 11:50:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/uhci-pci.c 2014-05-05 12:46:24.000000000 +0000 +@@ -293,7 +293,7 @@ + .remove = usb_hcd_pci_remove, + .shutdown = uhci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +Index: linux-3.10-3.10.11/drivers/usb/host/xhci-pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci-pci.c 2014-05-05 11:50:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci-pci.c 2014-05-05 12:46:24.000000000 +0000 +@@ -345,7 +345,7 @@ + /* suspend and resume implemented later */ + + .shutdown = usb_hcd_pci_shutdown, +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +Index: linux-3.10-3.10.11/dummy/rpi_1235_c9dd3462b3f99a4a397b7d90265c2e21831ed3a0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1235_c9dd3462b3f99a4a397b7d90265c2e21831ed3a0.txt 2014-05-05 12:46:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1236_27e08a9885a9dab816af72f86b92f2f3513e8314.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1236_27e08a9885a9dab816af72f86b92f2f3513e8314.patch --- linux-3.10.11/debian/patches/rpi/rpi_1236_27e08a9885a9dab816af72f86b92f2f3513e8314.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1236_27e08a9885a9dab816af72f86b92f2f3513e8314.patch 2014-05-05 12:46:26.000000000 +0000 @@ -0,0 +1,44 @@ +commit 27e08a9885a9dab816af72f86b92f2f3513e8314 +Author: Florian Wolter +Date: Wed Aug 14 10:33:16 2013 +0200 + + xhci: Fix race between ep halt and URB cancellation + + commit 526867c3ca0caa2e3e846cb993b0f961c33c2abb upstream. + + The halted state of a endpoint cannot be cleared over CLEAR_HALT from a + user process, because the stopped_td variable was overwritten in the + handle_stopped_endpoint() function. So the xhci_endpoint_reset() function will + refuse the reset and communication with device can not run over this endpoint. + https://bugzilla.kernel.org/show_bug.cgi?id=60699 + + Signed-off-by: Florian Wolter + Signed-off-by: Sarah Sharp + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/xhci-ring.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/xhci-ring.c 2014-05-05 12:46:23.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/xhci-ring.c 2014-05-05 12:46:25.000000000 +0000 +@@ -857,8 +857,12 @@ + /* Otherwise ring the doorbell(s) to restart queued transfers */ + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + } +- ep->stopped_td = NULL; +- ep->stopped_trb = NULL; ++ ++ /* Clear stopped_td and stopped_trb if endpoint is not halted */ ++ if (!(ep->ep_state & EP_HALTED)) { ++ ep->stopped_td = NULL; ++ ep->stopped_trb = NULL; ++ } + + /* + * Drop the lock and complete the URBs in the cancelled TD list. +Index: linux-3.10-3.10.11/dummy/rpi_1236_27e08a9885a9dab816af72f86b92f2f3513e8314.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1236_27e08a9885a9dab816af72f86b92f2f3513e8314.txt 2014-05-05 12:46:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1237_7ca9229cd69ae54e9e124c6643e26c977dd82a6f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1237_7ca9229cd69ae54e9e124c6643e26c977dd82a6f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1237_7ca9229cd69ae54e9e124c6643e26c977dd82a6f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1237_7ca9229cd69ae54e9e124c6643e26c977dd82a6f.patch 2014-05-05 12:46:27.000000000 +0000 @@ -0,0 +1,168 @@ +commit 7ca9229cd69ae54e9e124c6643e26c977dd82a6f +Author: Alan Stern +Date: Tue Sep 24 15:46:45 2013 -0400 + + USB: OHCI: accept very late isochronous URBs + + commit a8693424c751b8247ee19bd8b857f1d4f432b972 upstream. + + Commit 24f531371de1 (USB: EHCI: accept very late isochronous URBs) + changed the isochronous API provided by ehci-hcd. URBs submitted too + late, so that the time slots for all their packets have already + expired, are no longer rejected outright. Instead the submission is + accepted, and the URB completes normally with a -EXDEV error for each + packet. This is what client drivers expect. + + This patch implements the same policy in ohci-hcd. The change is more + complicated than it was in ehci-hcd, because ohci-hcd doesn't scan for + isochronous completions in the same way as ehci-hcd does. Rather, it + depends on the hardware adding completed TDs to a "done queue". Some + OHCI controller don't handle this properly when a TD's time slot has + already expired, so we have to avoid adding such TDs to the schedule + in the first place. As a result, if the URB was submitted too late + then none of its TDs will get put on the schedule, so none of them + will end up on the done queue, so the driver will never realize that + the URB should be completed. + + To solve this problem, the patch adds one to urb_priv->td_cnt for such + URBs, making it larger than urb_priv->length (td_cnt already gets set + to the number of TD's that had to be skipped because their slots have + expired). Each time an URB is given back, the finish_urb() routine + looks to see if urb_priv->td_cnt for the next URB on the same endpoint + is marked in this way. If so, it gives back the next URB right away. + + This should be applied to all kernels containing commit 815fa7b91761 + (USB: OHCI: fix logic for scheduling isochronous URBs). + + Signed-off-by: Alan Stern + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/ohci-hcd.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/ohci-hcd.c 2014-05-05 11:50:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/ohci-hcd.c 2014-05-05 12:46:26.000000000 +0000 +@@ -231,31 +231,26 @@ + frame &= ~(ed->interval - 1); + frame |= ed->branch; + urb->start_frame = frame; ++ ed->last_iso = frame + ed->interval * (size - 1); + } + } else if (ed->type == PIPE_ISOCHRONOUS) { + u16 next = ohci_frame_no(ohci) + 1; + u16 frame = ed->last_iso + ed->interval; ++ u16 length = ed->interval * (size - 1); + + /* Behind the scheduling threshold? */ + if (unlikely(tick_before(frame, next))) { + +- /* USB_ISO_ASAP: Round up to the first available slot */ ++ /* URB_ISO_ASAP: Round up to the first available slot */ + if (urb->transfer_flags & URB_ISO_ASAP) { + frame += (next - frame + ed->interval - 1) & + -ed->interval; + + /* +- * Not ASAP: Use the next slot in the stream. If +- * the entire URB falls before the threshold, fail. ++ * Not ASAP: Use the next slot in the stream, ++ * no matter what. + */ + } else { +- if (tick_before(frame + ed->interval * +- (urb->number_of_packets - 1), next)) { +- retval = -EXDEV; +- usb_hcd_unlink_urb_from_ep(hcd, urb); +- goto fail; +- } +- + /* + * Some OHCI hardware doesn't handle late TDs + * correctly. After retiring them it proceeds +@@ -266,9 +261,16 @@ + urb_priv->td_cnt = DIV_ROUND_UP( + (u16) (next - frame), + ed->interval); ++ if (urb_priv->td_cnt >= urb_priv->length) { ++ ++urb_priv->td_cnt; /* Mark it */ ++ ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n", ++ urb, frame, length, ++ next); ++ } + } + } + urb->start_frame = frame; ++ ed->last_iso = frame + length; + } + + /* fill the TDs and link them to the ed; and +Index: linux-3.10-3.10.11/drivers/usb/host/ohci-q.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/ohci-q.c 2014-05-05 11:50:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/ohci-q.c 2014-05-05 12:46:26.000000000 +0000 +@@ -41,8 +41,12 @@ + __releases(ohci->lock) + __acquires(ohci->lock) + { ++ struct usb_host_endpoint *ep = urb->ep; ++ struct urb_priv *urb_priv; ++ + // ASSERT (urb->hcpriv != 0); + ++ restart: + urb_free_priv (ohci, urb->hcpriv); + urb->hcpriv = NULL; + if (likely(status == -EINPROGRESS)) +@@ -79,6 +83,21 @@ + ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE); + ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); + } ++ ++ /* ++ * An isochronous URB that is sumitted too late won't have any TDs ++ * (marked by the fact that the td_cnt value is larger than the ++ * actual number of TDs). If the next URB on this endpoint is like ++ * that, give it back now. ++ */ ++ if (!list_empty(&ep->urb_list)) { ++ urb = list_first_entry(&ep->urb_list, struct urb, urb_list); ++ urb_priv = urb->hcpriv; ++ if (urb_priv->td_cnt > urb_priv->length) { ++ status = 0; ++ goto restart; ++ } ++ } + } + + +@@ -545,7 +564,6 @@ + td->hwCBP = cpu_to_hc32 (ohci, data & 0xFFFFF000); + *ohci_hwPSWp(ohci, td, 0) = cpu_to_hc16 (ohci, + (data & 0x0FFF) | 0xE000); +- td->ed->last_iso = info & 0xffff; + } else { + td->hwCBP = cpu_to_hc32 (ohci, data); + } +@@ -994,7 +1012,7 @@ + urb_priv->td_cnt++; + + /* if URB is done, clean up */ +- if (urb_priv->td_cnt == urb_priv->length) { ++ if (urb_priv->td_cnt >= urb_priv->length) { + modified = completed = 1; + finish_urb(ohci, urb, 0); + } +@@ -1084,7 +1102,7 @@ + urb_priv->td_cnt++; + + /* If all this urb's TDs are done, call complete() */ +- if (urb_priv->td_cnt == urb_priv->length) ++ if (urb_priv->td_cnt >= urb_priv->length) + finish_urb(ohci, urb, status); + + /* clean schedule: unlink EDs that are no longer busy */ +Index: linux-3.10-3.10.11/dummy/rpi_1237_7ca9229cd69ae54e9e124c6643e26c977dd82a6f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1237_7ca9229cd69ae54e9e124c6643e26c977dd82a6f.txt 2014-05-05 12:46:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1238_01ec662c0cfe0304b583ab5b8a6aa8797f4c9828.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1238_01ec662c0cfe0304b583ab5b8a6aa8797f4c9828.patch --- linux-3.10.11/debian/patches/rpi/rpi_1238_01ec662c0cfe0304b583ab5b8a6aa8797f4c9828.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1238_01ec662c0cfe0304b583ab5b8a6aa8797f4c9828.patch 2014-05-05 12:46:27.000000000 +0000 @@ -0,0 +1,62 @@ +commit 01ec662c0cfe0304b583ab5b8a6aa8797f4c9828 +Author: Alan Stern +Date: Tue Sep 24 15:47:20 2013 -0400 + + USB: UHCI: accept very late isochronous URBs + + commit bef073b067a7b1874a6b381e0035bb0516d71a77 upstream. + + Commit 24f531371de1 (USB: EHCI: accept very late isochronous URBs) + changed the isochronous API provided by ehci-hcd. URBs submitted too + late, so that the time slots for all their packets have already + expired, are no longer rejected outright. Instead the submission is + accepted, and the URB completes normally with a -EXDEV error for each + packet. This is what client drivers expect. + + This patch implements the same policy in uhci-hcd. It should be + applied to all kernels containing commit c44b225077bb (UHCI: implement + new semantics for URB_ISO_ASAP). + + Signed-off-by: Alan Stern + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/uhci-q.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/uhci-q.c 2014-05-05 11:50:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/uhci-q.c 2014-05-05 12:46:27.000000000 +0000 +@@ -1303,7 +1303,7 @@ + } + + /* Fell behind? */ +- if (uhci_frame_before_eq(frame, next)) { ++ if (!uhci_frame_before_eq(next, frame)) { + + /* USB_ISO_ASAP: Round up to the first available slot */ + if (urb->transfer_flags & URB_ISO_ASAP) +@@ -1311,13 +1311,17 @@ + -qh->period; + + /* +- * Not ASAP: Use the next slot in the stream. If +- * the entire URB falls before the threshold, fail. ++ * Not ASAP: Use the next slot in the stream, ++ * no matter what. + */ + else if (!uhci_frame_before_eq(next, + frame + (urb->number_of_packets - 1) * + qh->period)) +- return -EXDEV; ++ dev_dbg(uhci_dev(uhci), "iso underrun %p (%u+%u < %u)\n", ++ urb, frame, ++ (urb->number_of_packets - 1) * ++ qh->period, ++ next); + } + } + +Index: linux-3.10-3.10.11/dummy/rpi_1238_01ec662c0cfe0304b583ab5b8a6aa8797f4c9828.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1238_01ec662c0cfe0304b583ab5b8a6aa8797f4c9828.txt 2014-05-05 12:46:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1239_88b1befdb45f9f5aee5d00a22c4c06bdf5193d4e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1239_88b1befdb45f9f5aee5d00a22c4c06bdf5193d4e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1239_88b1befdb45f9f5aee5d00a22c4c06bdf5193d4e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1239_88b1befdb45f9f5aee5d00a22c4c06bdf5193d4e.patch 2014-05-05 12:46:28.000000000 +0000 @@ -0,0 +1,190 @@ +commit 88b1befdb45f9f5aee5d00a22c4c06bdf5193d4e +Author: Al Viro +Date: Fri Sep 20 17:14:21 2013 +0100 + + USB: Fix breakage in ffs_fs_mount() + + commit 2606b28aabd7dea1766c23a105e1124c95409c96 upstream. + + There's a bunch of failure exits in ffs_fs_mount() with + seriously broken recovery logics. Most of that appears to stem + from misunderstanding of the ->kill_sb() semantics; unlike + ->put_super() it is called for *all* superblocks of given type, + no matter how (in)complete the setup had been. ->put_super() + is called only if ->s_root is not NULL; any failure prior to + setting ->s_root will have the call of ->put_super() skipped. + ->kill_sb(), OTOH, awaits every superblock that has come from + sget(). + + Current behaviour of ffs_fs_mount(): + + We have struct ffs_sb_fill_data data on stack there. We do + ffs_dev = functionfs_acquire_dev_callback(dev_name); + and store that in data.private_data. Then we call mount_nodev(), + passing it ffs_sb_fill() as a callback. That will either fail + outright, or manage to call ffs_sb_fill(). There we allocate an + instance of struct ffs_data, slap the value of ffs_dev (picked + from data.private_data) into ffs->private_data and overwrite + data.private_data by storing ffs into an overlapping member + (data.ffs_data). Then we store ffs into sb->s_fs_info and attempt + to set the rest of the things up (root inode, root dentry, then + create /ep0 there). Any of those might fail. Should that + happen, we get ffs_fs_kill_sb() called before mount_nodev() + returns. If mount_nodev() fails for any reason whatsoever, + we proceed to + functionfs_release_dev_callback(data.ffs_data); + + That's broken in a lot of ways. Suppose the thing has failed in + allocation of e.g. root inode or dentry. We have + functionfs_release_dev_callback(ffs); + ffs_data_put(ffs); + done by ffs_fs_kill_sb() (ffs accessed via sb->s_fs_info), followed by + functionfs_release_dev_callback(ffs); + from ffs_fs_mount() (via data.ffs_data). Note that the second + functionfs_release_dev_callback() has every chance to be done to freed memory. + + Suppose we fail *before* root inode allocation. What happens then? + ffs_fs_kill_sb() doesn't do anything to ffs (it's either not called at all, + or it doesn't have a pointer to ffs stored in sb->s_fs_info). And + functionfs_release_dev_callback(data.ffs_data); + is called by ffs_fs_mount(), but here we are in nasal daemon country - we + are reading from a member of union we'd never stored into. In practice, + we'll get what we used to store into the overlapping field, i.e. ffs_dev. + And then we get screwed, since we treat it (struct gfs_ffs_obj * in + disguise, returned by functionfs_acquire_dev_callback()) as struct + ffs_data *, pick what would've been ffs_data ->private_data from it + (*well* past the actual end of the struct gfs_ffs_obj - struct ffs_data + is much bigger) and poke in whatever it points to. + + FWIW, there's a minor leak on top of all that in case if ffs_sb_fill() + fails on kstrdup() - ffs is obviously forgotten. + + The thing is, there is no point in playing all those games with union. + Just allocate and initialize ffs_data *before* calling mount_nodev() and + pass a pointer to it via data.ffs_data. And once it's stored in + sb->s_fs_info, clear data.ffs_data, so that ffs_fs_mount() knows that + it doesn't need to kill the sucker manually - from that point on + we'll have it done by ->kill_sb(). + + Signed-off-by: Al Viro + Acked-by: Michal Nazarewicz + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/gadget/f_fs.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/gadget/f_fs.c 2014-05-05 11:50:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/gadget/f_fs.c 2014-05-05 12:46:28.000000000 +0000 +@@ -1034,37 +1034,19 @@ + struct ffs_file_perms perms; + umode_t root_mode; + const char *dev_name; +- union { +- /* set by ffs_fs_mount(), read by ffs_sb_fill() */ +- void *private_data; +- /* set by ffs_sb_fill(), read by ffs_fs_mount */ +- struct ffs_data *ffs_data; +- }; ++ struct ffs_data *ffs_data; + }; + + static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) + { + struct ffs_sb_fill_data *data = _data; + struct inode *inode; +- struct ffs_data *ffs; ++ struct ffs_data *ffs = data->ffs_data; + + ENTER(); + +- /* Initialise data */ +- ffs = ffs_data_new(); +- if (unlikely(!ffs)) +- goto Enomem; +- + ffs->sb = sb; +- ffs->dev_name = kstrdup(data->dev_name, GFP_KERNEL); +- if (unlikely(!ffs->dev_name)) +- goto Enomem; +- ffs->file_perms = data->perms; +- ffs->private_data = data->private_data; +- +- /* used by the caller of this function */ +- data->ffs_data = ffs; +- ++ data->ffs_data = NULL; + sb->s_fs_info = ffs; + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; +@@ -1080,17 +1062,14 @@ + &data->perms); + sb->s_root = d_make_root(inode); + if (unlikely(!sb->s_root)) +- goto Enomem; ++ return -ENOMEM; + + /* EP0 file */ + if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, + &ffs_ep0_operations, NULL))) +- goto Enomem; ++ return -ENOMEM; + + return 0; +- +-Enomem: +- return -ENOMEM; + } + + static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) +@@ -1193,6 +1172,7 @@ + struct dentry *rv; + int ret; + void *ffs_dev; ++ struct ffs_data *ffs; + + ENTER(); + +@@ -1200,18 +1180,30 @@ + if (unlikely(ret < 0)) + return ERR_PTR(ret); + ++ ffs = ffs_data_new(); ++ if (unlikely(!ffs)) ++ return ERR_PTR(-ENOMEM); ++ ffs->file_perms = data.perms; ++ ++ ffs->dev_name = kstrdup(dev_name, GFP_KERNEL); ++ if (unlikely(!ffs->dev_name)) { ++ ffs_data_put(ffs); ++ return ERR_PTR(-ENOMEM); ++ } ++ + ffs_dev = functionfs_acquire_dev_callback(dev_name); +- if (IS_ERR(ffs_dev)) +- return ffs_dev; ++ if (IS_ERR(ffs_dev)) { ++ ffs_data_put(ffs); ++ return ERR_CAST(ffs_dev); ++ } ++ ffs->private_data = ffs_dev; ++ data.ffs_data = ffs; + +- data.dev_name = dev_name; +- data.private_data = ffs_dev; + rv = mount_nodev(t, flags, &data, ffs_sb_fill); +- +- /* data.ffs_data is set by ffs_sb_fill */ +- if (IS_ERR(rv)) ++ if (IS_ERR(rv) && data.ffs_data) { + functionfs_release_dev_callback(data.ffs_data); +- ++ ffs_data_put(data.ffs_data); ++ } + return rv; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1239_88b1befdb45f9f5aee5d00a22c4c06bdf5193d4e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1239_88b1befdb45f9f5aee5d00a22c4c06bdf5193d4e.txt 2014-05-05 12:46:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1240_07fa74e048755aa8ff07a513e2362722a1c282e7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1240_07fa74e048755aa8ff07a513e2362722a1c282e7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1240_07fa74e048755aa8ff07a513e2362722a1c282e7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1240_07fa74e048755aa8ff07a513e2362722a1c282e7.patch 2014-05-05 12:46:29.000000000 +0000 @@ -0,0 +1,53 @@ +commit 07fa74e048755aa8ff07a513e2362722a1c282e7 +Author: Ramneek Mehresh +Date: Mon Sep 16 15:11:33 2013 +0530 + + fsl/usb: Resolve PHY_CLK_VLD instability issue for ULPI phy + + commit ad1260e9fbf768d6bed227d9604ebee76a84aae3 upstream. + + For controller versions greater than 1.6, setting ULPI_PHY_CLK_SEL + bit when USB_EN bit is already set causes instability issues with + PHY_CLK_VLD bit. So USB_EN is set only for IP controller version + below 1.6 before setting ULPI_PHY_CLK_SEL bit + + Signed-off-by: Ramneek Mehresh + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/host/ehci-fsl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/ehci-fsl.c 2014-05-05 11:50:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/ehci-fsl.c 2014-05-05 12:46:29.000000000 +0000 +@@ -130,7 +130,7 @@ + } + + /* Enable USB controller, 83xx or 8536 */ +- if (pdata->have_sysif_regs) ++ if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) + setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4); + + /* Don't need to set host mode here. It will be done by tdi_reset() */ +@@ -232,15 +232,9 @@ + case FSL_USB2_PHY_ULPI: + if (pdata->have_sysif_regs && pdata->controller_ver) { + /* controller version 1.6 or above */ ++ clrbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN); + setbits32(non_ehci + FSL_SOC_USB_CTRL, +- ULPI_PHY_CLK_SEL); +- /* +- * Due to controller issue of PHY_CLK_VALID in ULPI +- * mode, we set USB_CTRL_USB_EN before checking +- * PHY_CLK_VALID, otherwise PHY_CLK_VALID doesn't work. +- */ +- clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, +- UTMI_PHY_EN, USB_CTRL_USB_EN); ++ ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN); + } + portsc |= PORT_PTS_ULPI; + break; +Index: linux-3.10-3.10.11/dummy/rpi_1240_07fa74e048755aa8ff07a513e2362722a1c282e7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1240_07fa74e048755aa8ff07a513e2362722a1c282e7.txt 2014-05-05 12:46:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1241_85f78609d213684c3079a0e1716ee6082868814d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1241_85f78609d213684c3079a0e1716ee6082868814d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1241_85f78609d213684c3079a0e1716ee6082868814d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1241_85f78609d213684c3079a0e1716ee6082868814d.patch 2014-05-05 12:46:30.000000000 +0000 @@ -0,0 +1,40 @@ +commit 85f78609d213684c3079a0e1716ee6082868814d +Author: Heikki Krogerus +Date: Tue Sep 17 10:38:13 2013 +0300 + + usb: dwc3: pci: add support for BayTrail + + commit b62cd96de3161dfb125a769030eec35a4cab3d3a upstream. + + Add PCI id for Intel BayTrail. + + Signed-off-by: Heikki Krogerus + Signed-off-by: Felipe Balbi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/dwc3/dwc3-pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/dwc3/dwc3-pci.c 2014-05-05 11:50:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/dwc3/dwc3-pci.c 2014-05-05 12:46:29.000000000 +0000 +@@ -48,6 +48,7 @@ + /* FIXME define these in */ + #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd ++#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 + + struct dwc3_pci { + struct device *dev; +@@ -208,6 +209,7 @@ + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), + }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, + { } /* Terminating Entry */ + }; + MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); +Index: linux-3.10-3.10.11/dummy/rpi_1241_85f78609d213684c3079a0e1716ee6082868814d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1241_85f78609d213684c3079a0e1716ee6082868814d.txt 2014-05-05 12:46:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1242_3dbfe91ab236d6edd20c52d87b99c5de8b85429d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1242_3dbfe91ab236d6edd20c52d87b99c5de8b85429d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1242_3dbfe91ab236d6edd20c52d87b99c5de8b85429d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1242_3dbfe91ab236d6edd20c52d87b99c5de8b85429d.patch 2014-05-05 12:46:31.000000000 +0000 @@ -0,0 +1,39 @@ +commit 3dbfe91ab236d6edd20c52d87b99c5de8b85429d +Author: David Cohen +Date: Thu Sep 26 13:01:44 2013 -0700 + + usb: dwc3: add support for Merrifield + + commit 85601f8cf67c56a561a6dd5e130e65fdc179047d upstream. + + Add PCI id for Intel Merrifield + + Signed-off-by: David Cohen + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/dwc3/dwc3-pci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/dwc3/dwc3-pci.c 2014-05-05 12:46:29.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/dwc3/dwc3-pci.c 2014-05-05 12:46:30.000000000 +0000 +@@ -49,6 +49,7 @@ + #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd + #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 ++#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e + + struct dwc3_pci { + struct device *dev; +@@ -210,6 +211,7 @@ + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), + }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, + { } /* Terminating Entry */ + }; + MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); +Index: linux-3.10-3.10.11/dummy/rpi_1242_3dbfe91ab236d6edd20c52d87b99c5de8b85429d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1242_3dbfe91ab236d6edd20c52d87b99c5de8b85429d.txt 2014-05-05 12:46:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1243_0ce8614959e1630ed3ce1fd36a689e80ca945f94.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1243_0ce8614959e1630ed3ce1fd36a689e80ca945f94.patch --- linux-3.10.11/debian/patches/rpi/rpi_1243_0ce8614959e1630ed3ce1fd36a689e80ca945f94.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1243_0ce8614959e1630ed3ce1fd36a689e80ca945f94.patch 2014-05-05 12:46:32.000000000 +0000 @@ -0,0 +1,86 @@ +commit 0ce8614959e1630ed3ce1fd36a689e80ca945f94 +Author: Kurt Garloff +Date: Tue Sep 24 14:13:48 2013 +0200 + + usb/core/devio.c: Don't reject control message to endpoint with wrong direction bit + + commit 831abf76643555a99b80a3b54adfa7e4fa0a3259 upstream. + + Trying to read data from the Pegasus Technologies NoteTaker (0e20:0101) + [1] with the Windows App (EasyNote) works natively but fails when + Windows is running under KVM (and the USB device handed to KVM). + + The reason is a USB control message + usb 4-2.2: control urb: bRequestType=22 bRequest=09 wValue=0200 wIndex=0001 wLength=0008 + This goes to endpoint address 0x01 (wIndex); however, endpoint address + 0x01 does not exist. There is an endpoint 0x81 though (same number, + but other direction); the app may have meant that endpoint instead. + + The kernel thus rejects the IO and thus we see the failure. + + Apparently, Linux is more strict here than Windows ... we can't change + the Win app easily, so that's a problem. + + It seems that the Win app/driver is buggy here and the driver does not + behave fully according to the USB HID class spec that it claims to + belong to. The device seems to happily deal with that though (and + seems to not really care about this value much). + + So the question is whether the Linux kernel should filter here. + Rejecting has the risk that somewhat non-compliant userspace apps/ + drivers (most likely in a virtual machine) are prevented from working. + Not rejecting has the risk of confusing an overly sensitive device with + such a transfer. Given the fact that Windows does not filter it makes + this risk rather small though. + + The patch makes the kernel more tolerant: If the endpoint address in + wIndex does not exist, but an endpoint with toggled direction bit does, + it will let the transfer through. (It does NOT change the message.) + + With attached patch, the app in Windows in KVM works. + usb 4-2.2: check_ctrlrecip: process 13073 (qemu-kvm) requesting ep 01 but needs 81 + + I suspect this will mostly affect apps in virtual environments; as on + Linux the apps would have been adapted to the stricter handling of the + kernel. I have done that for mine[2]. + + [1] http://www.pegatech.com/ + [2] https://sourceforge.net/projects/notetakerpen/ + + Signed-off-by: Kurt Garloff + Acked-by: Alan Stern + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/core/devio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/devio.c 2014-05-05 11:50:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/devio.c 2014-05-05 12:46:31.000000000 +0000 +@@ -742,6 +742,22 @@ + if ((index & ~USB_DIR_IN) == 0) + return 0; + ret = findintfep(ps->dev, index); ++ if (ret < 0) { ++ /* ++ * Some not fully compliant Win apps seem to get ++ * index wrong and have the endpoint number here ++ * rather than the endpoint address (with the ++ * correct direction). Win does let this through, ++ * so we'll not reject it here but leave it to ++ * the device to not break KVM. But we warn. ++ */ ++ ret = findintfep(ps->dev, index ^ 0x80); ++ if (ret >= 0) ++ dev_info(&ps->dev->dev, ++ "%s: process %i (%s) requesting ep %02x but needs %02x\n", ++ __func__, task_pid_nr(current), ++ current->comm, index, index ^ 0x80); ++ } + if (ret >= 0) + ret = checkintf(ps, ret); + break; +Index: linux-3.10-3.10.11/dummy/rpi_1243_0ce8614959e1630ed3ce1fd36a689e80ca945f94.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1243_0ce8614959e1630ed3ce1fd36a689e80ca945f94.txt 2014-05-05 12:46:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1244_78421afdbf0ac17baee98a9caed80c8141a121d3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1244_78421afdbf0ac17baee98a9caed80c8141a121d3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1244_78421afdbf0ac17baee98a9caed80c8141a121d3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1244_78421afdbf0ac17baee98a9caed80c8141a121d3.patch 2014-05-05 12:46:32.000000000 +0000 @@ -0,0 +1,94 @@ +commit 78421afdbf0ac17baee98a9caed80c8141a121d3 +Author: Benson Leung +Date: Tue Sep 24 20:05:11 2013 -0700 + + driver core : Fix use after free of dev->parent in device_shutdown + + commit f123db8e9d6c84c863cb3c44d17e61995dc984fb upstream. + + The put_device(dev) at the bottom of the loop of device_shutdown + may result in the dev being cleaned up. In device_create_release, + the dev is kfreed. + + However, device_shutdown attempts to use the dev pointer again after + put_device by referring to dev->parent. + + Copy the parent pointer instead to avoid this condition. + + This bug was found on Chromium OS's chromeos-3.8, which is based on v3.8.11. + See bug report : https://code.google.com/p/chromium/issues/detail?id=297842 + This can easily be reproduced when shutting down with + hidraw devices that report battery condition. + Two examples are the HP Bluetooth Mouse X4000b and the Apple Magic Mouse. + For example, with the magic mouse : + The dev in question is "hidraw0" + dev->parent is "magicmouse" + + In the course of the shutdown for this device, the input event cleanup calls + a put on hidraw0, decrementing its reference count. + When we finally get to put_device(dev) in device_shutdown, kobject_cleanup + is called and device_create_release does kfree(dev). + dev->parent is no longer valid, and we may crash in + put_device(dev->parent). + + This change should be applied on any kernel with this change : + d1c6c030fcec6f860d9bb6c632a3ebe62e28440b + + Signed-off-by: Benson Leung + Reviewed-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/base/core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/base/core.c 2014-05-05 11:50:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/base/core.c 2014-05-05 12:46:32.000000000 +0000 +@@ -1839,7 +1839,7 @@ + */ + void device_shutdown(void) + { +- struct device *dev; ++ struct device *dev, *parent; + + spin_lock(&devices_kset->list_lock); + /* +@@ -1856,7 +1856,7 @@ + * prevent it from being freed because parent's + * lock is to be held + */ +- get_device(dev->parent); ++ parent = get_device(dev->parent); + get_device(dev); + /* + * Make sure the device is off the kset list, in the +@@ -1866,8 +1866,8 @@ + spin_unlock(&devices_kset->list_lock); + + /* hold lock to avoid race with probe/release */ +- if (dev->parent) +- device_lock(dev->parent); ++ if (parent) ++ device_lock(parent); + device_lock(dev); + + /* Don't allow any more runtime suspends */ +@@ -1885,11 +1885,11 @@ + } + + device_unlock(dev); +- if (dev->parent) +- device_unlock(dev->parent); ++ if (parent) ++ device_unlock(parent); + + put_device(dev); +- put_device(dev->parent); ++ put_device(parent); + + spin_lock(&devices_kset->list_lock); + } +Index: linux-3.10-3.10.11/dummy/rpi_1244_78421afdbf0ac17baee98a9caed80c8141a121d3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1244_78421afdbf0ac17baee98a9caed80c8141a121d3.txt 2014-05-05 12:46:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1245_4541f4e356fe1d9d47165a041f85235e394b0d61.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1245_4541f4e356fe1d9d47165a041f85235e394b0d61.patch --- linux-3.10.11/debian/patches/rpi/rpi_1245_4541f4e356fe1d9d47165a041f85235e394b0d61.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1245_4541f4e356fe1d9d47165a041f85235e394b0d61.patch 2014-05-05 12:46:33.000000000 +0000 @@ -0,0 +1,50 @@ +commit 4541f4e356fe1d9d47165a041f85235e394b0d61 +Author: Mikulas Patocka +Date: Wed Sep 18 19:14:22 2013 -0400 + + dm snapshot: workaround for a false positive lockdep warning + + commit 5ea330a75bd86b2b2a01d7b85c516983238306fb upstream. + + The kernel reports a lockdep warning if a snapshot is invalidated because + it runs out of space. + + The lockdep warning was triggered by commit 0976dfc1d0cd80a4e9dfaf87bd87 + ("workqueue: Catch more locking problems with flush_work()") in v3.5. + + The warning is false positive. The real cause for the warning is that + the lockdep engine treats different instances of md->lock as a single + lock. + + This patch is a workaround - we use flush_workqueue instead of flush_work. + This code path is not performance sensitive (it is called only on + initialization or invalidation), thus it doesn't matter that we flush the + whole workqueue. + + The real fix for the problem would be to teach the lockdep engine to treat + different instances of md->lock as separate locks. + + Signed-off-by: Mikulas Patocka + Acked-by: Alasdair G Kergon + Signed-off-by: Mike Snitzer + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/dm-snap-persistent.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/dm-snap-persistent.c 2014-05-05 11:50:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/dm-snap-persistent.c 2014-05-05 12:46:33.000000000 +0000 +@@ -256,7 +256,7 @@ + */ + INIT_WORK_ONSTACK(&req.work, do_metadata); + queue_work(ps->metadata_wq, &req.work); +- flush_work(&req.work); ++ flush_workqueue(ps->metadata_wq); + + return req.result; + } +Index: linux-3.10-3.10.11/dummy/rpi_1245_4541f4e356fe1d9d47165a041f85235e394b0d61.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1245_4541f4e356fe1d9d47165a041f85235e394b0d61.txt 2014-05-05 12:46:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1246_0f64fad39c9577f3eaa26b45a9ad774c415c19ff.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1246_0f64fad39c9577f3eaa26b45a9ad774c415c19ff.patch --- linux-3.10.11/debian/patches/rpi/rpi_1246_0f64fad39c9577f3eaa26b45a9ad774c415c19ff.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1246_0f64fad39c9577f3eaa26b45a9ad774c415c19ff.patch 2014-05-05 12:46:34.000000000 +0000 @@ -0,0 +1,53 @@ +commit 0f64fad39c9577f3eaa26b45a9ad774c415c19ff +Author: Mikulas Patocka +Date: Wed Sep 18 19:40:42 2013 -0400 + + dm-snapshot: fix performance degradation due to small hash size + + commit 60e356f381954d79088d0455e357db48cfdd6857 upstream. + + LVM2, since version 2.02.96, creates origin with zero size, then loads + the snapshot driver and then loads the origin. Consequently, the + snapshot driver sees the origin size zero and sets the hash size to the + lower bound 64. Such small hash table causes performance degradation. + + This patch changes it so that the hash size is determined by the size of + snapshot volume, not minimum of origin and snapshot size. It doesn't + make sense to set the snapshot size significantly larger than the origin + size, so we do not need to take origin size into account when + calculating the hash size. + + Signed-off-by: Mikulas Patocka + Signed-off-by: Mike Snitzer + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/dm-snap.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/dm-snap.c 2014-05-05 11:50:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/dm-snap.c 2014-05-05 12:46:33.000000000 +0000 +@@ -725,17 +725,16 @@ + */ + static int init_hash_tables(struct dm_snapshot *s) + { +- sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; ++ sector_t hash_size, cow_dev_size, max_buckets; + + /* + * Calculate based on the size of the original volume or + * the COW volume... + */ + cow_dev_size = get_dev_size(s->cow->bdev); +- origin_dev_size = get_dev_size(s->origin->bdev); + max_buckets = calc_max_buckets(); + +- hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; ++ hash_size = cow_dev_size >> s->store->chunk_shift; + hash_size = min(hash_size, max_buckets); + + if (hash_size < 64) +Index: linux-3.10-3.10.11/dummy/rpi_1246_0f64fad39c9577f3eaa26b45a9ad774c415c19ff.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1246_0f64fad39c9577f3eaa26b45a9ad774c415c19ff.txt 2014-05-05 12:46:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1247_e9d60f699108682bad9c4604feb408ac9198b232.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1247_e9d60f699108682bad9c4604feb408ac9198b232.patch --- linux-3.10.11/debian/patches/rpi/rpi_1247_e9d60f699108682bad9c4604feb408ac9198b232.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1247_e9d60f699108682bad9c4604feb408ac9198b232.patch 2014-05-05 12:46:35.000000000 +0000 @@ -0,0 +1,157 @@ +commit e9d60f699108682bad9c4604feb408ac9198b232 +Author: Mike Snitzer +Date: Thu Sep 19 12:13:58 2013 -0400 + + dm mpath: disable WRITE SAME if it fails + + commit f84cb8a46a771f36a04a02c61ea635c968ed5f6a upstream. + + Workaround the SCSI layer's problematic WRITE SAME heuristics by + disabling WRITE SAME in the DM multipath device's queue_limits if an + underlying device disabled it. + + The WRITE SAME heuristics, with both the original commit 5db44863b6eb + ("[SCSI] sd: Implement support for WRITE SAME") and the updated commit + 66c28f971 ("[SCSI] sd: Update WRITE SAME heuristics"), default to enabling + WRITE SAME(10) even without successfully determining it is supported. + After the first failed WRITE SAME the SCSI layer will disable WRITE SAME + for the device (by setting sdkp->device->no_write_same which results in + 'max_write_same_sectors' in device's queue_limits to be set to 0). + + When a device is stacked ontop of such a SCSI device any changes to that + SCSI device's queue_limits do not automatically propagate up the stack. + As such, a DM multipath device will not have its WRITE SAME support + disabled. This causes the block layer to continue to issue WRITE SAME + requests to the mpath device which causes paths to fail and (if mpath IO + isn't configured to queue when no paths are available) it will result in + actual IO errors to the upper layers. + + This fix doesn't help configurations that have additional devices + stacked ontop of the mpath device (e.g. LVM created linear DM devices + ontop). A proper fix that restacks all the queue_limits from the bottom + of the device stack up will need to be explored if SCSI will continue to + use this model of optimistically allowing op codes and then disabling + them after they fail for the first time. + + Before this patch: + + EXT4-fs (dm-6): mounted filesystem with ordered data mode. Opts: (null) + device-mapper: multipath: XXX snitm debugging: got -EREMOTEIO (-121) + device-mapper: multipath: XXX snitm debugging: failing WRITE SAME IO with error=-121 + end_request: critical target error, dev dm-6, sector 528 + dm-6: WRITE SAME failed. Manually zeroing. + device-mapper: multipath: Failing path 8:112. + end_request: I/O error, dev dm-6, sector 4616 + dm-6: WRITE SAME failed. Manually zeroing. + end_request: I/O error, dev dm-6, sector 4616 + end_request: I/O error, dev dm-6, sector 5640 + end_request: I/O error, dev dm-6, sector 6664 + end_request: I/O error, dev dm-6, sector 7688 + end_request: I/O error, dev dm-6, sector 524288 + Buffer I/O error on device dm-6, logical block 65536 + lost page write due to I/O error on dm-6 + JBD2: Error -5 detected when updating journal superblock for dm-6-8. + end_request: I/O error, dev dm-6, sector 524296 + Aborting journal on device dm-6-8. + end_request: I/O error, dev dm-6, sector 524288 + Buffer I/O error on device dm-6, logical block 65536 + lost page write due to I/O error on dm-6 + JBD2: Error -5 detected when updating journal superblock for dm-6-8. + + # cat /sys/block/sdh/queue/write_same_max_bytes + 0 + # cat /sys/block/dm-6/queue/write_same_max_bytes + 33553920 + + After this patch: + + EXT4-fs (dm-6): mounted filesystem with ordered data mode. Opts: (null) + device-mapper: multipath: XXX snitm debugging: got -EREMOTEIO (-121) + device-mapper: multipath: XXX snitm debugging: WRITE SAME I/O failed with error=-121 + end_request: critical target error, dev dm-6, sector 528 + dm-6: WRITE SAME failed. Manually zeroing. + + # cat /sys/block/sdh/queue/write_same_max_bytes + 0 + # cat /sys/block/dm-6/queue/write_same_max_bytes + 0 + + It should be noted that WRITE SAME support wasn't enabled in DM + multipath until v3.10. + + Signed-off-by: Mike Snitzer + Cc: Martin K. Petersen + Cc: Hannes Reinecke + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/dm-mpath.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/dm-mpath.c 2014-05-05 11:50:37.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/dm-mpath.c 2014-05-05 12:46:34.000000000 +0000 +@@ -1284,8 +1284,17 @@ + if (!error && !clone->errors) + return 0; /* I/O complete */ + +- if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) ++ if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) { ++ if ((clone->cmd_flags & REQ_WRITE_SAME) && ++ !clone->q->limits.max_write_same_sectors) { ++ struct queue_limits *limits; ++ ++ /* device doesn't really support WRITE SAME, disable it */ ++ limits = dm_get_queue_limits(dm_table_get_md(m->ti->table)); ++ limits->max_write_same_sectors = 0; ++ } + return error; ++ } + + if (mpio->pgpath) + fail_path(mpio->pgpath); +Index: linux-3.10-3.10.11/drivers/md/dm.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/dm.c 2014-05-05 11:50:37.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/dm.c 2014-05-05 12:46:34.000000000 +0000 +@@ -2219,6 +2219,17 @@ + } + + /* ++ * The queue_limits are only valid as long as you have a reference ++ * count on 'md'. ++ */ ++struct queue_limits *dm_get_queue_limits(struct mapped_device *md) ++{ ++ BUG_ON(!atomic_read(&md->holders)); ++ return &md->queue->limits; ++} ++EXPORT_SYMBOL_GPL(dm_get_queue_limits); ++ ++/* + * Fully initialize a request-based queue (->elevator, ->request_fn, etc). + */ + static int dm_init_request_based_queue(struct mapped_device *md) +Index: linux-3.10-3.10.11/include/linux/device-mapper.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/device-mapper.h 2014-05-05 11:50:37.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/device-mapper.h 2014-05-05 12:46:34.000000000 +0000 +@@ -405,13 +405,14 @@ + union map_info *dm_get_mapinfo(struct bio *bio); + union map_info *dm_get_rq_mapinfo(struct request *rq); + ++struct queue_limits *dm_get_queue_limits(struct mapped_device *md); ++ + /* + * Geometry functions. + */ + int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); + int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); + +- + /*----------------------------------------------------------------- + * Functions for manipulating device-mapper tables. + *---------------------------------------------------------------*/ +Index: linux-3.10-3.10.11/dummy/rpi_1247_e9d60f699108682bad9c4604feb408ac9198b232.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1247_e9d60f699108682bad9c4604feb408ac9198b232.txt 2014-05-05 12:46:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1248_f38af5d3f6aa1186b0ac9a1ef021d425550b479b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1248_f38af5d3f6aa1186b0ac9a1ef021d425550b479b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1248_f38af5d3f6aa1186b0ac9a1ef021d425550b479b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1248_f38af5d3f6aa1186b0ac9a1ef021d425550b479b.patch 2014-05-05 12:46:36.000000000 +0000 @@ -0,0 +1,34 @@ +commit f38af5d3f6aa1186b0ac9a1ef021d425550b479b +Author: NeilBrown +Date: Thu May 9 10:27:49 2013 +1000 + + dm-raid: silence compiler warning on rebuilds_per_group. + + commit 3f6bbd3ffd7b733dd705e494663e5761aa2cb9c1 upstream. + + This doesn't really need to be initialised, but it doesn't hurt, + silences the compiler, and as it is a counter it makes sense for it to + start at zero. + + Signed-off-by: NeilBrown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/dm-raid.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/dm-raid.c 2014-05-05 11:50:37.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/dm-raid.c 2014-05-05 12:46:35.000000000 +0000 +@@ -380,7 +380,7 @@ + static int validate_raid_redundancy(struct raid_set *rs) + { + unsigned i, rebuild_cnt = 0; +- unsigned rebuilds_per_group, copies, d; ++ unsigned rebuilds_per_group = 0, copies, d; + unsigned group_size, last_group_start; + + for (i = 0; i < rs->md.raid_disks; i++) +Index: linux-3.10-3.10.11/dummy/rpi_1248_f38af5d3f6aa1186b0ac9a1ef021d425550b479b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1248_f38af5d3f6aa1186b0ac9a1ef021d425550b479b.txt 2014-05-05 12:46:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1249_3ef7d935f87406489889c792ebc1218feaeaab44.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1249_3ef7d935f87406489889c792ebc1218feaeaab44.patch --- linux-3.10.11/debian/patches/rpi/rpi_1249_3ef7d935f87406489889c792ebc1218feaeaab44.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1249_3ef7d935f87406489889c792ebc1218feaeaab44.patch 2014-05-05 12:46:37.000000000 +0000 @@ -0,0 +1,60 @@ +commit 3ef7d935f87406489889c792ebc1218feaeaab44 +Author: Daniel Vetter +Date: Tue Sep 24 11:46:14 2013 +0200 + + drm/i915: preserve pipe A quirk in i9xx_set_pipeconf + + commit 67c72a12254101d4e8d9b9f3a02646ba0be84a2d upstream. + + This regression has been introduced in + + commit 9f11a9e4e50006b615ba94722dfc33ced89664cf + Author: Daniel Vetter + Date: Thu Jun 13 00:54:58 2013 +0200 + + drm/i915: set up PIPECONF explicitly for i9xx/vlv platforms + + Ville brough up the idea that this is just the pipe A quirk gone + wrong. + + Note that after resume the bios might or might not have enabled pipe A + already. We have a bit of magic to make sure that on resume we set up + a decent mode for pipe A, but I fear if I just smash pipe A to always + on we'd enable it in a bogus state and hang the hw. Hence the + readback. + + v2: Clarify the logic a bit as suggested by Chris. Also amend the + commit message to clarify why we don't unconditionally enable the + pipe. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66462 + References: https://lkml.org/lkml/2013/8/26/238 + Cc: Meelis Roos + Cc: Chris Wilson + Cc: Ville Syrjälä + Reviewed-by: Chris Wilson + [danvet: Use |= instead of = as suggested by Chris.] + Signed-off-by: Daniel Vetter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_display.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/i915/intel_display.c 2014-05-05 11:50:37.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_display.c 2014-05-05 12:46:36.000000000 +0000 +@@ -4564,6 +4564,10 @@ + + pipeconf = I915_READ(PIPECONF(intel_crtc->pipe)); + ++ if (dev_priv->quirks & QUIRK_PIPEA_FORCE && ++ I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE) ++ pipeconf |= PIPECONF_ENABLE; ++ + if (intel_crtc->pipe == 0 && INTEL_INFO(dev)->gen < 4) { + /* Enable pixel doubling when the dot clock is > 90% of the (display) + * core speed. +Index: linux-3.10-3.10.11/dummy/rpi_1249_3ef7d935f87406489889c792ebc1218feaeaab44.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1249_3ef7d935f87406489889c792ebc1218feaeaab44.txt 2014-05-05 12:46:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1250_d113feebb1081c4baa720c5fc99c984fb4e2e598.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1250_d113feebb1081c4baa720c5fc99c984fb4e2e598.patch --- linux-3.10.11/debian/patches/rpi/rpi_1250_d113feebb1081c4baa720c5fc99c984fb4e2e598.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1250_d113feebb1081c4baa720c5fc99c984fb4e2e598.patch 2014-05-05 12:46:38.000000000 +0000 @@ -0,0 +1,50 @@ +commit d113feebb1081c4baa720c5fc99c984fb4e2e598 +Author: Jani Nikula +Date: Fri Sep 20 16:42:15 2013 +0300 + + drm/i915/dp: increase i2c-over-aux retry interval on AUX DEFER + + commit 8d16f258217f2f583af1fd57c5144aa4bbe73e48 upstream. + + There is no clear cut rules or specs for the retry interval, as there + are many factors that affect overall response time. Increase the + interval, and even more so on branch devices which may have limited i2c + bit rates. + + Signed-off-by: Jani Nikula + Reference: https://bugs.freedesktop.org/show_bug.cgi?id=60263 + Tested-by: Nicolas Suzor + Reviewed-by: Todd Previte + Signed-off-by: Daniel Vetter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_dp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/i915/intel_dp.c 2014-05-05 11:50:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_dp.c 2014-05-05 12:46:37.000000000 +0000 +@@ -604,7 +604,18 @@ + DRM_DEBUG_KMS("aux_ch native nack\n"); + return -EREMOTEIO; + case AUX_NATIVE_REPLY_DEFER: +- udelay(100); ++ /* ++ * For now, just give more slack to branch devices. We ++ * could check the DPCD for I2C bit rate capabilities, ++ * and if available, adjust the interval. We could also ++ * be more careful with DP-to-Legacy adapters where a ++ * long legacy cable may force very low I2C bit rates. ++ */ ++ if (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & ++ DP_DWN_STRM_PORT_PRESENT) ++ usleep_range(500, 600); ++ else ++ usleep_range(300, 400); + continue; + default: + DRM_ERROR("aux_ch invalid native reply 0x%02x\n", +Index: linux-3.10-3.10.11/dummy/rpi_1250_d113feebb1081c4baa720c5fc99c984fb4e2e598.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1250_d113feebb1081c4baa720c5fc99c984fb4e2e598.txt 2014-05-05 12:46:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1251_6452230ccfffec35fc7ee2e5f3e3bb6f8ab6570d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1251_6452230ccfffec35fc7ee2e5f3e3bb6f8ab6570d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1251_6452230ccfffec35fc7ee2e5f3e3bb6f8ab6570d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1251_6452230ccfffec35fc7ee2e5f3e3bb6f8ab6570d.patch 2014-05-05 12:46:39.000000000 +0000 @@ -0,0 +1,36 @@ +commit 6452230ccfffec35fc7ee2e5f3e3bb6f8ab6570d +Author: Alex Deucher +Date: Sun Sep 15 23:23:07 2013 -0400 + + drm/radeon: avoid UVD corruption on AGP cards using GPU gart + + commit 4ca5a6cba53e13b8fd153b0762b4128fab6a3cfb upstream. + + If the user has forced the driver to use the internal GPU gart + rather than AGP on an AGP card, force the buffers to vram + as well. + + Signed-off-by: Alex Deucher + Reviewed-by: Christian König + Tested-by: Dieter Nützel + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_cs.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_cs.c 2014-05-05 12:45:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_cs.c 2014-05-05 12:46:38.000000000 +0000 +@@ -84,7 +84,7 @@ + VRAM, also but everything into VRAM on AGP cards to avoid + image corruptions */ + if (p->ring == R600_RING_TYPE_UVD_INDEX && +- (i == 0 || p->rdev->flags & RADEON_IS_AGP)) { ++ (i == 0 || drm_pci_device_is_agp(p->rdev->ddev))) { + /* TODO: is this still needed for NI+ ? */ + p->relocs[i].lobj.domain = + RADEON_GEM_DOMAIN_VRAM; +Index: linux-3.10-3.10.11/dummy/rpi_1251_6452230ccfffec35fc7ee2e5f3e3bb6f8ab6570d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1251_6452230ccfffec35fc7ee2e5f3e3bb6f8ab6570d.txt 2014-05-05 12:46:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1252_f329055796c2c2d4d0a6fe4691755213cfef6187.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1252_f329055796c2c2d4d0a6fe4691755213cfef6187.patch --- linux-3.10.11/debian/patches/rpi/rpi_1252_f329055796c2c2d4d0a6fe4691755213cfef6187.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1252_f329055796c2c2d4d0a6fe4691755213cfef6187.patch 2014-05-05 12:46:39.000000000 +0000 @@ -0,0 +1,63 @@ +commit f329055796c2c2d4d0a6fe4691755213cfef6187 +Author: Alex Ivanov +Date: Fri Sep 20 17:36:06 2013 +0400 + + drm/radeon: Make r100_cp_ring_info() and radeon_ring_gfx() safe (v2) + + commit 0eb3448aa6b31fbf24c31756aba7940cac5ad6b8 upstream. + + Prevent NULL pointer dereference in case when radeon_ring_fini() did it's job. + + Reading of r100_cp_ring_info and radeon_ring_gfx debugfs entries will lead to a KP if ring buffer was deallocated, e.g. on failed ring test. + Seen on PA-RISC machine having "radeon: ring test failed (scratch(0x8504)=0xCAFEDEAD)" issue. + + v2: agd5f: add some parens around ring->ready check + + Signed-off-by: Alex Ivanov + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/r100.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/r100.c 2014-05-05 12:41:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/r100.c 2014-05-05 12:46:39.000000000 +0000 +@@ -2932,9 +2932,11 @@ + seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); + seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); + seq_printf(m, "%u dwords in ring\n", count); +- for (j = 0; j <= count; j++) { +- i = (rdp + j) & ring->ptr_mask; +- seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); ++ if (ring->ready) { ++ for (j = 0; j <= count; j++) { ++ i = (rdp + j) & ring->ptr_mask; ++ seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); ++ } + } + return 0; + } +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_ring.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_ring.c 2014-05-05 11:50:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_ring.c 2014-05-05 12:46:39.000000000 +0000 +@@ -823,9 +823,11 @@ + * packet that is the root issue + */ + i = (ring->rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; +- for (j = 0; j <= (count + 32); j++) { +- seq_printf(m, "r[%5d]=0x%08x\n", i, ring->ring[i]); +- i = (i + 1) & ring->ptr_mask; ++ if (ring->ready) { ++ for (j = 0; j <= (count + 32); j++) { ++ seq_printf(m, "r[%5d]=0x%08x\n", i, ring->ring[i]); ++ i = (i + 1) & ring->ptr_mask; ++ } + } + return 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1252_f329055796c2c2d4d0a6fe4691755213cfef6187.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1252_f329055796c2c2d4d0a6fe4691755213cfef6187.txt 2014-05-05 12:46:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1253_05e1be66ed3e42ea63a30771531af4d9146efe3c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1253_05e1be66ed3e42ea63a30771531af4d9146efe3c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1253_05e1be66ed3e42ea63a30771531af4d9146efe3c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1253_05e1be66ed3e42ea63a30771531af4d9146efe3c.patch 2014-05-05 12:46:40.000000000 +0000 @@ -0,0 +1,52 @@ +commit 05e1be66ed3e42ea63a30771531af4d9146efe3c +Author: Alex Deucher +Date: Mon Sep 23 10:38:26 2013 -0400 + + drm/radeon: disable tests/benchmarks if accel is disabled + + commit 4a1132a023eb48cf10522d84c5908d43b612c041 upstream. + + The tests are only usable if the acceleration engines have + been successfully initialized. + + Based on an initial patch from: Alex Ivanov + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_device.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_device.c 2014-05-05 11:50:35.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_device.c 2014-05-05 12:46:40.000000000 +0000 +@@ -1196,13 +1196,22 @@ + return r; + } + if ((radeon_testing & 1)) { +- radeon_test_moves(rdev); ++ if (rdev->accel_working) ++ radeon_test_moves(rdev); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping move tests\n"); + } + if ((radeon_testing & 2)) { +- radeon_test_syncing(rdev); ++ if (rdev->accel_working) ++ radeon_test_syncing(rdev); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping sync tests\n"); + } + if (radeon_benchmarking) { +- radeon_benchmark(rdev, radeon_benchmarking); ++ if (rdev->accel_working) ++ radeon_benchmark(rdev, radeon_benchmarking); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n"); + } + return 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1253_05e1be66ed3e42ea63a30771531af4d9146efe3c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1253_05e1be66ed3e42ea63a30771531af4d9146efe3c.txt 2014-05-05 12:46:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1254_b2a9484006875ecd7d94582e7bcb72a02682be92.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1254_b2a9484006875ecd7d94582e7bcb72a02682be92.patch --- linux-3.10.11/debian/patches/rpi/rpi_1254_b2a9484006875ecd7d94582e7bcb72a02682be92.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1254_b2a9484006875ecd7d94582e7bcb72a02682be92.patch 2014-05-05 12:46:41.000000000 +0000 @@ -0,0 +1,39 @@ +commit b2a9484006875ecd7d94582e7bcb72a02682be92 +Author: Alex Deucher +Date: Mon Sep 23 15:47:08 2013 -0400 + + drm/radeon: add missing hdmi callbacks for rv6xx + + commit 99d79aa2f3b7729e7290e8bda5d0dd8b0240ec62 upstream. + + When dpm was merged, I added a new asic struct for + rv6xx, but it never got properly updated when the + hdmi callbacks were added due to the two patch sets + being developed in parallel. + + Fixes: + https://bugs.freedesktop.org/show_bug.cgi?id=69729 + + Signed-off-by: Alex Deucher + Reviewed-by: Christian König + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_asic.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_asic.c 2014-05-05 11:50:35.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_asic.c 2014-05-05 12:46:40.000000000 +0000 +@@ -892,6 +892,8 @@ + .wait_for_vblank = &avivo_wait_for_vblank, + .set_backlight_level = &atombios_set_backlight_level, + .get_backlight_level = &atombios_get_backlight_level, ++ .hdmi_enable = &r600_hdmi_enable, ++ .hdmi_setmode = &r600_hdmi_setmode, + }, + .copy = { + .blit = &r100_copy_blit, +Index: linux-3.10-3.10.11/dummy/rpi_1254_b2a9484006875ecd7d94582e7bcb72a02682be92.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1254_b2a9484006875ecd7d94582e7bcb72a02682be92.txt 2014-05-05 12:46:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1255_ddcca42fb47e59b1655d866b364c3dac4ba3f135.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1255_ddcca42fb47e59b1655d866b364c3dac4ba3f135.patch --- linux-3.10.11/debian/patches/rpi/rpi_1255_ddcca42fb47e59b1655d866b364c3dac4ba3f135.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1255_ddcca42fb47e59b1655d866b364c3dac4ba3f135.patch 2014-05-05 12:46:42.000000000 +0000 @@ -0,0 +1,60 @@ +commit ddcca42fb47e59b1655d866b364c3dac4ba3f135 +Author: Alex Deucher +Date: Wed Sep 25 12:04:37 2013 -0400 + + drm/radeon: fix hdmi audio on DCE3.0/3.1 asics + + commit 58d327da9721f7a0f6e46c8dfa5cc5546fd7078a upstream. + + These asics seem to use a mix of the DCE2.x and + DCE3.2 audio interfaces despite what the register spec + says. + + Fixes: + https://bugs.freedesktop.org/show_bug.cgi?id=69729 + https://bugs.freedesktop.org/show_bug.cgi?id=69671 + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600_hdmi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/r600_hdmi.c 2014-05-05 11:50:35.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600_hdmi.c 2014-05-05 12:46:41.000000000 +0000 +@@ -238,9 +238,19 @@ + * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE + * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator + */ +- if (ASIC_IS_DCE3(rdev)) { ++ if (ASIC_IS_DCE32(rdev)) { ++ if (dig->dig_encoder == 0) { ++ WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); ++ WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); ++ WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ ++ } else { ++ WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100); ++ WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); ++ WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ ++ } ++ } else if (ASIC_IS_DCE3(rdev)) { + /* according to the reg specs, this should DCE3.2 only, but in +- * practice it seems to cover DCE3.0 as well. ++ * practice it seems to cover DCE3.0/3.1 as well. + */ + if (dig->dig_encoder == 0) { + WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); +@@ -252,7 +262,7 @@ + WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ + } + } else { +- /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ ++ /* according to the reg specs, this should be DCE2.0 and DCE3.0/3.1 */ + WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | + AUDIO_DTO_MODULE(clock / 10)); + } +Index: linux-3.10-3.10.11/dummy/rpi_1255_ddcca42fb47e59b1655d866b364c3dac4ba3f135.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1255_ddcca42fb47e59b1655d866b364c3dac4ba3f135.txt 2014-05-05 12:46:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1256_37482f9cfb0269e082a817f31ad2a5f0204163f9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1256_37482f9cfb0269e082a817f31ad2a5f0204163f9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1256_37482f9cfb0269e082a817f31ad2a5f0204163f9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1256_37482f9cfb0269e082a817f31ad2a5f0204163f9.patch 2014-05-05 12:46:43.000000000 +0000 @@ -0,0 +1,37 @@ +commit 37482f9cfb0269e082a817f31ad2a5f0204163f9 +Author: Arnd Bergmann +Date: Mon Jun 3 16:00:22 2013 +0200 + + ARM: mxs: stub out mxs_pm_init for !CONFIG_PM + + commit 7a9caf59f60e55a8caf96f856713bd0ef0cc25a7 upstream. + + When building a kernel without CONFIG_PM, we get a link + error from referencing mxs_pm_init in the machine + descriptor. This defines a macro to NULL for that case. + + Signed-off-by: Arnd Bergmann + Acked-by: Shawn Guo + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/mach-mxs/pm.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mach-mxs/pm.h 2014-05-05 11:50:34.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-mxs/pm.h 2014-05-05 12:46:42.000000000 +0000 +@@ -9,6 +9,10 @@ + #ifndef __ARCH_MXS_PM_H + #define __ARCH_MXS_PM_H + ++#ifdef CONFIG_PM + void mxs_pm_init(void); ++#else ++#define mxs_pm_init NULL ++#endif + + #endif +Index: linux-3.10-3.10.11/dummy/rpi_1256_37482f9cfb0269e082a817f31ad2a5f0204163f9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1256_37482f9cfb0269e082a817f31ad2a5f0204163f9.txt 2014-05-05 12:46:42.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1257_332769e13b075c82ae7b9f79be29506f8c6aceb2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1257_332769e13b075c82ae7b9f79be29506f8c6aceb2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1257_332769e13b075c82ae7b9f79be29506f8c6aceb2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1257_332769e13b075c82ae7b9f79be29506f8c6aceb2.patch 2014-05-05 12:46:44.000000000 +0000 @@ -0,0 +1,56 @@ +commit 332769e13b075c82ae7b9f79be29506f8c6aceb2 +Author: Henrik Rydberg +Date: Thu Sep 26 08:33:16 2013 +0200 + + hwmon: (applesmc) Check key count before proceeding + + commit 5f4513864304672e6ea9eac60583eeac32e679f2 upstream. + + After reports from Chris and Josh Boyer of a rare crash in applesmc, + Guenter pointed at the initialization problem fixed below. The patch + has not been verified to fix the crash, but should be applied + regardless. + + Reported-by: + Suggested-by: Guenter Roeck + Signed-off-by: Henrik Rydberg + Signed-off-by: Guenter Roeck + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hwmon/applesmc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hwmon/applesmc.c 2014-05-05 11:50:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hwmon/applesmc.c 2014-05-05 12:46:43.000000000 +0000 +@@ -525,16 +525,25 @@ + { + struct applesmc_registers *s = &smcreg; + bool left_light_sensor, right_light_sensor; ++ unsigned int count; + u8 tmp[1]; + int ret; + + if (s->init_complete) + return 0; + +- ret = read_register_count(&s->key_count); ++ ret = read_register_count(&count); + if (ret) + return ret; + ++ if (s->cache && s->key_count != count) { ++ pr_warn("key count changed from %d to %d\n", ++ s->key_count, count); ++ kfree(s->cache); ++ s->cache = NULL; ++ } ++ s->key_count = count; ++ + if (!s->cache) + s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); + if (!s->cache) +Index: linux-3.10-3.10.11/dummy/rpi_1257_332769e13b075c82ae7b9f79be29506f8c6aceb2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1257_332769e13b075c82ae7b9f79be29506f8c6aceb2.txt 2014-05-05 12:46:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1258_1aff4161cc9ed30b6842030ec1b91b4cdca1a811.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1258_1aff4161cc9ed30b6842030ec1b91b4cdca1a811.patch --- linux-3.10.11/debian/patches/rpi/rpi_1258_1aff4161cc9ed30b6842030ec1b91b4cdca1a811.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1258_1aff4161cc9ed30b6842030ec1b91b4cdca1a811.patch 2014-05-05 12:46:44.000000000 +0000 @@ -0,0 +1,37 @@ +commit 1aff4161cc9ed30b6842030ec1b91b4cdca1a811 +Author: Liam Girdwood +Date: Fri Sep 13 17:43:17 2013 +0100 + + ALSA: compress: Fix compress device unregister. + + commit 4028b6c4c03f213260e9290ff3a6b5439aad07ce upstream. + + snd_unregister_device() should return the device type and not stream + direction. + + Signed-off-by: Liam Girdwood + Acked-by: Vinod Koul + Tested-by: Vinod Koul + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/core/compress_offload.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/core/compress_offload.c 2014-05-05 11:50:33.000000000 +0000 ++++ linux-3.10-3.10.11/sound/core/compress_offload.c 2014-05-05 12:46:44.000000000 +0000 +@@ -837,7 +837,8 @@ + struct snd_compr *compr; + + compr = device->device_data; +- snd_unregister_device(compr->direction, compr->card, compr->device); ++ snd_unregister_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card, ++ compr->device); + return 0; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1258_1aff4161cc9ed30b6842030ec1b91b4cdca1a811.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1258_1aff4161cc9ed30b6842030ec1b91b4cdca1a811.txt 2014-05-05 12:46:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1259_5ffe7285aa50470853f2a06188b5578c4397c7c2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1259_5ffe7285aa50470853f2a06188b5578c4397c7c2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1259_5ffe7285aa50470853f2a06188b5578c4397c7c2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1259_5ffe7285aa50470853f2a06188b5578c4397c7c2.patch 2014-05-05 12:46:45.000000000 +0000 @@ -0,0 +1,61 @@ +commit 5ffe7285aa50470853f2a06188b5578c4397c7c2 +Author: Daniel Vetter +Date: Fri Jul 26 11:27:49 2013 +0200 + + drm/i915: fix gen4 digital port hotplug definitions + + commit 0ce99f749b3834edeb500e17d6ad17e86b60ff83 upstream. + + Apparently Bspec is wrong in this case here even for gm45. Note that + Bspec is horribly misguided on i965g/gm, so we don't have any other + data points besides that it seems to make machines work better. + + With this changes all the bits in PORT_HOTPLUG_STAT for the digital + ports are ordered the same way. This seems to agree with what register + dumps from the hpd storm handling code shows, where the LIVE bit and + the short/long pulse STATUS bits light up at the same time with this + enumeration (but no with the one from Bspec). + + Also tested on my gm45 which has two DP+ ports, and everything seems + to still work as expected. + + References: http://www.mail-archive.com/intel-gfx@lists.freedesktop.org/msg23054.html + Cc: Egbert Eich + Cc: Jan Niggemann + Tested-by: Jan Niggemann + [danvet: Add a big warning that Bspec seems to be wrong for these + bits, suggested by Jani.] + Acked-by: Jani Nikula + Signed-off-by: Daniel Vetter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/i915/i915_reg.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/i915/i915_reg.h 2014-05-05 11:50:33.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/i915/i915_reg.h 2014-05-05 12:46:45.000000000 +0000 +@@ -1675,10 +1675,16 @@ + #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) + + #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) +-/* HDMI/DP bits are gen4+ */ +-#define PORTB_HOTPLUG_LIVE_STATUS (1 << 29) ++/* ++ * HDMI/DP bits are gen4+ ++ * ++ * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused. ++ * Please check the detailed lore in the commit message for for experimental ++ * evidence. ++ */ ++#define PORTD_HOTPLUG_LIVE_STATUS (1 << 29) + #define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) +-#define PORTD_HOTPLUG_LIVE_STATUS (1 << 27) ++#define PORTB_HOTPLUG_LIVE_STATUS (1 << 27) + #define PORTD_HOTPLUG_INT_STATUS (3 << 21) + #define PORTC_HOTPLUG_INT_STATUS (3 << 19) + #define PORTB_HOTPLUG_INT_STATUS (3 << 17) +Index: linux-3.10-3.10.11/dummy/rpi_1259_5ffe7285aa50470853f2a06188b5578c4397c7c2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1259_5ffe7285aa50470853f2a06188b5578c4397c7c2.txt 2014-05-05 12:46:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1260_cac65253a9c5a30d4c8d7bc4c60197935f9e2e70.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1260_cac65253a9c5a30d4c8d7bc4c60197935f9e2e70.patch --- linux-3.10.11/debian/patches/rpi/rpi_1260_cac65253a9c5a30d4c8d7bc4c60197935f9e2e70.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1260_cac65253a9c5a30d4c8d7bc4c60197935f9e2e70.patch 2014-05-05 12:46:47.000000000 +0000 @@ -0,0 +1,24 @@ +commit cac65253a9c5a30d4c8d7bc4c60197935f9e2e70 +Author: Greg Kroah-Hartman +Date: Sat Oct 5 07:13:21 2013 -0700 + + Linux 3.10.15 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:46:00.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:46:46.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 14 ++SUBLEVEL = 15 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1260_cac65253a9c5a30d4c8d7bc4c60197935f9e2e70.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1260_cac65253a9c5a30d4c8d7bc4c60197935f9e2e70.txt 2014-05-05 12:46:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1261_9e65b308202a4e6536c5b453d6b37fd0467dd5d2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1261_9e65b308202a4e6536c5b453d6b37fd0467dd5d2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1261_9e65b308202a4e6536c5b453d6b37fd0467dd5d2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1261_9e65b308202a4e6536c5b453d6b37fd0467dd5d2.patch 2014-05-05 12:46:48.000000000 +0000 @@ -0,0 +1,79 @@ +commit 9e65b308202a4e6536c5b453d6b37fd0467dd5d2 +Author: Daniel Drake +Date: Fri Jun 14 15:24:24 2013 -0400 + + mwifiex: fix memory corruption when unsetting multicast list + + commit 6390d88529835a8ad3563fe01a5da89fa52d6db2 upstream. + + When trying to unset a previously-set multicast list (i.e. the new list + has 0 entries), mwifiex_set_multicast_list() was calling down to + mwifiex_request_set_multicast_list() while leaving + mcast_list.num_multicast_addr as an uninitialized value. + + We were arriving at mwifiex_cmd_mac_multicast_adr() which would then + proceed to do an often huge memcpy of + mcast_list.num_multicast_addr*ETH_ALEN bytes, causing memory corruption + and hard to debug crashes. + + Fix this by setting mcast_list.num_multicast_addr to 0 when no multicast + list is provided. Similarly, fix up the logic in + mwifiex_request_set_multicast_list() to unset the multicast list that + was previously sent to the hardware in such cases. + + Signed-off-by: Daniel Drake + Acked-by: Bing Zhao + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/main.c 2014-05-05 12:43:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c 2014-05-05 12:46:47.000000000 +0000 +@@ -556,9 +556,8 @@ + mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; + } else { + mcast_list.mode = MWIFIEX_MULTICAST_MODE; +- if (netdev_mc_count(dev)) +- mcast_list.num_multicast_addr = +- mwifiex_copy_mcast_addr(&mcast_list, dev); ++ mcast_list.num_multicast_addr = ++ mwifiex_copy_mcast_addr(&mcast_list, dev); + } + mwifiex_request_set_multicast_list(priv, &mcast_list); + } +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/sta_ioctl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-05-05 11:50:31.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-05-05 12:46:47.000000000 +0000 +@@ -104,16 +104,14 @@ + } else { + priv->curr_pkt_filter &= + ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; +- if (mcast_list->num_multicast_addr) { +- dev_dbg(priv->adapter->dev, +- "info: Set multicast list=%d\n", +- mcast_list->num_multicast_addr); +- /* Send multicast addresses to firmware */ +- ret = mwifiex_send_cmd_async(priv, +- HostCmd_CMD_MAC_MULTICAST_ADR, +- HostCmd_ACT_GEN_SET, 0, +- mcast_list); +- } ++ dev_dbg(priv->adapter->dev, ++ "info: Set multicast list=%d\n", ++ mcast_list->num_multicast_addr); ++ /* Send multicast addresses to firmware */ ++ ret = mwifiex_send_cmd_async(priv, ++ HostCmd_CMD_MAC_MULTICAST_ADR, ++ HostCmd_ACT_GEN_SET, 0, ++ mcast_list); + } + } + dev_dbg(priv->adapter->dev, +Index: linux-3.10-3.10.11/dummy/rpi_1261_9e65b308202a4e6536c5b453d6b37fd0467dd5d2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1261_9e65b308202a4e6536c5b453d6b37fd0467dd5d2.txt 2014-05-05 12:46:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1262_d862d211b03663ae22149cff65ad71f836fe6f7b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1262_d862d211b03663ae22149cff65ad71f836fe6f7b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1262_d862d211b03663ae22149cff65ad71f836fe6f7b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1262_d862d211b03663ae22149cff65ad71f836fe6f7b.patch 2014-05-05 12:46:48.000000000 +0000 @@ -0,0 +1,37 @@ +commit d862d211b03663ae22149cff65ad71f836fe6f7b +Author: Dan Carpenter +Date: Tue Sep 24 15:27:44 2013 -0700 + + cpqarray: fix info leak in ida_locked_ioctl() + + commit 627aad1c01da6f881e7f98d71fd928ca0c316b1a upstream. + + The pciinfo struct has a two byte hole after ->dev_fn so stack + information could be leaked to the user. + + This was assigned CVE-2013-2147. + + Signed-off-by: Dan Carpenter + Acked-by: Mike Miller + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/block/cpqarray.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/block/cpqarray.c 2014-05-05 11:50:31.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/block/cpqarray.c 2014-05-05 12:46:48.000000000 +0000 +@@ -1193,6 +1193,7 @@ + ida_pci_info_struct pciinfo; + + if (!arg) return -EINVAL; ++ memset(&pciinfo, 0, sizeof(pciinfo)); + pciinfo.bus = host->pci_dev->bus->number; + pciinfo.dev_fn = host->pci_dev->devfn; + pciinfo.board_id = host->board_id; +Index: linux-3.10-3.10.11/dummy/rpi_1262_d862d211b03663ae22149cff65ad71f836fe6f7b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1262_d862d211b03663ae22149cff65ad71f836fe6f7b.txt 2014-05-05 12:46:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1263_698508f44ad8d2f4289f8fae4488576f2902703a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1263_698508f44ad8d2f4289f8fae4488576f2902703a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1263_698508f44ad8d2f4289f8fae4488576f2902703a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1263_698508f44ad8d2f4289f8fae4488576f2902703a.patch 2014-05-05 12:46:49.000000000 +0000 @@ -0,0 +1,38 @@ +commit 698508f44ad8d2f4289f8fae4488576f2902703a +Author: Dan Carpenter +Date: Tue Sep 24 15:27:45 2013 -0700 + + cciss: fix info leak in cciss_ioctl32_passthru() + + commit 58f09e00ae095e46ef9edfcf3a5fd9ccdfad065e upstream. + + The arg64 struct has a hole after ->buf_size which isn't cleared. Or if + any of the calls to copy_from_user() fail then that would cause an + information leak as well. + + This was assigned CVE-2013-2147. + + Signed-off-by: Dan Carpenter + Acked-by: Mike Miller + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/block/cciss.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/block/cciss.c 2014-05-05 11:50:29.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/block/cciss.c 2014-05-05 12:46:49.000000000 +0000 +@@ -1189,6 +1189,7 @@ + int err; + u32 cp; + ++ memset(&arg64, 0, sizeof(arg64)); + err = 0; + err |= + copy_from_user(&arg64.LUN_info, &arg32->LUN_info, +Index: linux-3.10-3.10.11/dummy/rpi_1263_698508f44ad8d2f4289f8fae4488576f2902703a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1263_698508f44ad8d2f4289f8fae4488576f2902703a.txt 2014-05-05 12:46:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1264_b2b6cadad699d44a8a5b2a60f3d960e00d6fb3b7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1264_b2b6cadad699d44a8a5b2a60f3d960e00d6fb3b7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1264_b2b6cadad699d44a8a5b2a60f3d960e00d6fb3b7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1264_b2b6cadad699d44a8a5b2a60f3d960e00d6fb3b7.patch 2014-05-05 12:46:50.000000000 +0000 @@ -0,0 +1,251 @@ +commit b2b6cadad699d44a8a5b2a60f3d960e00d6fb3b7 +Author: Jiri Kosina +Date: Wed Jul 10 19:56:27 2013 +0200 + + HID: fix data access in implement() + + commit 27ce405039bfe6d3f4143415c638f56a3df77dca upstream. + + implement() is setting bytes in LE data stream. In case the data is not + aligned to 64bits, it reads past the allocated buffer. It doesn't really + change any value there (it's properly bitmasked), but in case that this + read past the boundary hits a page boundary, pagefault happens when + accessing 64bits of 'x' in implement(), and kernel oopses. + + This happens much more often when numbered reports are in use, as the + initial 8bit skip in the buffer makes the whole process work on values + which are not aligned to 64bits. + + This problem dates back to attempts in 2005 and 2006 to make implement() + and extract() as generic as possible, and even back then the problem + was realized by Adam Kroperlin, but falsely assumed to be impossible + to cause any harm: + + http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg47690.html + + I have made several attempts at fixing it "on the spot" directly in + implement(), but the results were horrible; the special casing for processing + last 64bit chunk and switching to different math makes it unreadable mess. + + I therefore took a path to allocate a few bytes more which will never make + it into final report, but are there as a cushion for all the 64bit math + operations happening in implement() and extract(). + + All callers of hid_output_report() are converted at the same time to allocate + the buffer by newly introduced hid_alloc_report_buf() helper. + + Bruno noticed that the whole raw_size test can be dropped as well, as + hid_alloc_report_buf() makes sure that the buffer is always of a proper + size. + + Reviewed-by: Benjamin Tissoires + Acked-by: Gustavo Padovan + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-core.c 2014-05-05 12:45:27.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-core.c 2014-05-05 12:46:49.000000000 +0000 +@@ -1188,7 +1188,8 @@ + } + + /* +- * Create a report. ++ * Create a report. 'data' has to be allocated using ++ * hid_alloc_report_buf() so that it has proper size. + */ + + void hid_output_report(struct hid_report *report, __u8 *data) +@@ -1205,6 +1206,22 @@ + EXPORT_SYMBOL_GPL(hid_output_report); + + /* ++ * Allocator for buffer that is going to be passed to hid_output_report() ++ */ ++u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) ++{ ++ /* ++ * 7 extra bytes are necessary to achieve proper functionality ++ * of implement() working on 8 byte chunks ++ */ ++ ++ int len = ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7; ++ ++ return kmalloc(len, flags); ++} ++EXPORT_SYMBOL_GPL(hid_alloc_report_buf); ++ ++/* + * Set a field value. The report this field belongs to has to be + * created and transferred to the device, to set this value in the + * device. +Index: linux-3.10-3.10.11/drivers/hid/hid-logitech-dj.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-logitech-dj.c 2014-05-05 12:45:33.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-logitech-dj.c 2014-05-05 12:46:49.000000000 +0000 +@@ -574,7 +574,7 @@ + + struct hid_field *field; + struct hid_report *report; +- unsigned char data[8]; ++ unsigned char *data; + int offset; + + dbg_hid("%s: %s, type:%d | code:%d | value:%d\n", +@@ -590,6 +590,13 @@ + return -1; + } + hid_set_field(field, offset, value); ++ ++ data = hid_alloc_report_buf(field->report, GFP_KERNEL); ++ if (!data) { ++ dev_warn(&dev->dev, "failed to allocate report buf memory\n"); ++ return -1; ++ } ++ + hid_output_report(field->report, &data[0]); + + output_report_enum = &dj_rcv_hiddev->report_enum[HID_OUTPUT_REPORT]; +@@ -600,8 +607,9 @@ + + hid_hw_request(dj_rcv_hiddev, report, HID_REQ_SET_REPORT); + +- return 0; ++ kfree(data); + ++ return 0; + } + + static int logi_dj_ll_start(struct hid_device *hid) +Index: linux-3.10-3.10.11/drivers/hid/hid-picolcd_debugfs.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-picolcd_debugfs.c 2014-05-05 11:50:29.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-picolcd_debugfs.c 2014-05-05 12:46:49.000000000 +0000 +@@ -394,7 +394,7 @@ + void picolcd_debug_out_report(struct picolcd_data *data, + struct hid_device *hdev, struct hid_report *report) + { +- u8 raw_data[70]; ++ u8 *raw_data; + int raw_size = (report->size >> 3) + 1; + char *buff; + #define BUFF_SZ 256 +@@ -407,20 +407,20 @@ + if (!buff) + return; + +- snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ", +- report->id, raw_size); +- hid_debug_event(hdev, buff); +- if (raw_size + 5 > sizeof(raw_data)) { ++ raw_data = hid_alloc_report_buf(report, GFP_ATOMIC); ++ if (!raw_data) { + kfree(buff); +- hid_debug_event(hdev, " TOO BIG\n"); + return; +- } else { +- raw_data[0] = report->id; +- hid_output_report(report, raw_data); +- dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size); +- hid_debug_event(hdev, buff); + } + ++ snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ", ++ report->id, raw_size); ++ hid_debug_event(hdev, buff); ++ raw_data[0] = report->id; ++ hid_output_report(report, raw_data); ++ dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size); ++ hid_debug_event(hdev, buff); ++ + switch (report->id) { + case REPORT_LED_STATE: + /* 1 data byte with GPO state */ +@@ -644,6 +644,7 @@ + break; + } + wake_up_interruptible(&hdev->debug_wait); ++ kfree(raw_data); + kfree(buff); + } + +Index: linux-3.10-3.10.11/drivers/hid/usbhid/hid-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/usbhid/hid-core.c 2014-05-05 11:50:29.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/usbhid/hid-core.c 2014-05-05 12:46:49.000000000 +0000 +@@ -535,7 +535,6 @@ + { + int head; + struct usbhid_device *usbhid = hid->driver_data; +- int len = ((report->size - 1) >> 3) + 1 + (report->id > 0); + + if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) + return; +@@ -546,7 +545,7 @@ + return; + } + +- usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); ++ usbhid->out[usbhid->outhead].raw_report = hid_alloc_report_buf(report, GFP_ATOMIC); + if (!usbhid->out[usbhid->outhead].raw_report) { + hid_warn(hid, "output queueing failed\n"); + return; +@@ -595,7 +594,7 @@ + } + + if (dir == USB_DIR_OUT) { +- usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); ++ usbhid->ctrl[usbhid->ctrlhead].raw_report = hid_alloc_report_buf(report, GFP_ATOMIC); + if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { + hid_warn(hid, "control queueing failed\n"); + return; +Index: linux-3.10-3.10.11/include/linux/hid.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/hid.h 2014-05-05 12:45:26.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/hid.h 2014-05-05 12:46:49.000000000 +0000 +@@ -746,6 +746,7 @@ + unsigned int hidinput_count_leds(struct hid_device *hid); + __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code); + void hid_output_report(struct hid_report *report, __u8 *data); ++u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); + struct hid_device *hid_allocate_device(void); + struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); + int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); +Index: linux-3.10-3.10.11/net/bluetooth/hidp/core.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bluetooth/hidp/core.c 2014-05-05 11:50:29.000000000 +0000 ++++ linux-3.10-3.10.11/net/bluetooth/hidp/core.c 2014-05-05 12:46:49.000000000 +0000 +@@ -231,17 +231,21 @@ + + static int hidp_send_report(struct hidp_session *session, struct hid_report *report) + { +- unsigned char buf[32], hdr; +- int rsize; ++ unsigned char hdr; ++ u8 *buf; ++ int rsize, ret; + +- rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); +- if (rsize > sizeof(buf)) ++ buf = hid_alloc_report_buf(report, GFP_ATOMIC); ++ if (!buf) + return -EIO; + + hid_output_report(report, buf); + hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; + +- return hidp_send_intr_message(session, hdr, buf, rsize); ++ ret = hidp_send_intr_message(session, hdr, buf, rsize); ++ ++ kfree(buf); ++ return ret; + } + + static int hidp_get_raw_report(struct hid_device *hid, +Index: linux-3.10-3.10.11/dummy/rpi_1264_b2b6cadad699d44a8a5b2a60f3d960e00d6fb3b7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1264_b2b6cadad699d44a8a5b2a60f3d960e00d6fb3b7.txt 2014-05-05 12:46:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1265_88e2194c2aa9f29f80b2835295e298147c06f6e2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1265_88e2194c2aa9f29f80b2835295e298147c06f6e2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1265_88e2194c2aa9f29f80b2835295e298147c06f6e2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1265_88e2194c2aa9f29f80b2835295e298147c06f6e2.patch 2014-05-05 12:46:51.000000000 +0000 @@ -0,0 +1,33 @@ +commit 88e2194c2aa9f29f80b2835295e298147c06f6e2 +Author: Jiri Kosina +Date: Mon Jul 22 17:11:44 2013 +0200 + + HID: fix unused rsize usage + + commit bc197eedef1ae082ec662c64c3f4aa302821fb7a upstream. + + 27ce4050 ("HID: fix data access in implement()") by mistake removed + a setting of buffer size in hidp. Fix that by putting it back. + + Reported-by: kbuild test robot + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bluetooth/hidp/core.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bluetooth/hidp/core.c 2014-05-05 12:46:49.000000000 +0000 ++++ linux-3.10-3.10.11/net/bluetooth/hidp/core.c 2014-05-05 12:46:51.000000000 +0000 +@@ -242,6 +242,7 @@ + hid_output_report(report, buf); + hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; + ++ rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); + ret = hidp_send_intr_message(session, hdr, buf, rsize); + + kfree(buf); +Index: linux-3.10-3.10.11/dummy/rpi_1265_88e2194c2aa9f29f80b2835295e298147c06f6e2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1265_88e2194c2aa9f29f80b2835295e298147c06f6e2.txt 2014-05-05 12:46:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1266_a505becfe50ff2e1ba34e197f51eb18eb8e9dfbd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1266_a505becfe50ff2e1ba34e197f51eb18eb8e9dfbd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1266_a505becfe50ff2e1ba34e197f51eb18eb8e9dfbd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1266_a505becfe50ff2e1ba34e197f51eb18eb8e9dfbd.patch 2014-05-05 12:46:52.000000000 +0000 @@ -0,0 +1,39 @@ +commit a505becfe50ff2e1ba34e197f51eb18eb8e9dfbd +Author: Dave Jones +Date: Thu Sep 5 00:11:19 2013 -0400 + + caif: Add missing braces to multiline if in cfctrl_linkup_request + + [ Upstream commit 0c1db731bfcf3a9fd6c58132134f8b0f423552f0 ] + + The indentation here implies this was meant to be a multi-line if. + + Introduced several years back in commit c85c2951d4da1236e32f1858db418221e624aba5 + ("caif: Handle dev_queue_xmit errors.") + + Signed-off-by: Dave Jones + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/caif/cfctrl.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/caif/cfctrl.c 2014-05-05 11:50:28.000000000 +0000 ++++ linux-3.10-3.10.11/net/caif/cfctrl.c 2014-05-05 12:46:51.000000000 +0000 +@@ -293,9 +293,10 @@ + + count = cfctrl_cancel_req(&cfctrl->serv.layer, + user_layer); +- if (count != 1) ++ if (count != 1) { + pr_err("Could not remove request (%d)", count); + return -ENODEV; ++ } + } + return 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1266_a505becfe50ff2e1ba34e197f51eb18eb8e9dfbd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1266_a505becfe50ff2e1ba34e197f51eb18eb8e9dfbd.txt 2014-05-05 12:46:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1267_a4ae4c6176a7c878018adf470a47c1fae9090978.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1267_a4ae4c6176a7c878018adf470a47c1fae9090978.patch --- linux-3.10.11/debian/patches/rpi/rpi_1267_a4ae4c6176a7c878018adf470a47c1fae9090978.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1267_a4ae4c6176a7c878018adf470a47c1fae9090978.patch 2014-05-05 12:46:53.000000000 +0000 @@ -0,0 +1,36 @@ +commit a4ae4c6176a7c878018adf470a47c1fae9090978 +Author: Dave Jones +Date: Thu Sep 5 13:43:34 2013 -0400 + + tcp: Add missing braces to do_tcp_setsockopt + + [ Upstream commit e2e5c4c07caf810d7849658dca42f598b3938e21 ] + + Signed-off-by: Dave Jones + Acked-by: Neal Cardwell + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp.c 2014-05-05 12:43:19.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp.c 2014-05-05 12:46:52.000000000 +0000 +@@ -2447,10 +2447,11 @@ + case TCP_THIN_DUPACK: + if (val < 0 || val > 1) + err = -EINVAL; +- else ++ else { + tp->thin_dupack = val; + if (tp->thin_dupack) + tcp_disable_early_retrans(tp); ++ } + break; + + case TCP_REPAIR: +Index: linux-3.10-3.10.11/dummy/rpi_1267_a4ae4c6176a7c878018adf470a47c1fae9090978.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1267_a4ae4c6176a7c878018adf470a47c1fae9090978.txt 2014-05-05 12:46:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1268_711b8c96842e7e93b01caad6403488498d5cecfa.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1268_711b8c96842e7e93b01caad6403488498d5cecfa.patch --- linux-3.10.11/debian/patches/rpi/rpi_1268_711b8c96842e7e93b01caad6403488498d5cecfa.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1268_711b8c96842e7e93b01caad6403488498d5cecfa.patch 2014-05-05 12:46:53.000000000 +0000 @@ -0,0 +1,43 @@ +commit 711b8c96842e7e93b01caad6403488498d5cecfa +Author: Jiri Pirko +Date: Fri Sep 6 16:02:25 2013 +0200 + + ipv6/exthdrs: accept tlv which includes only padding + + [ Upstream commit 8112b1fe071be01a28a774ed55909e6f4b29712d ] + + In rfc4942 and rfc2460 I cannot find anything which would implicate to + drop packets which have only padding in tlv. + + Current behaviour breaks TAHI Test v6LC.1.2.6. + + Problem was intruduced in: + 9b905fe6843 "ipv6/exthdrs: strict Pad1 and PadN check" + + Signed-off-by: Jiri Pirko + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/exthdrs.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/exthdrs.c 2014-05-05 11:50:28.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/exthdrs.c 2014-05-05 12:46:53.000000000 +0000 +@@ -162,12 +162,6 @@ + off += optlen; + len -= optlen; + } +- /* This case will not be caught by above check since its padding +- * length is smaller than 7: +- * 1 byte NH + 1 byte Length + 6 bytes Padding +- */ +- if ((padlen == 6) && ((off - skb_network_header_len(skb)) == 8)) +- goto bad; + + if (len == 0) + return true; +Index: linux-3.10-3.10.11/dummy/rpi_1268_711b8c96842e7e93b01caad6403488498d5cecfa.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1268_711b8c96842e7e93b01caad6403488498d5cecfa.txt 2014-05-05 12:46:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1269_45d268c6b87c0c80fda9960a8b850ee0e82b71dc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1269_45d268c6b87c0c80fda9960a8b850ee0e82b71dc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1269_45d268c6b87c0c80fda9960a8b850ee0e82b71dc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1269_45d268c6b87c0c80fda9960a8b850ee0e82b71dc.patch 2014-05-05 12:46:54.000000000 +0000 @@ -0,0 +1,60 @@ +commit 45d268c6b87c0c80fda9960a8b850ee0e82b71dc +Author: Daniel Borkmann +Date: Sat Sep 7 15:13:20 2013 +0200 + + net: fib: fib6_add: fix potential NULL pointer dereference + + [ Upstream commit ae7b4e1f213aa659aedf9c6ecad0bf5f0476e1e2 ] + + When the kernel is compiled with CONFIG_IPV6_SUBTREES, and we return + with an error in fn = fib6_add_1(), then error codes are encoded into + the return pointer e.g. ERR_PTR(-ENOENT). In such an error case, we + write the error code into err and jump to out, hence enter the if(err) + condition. Now, if CONFIG_IPV6_SUBTREES is enabled, we check for: + + if (pn != fn && pn->leaf == rt) + ... + if (pn != fn && !pn->leaf && !(pn->fn_flags & RTN_RTINFO)) + ... + + Since pn is NULL and fn is f.e. ERR_PTR(-ENOENT), then pn != fn + evaluates to true and causes a NULL-pointer dereference on further + checks on pn. Fix it, by setting both NULL in error case, so that + pn != fn already evaluates to false and no further dereference + takes place. + + This was first correctly implemented in 4a287eba2 ("IPv6 routing, + NLM_F_* flag support: REPLACE and EXCL flags support, warn about + missing CREATE flag"), but the bug got later on introduced by + 188c517a0 ("ipv6: return errno pointers consistently for fib6_add_1()"). + + Signed-off-by: Daniel Borkmann + Cc: Lin Ming + Cc: Matti Vaittinen + Cc: Hannes Frederic Sowa + Acked-by: Hannes Frederic Sowa + Acked-by: Matti Vaittinen + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/ip6_fib.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_fib.c 2014-05-05 12:43:09.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_fib.c 2014-05-05 12:46:54.000000000 +0000 +@@ -825,9 +825,9 @@ + fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), + rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst), + allow_create, replace_required); +- + if (IS_ERR(fn)) { + err = PTR_ERR(fn); ++ fn = NULL; + goto out; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1269_45d268c6b87c0c80fda9960a8b850ee0e82b71dc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1269_45d268c6b87c0c80fda9960a8b850ee0e82b71dc.txt 2014-05-05 12:46:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1270_8b1ada497191ab2be429c74817a8de63f9aa2bf6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1270_8b1ada497191ab2be429c74817a8de63f9aa2bf6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1270_8b1ada497191ab2be429c74817a8de63f9aa2bf6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1270_8b1ada497191ab2be429c74817a8de63f9aa2bf6.patch 2014-05-05 12:46:55.000000000 +0000 @@ -0,0 +1,49 @@ +commit 8b1ada497191ab2be429c74817a8de63f9aa2bf6 +Author: Daniel Borkmann +Date: Sat Sep 7 16:44:59 2013 +0200 + + net: sctp: fix bug in sctp_poll for SOCK_SELECT_ERR_QUEUE + + [ Upstream commit a0fb05d1aef0f5df936f80b726d1b3bfd4275f95 ] + + If we do not add braces around ... + + mask |= POLLERR | + sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0; + + ... then this condition always evaluates to true as POLLERR is + defined as 8 and binary or'd with whatever result comes out of + sock_flag(). Hence instead of (X | Y) ? A : B, transform it into + X | (Y ? A : B). Unfortunatelty, commit 8facd5fb73 ("net: fix + smatch warnings inside datagram_poll") forgot about SCTP. :-( + + Introduced by 7d4c04fc170 ("net: add option to enable error queue + packets waking select"). + + Signed-off-by: Daniel Borkmann + Cc: Jacob Keller + Acked-by: Neil Horman + Acked-by: Vlad Yasevich + Acked-by: Jacob Keller + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sctp/socket.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sctp/socket.c 2014-05-05 11:50:27.000000000 +0000 ++++ linux-3.10-3.10.11/net/sctp/socket.c 2014-05-05 12:46:55.000000000 +0000 +@@ -6193,7 +6193,7 @@ + /* Is there any exceptional events? */ + if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + mask |= POLLERR | +- sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0; ++ (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0); + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP | POLLIN | POLLRDNORM; + if (sk->sk_shutdown == SHUTDOWN_MASK) +Index: linux-3.10-3.10.11/dummy/rpi_1270_8b1ada497191ab2be429c74817a8de63f9aa2bf6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1270_8b1ada497191ab2be429c74817a8de63f9aa2bf6.txt 2014-05-05 12:46:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1271_8ee62e8c9495a6d0f8d227bbe0f02e1b288bac30.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1271_8ee62e8c9495a6d0f8d227bbe0f02e1b288bac30.patch --- linux-3.10.11/debian/patches/rpi/rpi_1271_8ee62e8c9495a6d0f8d227bbe0f02e1b288bac30.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1271_8ee62e8c9495a6d0f8d227bbe0f02e1b288bac30.patch 2014-05-05 12:46:56.000000000 +0000 @@ -0,0 +1,64 @@ +commit 8ee62e8c9495a6d0f8d227bbe0f02e1b288bac30 +Author: Daniel Borkmann +Date: Sat Sep 7 20:51:21 2013 +0200 + + net: sctp: fix smatch warning in sctp_send_asconf_del_ip + + [ Upstream commit 88362ad8f9a6cea787420b57cc27ccacef000dbe ] + + This was originally reported in [1] and posted by Neil Horman [2], he said: + + Fix up a missed null pointer check in the asconf code. If we don't find + a local address, but we pass in an address length of more than 1, we may + dereference a NULL laddr pointer. Currently this can't happen, as the only + users of the function pass in the value 1 as the addrcnt parameter, but + its not hot path, and it doesn't hurt to check for NULL should that ever + be the case. + + The callpath from sctp_asconf_mgmt() looks okay. But this could be triggered + from sctp_setsockopt_bindx() call with SCTP_BINDX_REM_ADDR and addrcnt > 1 + while passing all possible addresses from the bind list to SCTP_BINDX_REM_ADDR + so that we do *not* find a single address in the association's bind address + list that is not in the packed array of addresses. If this happens when we + have an established association with ASCONF-capable peers, then we could get + a NULL pointer dereference as we only check for laddr == NULL && addrcnt == 1 + and call later sctp_make_asconf_update_ip() with NULL laddr. + + BUT: this actually won't happen as sctp_bindx_rem() will catch such a case + and return with an error earlier. As this is incredably unintuitive and error + prone, add a check to catch at least future bugs here. As Neil says, its not + hot path. Introduced by 8a07eb0a5 ("sctp: Add ASCONF operation on the + single-homed host"). + + [1] http://www.spinics.net/lists/linux-sctp/msg02132.html + [2] http://www.spinics.net/lists/linux-sctp/msg02133.html + + Reported-by: Dan Carpenter + Signed-off-by: Neil Horman + Signed-off-by: Daniel Borkmann + Cc: Michio Honda + Acked-By: Neil Horman + Acked-by: Vlad Yasevich + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sctp/socket.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sctp/socket.c 2014-05-05 12:46:55.000000000 +0000 ++++ linux-3.10-3.10.11/net/sctp/socket.c 2014-05-05 12:46:55.000000000 +0000 +@@ -820,6 +820,9 @@ + goto skip_mkasconf; + } + ++ if (laddr == NULL) ++ return -EINVAL; ++ + /* We do not need RCU protection throughout this loop + * because this is done under a socket lock from the + * setsockopt call. +Index: linux-3.10-3.10.11/dummy/rpi_1271_8ee62e8c9495a6d0f8d227bbe0f02e1b288bac30.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1271_8ee62e8c9495a6d0f8d227bbe0f02e1b288bac30.txt 2014-05-05 12:46:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1272_b991056a43fef79b2327b084f4296fba698b941b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1272_b991056a43fef79b2327b084f4296fba698b941b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1272_b991056a43fef79b2327b084f4296fba698b941b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1272_b991056a43fef79b2327b084f4296fba698b941b.patch 2014-05-05 12:46:57.000000000 +0000 @@ -0,0 +1,53 @@ +commit b991056a43fef79b2327b084f4296fba698b941b +Author: Eric Dumazet +Date: Sat Sep 7 12:02:57 2013 -0700 + + net: fix multiqueue selection + + [ Upstream commit 50d1784ee4683f073c0362ee360bfae7a3333d6c ] + + commit 416186fbf8c5b4e4465 ("net: Split core bits of netdev_pick_tx + into __netdev_pick_tx") added a bug that disables caching of queue + index in the socket. + + This is the source of packet reorders for TCP flows, and + again this is happening more often when using FQ pacing. + + Old code was doing + + if (queue_index != old_index) + sk_tx_queue_set(sk, queue_index); + + Alexander renamed the variables but forgot to change sk_tx_queue_set() + 2nd parameter. + + if (queue_index != new_index) + sk_tx_queue_set(sk, queue_index); + + This means we store -1 over and over in sk->sk_tx_queue_mapping + + Signed-off-by: Eric Dumazet + Cc: Alexander Duyck + Acked-by: Alexander Duyck + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/flow_dissector.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/flow_dissector.c 2014-05-05 12:43:31.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/flow_dissector.c 2014-05-05 12:46:56.000000000 +0000 +@@ -347,7 +347,7 @@ + + if (queue_index != new_index && sk && + rcu_access_pointer(sk->sk_dst_cache)) +- sk_tx_queue_set(sk, queue_index); ++ sk_tx_queue_set(sk, new_index); + + queue_index = new_index; + } +Index: linux-3.10-3.10.11/dummy/rpi_1272_b991056a43fef79b2327b084f4296fba698b941b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1272_b991056a43fef79b2327b084f4296fba698b941b.txt 2014-05-05 12:46:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1273_98913d0758e27087bbd47db734ff96521b180389.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1273_98913d0758e27087bbd47db734ff96521b180389.patch --- linux-3.10.11/debian/patches/rpi/rpi_1273_98913d0758e27087bbd47db734ff96521b180389.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1273_98913d0758e27087bbd47db734ff96521b180389.patch 2014-05-05 12:46:57.000000000 +0000 @@ -0,0 +1,45 @@ +commit 98913d0758e27087bbd47db734ff96521b180389 +Author: Eric Dumazet +Date: Thu Sep 26 08:44:06 2013 -0700 + + net: flow_dissector: fix thoff for IPPROTO_AH + + [ Upstream commit b86783587b3d1d552326d955acee37eac48800f1 ] + + In commit 8ed781668dd49 ("flow_keys: include thoff into flow_keys for + later usage"), we missed that existing code was using nhoff as a + temporary variable that could not always contain transport header + offset. + + This is not a problem for TCP/UDP because port offset (@poff) + is 0 for these protocols. + + Signed-off-by: Eric Dumazet + Cc: Daniel Borkmann + Cc: Nikolay Aleksandrov + Acked-by: Nikolay Aleksandrov + Acked-by: Daniel Borkmann + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/flow_dissector.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/flow_dissector.c 2014-05-05 12:46:56.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/flow_dissector.c 2014-05-05 12:46:57.000000000 +0000 +@@ -149,8 +149,8 @@ + if (poff >= 0) { + __be32 *ports, _ports; + +- nhoff += poff; +- ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports); ++ ports = skb_header_pointer(skb, nhoff + poff, ++ sizeof(_ports), &_ports); + if (ports) + flow->ports = *ports; + } +Index: linux-3.10-3.10.11/dummy/rpi_1273_98913d0758e27087bbd47db734ff96521b180389.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1273_98913d0758e27087bbd47db734ff96521b180389.txt 2014-05-05 12:46:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1274_5f584fec559756fd82796c2f7db58b10a3e479b1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1274_5f584fec559756fd82796c2f7db58b10a3e479b1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1274_5f584fec559756fd82796c2f7db58b10a3e479b1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1274_5f584fec559756fd82796c2f7db58b10a3e479b1.patch 2014-05-05 12:46:58.000000000 +0000 @@ -0,0 +1,40 @@ +commit 5f584fec559756fd82796c2f7db58b10a3e479b1 +Author: Vimalkumar +Date: Tue Sep 10 17:36:37 2013 -0700 + + net_sched: htb: fix a typo in htb_change_class() + + [ Upstream commit f3ad857e3da1abaea780dc892b592cd86c541c52 ] + + Fix a typo added in commit 56b765b79 ("htb: improved accuracy at high + rates") + + cbuffer should not be a copy of buffer. + + Signed-off-by: Vimalkumar + Signed-off-by: Eric Dumazet + Cc: Jesper Dangaard Brouer + Cc: Jiri Pirko + Reviewed-by: Jiri Pirko + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sched/sch_htb.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sched/sch_htb.c 2014-05-05 12:43:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/sched/sch_htb.c 2014-05-05 12:46:58.000000000 +0000 +@@ -1476,7 +1476,7 @@ + psched_ratecfg_precompute(&cl->ceil, &hopt->ceil); + + cl->buffer = PSCHED_TICKS2NS(hopt->buffer); +- cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer); ++ cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); + + sch_tree_unlock(sch); + +Index: linux-3.10-3.10.11/dummy/rpi_1274_5f584fec559756fd82796c2f7db58b10a3e479b1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1274_5f584fec559756fd82796c2f7db58b10a3e479b1.txt 2014-05-05 12:46:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1275_9fdd73559c439ba7216bce159a78e44328c3a573.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1275_9fdd73559c439ba7216bce159a78e44328c3a573.patch --- linux-3.10.11/debian/patches/rpi/rpi_1275_9fdd73559c439ba7216bce159a78e44328c3a573.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1275_9fdd73559c439ba7216bce159a78e44328c3a573.patch 2014-05-05 12:46:59.000000000 +0000 @@ -0,0 +1,39 @@ +commit 9fdd73559c439ba7216bce159a78e44328c3a573 +Author: Francois Romieu +Date: Sun Sep 8 01:15:35 2013 +0200 + + r8169: enforce RX_MULTI_EN for the 8168f. + + [ Upstream commit 3ced8c955e74d319f3e3997f7169c79d524dfd06 ] + + Same narrative as eb2dc35d99028b698cdedba4f5522bc43e576bd2 ("r8169: RxConfig + hack for the 8168evl.") regarding AMD IOMMU errors. + + RTL_GIGA_MAC_VER_36 - 8168f as well - has not been reported to behave the + same. + + Tested-by: David R + Tested-by: Frédéric Leroy + Cc: Hayes Wang + Signed-off-by: Francois Romieu + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/realtek/r8169.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/realtek/r8169.c 2014-05-05 11:50:25.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/realtek/r8169.c 2014-05-05 12:46:58.000000000 +0000 +@@ -4218,6 +4218,7 @@ + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_34: ++ case RTL_GIGA_MAC_VER_35: + RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); + break; + case RTL_GIGA_MAC_VER_40: +Index: linux-3.10-3.10.11/dummy/rpi_1275_9fdd73559c439ba7216bce159a78e44328c3a573.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1275_9fdd73559c439ba7216bce159a78e44328c3a573.txt 2014-05-05 12:46:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1276_0885f6b8bb0403a56546d302e749c1defe47339d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1276_0885f6b8bb0403a56546d302e749c1defe47339d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1276_0885f6b8bb0403a56546d302e749c1defe47339d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1276_0885f6b8bb0403a56546d302e749c1defe47339d.patch 2014-05-05 12:47:00.000000000 +0000 @@ -0,0 +1,36 @@ +commit 0885f6b8bb0403a56546d302e749c1defe47339d +Author: Sonic Zhang +Date: Wed Sep 11 11:31:53 2013 +0800 + + netpoll: Should handle ETH_P_ARP other than ETH_P_IP in netpoll_neigh_reply + + [ Upstream commit b0dd663b60944a3ce86430fa35549fb37968bda0 ] + + The received ARP request type in the Ethernet packet head is ETH_P_ARP other than ETH_P_IP. + + [ Bug introduced by commit b7394d2429c198b1da3d46ac39192e891029ec0f + ("netpoll: prepare for ipv6") ] + + Signed-off-by: Sonic Zhang + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/netpoll.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/netpoll.c 2014-05-05 11:50:25.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/netpoll.c 2014-05-05 12:46:59.000000000 +0000 +@@ -550,7 +550,7 @@ + return; + + proto = ntohs(eth_hdr(skb)->h_proto); +- if (proto == ETH_P_IP) { ++ if (proto == ETH_P_ARP) { + struct arphdr *arp; + unsigned char *arp_ptr; + /* No arp on this interface */ +Index: linux-3.10-3.10.11/dummy/rpi_1276_0885f6b8bb0403a56546d302e749c1defe47339d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1276_0885f6b8bb0403a56546d302e749c1defe47339d.txt 2014-05-05 12:46:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1277_e66bdd7106911886aebf118e1c1aebb5a26d0752.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1277_e66bdd7106911886aebf118e1c1aebb5a26d0752.patch --- linux-3.10.11/debian/patches/rpi/rpi_1277_e66bdd7106911886aebf118e1c1aebb5a26d0752.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1277_e66bdd7106911886aebf118e1c1aebb5a26d0752.patch 2014-05-05 12:47:01.000000000 +0000 @@ -0,0 +1,57 @@ +commit e66bdd7106911886aebf118e1c1aebb5a26d0752 +Author: Nikolay Aleksandrov +Date: Thu Sep 19 15:02:35 2013 +0200 + + netpoll: fix NULL pointer dereference in netpoll_cleanup + + [ Upstream commit d0fe8c888b1fd1a2f84b9962cabcb98a70988aec ] + + I've been hitting a NULL ptr deref while using netconsole because the + np->dev check and the pointer manipulation in netpoll_cleanup are done + without rtnl and the following sequence happens when having a netconsole + over a vlan and we remove the vlan while disabling the netconsole: + CPU 1 CPU2 + removes vlan and calls the notifier + enters store_enabled(), calls + netdev_cleanup which checks np->dev + and then waits for rtnl + executes the netconsole netdev + release notifier making np->dev + == NULL and releases rtnl + continues to dereference a member of + np->dev which at this point is == NULL + + Signed-off-by: Nikolay Aleksandrov + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/netpoll.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/netpoll.c 2014-05-05 12:46:59.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/netpoll.c 2014-05-05 12:47:00.000000000 +0000 +@@ -1289,15 +1289,14 @@ + + void netpoll_cleanup(struct netpoll *np) + { +- if (!np->dev) +- return; +- + rtnl_lock(); ++ if (!np->dev) ++ goto out; + __netpoll_cleanup(np); +- rtnl_unlock(); +- + dev_put(np->dev); + np->dev = NULL; ++out: ++ rtnl_unlock(); + } + EXPORT_SYMBOL(netpoll_cleanup); + +Index: linux-3.10-3.10.11/dummy/rpi_1277_e66bdd7106911886aebf118e1c1aebb5a26d0752.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1277_e66bdd7106911886aebf118e1c1aebb5a26d0752.txt 2014-05-05 12:47:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1278_a81a02460bdf054ca0c60c5aed29941f7134092d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1278_a81a02460bdf054ca0c60c5aed29941f7134092d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1278_a81a02460bdf054ca0c60c5aed29941f7134092d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1278_a81a02460bdf054ca0c60c5aed29941f7134092d.patch 2014-05-05 12:47:01.000000000 +0000 @@ -0,0 +1,63 @@ +commit a81a02460bdf054ca0c60c5aed29941f7134092d +Author: Jason Wang +Date: Wed Sep 11 18:09:48 2013 +0800 + + tuntap: correctly handle error in tun_set_iff() + + [ Upstream commit 662ca437e714caaab855b12415d6ffd815985bc0 ] + + Commit c8d68e6be1c3b242f1c598595830890b65cea64a + (tuntap: multiqueue support) only call free_netdev() on error in + tun_set_iff(). This causes several issues: + + - memory of tun security were leaked + - use after free since the flow gc timer was not deleted and the tfile + were not detached + + This patch solves the above issues. + + Reported-by: Wannes Rombouts + Cc: Michael S. Tsirkin + Signed-off-by: Jason Wang + Acked-by: Michael S. Tsirkin + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/tun.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/tun.c 2014-05-05 12:43:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/tun.c 2014-05-05 12:47:01.000000000 +0000 +@@ -1693,11 +1693,11 @@ + INIT_LIST_HEAD(&tun->disabled); + err = tun_attach(tun, file); + if (err < 0) +- goto err_free_dev; ++ goto err_free_flow; + + err = register_netdevice(tun->dev); + if (err < 0) +- goto err_free_dev; ++ goto err_detach; + + if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || + device_create_file(&tun->dev->dev, &dev_attr_owner) || +@@ -1741,7 +1741,12 @@ + strcpy(ifr->ifr_name, tun->dev->name); + return 0; + +- err_free_dev: ++err_detach: ++ tun_detach_all(dev); ++err_free_flow: ++ tun_flow_uninit(tun); ++ security_tun_dev_free_security(tun->security); ++err_free_dev: + free_netdev(dev); + return err; + } +Index: linux-3.10-3.10.11/dummy/rpi_1278_a81a02460bdf054ca0c60c5aed29941f7134092d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1278_a81a02460bdf054ca0c60c5aed29941f7134092d.txt 2014-05-05 12:47:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1279_872b11be53a4594c39262433c4176176fcb12bd2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1279_872b11be53a4594c39262433c4176176fcb12bd2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1279_872b11be53a4594c39262433c4176176fcb12bd2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1279_872b11be53a4594c39262433c4176176fcb12bd2.patch 2014-05-05 12:47:02.000000000 +0000 @@ -0,0 +1,195 @@ +commit 872b11be53a4594c39262433c4176176fcb12bd2 +Author: Daniel Borkmann +Date: Wed Sep 11 16:58:36 2013 +0200 + + net: sctp: fix ipv6 ipsec encryption bug in sctp_v6_xmit + + [ Upstream commit 95ee62083cb6453e056562d91f597552021e6ae7 ] + + Alan Chester reported an issue with IPv6 on SCTP that IPsec traffic is not + being encrypted, whereas on IPv4 it is. Setting up an AH + ESP transport + does not seem to have the desired effect: + + SCTP + IPv4: + + 22:14:20.809645 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 116) + 192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x1): ESP(spi=0x00000044,seq=0x1), length 72 + 22:14:20.813270 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 340) + 192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x1): + + SCTP + IPv6: + + 22:31:19.215029 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364) + fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp + 1) [INIT ACK] [init tag: 747759530] [rwnd: 62464] [OS: 10] [MIS: 10] + + Moreover, Alan says: + + This problem was seen with both Racoon and Racoon2. Other people have seen + this with OpenSwan. When IPsec is configured to encrypt all upper layer + protocols the SCTP connection does not initialize. After using Wireshark to + follow packets, this is because the SCTP packet leaves Box A unencrypted and + Box B believes all upper layer protocols are to be encrypted so it drops + this packet, causing the SCTP connection to fail to initialize. When IPsec + is configured to encrypt just SCTP, the SCTP packets are observed unencrypted. + + In fact, using `socat sctp6-listen:3333 -` on one end and transferring "plaintext" + string on the other end, results in cleartext on the wire where SCTP eventually + does not report any errors, thus in the latter case that Alan reports, the + non-paranoid user might think he's communicating over an encrypted transport on + SCTP although he's not (tcpdump ... -X): + + ... + 0x0030: 5d70 8e1a 0003 001a 177d eb6c 0000 0000 ]p.......}.l.... + 0x0040: 0000 0000 706c 6169 6e74 6578 740a 0000 ....plaintext... + + Only in /proc/net/xfrm_stat we can see XfrmInTmplMismatch increasing on the + receiver side. Initial follow-up analysis from Alan's bug report was done by + Alexey Dobriyan. Also thanks to Vlad Yasevich for feedback on this. + + SCTP has its own implementation of sctp_v6_xmit() not calling inet6_csk_xmit(). + This has the implication that it probably never really got updated along with + changes in inet6_csk_xmit() and therefore does not seem to invoke xfrm handlers. + + SCTP's IPv4 xmit however, properly calls ip_queue_xmit() to do the work. Since + a call to inet6_csk_xmit() would solve this problem, but result in unecessary + route lookups, let us just use the cached flowi6 instead that we got through + sctp_v6_get_dst(). Since all SCTP packets are being sent through sctp_packet_transmit(), + we do the route lookup / flow caching in sctp_transport_route(), hold it in + tp->dst and skb_dst_set() right after that. If we would alter fl6->daddr in + sctp_v6_xmit() to np->opt->srcrt, we possibly could run into the same effect + of not having xfrm layer pick it up, hence, use fl6_update_dst() in sctp_v6_get_dst() + instead to get the correct source routed dst entry, which we assign to the skb. + + Also source address routing example from 625034113 ("sctp: fix sctp to work with + ipv6 source address routing") still works with this patch! Nevertheless, in RFC5095 + it is actually 'recommended' to not use that anyway due to traffic amplification [1]. + So it seems we're not supposed to do that anyway in sctp_v6_xmit(). Moreover, if + we overwrite the flow destination here, the lower IPv6 layer will be unable to + put the correct destination address into IP header, as routing header is added in + ipv6_push_nfrag_opts() but then probably with wrong final destination. Things aside, + result of this patch is that we do not have any XfrmInTmplMismatch increase plus on + the wire with this patch it now looks like: + + SCTP + IPv6: + + 08:17:47.074080 IP6 2620:52:0:102f:7a2b:cbff:fe27:1b0a > 2620:52:0:102f:213:72ff:fe32:7eba: + AH(spi=0x00005fb4,seq=0x1): ESP(spi=0x00005fb5,seq=0x1), length 72 + 08:17:47.074264 IP6 2620:52:0:102f:213:72ff:fe32:7eba > 2620:52:0:102f:7a2b:cbff:fe27:1b0a: + AH(spi=0x00003d54,seq=0x1): ESP(spi=0x00003d55,seq=0x1), length 296 + + This fixes Kernel Bugzilla 24412. This security issue seems to be present since + 2.6.18 kernels. Lets just hope some big passive adversary in the wild didn't have + its fun with that. lksctp-tools IPv6 regression test suite passes as well with + this patch. + + [1] http://www.secdev.org/conf/IPv6_RH_security-csw07.pdf + + Reported-by: Alan Chester + Reported-by: Alexey Dobriyan + Signed-off-by: Daniel Borkmann + Cc: Steffen Klassert + Cc: Hannes Frederic Sowa + Acked-by: Vlad Yasevich + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sctp/ipv6.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sctp/ipv6.c 2014-05-05 11:50:24.000000000 +0000 ++++ linux-3.10-3.10.11/net/sctp/ipv6.c 2014-05-05 12:47:02.000000000 +0000 +@@ -210,45 +210,24 @@ + in6_dev_put(idev); + } + +-/* Based on tcp_v6_xmit() in tcp_ipv6.c. */ + static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) + { + struct sock *sk = skb->sk; + struct ipv6_pinfo *np = inet6_sk(sk); +- struct flowi6 fl6; +- +- memset(&fl6, 0, sizeof(fl6)); +- +- fl6.flowi6_proto = sk->sk_protocol; +- +- /* Fill in the dest address from the route entry passed with the skb +- * and the source address from the transport. +- */ +- fl6.daddr = transport->ipaddr.v6.sin6_addr; +- fl6.saddr = transport->saddr.v6.sin6_addr; +- +- fl6.flowlabel = np->flow_label; +- IP6_ECN_flow_xmit(sk, fl6.flowlabel); +- if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) +- fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; +- else +- fl6.flowi6_oif = sk->sk_bound_dev_if; +- +- if (np->opt && np->opt->srcrt) { +- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; +- fl6.daddr = *rt0->addr; +- } ++ struct flowi6 *fl6 = &transport->fl.u.ip6; + + SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", + __func__, skb, skb->len, +- &fl6.saddr, &fl6.daddr); ++ &fl6->saddr, &fl6->daddr); + +- SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); ++ IP6_ECN_flow_xmit(sk, fl6->flowlabel); + + if (!(transport->param_flags & SPP_PMTUD_ENABLE)) + skb->local_df = 1; + +- return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); ++ SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); ++ ++ return ip6_xmit(sk, skb, fl6, np->opt, np->tclass); + } + + /* Returns the dst cache entry for the given source and destination ip +@@ -261,10 +240,12 @@ + struct dst_entry *dst = NULL; + struct flowi6 *fl6 = &fl->u.ip6; + struct sctp_bind_addr *bp; ++ struct ipv6_pinfo *np = inet6_sk(sk); + struct sctp_sockaddr_entry *laddr; + union sctp_addr *baddr = NULL; + union sctp_addr *daddr = &t->ipaddr; + union sctp_addr dst_saddr; ++ struct in6_addr *final_p, final; + __u8 matchlen = 0; + __u8 bmatchlen; + sctp_scope_t scope; +@@ -287,7 +268,8 @@ + SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); + } + +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + if (!asoc || saddr) + goto out; + +@@ -339,10 +321,12 @@ + } + } + rcu_read_unlock(); ++ + if (baddr) { + fl6->saddr = baddr->v6.sin6_addr; + fl6->fl6_sport = baddr->v6.sin6_port; +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + } + + out: +Index: linux-3.10-3.10.11/dummy/rpi_1279_872b11be53a4594c39262433c4176176fcb12bd2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1279_872b11be53a4594c39262433c4176176fcb12bd2.txt 2014-05-05 12:47:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1280_0ff773f59ff375c42af2238457bda98ed4ddcd25.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1280_0ff773f59ff375c42af2238457bda98ed4ddcd25.patch --- linux-3.10.11/debian/patches/rpi/rpi_1280_0ff773f59ff375c42af2238457bda98ed4ddcd25.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1280_0ff773f59ff375c42af2238457bda98ed4ddcd25.patch 2014-05-05 12:47:03.000000000 +0000 @@ -0,0 +1,179 @@ +commit 0ff773f59ff375c42af2238457bda98ed4ddcd25 +Author: David Vrabel +Date: Wed Sep 11 14:52:48 2013 +0100 + + xen-netback: count number required slots for an skb more carefully + + [ Upstream commit 6e43fc04a6bc357d260583b8440882f28069207f ] + + When a VM is providing an iSCSI target and the LUN is used by the + backend domain, the generated skbs for direct I/O writes to the disk + have large, multi-page skb->data but no frags. + + With some lengths and starting offsets, xen_netbk_count_skb_slots() + would be one short because the simple calculation of + DIV_ROUND_UP(skb_headlen(), PAGE_SIZE) was not accounting for the + decisions made by start_new_rx_buffer() which does not guarantee + responses are fully packed. + + For example, a skb with length < 2 pages but which spans 3 pages would + be counted as requiring 2 slots but would actually use 3 slots. + + skb->data: + + | 1111|222222222222|3333 | + + Fully packed, this would need 2 slots: + + |111122222222|22223333 | + + But because the 2nd page wholy fits into a slot it is not split across + slots and goes into a slot of its own: + + |1111 |222222222222|3333 | + + Miscounting the number of slots means netback may push more responses + than the number of available requests. This will cause the frontend + to get very confused and report "Too many frags/slots". The frontend + never recovers and will eventually BUG. + + Fix this by counting the number of required slots more carefully. In + xen_netbk_count_skb_slots(), more closely follow the algorithm used by + xen_netbk_gop_skb() by introducing xen_netbk_count_frag_slots() which + is the dry-run equivalent of netbk_gop_frag_copy(). + + Signed-off-by: David Vrabel + Acked-by: Ian Campbell + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/xen-netback/netback.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/xen-netback/netback.c 2014-05-05 11:50:23.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/xen-netback/netback.c 2014-05-05 12:47:02.000000000 +0000 +@@ -354,6 +354,49 @@ + return false; + } + ++struct xenvif_count_slot_state { ++ unsigned long copy_off; ++ bool head; ++}; ++ ++unsigned int xenvif_count_frag_slots(struct xenvif *vif, ++ unsigned long offset, unsigned long size, ++ struct xenvif_count_slot_state *state) ++{ ++ unsigned count = 0; ++ ++ offset &= ~PAGE_MASK; ++ ++ while (size > 0) { ++ unsigned long bytes; ++ ++ bytes = PAGE_SIZE - offset; ++ ++ if (bytes > size) ++ bytes = size; ++ ++ if (start_new_rx_buffer(state->copy_off, bytes, state->head)) { ++ count++; ++ state->copy_off = 0; ++ } ++ ++ if (state->copy_off + bytes > MAX_BUFFER_OFFSET) ++ bytes = MAX_BUFFER_OFFSET - state->copy_off; ++ ++ state->copy_off += bytes; ++ ++ offset += bytes; ++ size -= bytes; ++ ++ if (offset == PAGE_SIZE) ++ offset = 0; ++ ++ state->head = false; ++ } ++ ++ return count; ++} ++ + /* + * Figure out how many ring slots we're going to need to send @skb to + * the guest. This function is essentially a dry run of +@@ -361,48 +404,39 @@ + */ + unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) + { ++ struct xenvif_count_slot_state state; + unsigned int count; +- int i, copy_off; ++ unsigned char *data; ++ unsigned i; + +- count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE); ++ state.head = true; ++ state.copy_off = 0; + +- copy_off = skb_headlen(skb) % PAGE_SIZE; ++ /* Slot for the first (partial) page of data. */ ++ count = 1; + ++ /* Need a slot for the GSO prefix for GSO extra data? */ + if (skb_shinfo(skb)->gso_size) + count++; + +- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { +- unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]); +- unsigned long offset = skb_shinfo(skb)->frags[i].page_offset; +- unsigned long bytes; +- +- offset &= ~PAGE_MASK; +- +- while (size > 0) { +- BUG_ON(offset >= PAGE_SIZE); +- BUG_ON(copy_off > MAX_BUFFER_OFFSET); ++ data = skb->data; ++ while (data < skb_tail_pointer(skb)) { ++ unsigned long offset = offset_in_page(data); ++ unsigned long size = PAGE_SIZE - offset; + +- bytes = PAGE_SIZE - offset; ++ if (data + size > skb_tail_pointer(skb)) ++ size = skb_tail_pointer(skb) - data; + +- if (bytes > size) +- bytes = size; ++ count += xenvif_count_frag_slots(vif, offset, size, &state); + +- if (start_new_rx_buffer(copy_off, bytes, 0)) { +- count++; +- copy_off = 0; +- } +- +- if (copy_off + bytes > MAX_BUFFER_OFFSET) +- bytes = MAX_BUFFER_OFFSET - copy_off; +- +- copy_off += bytes; ++ data += size; ++ } + +- offset += bytes; +- size -= bytes; ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]); ++ unsigned long offset = skb_shinfo(skb)->frags[i].page_offset; + +- if (offset == PAGE_SIZE) +- offset = 0; +- } ++ count += xenvif_count_frag_slots(vif, offset, size, &state); + } + return count; + } +Index: linux-3.10-3.10.11/dummy/rpi_1280_0ff773f59ff375c42af2238457bda98ed4ddcd25.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1280_0ff773f59ff375c42af2238457bda98ed4ddcd25.txt 2014-05-05 12:47:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1281_10a559a0df3eaa0c3cfbf780f88caf7f85c47106.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1281_10a559a0df3eaa0c3cfbf780f88caf7f85c47106.patch --- linux-3.10.11/debian/patches/rpi/rpi_1281_10a559a0df3eaa0c3cfbf780f88caf7f85c47106.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1281_10a559a0df3eaa0c3cfbf780f88caf7f85c47106.patch 2014-05-05 12:47:04.000000000 +0000 @@ -0,0 +1,41 @@ +commit 10a559a0df3eaa0c3cfbf780f88caf7f85c47106 +Author: Chris Healy +Date: Wed Sep 11 21:37:47 2013 -0700 + + resubmit bridge: fix message_age_timer calculation + + [ Upstream commit 9a0620133ccce9dd35c00a96405c8d80938c2cc0 ] + + This changes the message_age_timer calculation to use the BPDU's max age as + opposed to the local bridge's max age. This is in accordance with section + 8.6.2.3.2 Step 2 of the 802.1D-1998 sprecification. + + With the current implementation, when running with very large bridge + diameters, convergance will not always occur even if a root bridge is + configured to have a longer max age. + + Tested successfully on bridge diameters of ~200. + + Signed-off-by: Chris Healy + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_stp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_stp.c 2014-05-05 11:50:23.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_stp.c 2014-05-05 12:47:03.000000000 +0000 +@@ -209,7 +209,7 @@ + p->designated_age = jiffies - bpdu->message_age; + + mod_timer(&p->message_age_timer, jiffies +- + (p->br->max_age - bpdu->message_age)); ++ + (bpdu->max_age - bpdu->message_age)); + } + + /* called under bridge lock */ +Index: linux-3.10-3.10.11/dummy/rpi_1281_10a559a0df3eaa0c3cfbf780f88caf7f85c47106.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1281_10a559a0df3eaa0c3cfbf780f88caf7f85c47106.txt 2014-05-05 12:47:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1282_dc45b846e96d5a656ddd926334b6496e6916b446.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1282_dc45b846e96d5a656ddd926334b6496e6916b446.patch --- linux-3.10.11/debian/patches/rpi/rpi_1282_dc45b846e96d5a656ddd926334b6496e6916b446.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1282_dc45b846e96d5a656ddd926334b6496e6916b446.patch 2014-05-05 12:47:05.000000000 +0000 @@ -0,0 +1,112 @@ +commit dc45b846e96d5a656ddd926334b6496e6916b446 +Author: Herbert Xu +Date: Thu Sep 12 17:12:05 2013 +1000 + + bridge: Clamp forward_delay when enabling STP + + [ Upstream commit be4f154d5ef0ca147ab6bcd38857a774133f5450 ] + + At some point limits were added to forward_delay. However, the + limits are only enforced when STP is enabled. This created a + scenario where you could have a value outside the allowed range + while STP is disabled, which then stuck around even after STP + is enabled. + + This patch fixes this by clamping the value when we enable STP. + + I had to move the locking around a bit to ensure that there is + no window where someone could insert a value outside the range + while we're in the middle of enabling STP. + + Signed-off-by: Herbert Xu + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_private.h +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_private.h 2014-05-05 11:50:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_private.h 2014-05-05 12:47:04.000000000 +0000 +@@ -714,6 +714,7 @@ + extern void br_init_port(struct net_bridge_port *p); + extern void br_become_designated_port(struct net_bridge_port *p); + ++extern void __br_set_forward_delay(struct net_bridge *br, unsigned long t); + extern int br_set_forward_delay(struct net_bridge *br, unsigned long x); + extern int br_set_hello_time(struct net_bridge *br, unsigned long x); + extern int br_set_max_age(struct net_bridge *br, unsigned long x); +Index: linux-3.10-3.10.11/net/bridge/br_stp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_stp.c 2014-05-05 12:47:03.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_stp.c 2014-05-05 12:47:04.000000000 +0000 +@@ -544,18 +544,27 @@ + + } + ++void __br_set_forward_delay(struct net_bridge *br, unsigned long t) ++{ ++ br->bridge_forward_delay = t; ++ if (br_is_root_bridge(br)) ++ br->forward_delay = br->bridge_forward_delay; ++} ++ + int br_set_forward_delay(struct net_bridge *br, unsigned long val) + { + unsigned long t = clock_t_to_jiffies(val); ++ int err = -ERANGE; + ++ spin_lock_bh(&br->lock); + if (br->stp_enabled != BR_NO_STP && + (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)) +- return -ERANGE; ++ goto unlock; + +- spin_lock_bh(&br->lock); +- br->bridge_forward_delay = t; +- if (br_is_root_bridge(br)) +- br->forward_delay = br->bridge_forward_delay; ++ __br_set_forward_delay(br, t); ++ err = 0; ++ ++unlock: + spin_unlock_bh(&br->lock); +- return 0; ++ return err; + } +Index: linux-3.10-3.10.11/net/bridge/br_stp_if.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_stp_if.c 2014-05-05 11:50:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_stp_if.c 2014-05-05 12:47:04.000000000 +0000 +@@ -129,6 +129,14 @@ + char *envp[] = { NULL }; + + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); ++ ++ spin_lock_bh(&br->lock); ++ ++ if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); ++ else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); ++ + if (r == 0) { + br->stp_enabled = BR_USER_STP; + br_debug(br, "userspace STP started\n"); +@@ -137,10 +145,10 @@ + br_debug(br, "using kernel STP\n"); + + /* To start timers on any ports left in blocking */ +- spin_lock_bh(&br->lock); + br_port_state_selection(br); +- spin_unlock_bh(&br->lock); + } ++ ++ spin_unlock_bh(&br->lock); + } + + static void br_stp_stop(struct net_bridge *br) +Index: linux-3.10-3.10.11/dummy/rpi_1282_dc45b846e96d5a656ddd926334b6496e6916b446.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1282_dc45b846e96d5a656ddd926334b6496e6916b446.txt 2014-05-05 12:47:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1283_97ddc3e1f9d6637c81aaa470fde5669ffb854d14.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1283_97ddc3e1f9d6637c81aaa470fde5669ffb854d14.patch --- linux-3.10.11/debian/patches/rpi/rpi_1283_97ddc3e1f9d6637c81aaa470fde5669ffb854d14.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1283_97ddc3e1f9d6637c81aaa470fde5669ffb854d14.patch 2014-05-05 12:47:06.000000000 +0000 @@ -0,0 +1,57 @@ +commit 97ddc3e1f9d6637c81aaa470fde5669ffb854d14 +Author: Hong Zhiguo +Date: Sat Sep 14 22:42:27 2013 +0800 + + bridge: use br_port_get_rtnl within rtnl lock + + [ Upstream commit 1fb1754a8c70d69ab480763c423e0a74369c4a67 ] + + current br_port_get_rcu is problematic in bridging path + (NULL deref). Change these calls in netlink path first. + + Signed-off-by: Hong Zhiguo + Acked-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_netlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_netlink.c 2014-05-05 12:43:21.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_netlink.c 2014-05-05 12:47:05.000000000 +0000 +@@ -203,7 +203,7 @@ + struct net_device *dev, u32 filter_mask) + { + int err = 0; +- struct net_bridge_port *port = br_port_get_rcu(dev); ++ struct net_bridge_port *port = br_port_get_rtnl(dev); + + /* not a bridge port and */ + if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN)) +@@ -443,7 +443,7 @@ + struct net_port_vlans *pv; + + if (br_port_exists(dev)) +- pv = nbp_get_vlan_info(br_port_get_rcu(dev)); ++ pv = nbp_get_vlan_info(br_port_get_rtnl(dev)); + else if (dev->priv_flags & IFF_EBRIDGE) + pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev)); + else +Index: linux-3.10-3.10.11/net/bridge/br_private.h +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_private.h 2014-05-05 12:47:04.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_private.h 2014-05-05 12:47:05.000000000 +0000 +@@ -189,7 +189,7 @@ + return br_port_exists(dev) ? port : NULL; + } + +-static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev) ++static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev) + { + return br_port_exists(dev) ? + rtnl_dereference(dev->rx_handler_data) : NULL; +Index: linux-3.10-3.10.11/dummy/rpi_1283_97ddc3e1f9d6637c81aaa470fde5669ffb854d14.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1283_97ddc3e1f9d6637c81aaa470fde5669ffb854d14.txt 2014-05-05 12:47:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1284_960b8e5018a552f62cfbc0dfe94be7b6ba178f13.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1284_960b8e5018a552f62cfbc0dfe94be7b6ba178f13.patch --- linux-3.10.11/debian/patches/rpi/rpi_1284_960b8e5018a552f62cfbc0dfe94be7b6ba178f13.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1284_960b8e5018a552f62cfbc0dfe94be7b6ba178f13.patch 2014-05-05 12:47:06.000000000 +0000 @@ -0,0 +1,51 @@ +commit 960b8e5018a552f62cfbc0dfe94be7b6ba178f13 +Author: Hong Zhiguo +Date: Sat Sep 14 22:42:28 2013 +0800 + + bridge: fix NULL pointer deref of br_port_get_rcu + + [ Upstream commit 716ec052d2280d511e10e90ad54a86f5b5d4dcc2 ] + + The NULL deref happens when br_handle_frame is called between these + 2 lines of del_nbp: + dev->priv_flags &= ~IFF_BRIDGE_PORT; + /* --> br_handle_frame is called at this time */ + netdev_rx_handler_unregister(dev); + + In br_handle_frame the return of br_port_get_rcu(dev) is dereferenced + without check but br_port_get_rcu(dev) returns NULL if: + !(dev->priv_flags & IFF_BRIDGE_PORT) + + Eric Dumazet pointed out the testing of IFF_BRIDGE_PORT is not necessary + here since we're in rcu_read_lock and we have synchronize_net() in + netdev_rx_handler_unregister. So remove the testing of IFF_BRIDGE_PORT + and by the previous patch, make sure br_port_get_rcu is called in + bridging code. + + Signed-off-by: Hong Zhiguo + Acked-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_private.h +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_private.h 2014-05-05 12:47:05.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_private.h 2014-05-05 12:47:06.000000000 +0000 +@@ -183,10 +183,7 @@ + + static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) + { +- struct net_bridge_port *port = +- rcu_dereference_rtnl(dev->rx_handler_data); +- +- return br_port_exists(dev) ? port : NULL; ++ return rcu_dereference(dev->rx_handler_data); + } + + static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev) +Index: linux-3.10-3.10.11/dummy/rpi_1284_960b8e5018a552f62cfbc0dfe94be7b6ba178f13.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1284_960b8e5018a552f62cfbc0dfe94be7b6ba178f13.txt 2014-05-05 12:47:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1285_fa42a01cb0b985d0d7321956dfdfee2e3e179899.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1285_fa42a01cb0b985d0d7321956dfdfee2e3e179899.patch --- linux-3.10.11/debian/patches/rpi/rpi_1285_fa42a01cb0b985d0d7321956dfdfee2e3e179899.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1285_fa42a01cb0b985d0d7321956dfdfee2e3e179899.patch 2014-05-05 12:47:07.000000000 +0000 @@ -0,0 +1,39 @@ +commit fa42a01cb0b985d0d7321956dfdfee2e3e179899 +Author: Ding Zhi +Date: Mon Sep 16 11:31:15 2013 +0200 + + ip6_tunnels: raddr and laddr are inverted in nl msg + + [ Upstream commit 0d2ede929f61783aebfb9228e4d32a0546ee4d23 ] + + IFLA_IPTUN_LOCAL and IFLA_IPTUN_REMOTE were inverted. + + Introduced by c075b13098b3 (ip6tnl: advertise tunnel param via rtnl). + + Signed-off-by: Ding Zhi + Signed-off-by: Nicolas Dichtel + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/ip6_tunnel.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_tunnel.c 2014-05-05 11:50:21.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_tunnel.c 2014-05-05 12:47:07.000000000 +0000 +@@ -1646,9 +1646,9 @@ + + if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || + nla_put(skb, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), +- &parm->raddr) || +- nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), + &parm->laddr) || ++ nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), ++ &parm->raddr) || + nla_put_u8(skb, IFLA_IPTUN_TTL, parm->hop_limit) || + nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) || + nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || +Index: linux-3.10-3.10.11/dummy/rpi_1285_fa42a01cb0b985d0d7321956dfdfee2e3e179899.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1285_fa42a01cb0b985d0d7321956dfdfee2e3e179899.txt 2014-05-05 12:47:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1286_e4e7ba12fab4eba6eb6fe2863a6e0e91cd77c7cc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1286_e4e7ba12fab4eba6eb6fe2863a6e0e91cd77c7cc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1286_e4e7ba12fab4eba6eb6fe2863a6e0e91cd77c7cc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1286_e4e7ba12fab4eba6eb6fe2863a6e0e91cd77c7cc.patch 2014-05-05 12:47:08.000000000 +0000 @@ -0,0 +1,64 @@ +commit e4e7ba12fab4eba6eb6fe2863a6e0e91cd77c7cc +Author: Daniel Borkmann +Date: Mon Sep 16 12:36:02 2013 +0200 + + net: sctp: rfc4443: do not report ICMP redirects to user space + + [ Upstream commit 3f96a532113131d5a65ac9e00fc83cfa31b0295f ] + + Adapt the same behaviour for SCTP as present in TCP for ICMP redirect + messages. For IPv6, RFC4443, section 2.4. says: + + ... + (e) An ICMPv6 error message MUST NOT be originated as a result of + receiving the following: + ... + (e.2) An ICMPv6 redirect message [IPv6-DISC]. + ... + + Therefore, do not report an error to user space, just invoke dst's redirect + callback and leave, same for IPv4 as done in TCP as well. The implication + w/o having this patch could be that the reception of such packets would + generate a poll notification and in worst case it could even tear down the + whole connection. Therefore, stop updating sk_err on redirects. + + Reported-by: Duan Jiong + Reported-by: Hannes Frederic Sowa + Suggested-by: Vlad Yasevich + Signed-off-by: Daniel Borkmann + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sctp/input.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sctp/input.c 2014-05-05 11:50:21.000000000 +0000 ++++ linux-3.10-3.10.11/net/sctp/input.c 2014-05-05 12:47:08.000000000 +0000 +@@ -648,8 +648,7 @@ + break; + case ICMP_REDIRECT: + sctp_icmp_redirect(sk, transport, skb); +- err = 0; +- break; ++ /* Fall through to out_unlock. */ + default: + goto out_unlock; + } +Index: linux-3.10-3.10.11/net/sctp/ipv6.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sctp/ipv6.c 2014-05-05 12:47:02.000000000 +0000 ++++ linux-3.10-3.10.11/net/sctp/ipv6.c 2014-05-05 12:47:08.000000000 +0000 +@@ -189,7 +189,7 @@ + break; + case NDISC_REDIRECT: + sctp_icmp_redirect(sk, transport, skb); +- break; ++ goto out_unlock; + default: + break; + } +Index: linux-3.10-3.10.11/dummy/rpi_1286_e4e7ba12fab4eba6eb6fe2863a6e0e91cd77c7cc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1286_e4e7ba12fab4eba6eb6fe2863a6e0e91cd77c7cc.txt 2014-05-05 12:47:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1287_f25e4f35defd609b3e6ad2ae5e871bdbcc0af333.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1287_f25e4f35defd609b3e6ad2ae5e871bdbcc0af333.patch --- linux-3.10.11/debian/patches/rpi/rpi_1287_f25e4f35defd609b3e6ad2ae5e871bdbcc0af333.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1287_f25e4f35defd609b3e6ad2ae5e871bdbcc0af333.patch 2014-05-05 12:47:09.000000000 +0000 @@ -0,0 +1,35 @@ +commit f25e4f35defd609b3e6ad2ae5e871bdbcc0af333 +Author: Duan Jiong +Date: Wed Sep 18 20:03:27 2013 +0800 + + net:dccp: do not report ICMP redirects to user space + + [ Upstream commit bd784a140712fd06674f2240eecfc4ccae421129 ] + + DCCP shouldn't be setting sk_err on redirects as it + isn't an error condition. it should be doing exactly + what tcp is doing and leaving the error handler without + touching the socket. + + Signed-off-by: Duan Jiong + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/dccp/ipv6.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/dccp/ipv6.c 2014-05-05 11:50:21.000000000 +0000 ++++ linux-3.10-3.10.11/net/dccp/ipv6.c 2014-05-05 12:47:08.000000000 +0000 +@@ -135,6 +135,7 @@ + + if (dst) + dst->ops->redirect(dst, sk, skb); ++ goto out; + } + + if (type == ICMPV6_PKT_TOOBIG) { +Index: linux-3.10-3.10.11/dummy/rpi_1287_f25e4f35defd609b3e6ad2ae5e871bdbcc0af333.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1287_f25e4f35defd609b3e6ad2ae5e871bdbcc0af333.txt 2014-05-05 12:47:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1288_cd176b578d356844f68176a1e0b6346c1cc9e33d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1288_cd176b578d356844f68176a1e0b6346c1cc9e33d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1288_cd176b578d356844f68176a1e0b6346c1cc9e33d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1288_cd176b578d356844f68176a1e0b6346c1cc9e33d.patch 2014-05-05 12:47:10.000000000 +0000 @@ -0,0 +1,34 @@ +commit cd176b578d356844f68176a1e0b6346c1cc9e33d +Author: Ansis Atteka +Date: Wed Sep 18 15:29:52 2013 -0700 + + ip: use ip_hdr() in __ip_make_skb() to retrieve IP header + + [ Upstream commit 749154aa56b57652a282cbde57a57abc278d1205 ] + + skb->data already points to IP header, but for the sake of + consistency we can also use ip_hdr() to retrieve it. + + Signed-off-by: Ansis Atteka + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/ip_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ip_output.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ip_output.c 2014-05-05 12:47:09.000000000 +0000 +@@ -1324,7 +1324,7 @@ + else + ttl = ip_select_ttl(inet, &rt->dst); + +- iph = (struct iphdr *)skb->data; ++ iph = ip_hdr(skb); + iph->version = 4; + iph->ihl = 5; + iph->tos = inet->tos; +Index: linux-3.10-3.10.11/dummy/rpi_1288_cd176b578d356844f68176a1e0b6346c1cc9e33d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1288_cd176b578d356844f68176a1e0b6346c1cc9e33d.txt 2014-05-05 12:47:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1289_68a9e707892caf0fda14656963fd99c6a1c10e46.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1289_68a9e707892caf0fda14656963fd99c6a1c10e46.patch --- linux-3.10.11/debian/patches/rpi/rpi_1289_68a9e707892caf0fda14656963fd99c6a1c10e46.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1289_68a9e707892caf0fda14656963fd99c6a1c10e46.patch 2014-05-05 12:47:12.000000000 +0000 @@ -0,0 +1,208 @@ +commit 68a9e707892caf0fda14656963fd99c6a1c10e46 +Author: Ansis Atteka +Date: Wed Sep 18 15:29:53 2013 -0700 + + ip: generate unique IP identificator if local fragmentation is allowed + + [ Upstream commit 703133de331a7a7df47f31fb9de51dc6f68a9de8 ] + + If local fragmentation is allowed, then ip_select_ident() and + ip_select_ident_more() need to generate unique IDs to ensure + correct defragmentation on the peer. + + For example, if IPsec (tunnel mode) has to encrypt large skbs + that have local_df bit set, then all IP fragments that belonged + to different ESP datagrams would have used the same identificator. + If one of these IP fragments would get lost or reordered, then + peer could possibly stitch together wrong IP fragments that did + not belong to the same datagram. This would lead to a packet loss + or data corruption. + + Signed-off-by: Ansis Atteka + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ppp/pptp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ppp/pptp.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ppp/pptp.c 2014-05-05 12:47:10.000000000 +0000 +@@ -281,7 +281,7 @@ + nf_reset(skb); + + skb->ip_summed = CHECKSUM_NONE; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ip_send_check(iph); + + ip_local_out(skb); +Index: linux-3.10-3.10.11/include/net/ip.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/ip.h 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/ip.h 2014-05-05 12:47:10.000000000 +0000 +@@ -254,9 +254,11 @@ + + extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); + +-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk) ++static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + /* This is only to work around buggy Windows95/2000 + * VJ compression implementations. If the ID field + * does not change, they drop every other packet in +@@ -268,9 +270,11 @@ + __ip_select_ident(iph, dst, 0); + } + +-static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more) ++static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + if (sk && inet_sk(sk)->inet_daddr) { + iph->id = htons(inet_sk(sk)->inet_id); + inet_sk(sk)->inet_id += 1 + more; +Index: linux-3.10-3.10.11/net/ipv4/igmp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/igmp.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/igmp.c 2014-05-05 12:47:10.000000000 +0000 +@@ -343,7 +343,7 @@ + pip->saddr = fl4.saddr; + pip->protocol = IPPROTO_IGMP; + pip->tot_len = 0; /* filled in later */ +- ip_select_ident(pip, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8 *)&pip[1])[0] = IPOPT_RA; + ((u8 *)&pip[1])[1] = 4; + ((u8 *)&pip[1])[2] = 0; +@@ -687,7 +687,7 @@ + iph->daddr = dst; + iph->saddr = fl4.saddr; + iph->protocol = IPPROTO_IGMP; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8 *)&iph[1])[0] = IPOPT_RA; + ((u8 *)&iph[1])[1] = 4; + ((u8 *)&iph[1])[2] = 0; +Index: linux-3.10-3.10.11/net/ipv4/inetpeer.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/inetpeer.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/inetpeer.c 2014-05-05 12:47:10.000000000 +0000 +@@ -32,8 +32,8 @@ + * At the moment of writing this notes identifier of IP packets is generated + * to be unpredictable using this code only for packets subjected + * (actually or potentially) to defragmentation. I.e. DF packets less than +- * PMTU in size uses a constant ID and do not use this code (see +- * ip_select_ident() in include/net/ip.h). ++ * PMTU in size when local fragmentation is disabled use a constant ID and do ++ * not use this code (see ip_select_ident() in include/net/ip.h). + * + * Route cache entries hold references to our nodes. + * New cache entries get references via lookup by destination IP address in +Index: linux-3.10-3.10.11/net/ipv4/ip_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ip_output.c 2014-05-05 12:47:09.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ip_output.c 2014-05-05 12:47:10.000000000 +0000 +@@ -148,7 +148,7 @@ + iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); + iph->saddr = saddr; + iph->protocol = sk->sk_protocol; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + + if (opt && opt->opt.optlen) { + iph->ihl += opt->opt.optlen>>2; +@@ -394,7 +394,7 @@ + ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); + } + +- ip_select_ident_more(iph, &rt->dst, sk, ++ ip_select_ident_more(skb, &rt->dst, sk, + (skb_shinfo(skb)->gso_segs ?: 1) - 1); + + skb->priority = sk->sk_priority; +@@ -1332,7 +1332,7 @@ + iph->ttl = ttl; + iph->protocol = sk->sk_protocol; + ip_copy_addrs(iph, fl4); +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + + if (opt) { + iph->ihl += opt->optlen>>2; +Index: linux-3.10-3.10.11/net/ipv4/ipmr.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ipmr.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ipmr.c 2014-05-05 12:47:10.000000000 +0000 +@@ -1658,7 +1658,7 @@ + iph->protocol = IPPROTO_IPIP; + iph->ihl = 5; + iph->tot_len = htons(skb->len); +- ip_select_ident(iph, skb_dst(skb), NULL); ++ ip_select_ident(skb, skb_dst(skb), NULL); + ip_send_check(iph); + + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); +Index: linux-3.10-3.10.11/net/ipv4/raw.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/raw.c 2014-05-05 12:43:27.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/raw.c 2014-05-05 12:47:10.000000000 +0000 +@@ -387,7 +387,7 @@ + iph->check = 0; + iph->tot_len = htons(length); + if (!iph->id) +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + } +Index: linux-3.10-3.10.11/net/ipv4/xfrm4_mode_tunnel.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/xfrm4_mode_tunnel.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/xfrm4_mode_tunnel.c 2014-05-05 12:47:10.000000000 +0000 +@@ -117,7 +117,7 @@ + + top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? + 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); +- ip_select_ident(top_iph, dst->child, NULL); ++ ip_select_ident(skb, dst->child, NULL); + + top_iph->ttl = ip4_dst_hoplimit(dst->child); + +Index: linux-3.10-3.10.11/net/ipv6/sit.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/sit.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/sit.c 2014-05-05 12:47:10.000000000 +0000 +@@ -865,7 +865,7 @@ + iph->ttl = iph6->hop_limit; + + skb->ip_summed = CHECKSUM_NONE; +- ip_select_ident(iph, skb_dst(skb), NULL); ++ ip_select_ident(skb, skb_dst(skb), NULL); + iptunnel_xmit(skb, dev); + return NETDEV_TX_OK; + +Index: linux-3.10-3.10.11/net/netfilter/ipvs/ip_vs_xmit.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/netfilter/ipvs/ip_vs_xmit.c 2014-05-05 11:50:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/netfilter/ipvs/ip_vs_xmit.c 2014-05-05 12:47:10.000000000 +0000 +@@ -883,7 +883,7 @@ + iph->daddr = cp->daddr.ip; + iph->saddr = saddr; + iph->ttl = old_iph->ttl; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + /* Another hack: avoid icmp_send in ip_fragment */ + skb->local_df = 1; +Index: linux-3.10-3.10.11/dummy/rpi_1289_68a9e707892caf0fda14656963fd99c6a1c10e46.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1289_68a9e707892caf0fda14656963fd99c6a1c10e46.txt 2014-05-05 12:47:10.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1290_f5a30bc1d6b338ecba5b948798a48bc5b59ef30f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1290_f5a30bc1d6b338ecba5b948798a48bc5b59ef30f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1290_f5a30bc1d6b338ecba5b948798a48bc5b59ef30f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1290_f5a30bc1d6b338ecba5b948798a48bc5b59ef30f.patch 2014-05-05 12:47:12.000000000 +0000 @@ -0,0 +1,126 @@ +commit f5a30bc1d6b338ecba5b948798a48bc5b59ef30f +Author: Hannes Frederic Sowa +Date: Sat Sep 21 06:27:00 2013 +0200 + + ipv6: udp packets following an UFO enqueued packet need also be handled by UFO + + [ Upstream commit 2811ebac2521ceac84f2bdae402455baa6a7fb47 ] + + In the following scenario the socket is corked: + If the first UDP packet is larger then the mtu we try to append it to the + write queue via ip6_ufo_append_data. A following packet, which is smaller + than the mtu would be appended to the already queued up gso-skb via + plain ip6_append_data. This causes random memory corruptions. + + In ip6_ufo_append_data we also have to be careful to not queue up the + same skb multiple times. So setup the gso frame only when no first skb + is available. + + This also fixes a shortcoming where we add the current packet's length to + cork->length but return early because of a packet > mtu with dontfrag set + (instead of sutracting it again). + + Found with trinity. + + Cc: YOSHIFUJI Hideaki + Signed-off-by: Hannes Frederic Sowa + Reported-by: Dmitry Vyukov + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/ip6_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_output.c 2014-05-05 11:50:19.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_output.c 2014-05-05 12:47:12.000000000 +0000 +@@ -1039,6 +1039,8 @@ + * udp datagram + */ + if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { ++ struct frag_hdr fhdr; ++ + skb = sock_alloc_send_skb(sk, + hh_len + fragheaderlen + transhdrlen + 20, + (flags & MSG_DONTWAIT), &err); +@@ -1059,12 +1061,6 @@ + + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum = 0; +- } +- +- err = skb_append_datato_frags(sk,skb, getfrag, from, +- (length - transhdrlen)); +- if (!err) { +- struct frag_hdr fhdr; + + /* Specify the length of each IPv6 datagram fragment. + * It has to be a multiple of 8. +@@ -1075,15 +1071,10 @@ + ipv6_select_ident(&fhdr, rt); + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; + __skb_queue_tail(&sk->sk_write_queue, skb); +- +- return 0; + } +- /* There is not enough support do UPD LSO, +- * so follow normal path +- */ +- kfree_skb(skb); + +- return err; ++ return skb_append_datato_frags(sk, skb, getfrag, from, ++ (length - transhdrlen)); + } + + static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, +@@ -1250,27 +1241,27 @@ + * --yoshfuji + */ + +- cork->length += length; +- if (length > mtu) { +- int proto = sk->sk_protocol; +- if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ +- ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); +- return -EMSGSIZE; +- } +- +- if (proto == IPPROTO_UDP && +- (rt->dst.dev->features & NETIF_F_UFO)) { ++ if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || ++ sk->sk_protocol == IPPROTO_RAW)) { ++ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); ++ return -EMSGSIZE; ++ } + +- err = ip6_ufo_append_data(sk, getfrag, from, length, +- hh_len, fragheaderlen, +- transhdrlen, mtu, flags, rt); +- if (err) +- goto error; +- return 0; +- } ++ skb = skb_peek_tail(&sk->sk_write_queue); ++ cork->length += length; ++ if (((length > mtu) || ++ (skb && skb_is_gso(skb))) && ++ (sk->sk_protocol == IPPROTO_UDP) && ++ (rt->dst.dev->features & NETIF_F_UFO)) { ++ err = ip6_ufo_append_data(sk, getfrag, from, length, ++ hh_len, fragheaderlen, ++ transhdrlen, mtu, flags, rt); ++ if (err) ++ goto error; ++ return 0; + } + +- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) ++ if (!skb) + goto alloc_new_skb; + + while (length > 0) { +Index: linux-3.10-3.10.11/dummy/rpi_1290_f5a30bc1d6b338ecba5b948798a48bc5b59ef30f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1290_f5a30bc1d6b338ecba5b948798a48bc5b59ef30f.txt 2014-05-05 12:47:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1291_f7036a444e8a9eb1e41f4e157c8f19b8efbc2cb7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1291_f7036a444e8a9eb1e41f4e157c8f19b8efbc2cb7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1291_f7036a444e8a9eb1e41f4e157c8f19b8efbc2cb7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1291_f7036a444e8a9eb1e41f4e157c8f19b8efbc2cb7.patch 2014-05-05 12:47:13.000000000 +0000 @@ -0,0 +1,52 @@ +commit f7036a444e8a9eb1e41f4e157c8f19b8efbc2cb7 +Author: Roger Luethi +Date: Sat Sep 21 14:24:11 2013 +0200 + + via-rhine: fix VLAN priority field (PCP, IEEE 802.1p) + + [ Upstream commit 207070f5221e2a901d56a49df9cde47d9b716cd7 ] + + Outgoing packets sent by via-rhine have their VLAN PCP field off by one + (when hardware acceleration is enabled). The TX descriptor expects only VID + and PCP (without a CFI/DEI bit). + + Peter Boström noticed and reported the bug. + + Signed-off-by: Roger Luethi + Cc: Peter Boström + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/via/via-rhine.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/via/via-rhine.c 2014-05-05 11:50:19.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/via/via-rhine.c 2014-05-05 12:47:13.000000000 +0000 +@@ -32,7 +32,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #define DRV_NAME "via-rhine" +-#define DRV_VERSION "1.5.0" ++#define DRV_VERSION "1.5.1" + #define DRV_RELDATE "2010-10-09" + + #include +@@ -1694,7 +1694,12 @@ + cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); + + if (unlikely(vlan_tx_tag_present(skb))) { +- rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); ++ u16 vid_pcp = vlan_tx_tag_get(skb); ++ ++ /* drop CFI/DEI bit, register needs VID and PCP */ ++ vid_pcp = (vid_pcp & VLAN_VID_MASK) | ++ ((vid_pcp & VLAN_PRIO_MASK) >> 1); ++ rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16); + /* request tagging */ + rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); + } +Index: linux-3.10-3.10.11/dummy/rpi_1291_f7036a444e8a9eb1e41f4e157c8f19b8efbc2cb7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1291_f7036a444e8a9eb1e41f4e157c8f19b8efbc2cb7.txt 2014-05-05 12:47:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1292_6ea2edb3b6cbe72d2f943e205c463f6cb8bafe56.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1292_6ea2edb3b6cbe72d2f943e205c463f6cb8bafe56.patch --- linux-3.10.11/debian/patches/rpi/rpi_1292_6ea2edb3b6cbe72d2f943e205c463f6cb8bafe56.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1292_6ea2edb3b6cbe72d2f943e205c463f6cb8bafe56.patch 2014-05-05 12:47:14.000000000 +0000 @@ -0,0 +1,196 @@ +commit 6ea2edb3b6cbe72d2f943e205c463f6cb8bafe56 +Author: Catalin(ux) M. BOIE +Date: Mon Sep 23 23:04:19 2013 +0300 + + IPv6 NAT: Do not drop DNATed 6to4/6rd packets + + [ Upstream commit 7df37ff33dc122f7bd0614d707939fe84322d264 ] + + When a router is doing DNAT for 6to4/6rd packets the latest + anti-spoofing commit 218774dc ("ipv6: add anti-spoofing checks for + 6to4 and 6rd") will drop them because the IPv6 address embedded does + not match the IPv4 destination. This patch will allow them to pass by + testing if we have an address that matches on 6to4/6rd interface. I + have been hit by this problem using Fedora and IPV6TO4_IPV4ADDR. + Also, log the dropped packets (with rate limit). + + Signed-off-by: Catalin(ux) M. BOIE + Acked-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/addrconf.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/addrconf.h 2014-05-05 11:50:18.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/addrconf.h 2014-05-05 12:47:13.000000000 +0000 +@@ -73,6 +73,10 @@ + const struct in6_addr *addr); + #endif + ++bool ipv6_chk_custom_prefix(const struct in6_addr *addr, ++ const unsigned int prefix_len, ++ struct net_device *dev); ++ + extern int ipv6_chk_prefix(const struct in6_addr *addr, + struct net_device *dev); + +Index: linux-3.10-3.10.11/net/ipv6/addrconf.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/addrconf.c 2014-05-05 12:43:18.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/addrconf.c 2014-05-05 12:47:13.000000000 +0000 +@@ -1533,6 +1533,33 @@ + return false; + } + ++/* Compares an address/prefix_len with addresses on device @dev. ++ * If one is found it returns true. ++ */ ++bool ipv6_chk_custom_prefix(const struct in6_addr *addr, ++ const unsigned int prefix_len, struct net_device *dev) ++{ ++ struct inet6_dev *idev; ++ struct inet6_ifaddr *ifa; ++ bool ret = false; ++ ++ rcu_read_lock(); ++ idev = __in6_dev_get(dev); ++ if (idev) { ++ read_lock_bh(&idev->lock); ++ list_for_each_entry(ifa, &idev->addr_list, if_list) { ++ ret = ipv6_prefix_equal(addr, &ifa->addr, prefix_len); ++ if (ret) ++ break; ++ } ++ read_unlock_bh(&idev->lock); ++ } ++ rcu_read_unlock(); ++ ++ return ret; ++} ++EXPORT_SYMBOL(ipv6_chk_custom_prefix); ++ + int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev) + { + struct inet6_dev *idev; +Index: linux-3.10-3.10.11/net/ipv6/sit.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/sit.c 2014-05-05 12:47:10.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/sit.c 2014-05-05 12:47:13.000000000 +0000 +@@ -566,6 +566,70 @@ + return false; + } + ++/* Checks if an address matches an address on the tunnel interface. ++ * Used to detect the NAT of proto 41 packets and let them pass spoofing test. ++ * Long story: ++ * This function is called after we considered the packet as spoofed ++ * in is_spoofed_6rd. ++ * We may have a router that is doing NAT for proto 41 packets ++ * for an internal station. Destination a.a.a.a/PREFIX:bbbb:bbbb ++ * will be translated to n.n.n.n/PREFIX:bbbb:bbbb. And is_spoofed_6rd ++ * function will return true, dropping the packet. ++ * But, we can still check if is spoofed against the IP ++ * addresses associated with the interface. ++ */ ++static bool only_dnatted(const struct ip_tunnel *tunnel, ++ const struct in6_addr *v6dst) ++{ ++ int prefix_len; ++ ++#ifdef CONFIG_IPV6_SIT_6RD ++ prefix_len = tunnel->ip6rd.prefixlen + 32 ++ - tunnel->ip6rd.relay_prefixlen; ++#else ++ prefix_len = 48; ++#endif ++ return ipv6_chk_custom_prefix(v6dst, prefix_len, tunnel->dev); ++} ++ ++/* Returns true if a packet is spoofed */ ++static bool packet_is_spoofed(struct sk_buff *skb, ++ const struct iphdr *iph, ++ struct ip_tunnel *tunnel) ++{ ++ const struct ipv6hdr *ipv6h; ++ ++ if (tunnel->dev->priv_flags & IFF_ISATAP) { ++ if (!isatap_chksrc(skb, iph, tunnel)) ++ return true; ++ ++ return false; ++ } ++ ++ if (tunnel->dev->flags & IFF_POINTOPOINT) ++ return false; ++ ++ ipv6h = ipv6_hdr(skb); ++ ++ if (unlikely(is_spoofed_6rd(tunnel, iph->saddr, &ipv6h->saddr))) { ++ net_warn_ratelimited("Src spoofed %pI4/%pI6c -> %pI4/%pI6c\n", ++ &iph->saddr, &ipv6h->saddr, ++ &iph->daddr, &ipv6h->daddr); ++ return true; ++ } ++ ++ if (likely(!is_spoofed_6rd(tunnel, iph->daddr, &ipv6h->daddr))) ++ return false; ++ ++ if (only_dnatted(tunnel, &ipv6h->daddr)) ++ return false; ++ ++ net_warn_ratelimited("Dst spoofed %pI4/%pI6c -> %pI4/%pI6c\n", ++ &iph->saddr, &ipv6h->saddr, ++ &iph->daddr, &ipv6h->daddr); ++ return true; ++} ++ + static int ipip6_rcv(struct sk_buff *skb) + { + const struct iphdr *iph = ip_hdr(skb); +@@ -584,19 +648,9 @@ + skb->protocol = htons(ETH_P_IPV6); + skb->pkt_type = PACKET_HOST; + +- if (tunnel->dev->priv_flags & IFF_ISATAP) { +- if (!isatap_chksrc(skb, iph, tunnel)) { +- tunnel->dev->stats.rx_errors++; +- goto out; +- } +- } else if (!(tunnel->dev->flags&IFF_POINTOPOINT)) { +- if (is_spoofed_6rd(tunnel, iph->saddr, +- &ipv6_hdr(skb)->saddr) || +- is_spoofed_6rd(tunnel, iph->daddr, +- &ipv6_hdr(skb)->daddr)) { +- tunnel->dev->stats.rx_errors++; +- goto out; +- } ++ if (packet_is_spoofed(skb, iph, tunnel)) { ++ tunnel->dev->stats.rx_errors++; ++ goto out; + } + + __skb_tunnel_rx(skb, tunnel->dev); +@@ -713,7 +767,7 @@ + neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); + + if (neigh == NULL) { +- net_dbg_ratelimited("sit: nexthop == NULL\n"); ++ net_dbg_ratelimited("nexthop == NULL\n"); + goto tx_error; + } + +@@ -742,7 +796,7 @@ + neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); + + if (neigh == NULL) { +- net_dbg_ratelimited("sit: nexthop == NULL\n"); ++ net_dbg_ratelimited("nexthop == NULL\n"); + goto tx_error; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1292_6ea2edb3b6cbe72d2f943e205c463f6cb8bafe56.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1292_6ea2edb3b6cbe72d2f943e205c463f6cb8bafe56.txt 2014-05-05 12:47:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1293_bdf831a681dd237fcde669e07e5202daddfa0c65.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1293_bdf831a681dd237fcde669e07e5202daddfa0c65.patch --- linux-3.10.11/debian/patches/rpi/rpi_1293_bdf831a681dd237fcde669e07e5202daddfa0c65.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1293_bdf831a681dd237fcde669e07e5202daddfa0c65.patch 2014-05-05 12:47:15.000000000 +0000 @@ -0,0 +1,151 @@ +commit bdf831a681dd237fcde669e07e5202daddfa0c65 +Author: Eric Dumazet +Date: Tue Sep 24 06:19:57 2013 -0700 + + net: net_secret should not depend on TCP + + [ Upstream commit 9a3bab6b05383f1e4c3716b3615500c51285959e ] + + A host might need net_secret[] and never open a single socket. + + Problem added in commit aebda156a570782 + ("net: defer net_secret[] initialization") + + Based on prior patch from Hannes Frederic Sowa. + + Reported-by: Hannes Frederic Sowa + Signed-off-by: Eric Dumazet + Acked-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/secure_seq.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/secure_seq.h 2014-05-05 11:50:18.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/secure_seq.h 2014-05-05 12:47:14.000000000 +0000 +@@ -3,7 +3,6 @@ + + #include + +-extern void net_secret_init(void); + extern __u32 secure_ip_id(__be32 daddr); + extern __u32 secure_ipv6_id(const __be32 daddr[4]); + extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); +Index: linux-3.10-3.10.11/net/core/secure_seq.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/secure_seq.c 2014-05-05 11:50:18.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/secure_seq.c 2014-05-05 12:47:14.000000000 +0000 +@@ -10,11 +10,24 @@ + + #include + +-static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; ++#define NET_SECRET_SIZE (MD5_MESSAGE_BYTES / 4) + +-void net_secret_init(void) ++static u32 net_secret[NET_SECRET_SIZE] ____cacheline_aligned; ++ ++static void net_secret_init(void) + { +- get_random_bytes(net_secret, sizeof(net_secret)); ++ u32 tmp; ++ int i; ++ ++ if (likely(net_secret[0])) ++ return; ++ ++ for (i = NET_SECRET_SIZE; i > 0;) { ++ do { ++ get_random_bytes(&tmp, sizeof(tmp)); ++ } while (!tmp); ++ cmpxchg(&net_secret[--i], 0, tmp); ++ } + } + + #ifdef CONFIG_INET +@@ -42,6 +55,7 @@ + u32 hash[MD5_DIGEST_WORDS]; + u32 i; + ++ net_secret_init(); + memcpy(hash, saddr, 16); + for (i = 0; i < 4; i++) + secret[i] = net_secret[i] + (__force u32)daddr[i]; +@@ -63,6 +77,7 @@ + u32 hash[MD5_DIGEST_WORDS]; + u32 i; + ++ net_secret_init(); + memcpy(hash, saddr, 16); + for (i = 0; i < 4; i++) + secret[i] = net_secret[i] + (__force u32) daddr[i]; +@@ -82,6 +97,7 @@ + { + u32 hash[MD5_DIGEST_WORDS]; + ++ net_secret_init(); + hash[0] = (__force __u32) daddr; + hash[1] = net_secret[13]; + hash[2] = net_secret[14]; +@@ -96,6 +112,7 @@ + { + __u32 hash[4]; + ++ net_secret_init(); + memcpy(hash, daddr, 16); + md5_transform(hash, net_secret); + +@@ -107,6 +124,7 @@ + { + u32 hash[MD5_DIGEST_WORDS]; + ++ net_secret_init(); + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; +@@ -121,6 +139,7 @@ + { + u32 hash[MD5_DIGEST_WORDS]; + ++ net_secret_init(); + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = (__force u32)dport ^ net_secret[14]; +@@ -140,6 +159,7 @@ + u32 hash[MD5_DIGEST_WORDS]; + u64 seq; + ++ net_secret_init(); + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; +@@ -164,6 +184,7 @@ + u64 seq; + u32 i; + ++ net_secret_init(); + memcpy(hash, saddr, 16); + for (i = 0; i < 4; i++) + secret[i] = net_secret[i] + daddr[i]; +Index: linux-3.10-3.10.11/net/ipv4/af_inet.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/af_inet.c 2014-05-05 11:50:18.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/af_inet.c 2014-05-05 12:47:14.000000000 +0000 +@@ -263,10 +263,8 @@ + get_random_bytes(&rnd, sizeof(rnd)); + } while (rnd == 0); + +- if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) { ++ if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) + get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret)); +- net_secret_init(); +- } + } + EXPORT_SYMBOL(build_ehash_secret); + +Index: linux-3.10-3.10.11/dummy/rpi_1293_bdf831a681dd237fcde669e07e5202daddfa0c65.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1293_bdf831a681dd237fcde669e07e5202daddfa0c65.txt 2014-05-05 12:47:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1294_f17c9815499705904d67157cb274a260d944e5f2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1294_f17c9815499705904d67157cb274a260d944e5f2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1294_f17c9815499705904d67157cb274a260d944e5f2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1294_f17c9815499705904d67157cb274a260d944e5f2.patch 2014-05-05 12:47:16.000000000 +0000 @@ -0,0 +1,35 @@ +commit f17c9815499705904d67157cb274a260d944e5f2 +Author: Peter Korsgaard +Date: Mon Sep 30 23:28:20 2013 +0200 + + dm9601: fix IFF_ALLMULTI handling + + [ Upstream commit bf0ea6380724beb64f27a722dfc4b0edabff816e ] + + Pass-all-multicast is controlled by bit 3 in RX control, not bit 2 + (pass undersized frames). + + Reported-by: Joseph Chang + Signed-off-by: Peter Korsgaard + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/usb/dm9601.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/usb/dm9601.c 2014-05-05 11:50:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/usb/dm9601.c 2014-05-05 12:47:15.000000000 +0000 +@@ -303,7 +303,7 @@ + rx_ctl |= 0x02; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > DM_MAX_MCAST) { +- rx_ctl |= 0x04; ++ rx_ctl |= 0x08; + } else if (!netdev_mc_empty(net)) { + struct netdev_hw_addr *ha; + +Index: linux-3.10-3.10.11/dummy/rpi_1294_f17c9815499705904d67157cb274a260d944e5f2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1294_f17c9815499705904d67157cb274a260d944e5f2.txt 2014-05-05 12:47:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1295_c9b391f6d166118c5543e9d1708e67977dbdbe1f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1295_c9b391f6d166118c5543e9d1708e67977dbdbe1f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1295_c9b391f6d166118c5543e9d1708e67977dbdbe1f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1295_c9b391f6d166118c5543e9d1708e67977dbdbe1f.patch 2014-05-05 12:47:16.000000000 +0000 @@ -0,0 +1,81 @@ +commit c9b391f6d166118c5543e9d1708e67977dbdbe1f +Author: Neil Horman +Date: Fri Sep 27 12:22:15 2013 -0400 + + bonding: Fix broken promiscuity reference counting issue + + [ Upstream commit 5a0068deb611109c5ba77358be533f763f395ee4 ] + + Recently grabbed this report: + https://bugzilla.redhat.com/show_bug.cgi?id=1005567 + + Of an issue in which the bonding driver, with an attached vlan encountered the + following errors when bond0 was taken down and back up: + + dummy1: promiscuity touches roof, set promiscuity failed. promiscuity feature of + device might be broken. + + The error occurs because, during __bond_release_one, if we release our last + slave, we take on a random mac address and issue a NETDEV_CHANGEADDR + notification. With an attached vlan, the vlan may see that the vlan and bond + mac address were in sync, but no longer are. This triggers a call to dev_uc_add + and dev_set_rx_mode, which enables IFF_PROMISC on the bond device. Then, when + we complete __bond_release_one, we use the current state of the bond flags to + determine if we should decrement the promiscuity of the releasing slave. But + since the bond changed promiscuity state during the release operation, we + incorrectly decrement the slave promisc count when it wasn't in promiscuous mode + to begin with, causing the above error + + Fix is pretty simple, just cache the bonding flags at the start of the function + and use those when determining the need to set promiscuity. + + This is also needed for the ALLMULTI flag + + Reported-by: Mark Wu + CC: Jay Vosburgh + CC: Andy Gospodarek + CC: Mark Wu + CC: "David S. Miller" + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/bonding/bond_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/bonding/bond_main.c 2014-05-05 12:43:05.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/bonding/bond_main.c 2014-05-05 12:47:16.000000000 +0000 +@@ -1991,6 +1991,7 @@ + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *oldcurrent; + struct sockaddr addr; ++ int old_flags = bond_dev->flags; + netdev_features_t old_features = bond_dev->features; + + /* slave is not a slave or master is not master of this slave */ +@@ -2123,12 +2124,18 @@ + * already taken care of above when we detached the slave + */ + if (!USES_PRIMARY(bond->params.mode)) { +- /* unset promiscuity level from slave */ +- if (bond_dev->flags & IFF_PROMISC) ++ /* unset promiscuity level from slave ++ * NOTE: The NETDEV_CHANGEADDR call above may change the value ++ * of the IFF_PROMISC flag in the bond_dev, but we need the ++ * value of that flag before that change, as that was the value ++ * when this slave was attached, so we cache at the start of the ++ * function and use it here. Same goes for ALLMULTI below ++ */ ++ if (old_flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, -1); + + /* unset allmulti level from slave */ +- if (bond_dev->flags & IFF_ALLMULTI) ++ if (old_flags & IFF_ALLMULTI) + dev_set_allmulti(slave_dev, -1); + + /* flush master's mc_list from slave */ +Index: linux-3.10-3.10.11/dummy/rpi_1295_c9b391f6d166118c5543e9d1708e67977dbdbe1f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1295_c9b391f6d166118c5543e9d1708e67977dbdbe1f.txt 2014-05-05 12:47:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1296_102ce961c8d54d613eb49d6bc71ecec674505815.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1296_102ce961c8d54d613eb49d6bc71ecec674505815.patch --- linux-3.10.11/debian/patches/rpi/rpi_1296_102ce961c8d54d613eb49d6bc71ecec674505815.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1296_102ce961c8d54d613eb49d6bc71ecec674505815.patch 2014-05-05 12:47:17.000000000 +0000 @@ -0,0 +1,54 @@ +commit 102ce961c8d54d613eb49d6bc71ecec674505815 +Author: Hannes Frederic Sowa +Date: Sun Sep 29 05:40:50 2013 +0200 + + ipv6: gre: correct calculation of max_headroom + + [ Upstream commit 3da812d860755925da890e8c713f2d2e2d7b1bae ] + + gre_hlen already accounts for sizeof(struct ipv6_hdr) + gre header, + so initialize max_headroom to zero. Otherwise the + + if (encap_limit >= 0) { + max_headroom += 8; + mtu -= 8; + } + + increments an uninitialized variable before max_headroom was reset. + + Found with coverity: 728539 + + Cc: Dmitry Kozlov + Signed-off-by: Hannes Frederic Sowa + Acked-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/ip6_gre.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_gre.c 2014-05-05 11:50:16.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_gre.c 2014-05-05 12:47:17.000000000 +0000 +@@ -620,7 +620,7 @@ + struct ip6_tnl *tunnel = netdev_priv(dev); + struct net_device *tdev; /* Device to other host */ + struct ipv6hdr *ipv6h; /* Our new IP header */ +- unsigned int max_headroom; /* The extra header space needed */ ++ unsigned int max_headroom = 0; /* The extra header space needed */ + int gre_hlen; + struct ipv6_tel_txoption opt; + int mtu; +@@ -693,7 +693,7 @@ + tunnel->err_count = 0; + } + +- max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len; ++ max_headroom += LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len; + + if (skb_headroom(skb) < max_headroom || skb_shared(skb) || + (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { +Index: linux-3.10-3.10.11/dummy/rpi_1296_102ce961c8d54d613eb49d6bc71ecec674505815.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1296_102ce961c8d54d613eb49d6bc71ecec674505815.txt 2014-05-05 12:47:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1297_fbf96d75f4a320c66e03a21b2a46d0985b6d096b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1297_fbf96d75f4a320c66e03a21b2a46d0985b6d096b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1297_fbf96d75f4a320c66e03a21b2a46d0985b6d096b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1297_fbf96d75f4a320c66e03a21b2a46d0985b6d096b.patch 2014-05-05 12:47:18.000000000 +0000 @@ -0,0 +1,51 @@ +commit fbf96d75f4a320c66e03a21b2a46d0985b6d096b +Author: Salam Noureddine +Date: Sun Sep 29 13:39:42 2013 -0700 + + ipv4 igmp: use in_dev_put in timer handlers instead of __in_dev_put + + [ Upstream commit e2401654dd0f5f3fb7a8d80dad9554d73d7ca394 ] + + It is possible for the timer handlers to run after the call to + ip_mc_down so use in_dev_put instead of __in_dev_put in the handler + function in order to do proper cleanup when the refcnt reaches 0. + Otherwise, the refcnt can reach zero without the in_device being + destroyed and we end up leaking a reference to the net_device and + see messages like the following, + + unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + + Tested on linux-3.4.43. + + Signed-off-by: Salam Noureddine + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/igmp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/igmp.c 2014-05-05 12:47:10.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/igmp.c 2014-05-05 12:47:18.000000000 +0000 +@@ -709,7 +709,7 @@ + + in_dev->mr_gq_running = 0; + igmpv3_send_report(in_dev, NULL); +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_timer_expire(unsigned long data) +@@ -721,7 +721,7 @@ + in_dev->mr_ifc_count--; + igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval); + } +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_event(struct in_device *in_dev) +Index: linux-3.10-3.10.11/dummy/rpi_1297_fbf96d75f4a320c66e03a21b2a46d0985b6d096b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1297_fbf96d75f4a320c66e03a21b2a46d0985b6d096b.txt 2014-05-05 12:47:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1298_ef04c1db0aef35f8d006d18c79cacd11925078ec.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1298_ef04c1db0aef35f8d006d18c79cacd11925078ec.patch --- linux-3.10.11/debian/patches/rpi/rpi_1298_ef04c1db0aef35f8d006d18c79cacd11925078ec.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1298_ef04c1db0aef35f8d006d18c79cacd11925078ec.patch 2014-05-05 12:47:19.000000000 +0000 @@ -0,0 +1,51 @@ +commit ef04c1db0aef35f8d006d18c79cacd11925078ec +Author: Salam Noureddine +Date: Sun Sep 29 13:41:34 2013 -0700 + + ipv6 mcast: use in6_dev_put in timer handlers instead of __in6_dev_put + + [ Upstream commit 9260d3e1013701aa814d10c8fc6a9f92bd17d643 ] + + It is possible for the timer handlers to run after the call to + ipv6_mc_down so use in6_dev_put instead of __in6_dev_put in the + handler function in order to do proper cleanup when the refcnt + reaches 0. Otherwise, the refcnt can reach zero without the + inet6_dev being destroyed and we end up leaking a reference to + the net_device and see messages like the following, + + unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + + Tested on linux-3.4.43. + + Signed-off-by: Salam Noureddine + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/mcast.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/mcast.c 2014-05-05 11:50:16.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/mcast.c 2014-05-05 12:47:18.000000000 +0000 +@@ -2158,7 +2158,7 @@ + + idev->mc_gq_running = 0; + mld_send_report(idev, NULL); +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_timer_expire(unsigned long data) +@@ -2171,7 +2171,7 @@ + if (idev->mc_ifc_count) + mld_ifc_start_timer(idev, idev->mc_maxdelay); + } +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_event(struct inet6_dev *idev) +Index: linux-3.10-3.10.11/dummy/rpi_1298_ef04c1db0aef35f8d006d18c79cacd11925078ec.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1298_ef04c1db0aef35f8d006d18c79cacd11925078ec.txt 2014-05-05 12:47:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1299_c7bd0696131d1cc596afea05d06c6fee5b7a51ca.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1299_c7bd0696131d1cc596afea05d06c6fee5b7a51ca.patch --- linux-3.10.11/debian/patches/rpi/rpi_1299_c7bd0696131d1cc596afea05d06c6fee5b7a51ca.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1299_c7bd0696131d1cc596afea05d06c6fee5b7a51ca.patch 2014-05-05 12:47:20.000000000 +0000 @@ -0,0 +1,46 @@ +commit c7bd0696131d1cc596afea05d06c6fee5b7a51ca +Author: Ricardo Ribalda +Date: Tue Oct 1 08:17:10 2013 +0200 + + ll_temac: Reset dma descriptors indexes on ndo_open + + [ Upstream commit 7167cf0e8cd10287b7912b9ffcccd9616f382922 ] + + The dma descriptors indexes are only initialized on the probe function. + + If a packet is on the buffer when temac_stop is called, the dma + descriptors indexes can be left on a incorrect state where no other + package can be sent. + + So an interface could be left in an usable state after ifdow/ifup. + + This patch makes sure that the descriptors indexes are in a proper + status when the device is open. + + Signed-off-by: Ricardo Ribalda Delgado + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/xilinx/ll_temac_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/xilinx/ll_temac_main.c 2014-05-05 11:50:16.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/xilinx/ll_temac_main.c 2014-05-05 12:47:19.000000000 +0000 +@@ -297,6 +297,12 @@ + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + ++ /* Init descriptor indexes */ ++ lp->tx_bd_ci = 0; ++ lp->tx_bd_next = 0; ++ lp->tx_bd_tail = 0; ++ lp->rx_bd_ci = 0; ++ + return 0; + + out: +Index: linux-3.10-3.10.11/dummy/rpi_1299_c7bd0696131d1cc596afea05d06c6fee5b7a51ca.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1299_c7bd0696131d1cc596afea05d06c6fee5b7a51ca.txt 2014-05-05 12:47:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1300_23d6f8dd1cc9ca2a3aaed9c6bb24f80b39e071df.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1300_23d6f8dd1cc9ca2a3aaed9c6bb24f80b39e071df.patch --- linux-3.10.11/debian/patches/rpi/rpi_1300_23d6f8dd1cc9ca2a3aaed9c6bb24f80b39e071df.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1300_23d6f8dd1cc9ca2a3aaed9c6bb24f80b39e071df.patch 2014-05-05 12:47:20.000000000 +0000 @@ -0,0 +1,50 @@ +commit 23d6f8dd1cc9ca2a3aaed9c6bb24f80b39e071df +Author: Steffen Klassert +Date: Tue Oct 1 11:33:59 2013 +0200 + + ip_tunnel: Fix a memory corruption in ip_tunnel_xmit + + [ Upstream commit 3e08f4a72f689c6296d336c2aab4bddd60c93ae2 ] + + We might extend the used aera of a skb beyond the total + headroom when we install the ipip header. Fix this by + calling skb_cow_head() unconditionally. + + Bug was introduced with commit c544193214 + ("GRE: Refactor GRE tunneling code.") + + Cc: Pravin Shelar + Signed-off-by: Steffen Klassert + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/ip_tunnel.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ip_tunnel.c 2014-05-05 12:43:15.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ip_tunnel.c 2014-05-05 12:47:20.000000000 +0000 +@@ -659,13 +659,13 @@ + + max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(struct iphdr) + + rt->dst.header_len; +- if (max_headroom > dev->needed_headroom) { ++ if (max_headroom > dev->needed_headroom) + dev->needed_headroom = max_headroom; +- if (skb_cow_head(skb, dev->needed_headroom)) { +- dev->stats.tx_dropped++; +- dev_kfree_skb(skb); +- return; +- } ++ ++ if (skb_cow_head(skb, dev->needed_headroom)) { ++ dev->stats.tx_dropped++; ++ dev_kfree_skb(skb); ++ return; + } + + skb_dst_drop(skb); +Index: linux-3.10-3.10.11/dummy/rpi_1300_23d6f8dd1cc9ca2a3aaed9c6bb24f80b39e071df.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1300_23d6f8dd1cc9ca2a3aaed9c6bb24f80b39e071df.txt 2014-05-05 12:47:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1301_20300db1bd1b9f45477c7af15b358deb87742bd1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1301_20300db1bd1b9f45477c7af15b358deb87742bd1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1301_20300db1bd1b9f45477c7af15b358deb87742bd1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1301_20300db1bd1b9f45477c7af15b358deb87742bd1.patch 2014-05-05 12:47:21.000000000 +0000 @@ -0,0 +1,38 @@ +commit 20300db1bd1b9f45477c7af15b358deb87742bd1 +Author: Nicolas Dichtel +Date: Tue Oct 1 18:04:59 2013 +0200 + + sit: allow to use rtnl ops on fb tunnel + + [ Upstream commit 205983c43700ac3a81e7625273a3fa83cd2759b5 ] + + rtnl ops where introduced by ba3e3f50a0e5 ("sit: advertise tunnel param via + rtnl"), but I forget to assign rtnl ops to fb tunnels. + + Now that it is done, we must remove the explicit call to + unregister_netdevice_queue(), because the fallback tunnel is added to the queue + in sit_destroy_tunnels() when checking rtnl_link_ops of all netdevices (this + is valid since commit 5e6700b3bf98 ("sit: add support of x-netns")). + + Signed-off-by: Nicolas Dichtel + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/sit.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/sit.c 2014-05-05 12:47:13.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/sit.c 2014-05-05 12:47:21.000000000 +0000 +@@ -1561,6 +1561,7 @@ + goto err_alloc_dev; + } + dev_net_set(sitn->fb_tunnel_dev, net); ++ sitn->fb_tunnel_dev->rtnl_link_ops = &sit_link_ops; + + err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); + if (err) +Index: linux-3.10-3.10.11/dummy/rpi_1301_20300db1bd1b9f45477c7af15b358deb87742bd1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1301_20300db1bd1b9f45477c7af15b358deb87742bd1.txt 2014-05-05 12:47:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1302_506cdb8909a1a739c7585c680c6bd4b3d1247564.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1302_506cdb8909a1a739c7585c680c6bd4b3d1247564.patch --- linux-3.10.11/debian/patches/rpi/rpi_1302_506cdb8909a1a739c7585c680c6bd4b3d1247564.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1302_506cdb8909a1a739c7585c680c6bd4b3d1247564.patch 2014-05-05 12:47:22.000000000 +0000 @@ -0,0 +1,38 @@ +commit 506cdb8909a1a739c7585c680c6bd4b3d1247564 +Author: Nicolas Dichtel +Date: Tue Oct 1 18:05:00 2013 +0200 + + ip6tnl: allow to use rtnl ops on fb tunnel + + [ Upstream commit bb8140947a247b9aa15652cc24dc555ebb0b64b0 ] + + rtnl ops where introduced by c075b13098b3 ("ip6tnl: advertise tunnel param via + rtnl"), but I forget to assign rtnl ops to fb tunnels. + + Now that it is done, we must remove the explicit call to + unregister_netdevice_queue(), because the fallback tunnel is added to the queue + in ip6_tnl_destroy_tunnels() when checking rtnl_link_ops of all netdevices (this + is valid since commit 0bd8762824e7 ("ip6tnl: add x-netns support")). + + Signed-off-by: Nicolas Dichtel + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/ip6_tunnel.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_tunnel.c 2014-05-05 12:47:07.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_tunnel.c 2014-05-05 12:47:22.000000000 +0000 +@@ -1732,6 +1732,7 @@ + if (!ip6n->fb_tnl_dev) + goto err_alloc_dev; + dev_net_set(ip6n->fb_tnl_dev, net); ++ ip6n->fb_tnl_dev->rtnl_link_ops = &ip6_link_ops; + + err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); + if (err < 0) +Index: linux-3.10-3.10.11/dummy/rpi_1302_506cdb8909a1a739c7585c680c6bd4b3d1247564.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1302_506cdb8909a1a739c7585c680c6bd4b3d1247564.txt 2014-05-05 12:47:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1303_fd728b3e6bd0153c78425052da773c95f3fcf332.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1303_fd728b3e6bd0153c78425052da773c95f3fcf332.patch --- linux-3.10.11/debian/patches/rpi/rpi_1303_fd728b3e6bd0153c78425052da773c95f3fcf332.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1303_fd728b3e6bd0153c78425052da773c95f3fcf332.patch 2014-05-05 12:47:23.000000000 +0000 @@ -0,0 +1,75 @@ +commit fd728b3e6bd0153c78425052da773c95f3fcf332 +Author: Gabor Juhos +Date: Wed Sep 25 15:32:35 2013 +0200 + + avr32: fix clockevents kernel warning + + commit 1b0135b5e20c56b2edae29e92b91c0b12c983432 upstream. + + Since commit 01426478df3a8791ff5c8b6b82d409e699cfaf38 + (avr32: Use generic idle loop) the kernel throws the + following warning on avr32: + + WARNING: at 900322e4 [verbose debug info unavailable] + Modules linked in: + CPU: 0 PID: 0 Comm: swapper Not tainted 3.12.0-rc2 #117 + task: 901c3ecc ti: 901c0000 task.ti: 901c0000 + PC is at cpu_idle_poll_ctrl+0x1c/0x38 + LR is at comparator_mode+0x3e/0x40 + pc : [<900322e4>] lr : [<90014882>] Not tainted + sp : 901c1f74 r12: 00000000 r11: 901c74a0 + r10: 901d2510 r9 : 00000001 r8 : 901db4de + r7 : 901c74a0 r6 : 00000001 r5 : 00410020 r4 : 901db574 + r3 : 00410024 r2 : 90206fe0 r1 : 00000000 r0 : 007f0000 + Flags: qvnzc + Mode bits: hjmde....G + CPU Mode: Supervisor + Call trace: + [<90039ede>] clockevents_set_mode+0x16/0x2e + [<90039f00>] clockevents_shutdown+0xa/0x1e + [<9003a078>] clockevents_exchange_device+0x58/0x70 + [<9003a78c>] tick_check_new_device+0x38/0x54 + [<9003a1a2>] clockevents_register_device+0x32/0x90 + [<900035c4>] time_init+0xa8/0x108 + [<90000520>] start_kernel+0x128/0x23c + + When the 'avr32_comparator' clockevent device is registered, + the clockevent core sets the mode of that clockevent device + to CLOCK_EVT_MODE_SHUTDOWN. Due to this, the 'comparator_mode' + function calls the 'cpu_idle_poll_ctrl' to disables idle poll. + This results in the aforementioned warning because the polling + is not enabled yet. + + Change the code to only disable idle poll if it is enabled by + the same function to avoid the warning. + + Signed-off-by: Gabor Juhos + Acked-by: Hans-Christian Egtvedt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/avr32/kernel/time.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/avr32/kernel/time.c 2014-05-05 11:50:14.000000000 +0000 ++++ linux-3.10-3.10.11/arch/avr32/kernel/time.c 2014-05-05 12:47:22.000000000 +0000 +@@ -98,7 +98,14 @@ + case CLOCK_EVT_MODE_SHUTDOWN: + sysreg_write(COMPARE, 0); + pr_debug("%s: stop\n", evdev->name); +- cpu_idle_poll_ctrl(false); ++ if (evdev->mode == CLOCK_EVT_MODE_ONESHOT || ++ evdev->mode == CLOCK_EVT_MODE_RESUME) { ++ /* ++ * Only disable idle poll if we have forced that ++ * in a previous call. ++ */ ++ cpu_idle_poll_ctrl(false); ++ } + break; + default: + BUG(); +Index: linux-3.10-3.10.11/dummy/rpi_1303_fd728b3e6bd0153c78425052da773c95f3fcf332.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1303_fd728b3e6bd0153c78425052da773c95f3fcf332.txt 2014-05-05 12:47:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1304_cc748eed10e7e91c4fbc3a4503537f5748342b16.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1304_cc748eed10e7e91c4fbc3a4503537f5748342b16.patch --- linux-3.10.11/debian/patches/rpi/rpi_1304_cc748eed10e7e91c4fbc3a4503537f5748342b16.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1304_cc748eed10e7e91c4fbc3a4503537f5748342b16.patch 2014-05-05 12:47:24.000000000 +0000 @@ -0,0 +1,143 @@ +commit cc748eed10e7e91c4fbc3a4503537f5748342b16 +Author: Dan Aloni +Date: Mon Sep 30 13:45:02 2013 -0700 + + fs/binfmt_elf.c: prevent a coredump with a large vm_map_count from Oopsing + + commit 72023656961b8c81a168a7a6762d589339d0d7ec upstream. + + A high setting of max_map_count, and a process core-dumping with a large + enough vm_map_count could result in an NT_FILE note not being written, + and the kernel crashing immediately later because it has assumed + otherwise. + + Reproduction of the oops-causing bug described here: + + https://lkml.org/lkml/2013/8/30/50 + + Rge ussue originated in commit 2aa362c49c31 ("coredump: extend core dump + note section to contain file names of mapped file") from Oct 4, 2012. + + This patch make that section optional in that case. fill_files_note() + should signify the error, and also let the info struct in + elf_core_dump() be zero-initialized so that we can check for the + optionally written note. + + [akpm@linux-foundation.org: avoid abusing E2BIG, remove a couple of not-really-needed local variables] + [akpm@linux-foundation.org: fix sparse warning] + Signed-off-by: Dan Aloni + Cc: Al Viro + Cc: Denys Vlasenko + Reported-by: Martin MOKREJS + Tested-by: Martin MOKREJS + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/binfmt_elf.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/binfmt_elf.c 2014-05-05 11:50:14.000000000 +0000 ++++ linux-3.10-3.10.11/fs/binfmt_elf.c 2014-05-05 12:47:23.000000000 +0000 +@@ -1415,7 +1415,7 @@ + * long file_ofs + * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL... + */ +-static void fill_files_note(struct memelfnote *note) ++static int fill_files_note(struct memelfnote *note) + { + struct vm_area_struct *vma; + unsigned count, size, names_ofs, remaining, n; +@@ -1430,11 +1430,11 @@ + names_ofs = (2 + 3 * count) * sizeof(data[0]); + alloc: + if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */ +- goto err; ++ return -EINVAL; + size = round_up(size, PAGE_SIZE); + data = vmalloc(size); + if (!data) +- goto err; ++ return -ENOMEM; + + start_end_ofs = data + 2; + name_base = name_curpos = ((char *)data) + names_ofs; +@@ -1487,7 +1487,7 @@ + + size = name_curpos - (char *)data; + fill_note(note, "CORE", NT_FILE, size, data); +- err: ; ++ return 0; + } + + #ifdef CORE_DUMP_USE_REGSET +@@ -1688,8 +1688,8 @@ + fill_auxv_note(&info->auxv, current->mm); + info->size += notesize(&info->auxv); + +- fill_files_note(&info->files); +- info->size += notesize(&info->files); ++ if (fill_files_note(&info->files) == 0) ++ info->size += notesize(&info->files); + + return 1; + } +@@ -1721,7 +1721,8 @@ + return 0; + if (first && !writenote(&info->auxv, file, foffset)) + return 0; +- if (first && !writenote(&info->files, file, foffset)) ++ if (first && info->files.data && ++ !writenote(&info->files, file, foffset)) + return 0; + + for (i = 1; i < info->thread_notes; ++i) +@@ -1808,6 +1809,7 @@ + + struct elf_note_info { + struct memelfnote *notes; ++ struct memelfnote *notes_files; + struct elf_prstatus *prstatus; /* NT_PRSTATUS */ + struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */ + struct list_head thread_list; +@@ -1898,9 +1900,12 @@ + + fill_siginfo_note(info->notes + 2, &info->csigdata, siginfo); + fill_auxv_note(info->notes + 3, current->mm); +- fill_files_note(info->notes + 4); ++ info->numnote = 4; + +- info->numnote = 5; ++ if (fill_files_note(info->notes + info->numnote) == 0) { ++ info->notes_files = info->notes + info->numnote; ++ info->numnote++; ++ } + + /* Try to dump the FPU. */ + info->prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs, +@@ -1962,8 +1967,9 @@ + kfree(list_entry(tmp, struct elf_thread_status, list)); + } + +- /* Free data allocated by fill_files_note(): */ +- vfree(info->notes[4].data); ++ /* Free data possibly allocated by fill_files_note(): */ ++ if (info->notes_files) ++ vfree(info->notes_files->data); + + kfree(info->prstatus); + kfree(info->psinfo); +@@ -2046,7 +2052,7 @@ + struct vm_area_struct *vma, *gate_vma; + struct elfhdr *elf = NULL; + loff_t offset = 0, dataoff, foffset; +- struct elf_note_info info; ++ struct elf_note_info info = { }; + struct elf_phdr *phdr4note = NULL; + struct elf_shdr *shdr4extnum = NULL; + Elf_Half e_phnum; +Index: linux-3.10-3.10.11/dummy/rpi_1304_cc748eed10e7e91c4fbc3a4503537f5748342b16.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1304_cc748eed10e7e91c4fbc3a4503537f5748342b16.txt 2014-05-05 12:47:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1305_9dbd65f3bc7a1d75d474528360cfcb2f8816f5b7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1305_9dbd65f3bc7a1d75d474528360cfcb2f8816f5b7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1305_9dbd65f3bc7a1d75d474528360cfcb2f8816f5b7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1305_9dbd65f3bc7a1d75d474528360cfcb2f8816f5b7.patch 2014-05-05 12:47:25.000000000 +0000 @@ -0,0 +1,167 @@ +commit 9dbd65f3bc7a1d75d474528360cfcb2f8816f5b7 +Author: Javier Martinez Canillas +Date: Wed Sep 25 02:36:52 2013 +0200 + + gpio/omap: maintain GPIO and IRQ usage separately + + commit fa365e4d729065b5e85165df3dc9699ed47489cc upstream. + + The GPIO OMAP controller pins can be used as IRQ and GPIO + independently so is necessary to keep track GPIO pins and + IRQ lines usage separately to make sure that the bank will + always be enabled while being used. + + Also move gpio_is_input() definition in preparation for the + next patch that setups the controller's irq_chip driver when + a caller requests an interrupt line. + + Acked-by: Stephen Warren + Tested-by: George Cherian + Tested-by: Aaro Koskinen + Tested-by: Lars Poeschel + Reviewed-by: Kevin Hilman + Tested-by: Kevin Hilman + Acked-by: Santosh Shilimkar + Acked-by: Tony Lindgren + Signed-off-by: Javier Martinez Canillas + Signed-off-by: Linus Walleij + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpio/gpio-omap.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpio/gpio-omap.c 2014-05-05 11:50:13.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpio/gpio-omap.c 2014-05-05 12:47:24.000000000 +0000 +@@ -63,6 +63,7 @@ + struct gpio_chip chip; + struct clk *dbck; + u32 mod_usage; ++ u32 irq_usage; + u32 dbck_enable_mask; + bool dbck_enabled; + struct device *dev; +@@ -86,6 +87,9 @@ + #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) + #define GPIO_MOD_CTRL_BIT BIT(0) + ++#define BANK_USED(bank) (bank->mod_usage || bank->irq_usage) ++#define LINE_USED(line, offset) (line & (1 << offset)) ++ + static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) + { + return bank->chip.base + gpio_irq; +@@ -420,6 +424,13 @@ + return 0; + } + ++static int gpio_is_input(struct gpio_bank *bank, int mask) ++{ ++ void __iomem *reg = bank->base + bank->regs->direction; ++ ++ return __raw_readl(reg) & mask; ++} ++ + static int gpio_irq_type(struct irq_data *d, unsigned type) + { + struct gpio_bank *bank = irq_data_get_irq_chip_data(d); +@@ -427,7 +438,7 @@ + int retval; + unsigned long flags; + +- if (WARN_ON(!bank->mod_usage)) ++ if (WARN_ON(!BANK_USED(bank))) + return -EINVAL; + + #ifdef CONFIG_ARCH_OMAP1 +@@ -447,6 +458,7 @@ + + spin_lock_irqsave(&bank->lock, flags); + retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); ++ bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); + spin_unlock_irqrestore(&bank->lock, flags); + + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) +@@ -603,7 +615,7 @@ + * If this is the first gpio_request for the bank, + * enable the bank module. + */ +- if (!bank->mod_usage) ++ if (!BANK_USED(bank)) + pm_runtime_get_sync(bank->dev); + + spin_lock_irqsave(&bank->lock, flags); +@@ -619,7 +631,7 @@ + __raw_writel(__raw_readl(reg) | (1 << offset), reg); + } + +- if (bank->regs->ctrl && !bank->mod_usage) { ++ if (bank->regs->ctrl && !BANK_USED(bank)) { + void __iomem *reg = bank->base + bank->regs->ctrl; + u32 ctrl; + +@@ -654,7 +666,7 @@ + + bank->mod_usage &= ~(1 << offset); + +- if (bank->regs->ctrl && !bank->mod_usage) { ++ if (bank->regs->ctrl && !BANK_USED(bank)) { + void __iomem *reg = bank->base + bank->regs->ctrl; + u32 ctrl; + +@@ -672,7 +684,7 @@ + * If this is the last gpio to be freed in the bank, + * disable the bank module. + */ +- if (!bank->mod_usage) ++ if (!BANK_USED(bank)) + pm_runtime_put(bank->dev); + } + +@@ -762,8 +774,10 @@ + struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + unsigned int gpio = irq_to_gpio(bank, d->hwirq); + unsigned long flags; ++ unsigned offset = GPIO_INDEX(bank, gpio); + + spin_lock_irqsave(&bank->lock, flags); ++ bank->irq_usage &= ~(1 << offset); + _reset_gpio(bank, gpio); + spin_unlock_irqrestore(&bank->lock, flags); + } +@@ -897,13 +911,6 @@ + return 0; + } + +-static int gpio_is_input(struct gpio_bank *bank, int mask) +-{ +- void __iomem *reg = bank->base + bank->regs->direction; +- +- return __raw_readl(reg) & mask; +-} +- + static int gpio_get(struct gpio_chip *chip, unsigned offset) + { + struct gpio_bank *bank; +@@ -1400,7 +1407,7 @@ + struct gpio_bank *bank; + + list_for_each_entry(bank, &omap_gpio_list, node) { +- if (!bank->mod_usage || !bank->loses_context) ++ if (!BANK_USED(bank) || !bank->loses_context) + continue; + + bank->power_mode = pwr_mode; +@@ -1414,7 +1421,7 @@ + struct gpio_bank *bank; + + list_for_each_entry(bank, &omap_gpio_list, node) { +- if (!bank->mod_usage || !bank->loses_context) ++ if (!BANK_USED(bank) || !bank->loses_context) + continue; + + pm_runtime_get_sync(bank->dev); +Index: linux-3.10-3.10.11/dummy/rpi_1305_9dbd65f3bc7a1d75d474528360cfcb2f8816f5b7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1305_9dbd65f3bc7a1d75d474528360cfcb2f8816f5b7.txt 2014-05-05 12:47:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1306_517ff99417cf9a27a6c4f34f99977505d9928785.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1306_517ff99417cf9a27a6c4f34f99977505d9928785.patch --- linux-3.10.11/debian/patches/rpi/rpi_1306_517ff99417cf9a27a6c4f34f99977505d9928785.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1306_517ff99417cf9a27a6c4f34f99977505d9928785.patch 2014-05-05 12:47:25.000000000 +0000 @@ -0,0 +1,240 @@ +commit 517ff99417cf9a27a6c4f34f99977505d9928785 +Author: Javier Martinez Canillas +Date: Wed Sep 25 02:36:54 2013 +0200 + + gpio/omap: auto-setup a GPIO when used as an IRQ + + commit fac7fa162a19100298d5d91359960037dc5bfca9 upstream. + + The OMAP GPIO controller HW requires a pin to be configured in GPIO + input mode in order to operate as an interrupt input. Since drivers + should not be aware of whether an interrupt pin is also a GPIO or not, + the HW should be fully configured/enabled as an IRQ if a driver solely + uses IRQ APIs such as request_irq(), and never calls any GPIO-related + APIs. As such, add the missing HW setup to the OMAP GPIO controller's + irq_chip driver. + + Since this bypasses the GPIO subsystem we have to ensure that another + driver won't be able to request the same GPIO pin that is used as an + IRQ and set its direction as output. Requesting the GPIO and setting + its direction as input is allowed though. + + This fixes smsc911x ethernet support for tobi and igep OMAP3 boards + and OMAP4 SDP SPI based ethernet that use a GPIO as an interrupt line. + + Acked-by: Stephen Warren + Tested-by: George Cherian + Tested-by: Aaro Koskinen + Tested-by: Lars Poeschel + Reviewed-by: Kevin Hilman + Tested-by: Kevin Hilman + Acked-by: Santosh Shilimkar + Acked-by: Tony Lindgren + Signed-off-by: Javier Martinez Canillas + Signed-off-by: Linus Walleij + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpio/gpio-omap.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpio/gpio-omap.c 2014-05-05 12:47:24.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpio/gpio-omap.c 2014-05-05 12:47:25.000000000 +0000 +@@ -424,6 +424,52 @@ + return 0; + } + ++static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset) ++{ ++ if (bank->regs->pinctrl) { ++ void __iomem *reg = bank->base + bank->regs->pinctrl; ++ ++ /* Claim the pin for MPU */ ++ __raw_writel(__raw_readl(reg) | (1 << offset), reg); ++ } ++ ++ if (bank->regs->ctrl && !BANK_USED(bank)) { ++ void __iomem *reg = bank->base + bank->regs->ctrl; ++ u32 ctrl; ++ ++ ctrl = __raw_readl(reg); ++ /* Module is enabled, clocks are not gated */ ++ ctrl &= ~GPIO_MOD_CTRL_BIT; ++ __raw_writel(ctrl, reg); ++ bank->context.ctrl = ctrl; ++ } ++} ++ ++static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset) ++{ ++ void __iomem *base = bank->base; ++ ++ if (bank->regs->wkup_en && ++ !LINE_USED(bank->mod_usage, offset) && ++ !LINE_USED(bank->irq_usage, offset)) { ++ /* Disable wake-up during idle for dynamic tick */ ++ _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); ++ bank->context.wake_en = ++ __raw_readl(bank->base + bank->regs->wkup_en); ++ } ++ ++ if (bank->regs->ctrl && !BANK_USED(bank)) { ++ void __iomem *reg = bank->base + bank->regs->ctrl; ++ u32 ctrl; ++ ++ ctrl = __raw_readl(reg); ++ /* Module is disabled, clocks are gated */ ++ ctrl |= GPIO_MOD_CTRL_BIT; ++ __raw_writel(ctrl, reg); ++ bank->context.ctrl = ctrl; ++ } ++} ++ + static int gpio_is_input(struct gpio_bank *bank, int mask) + { + void __iomem *reg = bank->base + bank->regs->direction; +@@ -437,9 +483,10 @@ + unsigned gpio = 0; + int retval; + unsigned long flags; ++ unsigned offset; + +- if (WARN_ON(!BANK_USED(bank))) +- return -EINVAL; ++ if (!BANK_USED(bank)) ++ pm_runtime_get_sync(bank->dev); + + #ifdef CONFIG_ARCH_OMAP1 + if (d->irq > IH_MPUIO_BASE) +@@ -457,7 +504,16 @@ + return -EINVAL; + + spin_lock_irqsave(&bank->lock, flags); +- retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); ++ offset = GPIO_INDEX(bank, gpio); ++ retval = _set_gpio_triggering(bank, offset, type); ++ if (!LINE_USED(bank->mod_usage, offset)) { ++ _enable_gpio_module(bank, offset); ++ _set_gpio_direction(bank, offset, 1); ++ } else if (!gpio_is_input(bank, 1 << offset)) { ++ spin_unlock_irqrestore(&bank->lock, flags); ++ return -EINVAL; ++ } ++ + bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); + spin_unlock_irqrestore(&bank->lock, flags); + +@@ -620,30 +676,14 @@ + + spin_lock_irqsave(&bank->lock, flags); + /* Set trigger to none. You need to enable the desired trigger with +- * request_irq() or set_irq_type(). ++ * request_irq() or set_irq_type(). Only do this if the IRQ line has ++ * not already been requested. + */ +- _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); +- +- if (bank->regs->pinctrl) { +- void __iomem *reg = bank->base + bank->regs->pinctrl; +- +- /* Claim the pin for MPU */ +- __raw_writel(__raw_readl(reg) | (1 << offset), reg); ++ if (!LINE_USED(bank->irq_usage, offset)) { ++ _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); ++ _enable_gpio_module(bank, offset); + } +- +- if (bank->regs->ctrl && !BANK_USED(bank)) { +- void __iomem *reg = bank->base + bank->regs->ctrl; +- u32 ctrl; +- +- ctrl = __raw_readl(reg); +- /* Module is enabled, clocks are not gated */ +- ctrl &= ~GPIO_MOD_CTRL_BIT; +- __raw_writel(ctrl, reg); +- bank->context.ctrl = ctrl; +- } +- + bank->mod_usage |= 1 << offset; +- + spin_unlock_irqrestore(&bank->lock, flags); + + return 0; +@@ -652,31 +692,11 @@ + static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) + { + struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); +- void __iomem *base = bank->base; + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); +- +- if (bank->regs->wkup_en) { +- /* Disable wake-up during idle for dynamic tick */ +- _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); +- bank->context.wake_en = +- __raw_readl(bank->base + bank->regs->wkup_en); +- } +- + bank->mod_usage &= ~(1 << offset); +- +- if (bank->regs->ctrl && !BANK_USED(bank)) { +- void __iomem *reg = bank->base + bank->regs->ctrl; +- u32 ctrl; +- +- ctrl = __raw_readl(reg); +- /* Module is disabled, clocks are gated */ +- ctrl |= GPIO_MOD_CTRL_BIT; +- __raw_writel(ctrl, reg); +- bank->context.ctrl = ctrl; +- } +- ++ _disable_gpio_module(bank, offset); + _reset_gpio(bank, bank->chip.base + offset); + spin_unlock_irqrestore(&bank->lock, flags); + +@@ -778,8 +798,16 @@ + + spin_lock_irqsave(&bank->lock, flags); + bank->irq_usage &= ~(1 << offset); ++ _disable_gpio_module(bank, offset); + _reset_gpio(bank, gpio); + spin_unlock_irqrestore(&bank->lock, flags); ++ ++ /* ++ * If this is the last IRQ to be freed in the bank, ++ * disable the bank module. ++ */ ++ if (!BANK_USED(bank)) ++ pm_runtime_put(bank->dev); + } + + static void gpio_ack_irq(struct irq_data *d) +@@ -929,13 +957,22 @@ + { + struct gpio_bank *bank; + unsigned long flags; ++ int retval = 0; + + bank = container_of(chip, struct gpio_bank, chip); + spin_lock_irqsave(&bank->lock, flags); ++ ++ if (LINE_USED(bank->irq_usage, offset)) { ++ retval = -EINVAL; ++ goto exit; ++ } ++ + bank->set_dataout(bank, offset, value); + _set_gpio_direction(bank, offset, 0); ++ ++exit: + spin_unlock_irqrestore(&bank->lock, flags); +- return 0; ++ return retval; + } + + static int gpio_debounce(struct gpio_chip *chip, unsigned offset, +Index: linux-3.10-3.10.11/dummy/rpi_1306_517ff99417cf9a27a6c4f34f99977505d9928785.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1306_517ff99417cf9a27a6c4f34f99977505d9928785.txt 2014-05-05 12:47:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1307_9cea6e1ab0be55708d4aacf62dd69f99c700b9ab.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1307_9cea6e1ab0be55708d4aacf62dd69f99c700b9ab.patch --- linux-3.10.11/debian/patches/rpi/rpi_1307_9cea6e1ab0be55708d4aacf62dd69f99c700b9ab.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1307_9cea6e1ab0be55708d4aacf62dd69f99c700b9ab.patch 2014-05-05 12:47:26.000000000 +0000 @@ -0,0 +1,44 @@ +commit 9cea6e1ab0be55708d4aacf62dd69f99c700b9ab +Author: Dan Carpenter +Date: Fri Sep 13 10:52:14 2013 +0300 + + ASoC: max98095: a couple array underflows + + commit f8d7b13e14357ed19d2ca2799539600418dc3939 upstream. + + The ->put() function are called from snd_ctl_elem_write() with user + supplied data. The limit checks here could underflow leading to a + crash. + + Signed-off-by: Dan Carpenter + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/soc/codecs/max98095.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/codecs/max98095.c 2014-05-05 11:50:13.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/codecs/max98095.c 2014-05-05 12:47:26.000000000 +0000 +@@ -1863,7 +1863,7 @@ + struct max98095_pdata *pdata = max98095->pdata; + int channel = max98095_get_eq_channel(kcontrol->id.name); + struct max98095_cdata *cdata; +- int sel = ucontrol->value.integer.value[0]; ++ unsigned int sel = ucontrol->value.integer.value[0]; + struct max98095_eq_cfg *coef_set; + int fs, best, best_val, i; + int regmask, regsave; +@@ -2016,7 +2016,7 @@ + struct max98095_pdata *pdata = max98095->pdata; + int channel = max98095_get_bq_channel(codec, kcontrol->id.name); + struct max98095_cdata *cdata; +- int sel = ucontrol->value.integer.value[0]; ++ unsigned int sel = ucontrol->value.integer.value[0]; + struct max98095_biquad_cfg *coef_set; + int fs, best, best_val, i; + int regmask, regsave; +Index: linux-3.10-3.10.11/dummy/rpi_1307_9cea6e1ab0be55708d4aacf62dd69f99c700b9ab.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1307_9cea6e1ab0be55708d4aacf62dd69f99c700b9ab.txt 2014-05-05 12:47:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1308_7fe5daa3a267dc44677e471c3de88b8653aae541.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1308_7fe5daa3a267dc44677e471c3de88b8653aae541.patch --- linux-3.10.11/debian/patches/rpi/rpi_1308_7fe5daa3a267dc44677e471c3de88b8653aae541.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1308_7fe5daa3a267dc44677e471c3de88b8653aae541.patch 2014-05-05 12:47:27.000000000 +0000 @@ -0,0 +1,35 @@ +commit 7fe5daa3a267dc44677e471c3de88b8653aae541 +Author: Dan Carpenter +Date: Fri Sep 13 10:52:49 2013 +0300 + + ASoC: 88pm860x: array overflow in snd_soc_put_volsw_2r_st() + + commit d967967e8d1116fb38bad25e58714b5dddd03cca upstream. + + This is called from snd_ctl_elem_write() with user supplied data so we + need to add some bounds checking. + + Signed-off-by: Dan Carpenter + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/soc/codecs/88pm860x-codec.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/codecs/88pm860x-codec.c 2014-05-05 11:50:12.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/codecs/88pm860x-codec.c 2014-05-05 12:47:26.000000000 +0000 +@@ -351,6 +351,9 @@ + val = ucontrol->value.integer.value[0]; + val2 = ucontrol->value.integer.value[1]; + ++ if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table)) ++ return -EINVAL; ++ + err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m); + if (err < 0) + return err; +Index: linux-3.10-3.10.11/dummy/rpi_1308_7fe5daa3a267dc44677e471c3de88b8653aae541.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1308_7fe5daa3a267dc44677e471c3de88b8653aae541.txt 2014-05-05 12:47:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1309_7a7e86e4ef76e20e0e945c8216bbb0afa695d8ab.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1309_7a7e86e4ef76e20e0e945c8216bbb0afa695d8ab.patch --- linux-3.10.11/debian/patches/rpi/rpi_1309_7a7e86e4ef76e20e0e945c8216bbb0afa695d8ab.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1309_7a7e86e4ef76e20e0e945c8216bbb0afa695d8ab.patch 2014-05-05 12:47:28.000000000 +0000 @@ -0,0 +1,46 @@ +commit 7a7e86e4ef76e20e0e945c8216bbb0afa695d8ab +Author: Dan Carpenter +Date: Fri Sep 13 10:53:36 2013 +0300 + + ASoC: ab8500-codec: info leak in anc_status_control_put() + + commit d63733aed90b432e5cc489ddfa28e342f91b4652 upstream. + + If the user passes an invalid value it leads to an info leak when we + print the error message or it could oops. This is called with user + supplied data from snd_ctl_elem_write(). + + Signed-off-by: Dan Carpenter + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/soc/codecs/ab8500-codec.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/codecs/ab8500-codec.c 2014-05-05 11:50:12.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/codecs/ab8500-codec.c 2014-05-05 12:47:27.000000000 +0000 +@@ -1225,13 +1225,18 @@ + struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); + struct device *dev = codec->dev; + bool apply_fir, apply_iir; +- int req, status; ++ unsigned int req; ++ int status; + + dev_dbg(dev, "%s: Enter.\n", __func__); + + mutex_lock(&drvdata->anc_lock); + + req = ucontrol->value.integer.value[0]; ++ if (req >= ARRAY_SIZE(enum_anc_state)) { ++ status = -EINVAL; ++ goto cleanup; ++ } + if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR && + req != ANC_APPLY_IIR) { + dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n", +Index: linux-3.10-3.10.11/dummy/rpi_1309_7a7e86e4ef76e20e0e945c8216bbb0afa695d8ab.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1309_7a7e86e4ef76e20e0e945c8216bbb0afa695d8ab.txt 2014-05-05 12:47:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1310_e98d86aaa251cbd7c9745a3743ec4fa0c7c54c25.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1310_e98d86aaa251cbd7c9745a3743ec4fa0c7c54c25.patch --- linux-3.10.11/debian/patches/rpi/rpi_1310_e98d86aaa251cbd7c9745a3743ec4fa0c7c54c25.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1310_e98d86aaa251cbd7c9745a3743ec4fa0c7c54c25.patch 2014-05-05 12:47:29.000000000 +0000 @@ -0,0 +1,50 @@ +commit e98d86aaa251cbd7c9745a3743ec4fa0c7c54c25 +Author: Nishanth Aravamudan +Date: Tue Oct 1 14:04:53 2013 -0700 + + powerpc/iommu: Use GFP_KERNEL instead of GFP_ATOMIC in iommu_init_table() + + commit 1cf389df090194a0976dc867b7fffe99d9d490cb upstream. + + Under heavy (DLPAR?) stress, we tripped this panic() in + arch/powerpc/kernel/iommu.c::iommu_init_table(): + + page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz)); + if (!page) + panic("iommu_init_table: Can't allocate %ld bytes\n", sz); + + Before the panic() we got a page allocation failure for an order-2 + allocation. There appears to be memory free, but perhaps not in the + ATOMIC context. I looked through all the call-sites of + iommu_init_table() and didn't see any obvious reason to need an ATOMIC + allocation. Most call-sites in fact have an explicit GFP_KERNEL + allocation shortly before the call to iommu_init_table(), indicating we + are not in an atomic context. There is some indirection for some paths, + but I didn't see any locks indicating that GFP_KERNEL is inappropriate. + + With this change under the same conditions, we have not been able to + reproduce the panic. + + Signed-off-by: Nishanth Aravamudan + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/kernel/iommu.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kernel/iommu.c 2014-05-05 11:50:12.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kernel/iommu.c 2014-05-05 12:47:28.000000000 +0000 +@@ -658,7 +658,7 @@ + /* number of bytes needed for the bitmap */ + sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long); + +- page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz)); ++ page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz)); + if (!page) + panic("iommu_init_table: Can't allocate %ld bytes\n", sz); + tbl->it_map = page_address(page); +Index: linux-3.10-3.10.11/dummy/rpi_1310_e98d86aaa251cbd7c9745a3743ec4fa0c7c54c25.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1310_e98d86aaa251cbd7c9745a3743ec4fa0c7c54c25.txt 2014-05-05 12:47:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1311_09bee3bc290da5f7f39b62f65f1a3deeaa3834ac.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1311_09bee3bc290da5f7f39b62f65f1a3deeaa3834ac.patch --- linux-3.10.11/debian/patches/rpi/rpi_1311_09bee3bc290da5f7f39b62f65f1a3deeaa3834ac.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1311_09bee3bc290da5f7f39b62f65f1a3deeaa3834ac.patch 2014-05-05 12:47:30.000000000 +0000 @@ -0,0 +1,55 @@ +commit 09bee3bc290da5f7f39b62f65f1a3deeaa3834ac +Author: Michael Ellerman +Date: Wed Oct 2 18:04:06 2013 +1000 + + powerpc/perf: Fix handling of FAB events + + commit a53b27b3abeef406de92a2bb0ceb6fb4c3fb8fc4 upstream. + + Commit 4df4899 "Add power8 EBB support" included a bug in the handling + of the FAB_CRESP_MATCH and FAB_TYPE_MATCH fields. + + These values are pulled out of the event code using EVENT_THR_CTL_SHIFT, + however we were then or'ing that value directly into MMCR1. + + This meant we were failing to set the FAB fields correctly, and also + potentially corrupting the value for PMC4SEL. Leading to no counts for + the FAB events and incorrect counts for PMC4. + + The fix is simply to shift left the FAB value correctly before or'ing it + with MMCR1. + + Reported-by: Sooraj Ravindran Nair + Signed-off-by: Michael Ellerman + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/perf/power8-pmu.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/perf/power8-pmu.c 2014-05-05 11:50:12.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/perf/power8-pmu.c 2014-05-05 12:47:29.000000000 +0000 +@@ -194,6 +194,7 @@ + #define MMCR1_UNIT_SHIFT(pmc) (60 - (4 * ((pmc) - 1))) + #define MMCR1_COMBINE_SHIFT(pmc) (35 - ((pmc) - 1)) + #define MMCR1_PMCSEL_SHIFT(pmc) (24 - (((pmc) - 1)) * 8) ++#define MMCR1_FAB_SHIFT 36 + #define MMCR1_DC_QUAL_SHIFT 47 + #define MMCR1_IC_QUAL_SHIFT 46 + +@@ -367,8 +368,8 @@ + * the threshold bits are used for the match value. + */ + if (event_is_fab_match(event[i])) { +- mmcr1 |= (event[i] >> EVENT_THR_CTL_SHIFT) & +- EVENT_THR_CTL_MASK; ++ mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) & ++ EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT; + } else { + val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK; + mmcra |= val << MMCRA_THR_CTL_SHIFT; +Index: linux-3.10-3.10.11/dummy/rpi_1311_09bee3bc290da5f7f39b62f65f1a3deeaa3834ac.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1311_09bee3bc290da5f7f39b62f65f1a3deeaa3834ac.txt 2014-05-05 12:47:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1312_72daf965bb8fe1447069db3ea511047f20eca947.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1312_72daf965bb8fe1447069db3ea511047f20eca947.patch --- linux-3.10.11/debian/patches/rpi/rpi_1312_72daf965bb8fe1447069db3ea511047f20eca947.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1312_72daf965bb8fe1447069db3ea511047f20eca947.patch 2014-05-05 12:47:30.000000000 +0000 @@ -0,0 +1,214 @@ +commit 72daf965bb8fe1447069db3ea511047f20eca947 +Author: Michael Neuling +Date: Thu Sep 26 13:29:09 2013 +1000 + + powerpc/tm: Switch out userspace PPR and DSCR sooner + + commit e9bdc3d6143d1c4b8d8ce5231fc958268331f983 upstream. + + When we do a treclaim or trecheckpoint we end up running with userspace + PPR and DSCR values. Currently we don't do anything special to avoid + running with user values which could cause a severe performance + degradation. + + This patch moves the PPR and DSCR save and restore around treclaim and + trecheckpoint so that we run with user values for a much shorter period. + More care is taken with the PPR as it's impact is greater than the DSCR. + + This is similar to user exceptions, where we run HTM_MEDIUM early to + ensure that we don't run with a userspace PPR values in the kernel. + + Signed-off-by: Michael Neuling + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/kernel/tm.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kernel/tm.S 2014-05-05 11:50:11.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kernel/tm.S 2014-05-05 12:47:30.000000000 +0000 +@@ -79,6 +79,11 @@ + TABORT(R3) + blr + ++ .section ".toc","aw" ++DSCR_DEFAULT: ++ .tc dscr_default[TC],dscr_default ++ ++ .section ".text" + + /* void tm_reclaim(struct thread_struct *thread, + * unsigned long orig_msr, +@@ -178,11 +183,18 @@ + std r1, PACATMSCRATCH(r13) + ld r1, PACAR1(r13) + ++ /* Store the PPR in r11 and reset to decent value */ ++ std r11, GPR11(r1) /* Temporary stash */ ++ mfspr r11, SPRN_PPR ++ HMT_MEDIUM ++ + /* Now get some more GPRS free */ + std r7, GPR7(r1) /* Temporary stash */ + std r12, GPR12(r1) /* '' '' '' */ + ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ + ++ std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ ++ + addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */ + + /* Make r7 look like an exception frame so that we +@@ -194,15 +206,19 @@ + SAVE_GPR(0, r7) /* user r0 */ + SAVE_GPR(2, r7) /* user r2 */ + SAVE_4GPRS(3, r7) /* user r3-r6 */ +- SAVE_4GPRS(8, r7) /* user r8-r11 */ ++ SAVE_GPR(8, r7) /* user r8 */ ++ SAVE_GPR(9, r7) /* user r9 */ ++ SAVE_GPR(10, r7) /* user r10 */ + ld r3, PACATMSCRATCH(r13) /* user r1 */ + ld r4, GPR7(r1) /* user r7 */ +- ld r5, GPR12(r1) /* user r12 */ +- GET_SCRATCH0(6) /* user r13 */ ++ ld r5, GPR11(r1) /* user r11 */ ++ ld r6, GPR12(r1) /* user r12 */ ++ GET_SCRATCH0(8) /* user r13 */ + std r3, GPR1(r7) + std r4, GPR7(r7) +- std r5, GPR12(r7) +- std r6, GPR13(r7) ++ std r5, GPR11(r7) ++ std r6, GPR12(r7) ++ std r8, GPR13(r7) + + SAVE_NVGPRS(r7) /* user r14-r31 */ + +@@ -225,14 +241,12 @@ + std r6, _XER(r7) + + +- /* ******************** TAR, PPR, DSCR ********** */ ++ /* ******************** TAR, DSCR ********** */ + mfspr r3, SPRN_TAR +- mfspr r4, SPRN_PPR +- mfspr r5, SPRN_DSCR ++ mfspr r4, SPRN_DSCR + + std r3, THREAD_TM_TAR(r12) +- std r4, THREAD_TM_PPR(r12) +- std r5, THREAD_TM_DSCR(r12) ++ std r4, THREAD_TM_DSCR(r12) + + /* MSR and flags: We don't change CRs, and we don't need to alter + * MSR. +@@ -249,7 +263,7 @@ + std r3, THREAD_TM_TFHAR(r12) + std r4, THREAD_TM_TFIAR(r12) + +- /* AMR and PPR are checkpointed too, but are unsupported by Linux. */ ++ /* AMR is checkpointed too, but is unsupported by Linux. */ + + /* Restore original MSR/IRQ state & clear TM mode */ + ld r14, TM_FRAME_L0(r1) /* Orig MSR */ +@@ -265,6 +279,12 @@ + mtcr r4 + mtlr r0 + ld r2, 40(r1) ++ ++ /* Load system default DSCR */ ++ ld r4, DSCR_DEFAULT@toc(r2) ++ ld r0, 0(r4) ++ mtspr SPRN_DSCR, r0 ++ + blr + + +@@ -349,44 +369,50 @@ + + restore_gprs: + +- /* ******************** TAR, PPR, DSCR ********** */ +- ld r4, THREAD_TM_TAR(r3) +- ld r5, THREAD_TM_PPR(r3) +- ld r6, THREAD_TM_DSCR(r3) ++ /* ******************** CR,LR,CCR,MSR ********** */ ++ ld r4, _CTR(r7) ++ ld r5, _LINK(r7) ++ ld r6, _CCR(r7) ++ ld r8, _XER(r7) ++ ++ mtctr r4 ++ mtlr r5 ++ mtcr r6 ++ mtxer r8 + ++ /* ******************** TAR ******************** */ ++ ld r4, THREAD_TM_TAR(r3) + mtspr SPRN_TAR, r4 +- mtspr SPRN_PPR, r5 +- mtspr SPRN_DSCR, r6 + +- /* ******************** CR,LR,CCR,MSR ********** */ +- ld r3, _CTR(r7) +- ld r4, _LINK(r7) +- ld r5, _CCR(r7) +- ld r6, _XER(r7) +- +- mtctr r3 +- mtlr r4 +- mtcr r5 +- mtxer r6 ++ /* Load up the PPR and DSCR in GPRs only at this stage */ ++ ld r5, THREAD_TM_DSCR(r3) ++ ld r6, THREAD_TM_PPR(r3) + + /* MSR and flags: We don't change CRs, and we don't need to alter + * MSR. + */ + + REST_4GPRS(0, r7) /* GPR0-3 */ +- REST_GPR(4, r7) /* GPR4-6 */ +- REST_GPR(5, r7) +- REST_GPR(6, r7) ++ REST_GPR(4, r7) /* GPR4 */ + REST_4GPRS(8, r7) /* GPR8-11 */ + REST_2GPRS(12, r7) /* GPR12-13 */ + + REST_NVGPRS(r7) /* GPR14-31 */ + +- ld r7, GPR7(r7) /* GPR7 */ ++ /* Load up PPR and DSCR here so we don't run with user values for long ++ */ ++ mtspr SPRN_DSCR, r5 ++ mtspr SPRN_PPR, r6 ++ ++ REST_GPR(5, r7) /* GPR5-7 */ ++ REST_GPR(6, r7) ++ ld r7, GPR7(r7) + + /* Commit register state as checkpointed state: */ + TRECHKPT + ++ HMT_MEDIUM ++ + /* Our transactional state has now changed. + * + * Now just get out of here. Transactional (current) state will be +@@ -405,6 +431,12 @@ + mtcr r4 + mtlr r0 + ld r2, 40(r1) ++ ++ /* Load system default DSCR */ ++ ld r4, DSCR_DEFAULT@toc(r2) ++ ld r0, 0(r4) ++ mtspr SPRN_DSCR, r0 ++ + blr + + /* ****************************************************************** */ +Index: linux-3.10-3.10.11/dummy/rpi_1312_72daf965bb8fe1447069db3ea511047f20eca947.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1312_72daf965bb8fe1447069db3ea511047f20eca947.txt 2014-05-05 12:47:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1313_470d4d6fe7349299ed565948e539260c4d0d041c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1313_470d4d6fe7349299ed565948e539260c4d0d041c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1313_470d4d6fe7349299ed565948e539260c4d0d041c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1313_470d4d6fe7349299ed565948e539260c4d0d041c.patch 2014-05-05 12:47:31.000000000 +0000 @@ -0,0 +1,53 @@ +commit 470d4d6fe7349299ed565948e539260c4d0d041c +Author: Prarit Bhargava +Date: Mon Sep 23 09:33:36 2013 -0400 + + powerpc/vio: Fix modalias_show return values + + commit e82b89a6f19bae73fb064d1b3dd91fcefbb478f4 upstream. + + modalias_show() should return an empty string on error, not -ENODEV. + + This causes the following false and annoying error: + + > find /sys/devices -name modalias -print0 | xargs -0 cat >/dev/null + cat: /sys/devices/vio/4000/modalias: No such device + cat: /sys/devices/vio/4001/modalias: No such device + cat: /sys/devices/vio/4002/modalias: No such device + cat: /sys/devices/vio/4004/modalias: No such device + cat: /sys/devices/vio/modalias: No such device + + Signed-off-by: Prarit Bhargava + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/kernel/vio.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kernel/vio.c 2014-05-05 11:50:11.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kernel/vio.c 2014-05-05 12:47:31.000000000 +0000 +@@ -1529,11 +1529,15 @@ + const char *cp; + + dn = dev->of_node; +- if (!dn) +- return -ENODEV; ++ if (!dn) { ++ strcat(buf, "\n"); ++ return strlen(buf); ++ } + cp = of_get_property(dn, "compatible", NULL); +- if (!cp) +- return -ENODEV; ++ if (!cp) { ++ strcat(buf, "\n"); ++ return strlen(buf); ++ } + + return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp); + } +Index: linux-3.10-3.10.11/dummy/rpi_1313_470d4d6fe7349299ed565948e539260c4d0d041c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1313_470d4d6fe7349299ed565948e539260c4d0d041c.txt 2014-05-05 12:47:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1314_65ddee385ba4ba923eeb64182963815dc24f7bc1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1314_65ddee385ba4ba923eeb64182963815dc24f7bc1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1314_65ddee385ba4ba923eeb64182963815dc24f7bc1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1314_65ddee385ba4ba923eeb64182963815dc24f7bc1.patch 2014-05-05 12:47:32.000000000 +0000 @@ -0,0 +1,41 @@ +commit 65ddee385ba4ba923eeb64182963815dc24f7bc1 +Author: Paul E. McKenney +Date: Tue Oct 1 16:54:05 2013 +1000 + + powerpc: Fix parameter clobber in csum_partial_copy_generic() + + commit d9813c3681a36774b254c0cdc9cce53c9e22c756 upstream. + + The csum_partial_copy_generic() uses register r7 to adjust the remaining + bytes to process. Unfortunately, r7 also holds a parameter, namely the + address of the flag to set in case of access exceptions while reading + the source buffer. Lacking a quantum implementation of PowerPC, this + commit instead uses register r9 to do the adjusting, leaving r7's + pointer uncorrupted. + + Signed-off-by: Paul E. McKenney + Signed-off-by: Anton Blanchard + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/lib/checksum_64.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/lib/checksum_64.S 2014-05-05 11:50:11.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/lib/checksum_64.S 2014-05-05 12:47:31.000000000 +0000 +@@ -269,8 +269,8 @@ + rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */ + beq .Lcopy_aligned + +- li r7,4 +- sub r6,r7,r6 ++ li r9,4 ++ sub r6,r9,r6 + mtctr r6 + + 1: +Index: linux-3.10-3.10.11/dummy/rpi_1314_65ddee385ba4ba923eeb64182963815dc24f7bc1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1314_65ddee385ba4ba923eeb64182963815dc24f7bc1.txt 2014-05-05 12:47:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1315_4d358e9e19f001d2d7b33c2c8daa7b83b85ae1fc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1315_4d358e9e19f001d2d7b33c2c8daa7b83b85ae1fc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1315_4d358e9e19f001d2d7b33c2c8daa7b83b85ae1fc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1315_4d358e9e19f001d2d7b33c2c8daa7b83b85ae1fc.patch 2014-05-05 12:47:33.000000000 +0000 @@ -0,0 +1,74 @@ +commit 4d358e9e19f001d2d7b33c2c8daa7b83b85ae1fc +Author: Madhavan Srinivasan +Date: Wed Oct 2 00:34:10 2013 +0530 + + powerpc/sysfs: Disable writing to PURR in guest mode + + commit d1211af3049f4c9c1d8d4eb8f8098cc4f4f0d0c7 upstream. + + arch/powerpc/kernel/sysfs.c exports PURR with write permission. + This may be valid for kernel in phyp mode. But writing to + the file in guest mode causes crash due to a priviledge violation + + Signed-off-by: Madhavan Srinivasan + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/kernel/sysfs.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kernel/sysfs.c 2014-05-05 11:50:10.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kernel/sysfs.c 2014-05-05 12:47:32.000000000 +0000 +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + + #include "cacheinfo.h" + +@@ -179,15 +180,25 @@ + SYSFS_PMCSETUP(dscr, SPRN_DSCR); + SYSFS_PMCSETUP(pir, SPRN_PIR); + ++/* ++ Lets only enable read for phyp resources and ++ enable write when needed with a separate function. ++ Lets be conservative and default to pseries. ++*/ + static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra); + static DEVICE_ATTR(spurr, 0400, show_spurr, NULL); + static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr); +-static DEVICE_ATTR(purr, 0600, show_purr, store_purr); ++static DEVICE_ATTR(purr, 0400, show_purr, store_purr); + static DEVICE_ATTR(pir, 0400, show_pir, NULL); + + unsigned long dscr_default = 0; + EXPORT_SYMBOL(dscr_default); + ++static void add_write_permission_dev_attr(struct device_attribute *attr) ++{ ++ attr->attr.mode |= 0200; ++} ++ + static ssize_t show_dscr_default(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -394,8 +405,11 @@ + if (cpu_has_feature(CPU_FTR_MMCRA)) + device_create_file(s, &dev_attr_mmcra); + +- if (cpu_has_feature(CPU_FTR_PURR)) ++ if (cpu_has_feature(CPU_FTR_PURR)) { ++ if (!firmware_has_feature(FW_FEATURE_LPAR)) ++ add_write_permission_dev_attr(&dev_attr_purr); + device_create_file(s, &dev_attr_purr); ++ } + + if (cpu_has_feature(CPU_FTR_SPURR)) + device_create_file(s, &dev_attr_spurr); +Index: linux-3.10-3.10.11/dummy/rpi_1315_4d358e9e19f001d2d7b33c2c8daa7b83b85ae1fc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1315_4d358e9e19f001d2d7b33c2c8daa7b83b85ae1fc.txt 2014-05-05 12:47:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1316_17cb5c2fef8f1b1b2f3a4ac10f0801c9ad258cb6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1316_17cb5c2fef8f1b1b2f3a4ac10f0801c9ad258cb6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1316_17cb5c2fef8f1b1b2f3a4ac10f0801c9ad258cb6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1316_17cb5c2fef8f1b1b2f3a4ac10f0801c9ad258cb6.patch 2014-05-05 12:47:34.000000000 +0000 @@ -0,0 +1,161 @@ +commit 17cb5c2fef8f1b1b2f3a4ac10f0801c9ad258cb6 +Author: Paul E. McKenney +Date: Tue Oct 1 17:11:35 2013 +1000 + + powerpc: Restore registers on error exit from csum_partial_copy_generic() + + commit 8f21bd0090052e740944f9397e2be5ac7957ded7 upstream. + + The csum_partial_copy_generic() function saves the PowerPC non-volatile + r14, r15, and r16 registers for the main checksum-and-copy loop. + Unfortunately, it fails to restore them upon error exit from this loop, + which results in silent corruption of these registers in the presumably + rare event of an access exception within that loop. + + This commit therefore restores these register on error exit from the loop. + + Signed-off-by: Paul E. McKenney + Signed-off-by: Anton Blanchard + Signed-off-by: Benjamin Herrenschmidt + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/lib/checksum_64.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/lib/checksum_64.S 2014-05-05 12:47:31.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/lib/checksum_64.S 2014-05-05 12:47:33.000000000 +0000 +@@ -226,19 +226,35 @@ + blr + + +- .macro source ++ .macro srcnr + 100: + .section __ex_table,"a" + .align 3 +- .llong 100b,.Lsrc_error ++ .llong 100b,.Lsrc_error_nr + .previous + .endm + +- .macro dest ++ .macro source ++150: ++ .section __ex_table,"a" ++ .align 3 ++ .llong 150b,.Lsrc_error ++ .previous ++ .endm ++ ++ .macro dstnr + 200: + .section __ex_table,"a" + .align 3 +- .llong 200b,.Ldest_error ++ .llong 200b,.Ldest_error_nr ++ .previous ++ .endm ++ ++ .macro dest ++250: ++ .section __ex_table,"a" ++ .align 3 ++ .llong 250b,.Ldest_error + .previous + .endm + +@@ -274,11 +290,11 @@ + mtctr r6 + + 1: +-source; lhz r6,0(r3) /* align to doubleword */ ++srcnr; lhz r6,0(r3) /* align to doubleword */ + subi r5,r5,2 + addi r3,r3,2 + adde r0,r0,r6 +-dest; sth r6,0(r4) ++dstnr; sth r6,0(r4) + addi r4,r4,2 + bdnz 1b + +@@ -392,10 +408,10 @@ + + mtctr r6 + 3: +-source; ld r6,0(r3) ++srcnr; ld r6,0(r3) + addi r3,r3,8 + adde r0,r0,r6 +-dest; std r6,0(r4) ++dstnr; std r6,0(r4) + addi r4,r4,8 + bdnz 3b + +@@ -405,10 +421,10 @@ + srdi. r6,r5,2 + beq .Lcopy_tail_halfword + +-source; lwz r6,0(r3) ++srcnr; lwz r6,0(r3) + addi r3,r3,4 + adde r0,r0,r6 +-dest; stw r6,0(r4) ++dstnr; stw r6,0(r4) + addi r4,r4,4 + subi r5,r5,4 + +@@ -416,10 +432,10 @@ + srdi. r6,r5,1 + beq .Lcopy_tail_byte + +-source; lhz r6,0(r3) ++srcnr; lhz r6,0(r3) + addi r3,r3,2 + adde r0,r0,r6 +-dest; sth r6,0(r4) ++dstnr; sth r6,0(r4) + addi r4,r4,2 + subi r5,r5,2 + +@@ -427,10 +443,10 @@ + andi. r6,r5,1 + beq .Lcopy_finish + +-source; lbz r6,0(r3) ++srcnr; lbz r6,0(r3) + sldi r9,r6,8 /* Pad the byte out to 16 bits */ + adde r0,r0,r9 +-dest; stb r6,0(r4) ++dstnr; stb r6,0(r4) + + .Lcopy_finish: + addze r0,r0 /* add in final carry */ +@@ -440,6 +456,11 @@ + blr + + .Lsrc_error: ++ ld r14,STK_REG(R14)(r1) ++ ld r15,STK_REG(R15)(r1) ++ ld r16,STK_REG(R16)(r1) ++ addi r1,r1,STACKFRAMESIZE ++.Lsrc_error_nr: + cmpdi 0,r7,0 + beqlr + li r6,-EFAULT +@@ -447,6 +468,11 @@ + blr + + .Ldest_error: ++ ld r14,STK_REG(R14)(r1) ++ ld r15,STK_REG(R15)(r1) ++ ld r16,STK_REG(R16)(r1) ++ addi r1,r1,STACKFRAMESIZE ++.Ldest_error_nr: + cmpdi 0,r8,0 + beqlr + li r6,-EFAULT +Index: linux-3.10-3.10.11/dummy/rpi_1316_17cb5c2fef8f1b1b2f3a4ac10f0801c9ad258cb6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1316_17cb5c2fef8f1b1b2f3a4ac10f0801c9ad258cb6.txt 2014-05-05 12:47:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1317_eb12ca30f11b89eab811b23562e976c1c954c7f3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1317_eb12ca30f11b89eab811b23562e976c1c954c7f3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1317_eb12ca30f11b89eab811b23562e976c1c954c7f3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1317_eb12ca30f11b89eab811b23562e976c1c954c7f3.patch 2014-05-05 12:47:34.000000000 +0000 @@ -0,0 +1,76 @@ +commit eb12ca30f11b89eab811b23562e976c1c954c7f3 +Author: Maxim Patlasov +Date: Fri Sep 13 19:19:54 2013 +0400 + + fuse: wait for writeback in fuse_file_fallocate() + + commit bde52788bdb755b9e4b75db6c434f30e32a0ca0b upstream. + + The patch fixes a race between mmap-ed write and fallocate(PUNCH_HOLE): + + 1) An user makes a page dirty via mmap-ed write. + 2) The user performs fallocate(2) with mode == PUNCH_HOLE|KEEP_SIZE + and covering the page. + 3) Before truncate_pagecache_range call from fuse_file_fallocate, + the page goes to write-back. The page is fully processed by fuse_writepage + (including end_page_writeback on the page), but fuse_flush_writepages did + nothing because fi->writectr < 0. + 4) truncate_pagecache_range is called and fuse_file_fallocate is finishing + by calling fuse_release_nowrite. The latter triggers processing queued + write-back request which will write stale data to the hole soon. + + Changed in v2 (thanks to Brian for suggestion): + - Do not truncate page cache until FUSE_FALLOCATE succeeded. Otherwise, + we can end up in returning -ENOTSUPP while user data is already punched + from page cache. Use filemap_write_and_wait_range() instead. + Changed in v3 (thanks to Miklos for suggestion): + - fuse_wait_on_writeback() is prone to livelocks; use fuse_set_nowrite() + instead. So far as we need a dirty-page barrier only, fuse_sync_writes() + should be enough. + - rebased to for-linus branch of fuse.git + + Signed-off-by: Maxim Patlasov + Signed-off-by: Miklos Szeredi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/fuse/file.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/file.c 2014-05-05 12:45:17.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/file.c 2014-05-05 12:47:34.000000000 +0000 +@@ -2485,8 +2485,15 @@ + + if (lock_inode) { + mutex_lock(&inode->i_mutex); +- if (mode & FALLOC_FL_PUNCH_HOLE) +- fuse_set_nowrite(inode); ++ if (mode & FALLOC_FL_PUNCH_HOLE) { ++ loff_t endbyte = offset + length - 1; ++ err = filemap_write_and_wait_range(inode->i_mapping, ++ offset, endbyte); ++ if (err) ++ goto out; ++ ++ fuse_sync_writes(inode); ++ } + } + + req = fuse_get_req_nopages(fc); +@@ -2521,11 +2528,8 @@ + fuse_invalidate_attr(inode); + + out: +- if (lock_inode) { +- if (mode & FALLOC_FL_PUNCH_HOLE) +- fuse_release_nowrite(inode); ++ if (lock_inode) + mutex_unlock(&inode->i_mutex); +- } + + return err; + } +Index: linux-3.10-3.10.11/dummy/rpi_1317_eb12ca30f11b89eab811b23562e976c1c954c7f3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1317_eb12ca30f11b89eab811b23562e976c1c954c7f3.txt 2014-05-05 12:47:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1318_9abd30b435085cf2d897a77d657a4b6b8a56fd2c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1318_9abd30b435085cf2d897a77d657a4b6b8a56fd2c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1318_9abd30b435085cf2d897a77d657a4b6b8a56fd2c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1318_9abd30b435085cf2d897a77d657a4b6b8a56fd2c.patch 2014-05-05 12:47:35.000000000 +0000 @@ -0,0 +1,65 @@ +commit 9abd30b435085cf2d897a77d657a4b6b8a56fd2c +Author: Maxim Patlasov +Date: Fri Sep 13 19:20:16 2013 +0400 + + fuse: fix fallocate vs. ftruncate race + + commit 0ab08f576b9e6a6b689fc6b4e632079b978e619b upstream. + + A former patch introducing FUSE_I_SIZE_UNSTABLE flag provided detailed + description of races between ftruncate and anyone who can extend i_size: + + > 1. As in the previous scenario fuse_dentry_revalidate() discovered that i_size + > changed (due to our own fuse_do_setattr()) and is going to call + > truncate_pagecache() for some 'new_size' it believes valid right now. But by + > the time that particular truncate_pagecache() is called ... + > 2. fuse_do_setattr() returns (either having called truncate_pagecache() or + > not -- it doesn't matter). + > 3. The file is extended either by write(2) or ftruncate(2) or fallocate(2). + > 4. mmap-ed write makes a page in the extended region dirty. + + This patch adds necessary bits to fuse_file_fallocate() to protect from that + race. + + Signed-off-by: Maxim Patlasov + Signed-off-by: Miklos Szeredi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/fuse/file.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/fuse/file.c 2014-05-05 12:47:34.000000000 +0000 ++++ linux-3.10-3.10.11/fs/fuse/file.c 2014-05-05 12:47:34.000000000 +0000 +@@ -2468,6 +2468,7 @@ + { + struct fuse_file *ff = file->private_data; + struct inode *inode = file->f_inode; ++ struct fuse_inode *fi = get_fuse_inode(inode); + struct fuse_conn *fc = ff->fc; + struct fuse_req *req; + struct fuse_fallocate_in inarg = { +@@ -2496,6 +2497,9 @@ + } + } + ++ if (!(mode & FALLOC_FL_KEEP_SIZE)) ++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ + req = fuse_get_req_nopages(fc); + if (IS_ERR(req)) { + err = PTR_ERR(req); +@@ -2528,6 +2532,9 @@ + fuse_invalidate_attr(inode); + + out: ++ if (!(mode & FALLOC_FL_KEEP_SIZE)) ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ + if (lock_inode) + mutex_unlock(&inode->i_mutex); + +Index: linux-3.10-3.10.11/dummy/rpi_1318_9abd30b435085cf2d897a77d657a4b6b8a56fd2c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1318_9abd30b435085cf2d897a77d657a4b6b8a56fd2c.txt 2014-05-05 12:47:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1319_37afef393d94a49bea7ee44d255b05a922d7b791.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1319_37afef393d94a49bea7ee44d255b05a922d7b791.patch --- linux-3.10.11/debian/patches/rpi/rpi_1319_37afef393d94a49bea7ee44d255b05a922d7b791.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1319_37afef393d94a49bea7ee44d255b05a922d7b791.patch 2014-05-05 12:47:36.000000000 +0000 @@ -0,0 +1,201 @@ +commit 37afef393d94a49bea7ee44d255b05a922d7b791 +Author: Arend van Spriel +Date: Wed Sep 25 12:11:01 2013 +0200 + + brcmfmac: obtain platform data upon module initialization + + commit db4efbbeb457b6f9f4d8c4b090d1170d12f026e1 upstream. + + The driver uses platform_driver_probe() to obtain platform data + if any. However, that function is placed in the .init section so + it must be called upon driver module initialization. + + The problem was reported by Fenguang Wu resulting in a kernel + oops because the .init section was already freed. + + [ 48.966342] Switched to clocksource tsc + [ 48.970002] kernel tried to execute NX-protected page - exploit attempt? (uid: 0) + [ 48.970851] BUG: unable to handle kernel paging request at ffffffff82196446 + [ 48.970957] IP: [] classes_init+0x26/0x26 + [ 48.970957] PGD 1e76067 PUD 1e77063 PMD f388063 PTE 8000000002196163 + [ 48.970957] Oops: 0011 [#1] + [ 48.970957] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 3.11.0-rc7-00444-gc52dd7f #23 + [ 48.970957] Workqueue: events brcmf_driver_init + [ 48.970957] task: ffff8800001d2000 ti: ffff8800001d4000 task.ti: ffff8800001d4000 + [ 48.970957] RIP: 0010:[] [] classes_init+0x26/0x26 + [ 48.970957] RSP: 0000:ffff8800001d5d40 EFLAGS: 00000286 + [ 48.970957] RAX: 0000000000000001 RBX: ffffffff820c5620 RCX: 0000000000000000 + [ 48.970957] RDX: 0000000000000001 RSI: ffffffff816f7380 RDI: ffffffff820c56c0 + [ 48.970957] RBP: ffff8800001d5d50 R08: ffff8800001d2508 R09: 0000000000000002 + [ 48.970957] R10: 0000000000000000 R11: 0001f7ce298c5620 R12: ffff8800001c76b0 + [ 48.970957] R13: ffffffff81e91d40 R14: 0000000000000000 R15: ffff88000e0ce300 + [ 48.970957] FS: 0000000000000000(0000) GS:ffffffff81e84000(0000) knlGS:0000000000000000 + [ 48.970957] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b + [ 48.970957] CR2: ffffffff82196446 CR3: 0000000001e75000 CR4: 00000000000006b0 + [ 48.970957] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + [ 48.970957] DR3: 0000000000000000 DR6: 0000000000000000 DR7: 0000000000000000 + [ 48.970957] Stack: + [ 48.970957] ffffffff816f7df8 ffffffff820c5620 ffff8800001d5d60 ffffffff816eeec9 + [ 48.970957] ffff8800001d5de0 ffffffff81073dc5 ffffffff81073d68 ffff8800001d5db8 + [ 48.970957] 0000000000000086 ffffffff820c5620 ffffffff824f7fd0 0000000000000000 + [ 48.970957] Call Trace: + [ 48.970957] [] ? brcmf_sdio_init+0x18/0x70 + [ 48.970957] [] brcmf_driver_init+0x9/0x10 + [ 48.970957] [] process_one_work+0x1d5/0x480 + [ 48.970957] [] ? process_one_work+0x178/0x480 + [ 48.970957] [] worker_thread+0x118/0x3a0 + [ 48.970957] [] ? process_one_work+0x480/0x480 + [ 48.970957] [] kthread+0xe7/0xf0 + [ 48.970957] [] ? finish_task_switch.constprop.57+0x37/0xd0 + [ 48.970957] [] ? __kthread_parkme+0x80/0x80 + [ 48.970957] [] ret_from_fork+0x7a/0xb0 + [ 48.970957] [] ? __kthread_parkme+0x80/0x80 + [ 48.970957] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc + cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc + [ 48.970957] RIP [] classes_init+0x26/0x26 + [ 48.970957] RSP + [ 48.970957] CR2: ffffffff82196446 + [ 48.970957] ---[ end trace 62980817cd525f14 ]--- + + Reported-by: Fengguang Wu + Reviewed-by: Hante Meuleman + Reviewed-by: Pieter-Paul Giesberts + Tested-by: Fengguang Wu + Signed-off-by: Arend van Spriel + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c 2014-05-05 11:50:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c 2014-05-05 12:47:35.000000000 +0000 +@@ -575,8 +575,6 @@ + + static int brcmf_sdio_pd_probe(struct platform_device *pdev) + { +- int ret; +- + brcmf_dbg(SDIO, "Enter\n"); + + brcmfmac_sdio_pdata = pdev->dev.platform_data; +@@ -584,11 +582,7 @@ + if (brcmfmac_sdio_pdata->power_on) + brcmfmac_sdio_pdata->power_on(); + +- ret = sdio_register_driver(&brcmf_sdmmc_driver); +- if (ret) +- brcmf_err("sdio_register_driver failed: %d\n", ret); +- +- return ret; ++ return 0; + } + + static int brcmf_sdio_pd_remove(struct platform_device *pdev) +@@ -610,6 +604,15 @@ + } + }; + ++void brcmf_sdio_register(void) ++{ ++ int ret; ++ ++ ret = sdio_register_driver(&brcmf_sdmmc_driver); ++ if (ret) ++ brcmf_err("sdio_register_driver failed: %d\n", ret); ++} ++ + void brcmf_sdio_exit(void) + { + brcmf_dbg(SDIO, "Enter\n"); +@@ -620,18 +623,13 @@ + sdio_unregister_driver(&brcmf_sdmmc_driver); + } + +-void brcmf_sdio_init(void) ++void __init brcmf_sdio_init(void) + { + int ret; + + brcmf_dbg(SDIO, "Enter\n"); + + ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); +- if (ret == -ENODEV) { +- brcmf_dbg(SDIO, "No platform data available, registering without.\n"); +- ret = sdio_register_driver(&brcmf_sdmmc_driver); +- } +- +- if (ret) +- brcmf_err("driver registration failed: %d\n", ret); ++ if (ret == -ENODEV) ++ brcmf_dbg(SDIO, "No platform data available.\n"); + } +Index: linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-05-05 11:50:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-05-05 12:47:35.000000000 +0000 +@@ -154,10 +154,11 @@ + #ifdef CONFIG_BRCMFMAC_SDIO + extern void brcmf_sdio_exit(void); + extern void brcmf_sdio_init(void); ++extern void brcmf_sdio_register(void); + #endif + #ifdef CONFIG_BRCMFMAC_USB + extern void brcmf_usb_exit(void); +-extern void brcmf_usb_init(void); ++extern void brcmf_usb_register(void); + #endif + + #endif /* _BRCMF_BUS_H_ */ +Index: linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-05-05 11:50:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-05-05 12:47:35.000000000 +0000 +@@ -1034,21 +1034,23 @@ + return bus->chip << 4 | bus->chiprev; + } + +-static void brcmf_driver_init(struct work_struct *work) ++static void brcmf_driver_register(struct work_struct *work) + { +- brcmf_debugfs_init(); +- + #ifdef CONFIG_BRCMFMAC_SDIO +- brcmf_sdio_init(); ++ brcmf_sdio_register(); + #endif + #ifdef CONFIG_BRCMFMAC_USB +- brcmf_usb_init(); ++ brcmf_usb_register(); + #endif + } +-static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); ++static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); + + static int __init brcmfmac_module_init(void) + { ++ brcmf_debugfs_init(); ++#ifdef CONFIG_BRCMFMAC_SDIO ++ brcmf_sdio_init(); ++#endif + if (!schedule_work(&brcmf_driver_work)) + return -EBUSY; + +Index: linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-05-05 11:50:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-05-05 12:47:35.000000000 +0000 +@@ -1532,7 +1532,7 @@ + brcmf_release_fw(&fw_image_list); + } + +-void brcmf_usb_init(void) ++void brcmf_usb_register(void) + { + brcmf_dbg(USB, "Enter\n"); + INIT_LIST_HEAD(&fw_image_list); +Index: linux-3.10-3.10.11/dummy/rpi_1319_37afef393d94a49bea7ee44d255b05a922d7b791.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1319_37afef393d94a49bea7ee44d255b05a922d7b791.txt 2014-05-05 12:47:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1320_a508ba2c07af1c6b1255e334fadfeddda2887f93.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1320_a508ba2c07af1c6b1255e334fadfeddda2887f93.patch --- linux-3.10.11/debian/patches/rpi/rpi_1320_a508ba2c07af1c6b1255e334fadfeddda2887f93.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1320_a508ba2c07af1c6b1255e334fadfeddda2887f93.patch 2014-05-05 12:47:37.000000000 +0000 @@ -0,0 +1,46 @@ +commit a508ba2c07af1c6b1255e334fadfeddda2887f93 +Author: Andre Guedes +Date: Wed Jul 31 16:25:28 2013 -0300 + + Bluetooth: Fix security level for peripheral role + + commit f8776218e8546397be64ad2bc0ebf4748522d6e3 upstream. + + While playing the peripheral role, the host gets a LE Long Term Key + Request Event from the controller when a connection is established + with a bonded device. The host then informs the LTK which should be + used for the connection. Once the link is encrypted, the host gets + an Encryption Change Event. + + Therefore we should set conn->pending_sec_level instead of conn-> + sec_level in hci_le_ltk_request_evt. This way, conn->sec_level is + properly updated in hci_encrypt_change_evt. + + Moreover, since we have a LTK associated to the device, we have at + least BT_SECURITY_MEDIUM security level. + + Signed-off-by: Andre Guedes + Signed-off-by: Gustavo Padovan + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bluetooth/hci_event.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bluetooth/hci_event.c 2014-05-05 11:50:09.000000000 +0000 ++++ linux-3.10-3.10.11/net/bluetooth/hci_event.c 2014-05-05 12:47:36.000000000 +0000 +@@ -3611,7 +3611,9 @@ + cp.handle = cpu_to_le16(conn->handle); + + if (ltk->authenticated) +- conn->sec_level = BT_SECURITY_HIGH; ++ conn->pending_sec_level = BT_SECURITY_HIGH; ++ else ++ conn->pending_sec_level = BT_SECURITY_MEDIUM; + + hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); + +Index: linux-3.10-3.10.11/dummy/rpi_1320_a508ba2c07af1c6b1255e334fadfeddda2887f93.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1320_a508ba2c07af1c6b1255e334fadfeddda2887f93.txt 2014-05-05 12:47:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1321_ad04e6cbe9e091059096748285655caf16da97d0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1321_ad04e6cbe9e091059096748285655caf16da97d0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1321_ad04e6cbe9e091059096748285655caf16da97d0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1321_ad04e6cbe9e091059096748285655caf16da97d0.patch 2014-05-05 12:47:37.000000000 +0000 @@ -0,0 +1,35 @@ +commit ad04e6cbe9e091059096748285655caf16da97d0 +Author: Andre Guedes +Date: Wed Jul 31 16:25:29 2013 -0300 + + Bluetooth: Fix encryption key size for peripheral role + + commit 89cbb4da0abee2f39d75f67f9fd57f7410c8b65c upstream. + + This patch fixes the connection encryption key size information when + the host is playing the peripheral role. We should set conn->enc_key_ + size in hci_le_ltk_request_evt, otherwise it is left uninitialized. + + Signed-off-by: Andre Guedes + Signed-off-by: Gustavo Padovan + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bluetooth/hci_event.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bluetooth/hci_event.c 2014-05-05 12:47:36.000000000 +0000 ++++ linux-3.10-3.10.11/net/bluetooth/hci_event.c 2014-05-05 12:47:37.000000000 +0000 +@@ -3615,6 +3615,8 @@ + else + conn->pending_sec_level = BT_SECURITY_MEDIUM; + ++ conn->enc_key_size = ltk->enc_size; ++ + hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); + + if (ltk->type & HCI_SMP_STK) { +Index: linux-3.10-3.10.11/dummy/rpi_1321_ad04e6cbe9e091059096748285655caf16da97d0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1321_ad04e6cbe9e091059096748285655caf16da97d0.txt 2014-05-05 12:47:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1322_877ed5f4e67d3142df09048e037c62f3a3ae6ca9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1322_877ed5f4e67d3142df09048e037c62f3a3ae6ca9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1322_877ed5f4e67d3142df09048e037c62f3a3ae6ca9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1322_877ed5f4e67d3142df09048e037c62f3a3ae6ca9.patch 2014-05-05 12:47:38.000000000 +0000 @@ -0,0 +1,64 @@ +commit 877ed5f4e67d3142df09048e037c62f3a3ae6ca9 +Author: Peng Chen +Date: Fri Aug 30 17:41:40 2013 +0800 + + Bluetooth: Add a new PID/VID 0cf3/e005 for AR3012. + + commit 0a3658cccdf5326ea508efeb1879b0e2508bb0c3 upstream. + + usb device info: + + T: Bus=06 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 15 Spd=12 MxCh= 0 + D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 + P: Vendor=0cf3 ProdID=e005 Rev= 0.02 + C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA + I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms + E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms + E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms + I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms + E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms + + Signed-off-by: Peng Chen + Signed-off-by: Gustavo Padovan + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/bluetooth/ath3k.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/ath3k.c 2014-05-05 12:41:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/ath3k.c 2014-05-05 12:47:38.000000000 +0000 +@@ -85,6 +85,7 @@ + { USB_DEVICE(0x04CA, 0x3008) }, + { USB_DEVICE(0x13d3, 0x3362) }, + { USB_DEVICE(0x0CF3, 0xE004) }, ++ { USB_DEVICE(0x0CF3, 0xE005) }, + { USB_DEVICE(0x0930, 0x0219) }, + { USB_DEVICE(0x0489, 0xe057) }, + { USB_DEVICE(0x13d3, 0x3393) }, +@@ -126,6 +127,7 @@ + { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, +Index: linux-3.10-3.10.11/drivers/bluetooth/btusb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/btusb.c 2014-05-05 11:50:08.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/btusb.c 2014-05-05 12:47:38.000000000 +0000 +@@ -148,6 +148,7 @@ + { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, +Index: linux-3.10-3.10.11/dummy/rpi_1322_877ed5f4e67d3142df09048e037c62f3a3ae6ca9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1322_877ed5f4e67d3142df09048e037c62f3a3ae6ca9.txt 2014-05-05 12:47:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1323_a7905fb906f2d43fbbdf2bd45c860ad0ee6c9465.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1323_a7905fb906f2d43fbbdf2bd45c860ad0ee6c9465.patch --- linux-3.10.11/debian/patches/rpi/rpi_1323_a7905fb906f2d43fbbdf2bd45c860ad0ee6c9465.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1323_a7905fb906f2d43fbbdf2bd45c860ad0ee6c9465.patch 2014-05-05 12:47:39.000000000 +0000 @@ -0,0 +1,45 @@ +commit a7905fb906f2d43fbbdf2bd45c860ad0ee6c9465 +Author: Raphael Kubo da Costa +Date: Mon Sep 2 14:57:51 2013 +0300 + + Bluetooth: Add support for BCM20702A0 [0b05, 17cb] + + commit 38a172bef8c93ecbfd69715fd88396988e4073fd upstream. + + Yet another vendor specific ID for this chipset; this one for the ASUS + USB-BT400 Bluetooth 4.0 adapter. + + T: Bus=03 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 + D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 + P: Vendor=0b05 ProdID=17cb Rev=01.12 + S: Manufacturer=Broadcom Corp + S: Product=BCM20702A0 + S: SerialNumber=000272C64400 + C: #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=100mA + I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) + I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) + I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) + I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) + + Signed-off-by: Raphael Kubo da Costa + Signed-off-by: Gustavo Padovan + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/bluetooth/btusb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/bluetooth/btusb.c 2014-05-05 12:47:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/bluetooth/btusb.c 2014-05-05 12:47:39.000000000 +0000 +@@ -102,6 +102,7 @@ + + /* Broadcom BCM20702A0 */ + { USB_DEVICE(0x0b05, 0x17b5) }, ++ { USB_DEVICE(0x0b05, 0x17cb) }, + { USB_DEVICE(0x04ca, 0x2003) }, + { USB_DEVICE(0x0489, 0xe042) }, + { USB_DEVICE(0x413c, 0x8197) }, +Index: linux-3.10-3.10.11/dummy/rpi_1323_a7905fb906f2d43fbbdf2bd45c860ad0ee6c9465.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1323_a7905fb906f2d43fbbdf2bd45c860ad0ee6c9465.txt 2014-05-05 12:47:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1324_ddc650c1b220e15a831ebc1624504a590ee0e8d9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1324_ddc650c1b220e15a831ebc1624504a590ee0e8d9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1324_ddc650c1b220e15a831ebc1624504a590ee0e8d9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1324_ddc650c1b220e15a831ebc1624504a590ee0e8d9.patch 2014-05-05 12:47:40.000000000 +0000 @@ -0,0 +1,76 @@ +commit ddc650c1b220e15a831ebc1624504a590ee0e8d9 +Author: Johan Hedberg +Date: Fri Sep 13 08:58:17 2013 +0300 + + Bluetooth: Introduce a new HCI_RFKILLED flag + + commit 5e130367d43ff22836bbae380d197d600fe8ddbb upstream. + + This makes it more convenient to check for rfkill (no need to check for + dev->rfkill before calling rfkill_blocked()) and also avoids potential + races if the RFKILL state needs to be checked from within the rfkill + callback. + + Signed-off-by: Johan Hedberg + Acked-by: Marcel Holtmann + Signed-off-by: Gustavo Padovan + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/bluetooth/hci.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/bluetooth/hci.h 2014-05-05 11:50:07.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/bluetooth/hci.h 2014-05-05 12:47:39.000000000 +0000 +@@ -104,6 +104,7 @@ + enum { + HCI_SETUP, + HCI_AUTO_OFF, ++ HCI_RFKILLED, + HCI_MGMT, + HCI_PAIRABLE, + HCI_SERVICE_CACHE, +Index: linux-3.10-3.10.11/net/bluetooth/hci_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bluetooth/hci_core.c 2014-05-05 11:50:07.000000000 +0000 ++++ linux-3.10-3.10.11/net/bluetooth/hci_core.c 2014-05-05 12:47:39.000000000 +0000 +@@ -1123,7 +1123,7 @@ + goto done; + } + +- if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { ++ if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { + ret = -ERFKILL; + goto done; + } +@@ -1545,10 +1545,12 @@ + + BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); + +- if (!blocked) +- return 0; +- +- hci_dev_do_close(hdev); ++ if (blocked) { ++ set_bit(HCI_RFKILLED, &hdev->dev_flags); ++ hci_dev_do_close(hdev); ++ } else { ++ clear_bit(HCI_RFKILLED, &hdev->dev_flags); ++} + + return 0; + } +@@ -2241,6 +2243,9 @@ + } + } + ++ if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) ++ set_bit(HCI_RFKILLED, &hdev->dev_flags); ++ + set_bit(HCI_SETUP, &hdev->dev_flags); + + if (hdev->dev_type != HCI_AMP) +Index: linux-3.10-3.10.11/dummy/rpi_1324_ddc650c1b220e15a831ebc1624504a590ee0e8d9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1324_ddc650c1b220e15a831ebc1624504a590ee0e8d9.txt 2014-05-05 12:47:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1325_230352711ef9d819bff5ccc18d407bfd5f51ef81.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1325_230352711ef9d819bff5ccc18d407bfd5f51ef81.patch --- linux-3.10.11/debian/patches/rpi/rpi_1325_230352711ef9d819bff5ccc18d407bfd5f51ef81.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1325_230352711ef9d819bff5ccc18d407bfd5f51ef81.patch 2014-05-05 12:47:41.000000000 +0000 @@ -0,0 +1,77 @@ +commit 230352711ef9d819bff5ccc18d407bfd5f51ef81 +Author: Johan Hedberg +Date: Fri Sep 13 08:58:18 2013 +0300 + + Bluetooth: Fix rfkill functionality during the HCI setup stage + + commit bf5430360ebe4b2d0c51d91f782e649107b502eb upstream. + + We need to let the setup stage complete cleanly even when the HCI device + is rfkilled. Otherwise the HCI device will stay in an undefined state + and never get notified to user space through mgmt (even when it gets + unblocked through rfkill). + + This patch makes sure that hci_dev_open() can be called in the HCI_SETUP + stage, that blocking the device doesn't abort the setup stage, and that + the device gets proper powered down as soon as the setup stage completes + in case it was blocked meanwhile. + + The bug that this patch fixed can be very easily reproduced using e.g. + the rfkill command line too. By running "rfkill block all" before + inserting a Bluetooth dongle the resulting HCI device goes into a state + where it is never announced over mgmt, not even when "rfkill unblock all" + is run. + + Signed-off-by: Johan Hedberg + Acked-by: Marcel Holtmann + Signed-off-by: Gustavo Padovan + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bluetooth/hci_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bluetooth/hci_core.c 2014-05-05 12:47:39.000000000 +0000 ++++ linux-3.10-3.10.11/net/bluetooth/hci_core.c 2014-05-05 12:47:40.000000000 +0000 +@@ -1123,7 +1123,11 @@ + goto done; + } + +- if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { ++ /* Check for rfkill but allow the HCI setup stage to proceed ++ * (which in itself doesn't cause any RF activity). ++ */ ++ if (test_bit(HCI_RFKILLED, &hdev->dev_flags) && ++ !test_bit(HCI_SETUP, &hdev->dev_flags)) { + ret = -ERFKILL; + goto done; + } +@@ -1547,7 +1551,8 @@ + + if (blocked) { + set_bit(HCI_RFKILLED, &hdev->dev_flags); +- hci_dev_do_close(hdev); ++ if (!test_bit(HCI_SETUP, &hdev->dev_flags)) ++ hci_dev_do_close(hdev); + } else { + clear_bit(HCI_RFKILLED, &hdev->dev_flags); + } +@@ -1572,9 +1577,13 @@ + return; + } + +- if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) ++ if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { ++ clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); ++ hci_dev_do_close(hdev); ++ } else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { + queue_delayed_work(hdev->req_workqueue, &hdev->power_off, + HCI_AUTO_OFF_TIMEOUT); ++ } + + if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) + mgmt_index_added(hdev); +Index: linux-3.10-3.10.11/dummy/rpi_1325_230352711ef9d819bff5ccc18d407bfd5f51ef81.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1325_230352711ef9d819bff5ccc18d407bfd5f51ef81.txt 2014-05-05 12:47:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1326_d8974c7fe717ee8fb0706e35cc92e0bcdf660ec5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1326_d8974c7fe717ee8fb0706e35cc92e0bcdf660ec5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1326_d8974c7fe717ee8fb0706e35cc92e0bcdf660ec5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1326_d8974c7fe717ee8fb0706e35cc92e0bcdf660ec5.patch 2014-05-05 12:47:42.000000000 +0000 @@ -0,0 +1,289 @@ +commit d8974c7fe717ee8fb0706e35cc92e0bcdf660ec5 +Author: Vyacheslav Dubeyko +Date: Mon Sep 30 13:45:12 2013 -0700 + + nilfs2: fix issue with race condition of competition between segments for dirty blocks + + commit 7f42ec3941560f0902fe3671e36f2c20ffd3af0a upstream. + + Many NILFS2 users were reported about strange file system corruption + (for example): + + NILFS: bad btree node (blocknr=185027): level = 0, flags = 0x0, nchildren = 768 + NILFS error (device sda4): nilfs_bmap_last_key: broken bmap (inode number=11540) + + But such error messages are consequence of file system's issue that takes + place more earlier. Fortunately, Jerome Poulin + and Anton Eliasson were reported about another + issue not so recently. These reports describe the issue with segctor + thread's crash: + + BUG: unable to handle kernel paging request at 0000000000004c83 + IP: nilfs_end_page_io+0x12/0xd0 [nilfs2] + + Call Trace: + nilfs_segctor_do_construct+0xf25/0x1b20 [nilfs2] + nilfs_segctor_construct+0x17b/0x290 [nilfs2] + nilfs_segctor_thread+0x122/0x3b0 [nilfs2] + kthread+0xc0/0xd0 + ret_from_fork+0x7c/0xb0 + + These two issues have one reason. This reason can raise third issue + too. Third issue results in hanging of segctor thread with eating of + 100% CPU. + + REPRODUCING PATH: + + One of the possible way or the issue reproducing was described by + Jermoe me Poulin : + + 1. init S to get to single user mode. + 2. sysrq+E to make sure only my shell is running + 3. start network-manager to get my wifi connection up + 4. login as root and launch "screen" + 5. cd /boot/log/nilfs which is a ext3 mount point and can log when NILFS dies. + 6. lscp | xz -9e > lscp.txt.xz + 7. mount my snapshot using mount -o cp=3360839,ro /dev/vgUbuntu/root /mnt/nilfs + 8. start a screen to dump /proc/kmsg to text file since rsyslog is killed + 9. start a screen and launch strace -f -o find-cat.log -t find + /mnt/nilfs -type f -exec cat {} > /dev/null \; + 10. start a screen and launch strace -f -o apt-get.log -t apt-get update + 11. launch the last command again as it did not crash the first time + 12. apt-get crashes + 13. ps aux > ps-aux-crashed.log + 13. sysrq+W + 14. sysrq+E wait for everything to terminate + 15. sysrq+SUSB + + Simplified way of the issue reproducing is starting kernel compilation + task and "apt-get update" in parallel. + + REPRODUCIBILITY: + + The issue is reproduced not stable [60% - 80%]. It is very important to + have proper environment for the issue reproducing. The critical + conditions for successful reproducing: + + (1) It should have big modified file by mmap() way. + + (2) This file should have the count of dirty blocks are greater that + several segments in size (for example, two or three) from time to time + during processing. + + (3) It should be intensive background activity of files modification + in another thread. + + INVESTIGATION: + + First of all, it is possible to see that the reason of crash is not valid + page address: + + NILFS [nilfs_segctor_complete_write]:2100 bh->b_count 0, bh->b_blocknr 13895680, bh->b_size 13897727, bh->b_page 0000000000001a82 + NILFS [nilfs_segctor_complete_write]:2101 segbuf->sb_segnum 6783 + + Moreover, value of b_page (0x1a82) is 6786. This value looks like segment + number. And b_blocknr with b_size values look like block numbers. So, + buffer_head's pointer points on not proper address value. + + Detailed investigation of the issue is discovered such picture: + + [-----------------------------SEGMENT 6783-------------------------------] + NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction + NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect + NILFS [nilfs_segctor_do_construct]:2336 nilfs_segctor_assign + NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage + NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write + NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs + NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write + NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111149024, segbuf->sb_segnum 6783 + + [-----------------------------SEGMENT 6784-------------------------------] + NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction + NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect + NILFS [nilfs_lookup_dirty_data_buffers]:782 bh->b_count 1, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 + NILFS [nilfs_lookup_dirty_data_buffers]:783 bh->b_assoc_buffers.next ffff8802174a6798, bh->b_assoc_buffers.prev ffff880221cffee8 + NILFS [nilfs_segctor_do_construct]:2336 nilfs_segctor_assign + NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage + NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write + NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs + NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write + NILFS [nilfs_segbuf_submit_bh]:575 bh->b_count 1, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 + NILFS [nilfs_segbuf_submit_bh]:576 segbuf->sb_segnum 6784 + NILFS [nilfs_segbuf_submit_bh]:577 bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880218bcdf50 + NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111150080, segbuf->sb_segnum 6784, segbuf->sb_nbio 0 + [----------] ditto + NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111164416, segbuf->sb_segnum 6784, segbuf->sb_nbio 15 + + [-----------------------------SEGMENT 6785-------------------------------] + NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction + NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect + NILFS [nilfs_lookup_dirty_data_buffers]:782 bh->b_count 2, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 + NILFS [nilfs_lookup_dirty_data_buffers]:783 bh->b_assoc_buffers.next ffff880219277e80, bh->b_assoc_buffers.prev ffff880221cffc88 + NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage + NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write + NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs + NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write + NILFS [nilfs_segbuf_submit_bh]:575 bh->b_count 2, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 + NILFS [nilfs_segbuf_submit_bh]:576 segbuf->sb_segnum 6785 + NILFS [nilfs_segbuf_submit_bh]:577 bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880222cc7ee8 + NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111165440, segbuf->sb_segnum 6785, segbuf->sb_nbio 0 + [----------] ditto + NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111177728, segbuf->sb_segnum 6785, segbuf->sb_nbio 12 + + NILFS [nilfs_segctor_do_construct]:2399 nilfs_segctor_wait + NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6783 + NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6784 + NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6785 + + NILFS [nilfs_segctor_complete_write]:2100 bh->b_count 0, bh->b_blocknr 13895680, bh->b_size 13897727, bh->b_page 0000000000001a82 + + BUG: unable to handle kernel paging request at 0000000000001a82 + IP: [] nilfs_end_page_io+0x12/0xd0 [nilfs2] + + Usually, for every segment we collect dirty files in list. Then, dirty + blocks are gathered for every dirty file, prepared for write and + submitted by means of nilfs_segbuf_submit_bh() call. Finally, it takes + place complete write phase after calling nilfs_end_bio_write() on the + block layer. Buffers/pages are marked as not dirty on final phase and + processed files removed from the list of dirty files. + + It is possible to see that we had three prepare_write and submit_bio + phases before segbuf_wait and complete_write phase. Moreover, segments + compete between each other for dirty blocks because on every iteration + of segments processing dirty buffer_heads are added in several lists of + payload_buffers: + + [SEGMENT 6784]: bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880218bcdf50 + [SEGMENT 6785]: bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880222cc7ee8 + + The next pointer is the same but prev pointer has changed. It means + that buffer_head has next pointer from one list but prev pointer from + another. Such modification can be made several times. And, finally, it + can be resulted in various issues: (1) segctor hanging, (2) segctor + crashing, (3) file system metadata corruption. + + FIX: + This patch adds: + + (1) setting of BH_Async_Write flag in nilfs_segctor_prepare_write() + for every proccessed dirty block; + + (2) checking of BH_Async_Write flag in + nilfs_lookup_dirty_data_buffers() and + nilfs_lookup_dirty_node_buffers(); + + (3) clearing of BH_Async_Write flag in nilfs_segctor_complete_write(), + nilfs_abort_logs(), nilfs_forget_buffer(), nilfs_clear_dirty_page(). + + Reported-by: Jerome Poulin + Reported-by: Anton Eliasson + Cc: Paul Fertser + Cc: ARAI Shun-ichi + Cc: Piotr Szymaniak + Cc: Juan Barry Manuel Canham + Cc: Zahid Chowdhury + Cc: Elmer Zhang + Cc: Kenneth Langga + Signed-off-by: Vyacheslav Dubeyko + Acked-by: Ryusuke Konishi + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/nilfs2/page.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/nilfs2/page.c 2014-05-05 11:50:06.000000000 +0000 ++++ linux-3.10-3.10.11/fs/nilfs2/page.c 2014-05-05 12:47:41.000000000 +0000 +@@ -94,6 +94,7 @@ + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_checked(bh); + clear_buffer_nilfs_redirected(bh); ++ clear_buffer_async_write(bh); + clear_buffer_dirty(bh); + if (nilfs_page_buffers_clean(page)) + __nilfs_clear_page_dirty(page); +@@ -429,6 +430,7 @@ + "discard block %llu, size %zu", + (u64)bh->b_blocknr, bh->b_size); + } ++ clear_buffer_async_write(bh); + clear_buffer_dirty(bh); + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_checked(bh); +Index: linux-3.10-3.10.11/fs/nilfs2/segment.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/nilfs2/segment.c 2014-05-05 11:50:06.000000000 +0000 ++++ linux-3.10-3.10.11/fs/nilfs2/segment.c 2014-05-05 12:47:41.000000000 +0000 +@@ -665,7 +665,7 @@ + + bh = head = page_buffers(page); + do { +- if (!buffer_dirty(bh)) ++ if (!buffer_dirty(bh) || buffer_async_write(bh)) + continue; + get_bh(bh); + list_add_tail(&bh->b_assoc_buffers, listp); +@@ -699,7 +699,8 @@ + for (i = 0; i < pagevec_count(&pvec); i++) { + bh = head = page_buffers(pvec.pages[i]); + do { +- if (buffer_dirty(bh)) { ++ if (buffer_dirty(bh) && ++ !buffer_async_write(bh)) { + get_bh(bh); + list_add_tail(&bh->b_assoc_buffers, + listp); +@@ -1579,6 +1580,7 @@ + + list_for_each_entry(bh, &segbuf->sb_segsum_buffers, + b_assoc_buffers) { ++ set_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) { + lock_page(bd_page); +@@ -1592,6 +1594,7 @@ + + list_for_each_entry(bh, &segbuf->sb_payload_buffers, + b_assoc_buffers) { ++ set_buffer_async_write(bh); + if (bh == segbuf->sb_super_root) { + if (bh->b_page != bd_page) { + lock_page(bd_page); +@@ -1677,6 +1680,7 @@ + list_for_each_entry(segbuf, logs, sb_list) { + list_for_each_entry(bh, &segbuf->sb_segsum_buffers, + b_assoc_buffers) { ++ clear_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) + end_page_writeback(bd_page); +@@ -1686,6 +1690,7 @@ + + list_for_each_entry(bh, &segbuf->sb_payload_buffers, + b_assoc_buffers) { ++ clear_buffer_async_write(bh); + if (bh == segbuf->sb_super_root) { + if (bh->b_page != bd_page) { + end_page_writeback(bd_page); +@@ -1755,6 +1760,7 @@ + b_assoc_buffers) { + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); ++ clear_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) + end_page_writeback(bd_page); +@@ -1776,6 +1782,7 @@ + b_assoc_buffers) { + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); ++ clear_buffer_async_write(bh); + clear_buffer_delay(bh); + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_redirected(bh); +Index: linux-3.10-3.10.11/dummy/rpi_1326_d8974c7fe717ee8fb0706e35cc92e0bcdf660ec5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1326_d8974c7fe717ee8fb0706e35cc92e0bcdf660ec5.txt 2014-05-05 12:47:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1327_74e8a9efa9f08394444ef6ea7a4349c35dd3e811.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1327_74e8a9efa9f08394444ef6ea7a4349c35dd3e811.patch --- linux-3.10.11/debian/patches/rpi/rpi_1327_74e8a9efa9f08394444ef6ea7a4349c35dd3e811.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1327_74e8a9efa9f08394444ef6ea7a4349c35dd3e811.patch 2014-05-05 12:47:42.000000000 +0000 @@ -0,0 +1,99 @@ +commit 74e8a9efa9f08394444ef6ea7a4349c35dd3e811 +Author: David S. Miller +Date: Thu Aug 1 18:08:34 2013 -0700 + + esp_scsi: Fix tag state corruption when autosensing. + + [ Upstream commit 21af8107f27878813d0364733c0b08813c2c192a ] + + Meelis Roos reports a crash in esp_free_lun_tag() in the presense + of a disk which has died. + + The issue is that when we issue an autosense command, we do so by + hijacking the original command that caused the check-condition. + + When we do so we clear out the ent->tag[] array when we issue it via + find_and_prep_issuable_command(). This is so that the autosense + command is forced to be issued non-tagged. + + That is problematic, because it is the value of ent->tag[] which + determines whether we issued the original scsi command as tagged + vs. non-tagged (see esp_alloc_lun_tag()). + + And that, in turn, is what trips up the sanity checks in + esp_free_lun_tag(). That function needs the original ->tag[] values + in order to free up the tag slot properly. + + Fix this by remembering the original command's tag values, and + having esp_alloc_lun_tag() and esp_free_lun_tag() use them. + + Reported-by: Meelis Roos + Tested-by: Meelis Roos + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/scsi/esp_scsi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/esp_scsi.c 2014-05-05 11:50:06.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/esp_scsi.c 2014-05-05 12:47:42.000000000 +0000 +@@ -530,7 +530,7 @@ + static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, + struct esp_lun_data *lp) + { +- if (!ent->tag[0]) { ++ if (!ent->orig_tag[0]) { + /* Non-tagged, slot already taken? */ + if (lp->non_tagged_cmd) + return -EBUSY; +@@ -564,9 +564,9 @@ + return -EBUSY; + } + +- BUG_ON(lp->tagged_cmds[ent->tag[1]]); ++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]); + +- lp->tagged_cmds[ent->tag[1]] = ent; ++ lp->tagged_cmds[ent->orig_tag[1]] = ent; + lp->num_tagged++; + + return 0; +@@ -575,9 +575,9 @@ + static void esp_free_lun_tag(struct esp_cmd_entry *ent, + struct esp_lun_data *lp) + { +- if (ent->tag[0]) { +- BUG_ON(lp->tagged_cmds[ent->tag[1]] != ent); +- lp->tagged_cmds[ent->tag[1]] = NULL; ++ if (ent->orig_tag[0]) { ++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent); ++ lp->tagged_cmds[ent->orig_tag[1]] = NULL; + lp->num_tagged--; + } else { + BUG_ON(lp->non_tagged_cmd != ent); +@@ -667,6 +667,8 @@ + ent->tag[0] = 0; + ent->tag[1] = 0; + } ++ ent->orig_tag[0] = ent->tag[0]; ++ ent->orig_tag[1] = ent->tag[1]; + + if (esp_alloc_lun_tag(ent, lp) < 0) + continue; +Index: linux-3.10-3.10.11/drivers/scsi/esp_scsi.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/esp_scsi.h 2014-05-05 11:50:06.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/esp_scsi.h 2014-05-05 12:47:42.000000000 +0000 +@@ -271,6 +271,7 @@ + #define ESP_CMD_FLAG_AUTOSENSE 0x04 /* Doing automatic REQUEST_SENSE */ + + u8 tag[2]; ++ u8 orig_tag[2]; + + u8 status; + u8 message; +Index: linux-3.10-3.10.11/dummy/rpi_1327_74e8a9efa9f08394444ef6ea7a4349c35dd3e811.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1327_74e8a9efa9f08394444ef6ea7a4349c35dd3e811.txt 2014-05-05 12:47:42.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1328_84c041cc9b2eb6305732e32f283d9fac2b0e8b6a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1328_84c041cc9b2eb6305732e32f283d9fac2b0e8b6a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1328_84c041cc9b2eb6305732e32f283d9fac2b0e8b6a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1328_84c041cc9b2eb6305732e32f283d9fac2b0e8b6a.patch 2014-05-05 12:47:43.000000000 +0000 @@ -0,0 +1,45 @@ +commit 84c041cc9b2eb6305732e32f283d9fac2b0e8b6a +Author: Kirill Tkhai +Date: Fri Aug 2 19:23:18 2013 +0400 + + sparc64: Fix ITLB handler of null page + + [ Upstream commit 1c2696cdaad84580545a2e9c0879ff597880b1a9 ] + + 1)Use kvmap_itlb_longpath instead of kvmap_dtlb_longpath. + + 2)Handle page #0 only, don't handle page #1: bleu -> blu + + (KERNBASE is 0x400000, so #1 does not exist too. But everything + is possible in the future. Fix to not to have problems later.) + + 3)Remove unused kvmap_itlb_nonlinear. + + Signed-off-by: Kirill Tkhai + CC: David Miller + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/sparc/kernel/ktlb.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/kernel/ktlb.S 2014-05-05 11:50:05.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/kernel/ktlb.S 2014-05-05 12:47:43.000000000 +0000 +@@ -25,11 +25,10 @@ + */ + kvmap_itlb_4v: + +-kvmap_itlb_nonlinear: + /* Catch kernel NULL pointer calls. */ + sethi %hi(PAGE_SIZE), %g5 + cmp %g4, %g5 +- bleu,pn %xcc, kvmap_dtlb_longpath ++ blu,pn %xcc, kvmap_itlb_longpath + nop + + KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_itlb_load) +Index: linux-3.10-3.10.11/dummy/rpi_1328_84c041cc9b2eb6305732e32f283d9fac2b0e8b6a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1328_84c041cc9b2eb6305732e32f283d9fac2b0e8b6a.txt 2014-05-05 12:47:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1329_32f0ba8e21166ec3ac11d692852d6d3e768942a4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1329_32f0ba8e21166ec3ac11d692852d6d3e768942a4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1329_32f0ba8e21166ec3ac11d692852d6d3e768942a4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1329_32f0ba8e21166ec3ac11d692852d6d3e768942a4.patch 2014-05-05 12:47:44.000000000 +0000 @@ -0,0 +1,52 @@ +commit 32f0ba8e21166ec3ac11d692852d6d3e768942a4 +Author: Kirill Tkhai +Date: Mon Aug 12 16:02:24 2013 +0400 + + sparc64: Remove RWSEM export leftovers + + [ Upstream commit 61d9b9355b0d427bd1e732bd54628ff9103e496f ] + + The functions + + __down_read + __down_read_trylock + __down_write + __down_write_trylock + __up_read + __up_write + __downgrade_write + + are implemented inline, so remove corresponding EXPORT_SYMBOLs + (They lead to compile errors on RT kernel). + + Signed-off-by: Kirill Tkhai + CC: David Miller + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/sparc/lib/ksyms.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/lib/ksyms.c 2014-05-05 11:50:05.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/lib/ksyms.c 2014-05-05 12:47:44.000000000 +0000 +@@ -98,15 +98,6 @@ + EXPORT_SYMBOL(___copy_in_user); + EXPORT_SYMBOL(__clear_user); + +-/* RW semaphores */ +-EXPORT_SYMBOL(__down_read); +-EXPORT_SYMBOL(__down_read_trylock); +-EXPORT_SYMBOL(__down_write); +-EXPORT_SYMBOL(__down_write_trylock); +-EXPORT_SYMBOL(__up_read); +-EXPORT_SYMBOL(__up_write); +-EXPORT_SYMBOL(__downgrade_write); +- + /* Atomic counter implementation. */ + EXPORT_SYMBOL(atomic_add); + EXPORT_SYMBOL(atomic_add_ret); +Index: linux-3.10-3.10.11/dummy/rpi_1329_32f0ba8e21166ec3ac11d692852d6d3e768942a4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1329_32f0ba8e21166ec3ac11d692852d6d3e768942a4.txt 2014-05-05 12:47:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1330_34b6bdb2a889231e450774b5227a80c2f5051bc0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1330_34b6bdb2a889231e450774b5227a80c2f5051bc0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1330_34b6bdb2a889231e450774b5227a80c2f5051bc0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1330_34b6bdb2a889231e450774b5227a80c2f5051bc0.patch 2014-05-05 12:47:45.000000000 +0000 @@ -0,0 +1,49 @@ +commit 34b6bdb2a889231e450774b5227a80c2f5051bc0 +Author: David S. Miller +Date: Fri Sep 27 13:46:04 2013 -0700 + + sparc64: Fix buggy strlcpy() conversion in ldom_reboot(). + + [ Upstream commit 2bd161a605f1f84a5fc8a4fe8410113a94f79355 ] + + Commit 117a0c5fc9c2d06045bd217385b2b39ea426b5a6 ("sparc: kernel: using + strlcpy() instead of strcpy()") added a bug to ldom_reboot in + arch/sparc/kernel/ds.c + + - strcpy(full_boot_str + strlen("boot "), boot_command); + + strlcpy(full_boot_str + strlen("boot "), boot_command, + + sizeof(full_boot_str + strlen("boot "))); + + That last sizeof() expression evaluates to sizeof(size_t) which is + not what was intended. + + Also even the corrected: + + sizeof(full_boot_str) + strlen("boot ") + + is not right as the destination buffer length is just plain + "sizeof(full_boot_str)" and that's what the final argument + should be. + + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/sparc/kernel/ds.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/kernel/ds.c 2014-05-05 11:50:05.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/kernel/ds.c 2014-05-05 12:47:44.000000000 +0000 +@@ -844,7 +844,7 @@ + + strcpy(full_boot_str, "boot "); + strlcpy(full_boot_str + strlen("boot "), boot_command, +- sizeof(full_boot_str + strlen("boot "))); ++ sizeof(full_boot_str)); + len = strlen(full_boot_str); + + if (reboot_data_supported) { +Index: linux-3.10-3.10.11/dummy/rpi_1330_34b6bdb2a889231e450774b5227a80c2f5051bc0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1330_34b6bdb2a889231e450774b5227a80c2f5051bc0.txt 2014-05-05 12:47:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1331_5c19adb25bc8d618619c24c4500bbbbc06bdba0b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1331_5c19adb25bc8d618619c24c4500bbbbc06bdba0b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1331_5c19adb25bc8d618619c24c4500bbbbc06bdba0b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1331_5c19adb25bc8d618619c24c4500bbbbc06bdba0b.patch 2014-05-05 12:47:46.000000000 +0000 @@ -0,0 +1,38 @@ +commit 5c19adb25bc8d618619c24c4500bbbbc06bdba0b +Author: Kees Cook +Date: Tue Oct 1 22:13:34 2013 -0700 + + sparc: fix ldom_reboot buffer overflow harder + + [ Upstream commit 20928bd3f08afb036c096d9559d581926b895918 ] + + The length argument to strlcpy was still wrong. It could overflow the end of + full_boot_str by 5 bytes. Instead of strcat and strlcpy, just use snprint. + + Reported-by: Brad Spengler + Signed-off-by: Kees Cook + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/sparc/kernel/ds.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/kernel/ds.c 2014-05-05 12:47:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/kernel/ds.c 2014-05-05 12:47:45.000000000 +0000 +@@ -842,9 +842,8 @@ + if (boot_command && strlen(boot_command)) { + unsigned long len; + +- strcpy(full_boot_str, "boot "); +- strlcpy(full_boot_str + strlen("boot "), boot_command, +- sizeof(full_boot_str)); ++ snprintf(full_boot_str, sizeof(full_boot_str), "boot %s", ++ boot_command); + len = strlen(full_boot_str); + + if (reboot_data_supported) { +Index: linux-3.10-3.10.11/dummy/rpi_1331_5c19adb25bc8d618619c24c4500bbbbc06bdba0b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1331_5c19adb25bc8d618619c24c4500bbbbc06bdba0b.txt 2014-05-05 12:47:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1332_ad779b05b451bf64ca159290339fd770539b298d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1332_ad779b05b451bf64ca159290339fd770539b298d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1332_ad779b05b451bf64ca159290339fd770539b298d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1332_ad779b05b451bf64ca159290339fd770539b298d.patch 2014-05-05 12:47:47.000000000 +0000 @@ -0,0 +1,38 @@ +commit ad779b05b451bf64ca159290339fd770539b298d +Author: David S. Miller +Date: Thu Aug 22 16:38:46 2013 -0700 + + sparc64: Fix off by one in trampoline TLB mapping installation loop. + + [ Upstream commit 63d499662aeec1864ec36d042aca8184ea6a938e ] + + Reported-by: Kirill Tkhai + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/sparc/kernel/trampoline_64.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/kernel/trampoline_64.S 2014-05-05 11:50:04.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/kernel/trampoline_64.S 2014-05-05 12:47:46.000000000 +0000 +@@ -131,7 +131,6 @@ + clr %l5 + sethi %hi(num_kernel_image_mappings), %l6 + lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 +- add %l6, 1, %l6 + + mov 15, %l7 + BRANCH_IF_ANY_CHEETAH(g1,g5,2f) +@@ -224,7 +223,6 @@ + clr %l5 + sethi %hi(num_kernel_image_mappings), %l6 + lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 +- add %l6, 1, %l6 + + 1: + mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 +Index: linux-3.10-3.10.11/dummy/rpi_1332_ad779b05b451bf64ca159290339fd770539b298d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1332_ad779b05b451bf64ca159290339fd770539b298d.txt 2014-05-05 12:47:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1333_4026b686478d8a3de4a10fd870a17ed53a7a2fc6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1333_4026b686478d8a3de4a10fd870a17ed53a7a2fc6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1333_4026b686478d8a3de4a10fd870a17ed53a7a2fc6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1333_4026b686478d8a3de4a10fd870a17ed53a7a2fc6.patch 2014-05-05 12:47:47.000000000 +0000 @@ -0,0 +1,56 @@ +commit 4026b686478d8a3de4a10fd870a17ed53a7a2fc6 +Author: Kirill Tkhai +Date: Fri Jul 26 17:21:12 2013 +0400 + + sparc64: Fix not SRA'ed %o5 in 32-bit traced syscall + + [ Upstream commit ab2abda6377723e0d5fbbfe5f5aa16a5523344d1 ] + + (From v1 to v2: changed comment) + + On the way linux_sparc_syscall32->linux_syscall_trace32->goto 2f, + register %o5 doesn't clear its second 32-bit. + + Fix that. + + Signed-off-by: Kirill Tkhai + CC: David Miller + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/sparc/kernel/syscalls.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/kernel/syscalls.S 2014-05-05 11:50:04.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/kernel/syscalls.S 2014-05-05 12:47:47.000000000 +0000 +@@ -152,7 +152,7 @@ + srl %i4, 0, %o4 + srl %i1, 0, %o1 + srl %i2, 0, %o2 +- ba,pt %xcc, 2f ++ ba,pt %xcc, 5f + srl %i3, 0, %o3 + + linux_syscall_trace: +@@ -182,13 +182,13 @@ + srl %i1, 0, %o1 ! IEU0 Group + ldx [%g6 + TI_FLAGS], %l0 ! Load + +- srl %i5, 0, %o5 ! IEU1 ++ srl %i3, 0, %o3 ! IEU0 + srl %i2, 0, %o2 ! IEU0 Group + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + bne,pn %icc, linux_syscall_trace32 ! CTI + mov %i0, %l5 ! IEU1 +- call %l7 ! CTI Group brk forced +- srl %i3, 0, %o3 ! IEU0 ++5: call %l7 ! CTI Group brk forced ++ srl %i5, 0, %o5 ! IEU1 + ba,a,pt %xcc, 3f + + /* Linux native system calls enter here... */ +Index: linux-3.10-3.10.11/dummy/rpi_1333_4026b686478d8a3de4a10fd870a17ed53a7a2fc6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1333_4026b686478d8a3de4a10fd870a17ed53a7a2fc6.txt 2014-05-05 12:47:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1334_04e7d3c0bcd0905d6977b926fd378280c0645e09.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1334_04e7d3c0bcd0905d6977b926fd378280c0645e09.patch --- linux-3.10.11/debian/patches/rpi/rpi_1334_04e7d3c0bcd0905d6977b926fd378280c0645e09.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1334_04e7d3c0bcd0905d6977b926fd378280c0645e09.patch 2014-05-05 12:47:48.000000000 +0000 @@ -0,0 +1,34 @@ +commit 04e7d3c0bcd0905d6977b926fd378280c0645e09 +Author: Kirill Tkhai +Date: Fri Jul 26 01:17:15 2013 +0400 + + sparc32: Fix exit flag passed from traced sys_sigreturn + + [ Upstream commit 7a3b0f89e3fea680f93932691ca41a68eee7ab5e ] + + Pass 1 in %o1 to indicate that syscall_trace accounts exit. + + Signed-off-by: Kirill Tkhai + CC: David Miller + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/sparc/kernel/entry.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/kernel/entry.S 2014-05-05 11:50:04.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/kernel/entry.S 2014-05-05 12:47:48.000000000 +0000 +@@ -839,7 +839,7 @@ + nop + + call syscall_trace +- nop ++ mov 1, %o1 + + 1: + /* We don't want to muck with user registers like a +Index: linux-3.10-3.10.11/dummy/rpi_1334_04e7d3c0bcd0905d6977b926fd378280c0645e09.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1334_04e7d3c0bcd0905d6977b926fd378280c0645e09.txt 2014-05-05 12:47:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1335_4dc59be5037f059421e302890165d5ccf6a386ac.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1335_4dc59be5037f059421e302890165d5ccf6a386ac.patch --- linux-3.10.11/debian/patches/rpi/rpi_1335_4dc59be5037f059421e302890165d5ccf6a386ac.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1335_4dc59be5037f059421e302890165d5ccf6a386ac.patch 2014-05-05 12:47:49.000000000 +0000 @@ -0,0 +1,51 @@ +commit 4dc59be5037f059421e302890165d5ccf6a386ac +Author: David Miller +Date: Wed Oct 2 14:25:09 2013 -0400 + + mm: Fix generic hugetlb pte check return type. + + [ Upstream commit 26794942461f438a6bc725ec7294b08a6bd782c4 ] + + The include/asm-generic/hugetlb.h stubs that just vector huge_pte_*() + calls to the pte_*() implementations won't work in certain situations. + + x86 and sparc, for example, return "unsigned long" from the bit + checks, and just go "return pte_val(pte) & PTE_BIT_FOO;" + + But since huge_pte_*() returns 'int', if any high bits on 64-bit are + relevant, they get chopped off. + + The net effect is that we can loop forever trying to COW a huge page, + because the huge_pte_write() check signals false all the time. + + Reported-by: Gurudas Pai + Tested-by: Gurudas Pai + Signed-off-by: David S. Miller + Acked-by: David Rientjes + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/asm-generic/hugetlb.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/asm-generic/hugetlb.h 2014-05-05 11:50:03.000000000 +0000 ++++ linux-3.10-3.10.11/include/asm-generic/hugetlb.h 2014-05-05 12:47:49.000000000 +0000 +@@ -6,12 +6,12 @@ + return mk_pte(page, pgprot); + } + +-static inline int huge_pte_write(pte_t pte) ++static inline unsigned long huge_pte_write(pte_t pte) + { + return pte_write(pte); + } + +-static inline int huge_pte_dirty(pte_t pte) ++static inline unsigned long huge_pte_dirty(pte_t pte) + { + return pte_dirty(pte); + } +Index: linux-3.10-3.10.11/dummy/rpi_1335_4dc59be5037f059421e302890165d5ccf6a386ac.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1335_4dc59be5037f059421e302890165d5ccf6a386ac.txt 2014-05-05 12:47:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1336_a1cccf25241ba0f2f373f6c94bf8ff9a747ae305.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1336_a1cccf25241ba0f2f373f6c94bf8ff9a747ae305.patch --- linux-3.10.11/debian/patches/rpi/rpi_1336_a1cccf25241ba0f2f373f6c94bf8ff9a747ae305.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1336_a1cccf25241ba0f2f373f6c94bf8ff9a747ae305.patch 2014-05-05 12:47:50.000000000 +0000 @@ -0,0 +1,42 @@ +commit a1cccf25241ba0f2f373f6c94bf8ff9a747ae305 +Author: Darrick J. Wong +Date: Mon Sep 30 13:45:09 2013 -0700 + + mm/bounce.c: fix a regression where MS_SNAP_STABLE (stable pages snapshotting) was ignored + + commit 83b2944fd2532b92db099cb3ada12df32a05b368 upstream. + + The "force" parameter in __blk_queue_bounce was being ignored, which + means that stable page snapshots are not always happening (on ext3). + This of course leads to DIF disks reporting checksum errors, so fix this + regression. + + The regression was introduced in commit 6bc454d15004 ("bounce: Refactor + __blk_queue_bounce to not use bi_io_vec") + + Reported-by: Mel Gorman + Signed-off-by: Darrick J. Wong + Cc: Kent Overstreet + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/bounce.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/bounce.c 2014-05-05 11:50:03.000000000 +0000 ++++ linux-3.10-3.10.11/mm/bounce.c 2014-05-05 12:47:49.000000000 +0000 +@@ -204,6 +204,8 @@ + struct bio_vec *to, *from; + unsigned i; + ++ if (force) ++ goto bounce; + bio_for_each_segment(from, *bio_orig, i) + if (page_to_pfn(from->bv_page) > queue_bounce_pfn(q)) + goto bounce; +Index: linux-3.10-3.10.11/dummy/rpi_1336_a1cccf25241ba0f2f373f6c94bf8ff9a747ae305.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1336_a1cccf25241ba0f2f373f6c94bf8ff9a747ae305.txt 2014-05-05 12:47:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1337_96baebd41aab7e82b6d6083d8f31c482dd5a576e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1337_96baebd41aab7e82b6d6083d8f31c482dd5a576e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1337_96baebd41aab7e82b6d6083d8f31c482dd5a576e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1337_96baebd41aab7e82b6d6083d8f31c482dd5a576e.patch 2014-05-05 12:47:51.000000000 +0000 @@ -0,0 +1,80 @@ +commit 96baebd41aab7e82b6d6083d8f31c482dd5a576e +Author: Ian Abbott +Date: Wed Oct 2 14:57:51 2013 +0100 + + staging: comedi: ni_65xx: (bug fix) confine insn_bits to one subdevice + + commit 677a31565692d596ef42ea589b53ba289abf4713 upstream. + + The `insn_bits` handler `ni_65xx_dio_insn_bits()` has a `for` loop that + currently writes (optionally) and reads back up to 5 "ports" consisting + of 8 channels each. It reads up to 32 1-bit channels but can only read + and write a whole port at once - it needs to handle up to 5 ports as the + first channel it reads might not be aligned on a port boundary. It + breaks out of the loop early if the next port it handles is beyond the + final port on the card. It also breaks out early on the 5th port in the + loop if the first channel was aligned. Unfortunately, it doesn't check + that the current port it is dealing with belongs to the comedi subdevice + the `insn_bits` handler is acting on. That's a bug. + + Redo the `for` loop to terminate after the final port belonging to the + subdevice, changing the loop variable in the process to simplify things + a bit. The `for` loop could now try and handle more than 5 ports if the + subdevice has more than 40 channels, but the test `if (bitshift >= 32)` + ensures it will break out early after 4 or 5 ports (depending on whether + the first channel is aligned on a port boundary). (`bitshift` will be + between -7 and 7 inclusive on the first iteration, increasing by 8 for + each subsequent operation.) + + Signed-off-by: Ian Abbott + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/comedi/drivers/ni_65xx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/comedi/drivers/ni_65xx.c 2014-05-05 11:50:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/comedi/drivers/ni_65xx.c 2014-05-05 12:47:50.000000000 +0000 +@@ -383,28 +383,23 @@ + { + const struct ni_65xx_board *board = comedi_board(dev); + struct ni_65xx_private *devpriv = dev->private; +- unsigned base_bitfield_channel; +- const unsigned max_ports_per_bitfield = 5; ++ int base_bitfield_channel; + unsigned read_bits = 0; +- unsigned j; ++ int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1); ++ int port_offset; + + base_bitfield_channel = CR_CHAN(insn->chanspec); +- for (j = 0; j < max_ports_per_bitfield; ++j) { +- const unsigned port_offset = +- ni_65xx_port_by_channel(base_bitfield_channel) + j; +- const unsigned port = +- sprivate(s)->base_port + port_offset; +- unsigned base_port_channel; ++ for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel); ++ port_offset <= last_port_offset; port_offset++) { ++ unsigned port = sprivate(s)->base_port + port_offset; ++ int base_port_channel = port_offset * ni_65xx_channels_per_port; + unsigned port_mask, port_data, port_read_bits; +- int bitshift; +- if (port >= ni_65xx_total_num_ports(board)) ++ int bitshift = base_port_channel - base_bitfield_channel; ++ ++ if (bitshift >= 32) + break; +- base_port_channel = port_offset * ni_65xx_channels_per_port; + port_mask = data[0]; + port_data = data[1]; +- bitshift = base_port_channel - base_bitfield_channel; +- if (bitshift >= 32 || bitshift <= -32) +- break; + if (bitshift > 0) { + port_mask >>= bitshift; + port_data >>= bitshift; +Index: linux-3.10-3.10.11/dummy/rpi_1337_96baebd41aab7e82b6d6083d8f31c482dd5a576e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1337_96baebd41aab7e82b6d6083d8f31c482dd5a576e.txt 2014-05-05 12:47:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1338_28f7ae257183e8064119db486190d2229caae369.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1338_28f7ae257183e8064119db486190d2229caae369.patch --- linux-3.10.11/debian/patches/rpi/rpi_1338_28f7ae257183e8064119db486190d2229caae369.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1338_28f7ae257183e8064119db486190d2229caae369.patch 2014-05-05 12:47:52.000000000 +0000 @@ -0,0 +1,70 @@ +commit 28f7ae257183e8064119db486190d2229caae369 +Author: Trond Myklebust +Date: Thu Sep 26 14:08:36 2013 -0400 + + NFSv4.1: nfs4_fl_prepare_ds - fix bugs when the connect attempt fails + + commit 52b26a3e1bb3e065c32b3febdac1e1f117d88e15 upstream. + + - Fix an Oops when nfs4_ds_connect() returns an error. + - Always check the device status after waiting for a connect to complete. + + Reported-by: Andy Adamson + Reported-by: Jeff Layton + Signed-off-by: Trond Myklebust + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/nfs/nfs4filelayoutdev.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/nfs/nfs4filelayoutdev.c 2014-05-05 11:50:03.000000000 +0000 ++++ linux-3.10-3.10.11/fs/nfs/nfs4filelayoutdev.c 2014-05-05 12:47:51.000000000 +0000 +@@ -797,34 +797,34 @@ + struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr; + struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx]; + struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); +- +- if (filelayout_test_devid_unavailable(devid)) +- return NULL; ++ struct nfs4_pnfs_ds *ret = ds; + + if (ds == NULL) { + printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", + __func__, ds_idx); + filelayout_mark_devid_invalid(devid); +- return NULL; ++ goto out; + } + if (ds->ds_clp) +- return ds; ++ goto out_test_devid; + + if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { + struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); + int err; + + err = nfs4_ds_connect(s, ds); +- if (err) { ++ if (err) + nfs4_mark_deviceid_unavailable(devid); +- ds = NULL; +- } + nfs4_clear_ds_conn_bit(ds); + } else { + /* Either ds is connected, or ds is NULL */ + nfs4_wait_ds_connect(ds); + } +- return ds; ++out_test_devid: ++ if (filelayout_test_devid_unavailable(devid)) ++ ret = NULL; ++out: ++ return ret; + } + + module_param(dataserver_retrans, uint, 0644); +Index: linux-3.10-3.10.11/dummy/rpi_1338_28f7ae257183e8064119db486190d2229caae369.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1338_28f7ae257183e8064119db486190d2229caae369.txt 2014-05-05 12:47:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1339_c7a448c3372a03c2a0848ed2c5c0ee76518a77b6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1339_c7a448c3372a03c2a0848ed2c5c0ee76518a77b6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1339_c7a448c3372a03c2a0848ed2c5c0ee76518a77b6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1339_c7a448c3372a03c2a0848ed2c5c0ee76518a77b6.patch 2014-05-05 12:47:52.000000000 +0000 @@ -0,0 +1,66 @@ +commit c7a448c3372a03c2a0848ed2c5c0ee76518a77b6 +Author: Bing Zhao +Date: Tue Sep 24 19:31:25 2013 -0700 + + mwifiex: fix NULL pointer dereference in usb suspend handler + + commit 346ece0b7ba2730b4d633b9e371fe55488803102 upstream. + + Bug 60815 - Interface hangs in mwifiex_usb + https://bugzilla.kernel.org/show_bug.cgi?id=60815 + + [ 2.883807] BUG: unable to handle kernel NULL pointer dereference + at 0000000000000048 + [ 2.883813] IP: [] pfifo_fast_enqueue+0x90/0x90 + + [ 2.883834] CPU: 1 PID: 3220 Comm: kworker/u8:90 Not tainted + 3.11.1-monotone-l0 #6 + [ 2.883834] Hardware name: Microsoft Corporation Surface with + Windows 8 Pro/Surface with Windows 8 Pro, + BIOS 1.03.0450 03/29/2013 + + On Surface Pro, suspend to ram gives a NULL pointer dereference in + pfifo_fast_enqueue(). The stack trace reveals that the offending + call is clearing carrier in mwifiex_usb suspend handler. + + Since commit 1499d9f "mwifiex: don't drop carrier flag over suspend" + has removed the carrier flag handling over suspend/resume in SDIO + and PCIe drivers, I'm removing it in USB driver too. This also fixes + the bug for Surface Pro. + + Tested-by: Dmitry Khromov + Signed-off-by: Bing Zhao + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/usb.c 2014-05-05 11:50:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/usb.c 2014-05-05 12:47:52.000000000 +0000 +@@ -446,9 +446,6 @@ + */ + adapter->is_suspended = true; + +- for (i = 0; i < adapter->priv_num; i++) +- netif_carrier_off(adapter->priv[i]->netdev); +- + if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) + usb_kill_urb(card->rx_cmd.urb); + +@@ -508,10 +505,6 @@ + MWIFIEX_RX_CMD_BUF_SIZE); + } + +- for (i = 0; i < adapter->priv_num; i++) +- if (adapter->priv[i]->media_connected) +- netif_carrier_on(adapter->priv[i]->netdev); +- + /* Disable Host Sleep */ + if (adapter->hs_activated) + mwifiex_cancel_hs(mwifiex_get_priv(adapter, +Index: linux-3.10-3.10.11/dummy/rpi_1339_c7a448c3372a03c2a0848ed2c5c0ee76518a77b6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1339_c7a448c3372a03c2a0848ed2c5c0ee76518a77b6.txt 2014-05-05 12:47:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1340_88fb132a74d2352bcabff8e6b1443210e9b99e9d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1340_88fb132a74d2352bcabff8e6b1443210e9b99e9d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1340_88fb132a74d2352bcabff8e6b1443210e9b99e9d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1340_88fb132a74d2352bcabff8e6b1443210e9b99e9d.patch 2014-05-05 12:47:53.000000000 +0000 @@ -0,0 +1,80 @@ +commit 88fb132a74d2352bcabff8e6b1443210e9b99e9d +Author: Amitkumar Karwar +Date: Tue Sep 24 19:31:24 2013 -0700 + + mwifiex: fix hang issue for USB chipsets + + commit bd1c6142edce787b8ac1be15635f845aa9905333 upstream. + + Bug 60815 - Interface hangs in mwifiex_usb + https://bugzilla.kernel.org/show_bug.cgi?id=60815 + + We have 4 bytes of interface header for packets delivered to SDIO + and PCIe, but not for USB interface. + + In Tx AMSDU case, currently 4 bytes of garbage data is unnecessarily + appended for USB packets. This sometimes leads to a firmware hang, + because it may not interpret the data packet correctly. + + Problem is fixed by removing this redundant headroom for USB. + + Tested-by: Dmitry Khromov + Signed-off-by: Amitkumar Karwar + Signed-off-by: Bing Zhao + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/11n_aggr.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/11n_aggr.c 2014-05-05 11:50:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/11n_aggr.c 2014-05-05 12:47:53.000000000 +0000 +@@ -149,7 +149,7 @@ + */ + int + mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, +- struct mwifiex_ra_list_tbl *pra_list, int headroom, ++ struct mwifiex_ra_list_tbl *pra_list, + int ptrindex, unsigned long ra_list_flags) + __releases(&priv->wmm.ra_list_spinlock) + { +@@ -159,6 +159,7 @@ + int pad = 0, ret; + struct mwifiex_tx_param tx_param; + struct txpd *ptx_pd = NULL; ++ int headroom = adapter->iface_type == MWIFIEX_USB ? 0 : INTF_HEADER_LEN; + + skb_src = skb_peek(&pra_list->skb_head); + if (!skb_src) { +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/11n_aggr.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/11n_aggr.h 2014-05-05 11:50:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/11n_aggr.h 2014-05-05 12:47:53.000000000 +0000 +@@ -26,7 +26,7 @@ + int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv, + struct sk_buff *skb); + int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, +- struct mwifiex_ra_list_tbl *ptr, int headroom, ++ struct mwifiex_ra_list_tbl *ptr, + int ptr_index, unsigned long flags) + __releases(&priv->wmm.ra_list_spinlock); + +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/wmm.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/wmm.c 2014-05-05 11:50:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/wmm.c 2014-05-05 12:47:53.000000000 +0000 +@@ -1236,8 +1236,7 @@ + if (mwifiex_is_amsdu_allowed(priv, tid) && + mwifiex_is_11n_aggragation_possible(priv, ptr, + adapter->tx_buf_size)) +- mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, +- ptr_index, flags); ++ mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); + /* ra_list_spinlock has been freed in + mwifiex_11n_aggregate_pkt() */ + else +Index: linux-3.10-3.10.11/dummy/rpi_1340_88fb132a74d2352bcabff8e6b1443210e9b99e9d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1340_88fb132a74d2352bcabff8e6b1443210e9b99e9d.txt 2014-05-05 12:47:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1341_e54fcd5bcf04a1623e0cd5bf1eff5948d5666990.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1341_e54fcd5bcf04a1623e0cd5bf1eff5948d5666990.patch --- linux-3.10.11/debian/patches/rpi/rpi_1341_e54fcd5bcf04a1623e0cd5bf1eff5948d5666990.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1341_e54fcd5bcf04a1623e0cd5bf1eff5948d5666990.patch 2014-05-05 12:47:54.000000000 +0000 @@ -0,0 +1,50 @@ +commit e54fcd5bcf04a1623e0cd5bf1eff5948d5666990 +Author: Bing Zhao +Date: Fri Sep 20 19:56:45 2013 -0700 + + mwifiex: fix PCIe hs_cfg cancel cmd timeout + + commit b7be1522def9a9988b67afd0be999c50a96394b5 upstream. + + For pcie8897, the hs_cfg cancel command (0xe5) times out when host + comes out of suspend. This is caused by an incompleted host sleep + handshake between driver and firmware. + + Like SDIO interface, PCIe also needs to go through firmware power + save events to complete the handshake for host sleep configuration. + Only USB interface doesn't require power save events for hs_cfg. + + Signed-off-by: Bing Zhao + Signed-off-by: Amitkumar Karwar + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/cmdevt.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/cmdevt.c 2014-05-05 11:50:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/cmdevt.c 2014-05-05 12:47:54.000000000 +0000 +@@ -1154,7 +1154,7 @@ + uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); + + if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) && +- adapter->iface_type == MWIFIEX_SDIO) { ++ adapter->iface_type != MWIFIEX_USB) { + mwifiex_hs_activated_event(priv, true); + return 0; + } else { +@@ -1166,8 +1166,7 @@ + } + if (conditions != HS_CFG_CANCEL) { + adapter->is_hs_configured = true; +- if (adapter->iface_type == MWIFIEX_USB || +- adapter->iface_type == MWIFIEX_PCIE) ++ if (adapter->iface_type == MWIFIEX_USB) + mwifiex_hs_activated_event(priv, true); + } else { + adapter->is_hs_configured = false; +Index: linux-3.10-3.10.11/dummy/rpi_1341_e54fcd5bcf04a1623e0cd5bf1eff5948d5666990.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1341_e54fcd5bcf04a1623e0cd5bf1eff5948d5666990.txt 2014-05-05 12:47:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1342_1b069646f53350d9c1188cef6d6bdd09a1df8b44.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1342_1b069646f53350d9c1188cef6d6bdd09a1df8b44.patch --- linux-3.10.11/debian/patches/rpi/rpi_1342_1b069646f53350d9c1188cef6d6bdd09a1df8b44.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1342_1b069646f53350d9c1188cef6d6bdd09a1df8b44.patch 2014-05-05 12:47:55.000000000 +0000 @@ -0,0 +1,48 @@ +commit 1b069646f53350d9c1188cef6d6bdd09a1df8b44 +Author: Michal Malý +Date: Sat Sep 28 19:50:27 2013 +0200 + + USB: serial: option: Ignore card reader interface on Huawei E1750 + + commit eb2addd4044b4b2ce77693bde5bc810536dd96ee upstream. + + Hi, + + my Huawei 3G modem has an embedded Smart Card reader which causes + trouble when the modem is being detected (a bunch of " (ttyUSBx): + open blocked by driver for more than 7 seconds!" in messages.log). This + trivial patch corrects the problem for me. The modem identifies itself + as "12d1:1406 Huawei Technologies Co., Ltd. E1750" in lsusb although the + description on the body says "Model E173u-1" + + Signed-off-by: Michal Malý + Cc: Bjørn Mork + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/option.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/option.c 2014-05-05 11:50:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/option.c 2014-05-05 12:47:54.000000000 +0000 +@@ -81,6 +81,7 @@ + + #define HUAWEI_VENDOR_ID 0x12D1 + #define HUAWEI_PRODUCT_E173 0x140C ++#define HUAWEI_PRODUCT_E1750 0x1406 + #define HUAWEI_PRODUCT_K4505 0x1464 + #define HUAWEI_PRODUCT_K3765 0x1465 + #define HUAWEI_PRODUCT_K4605 0x14C6 +@@ -567,6 +568,8 @@ + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), +Index: linux-3.10-3.10.11/dummy/rpi_1342_1b069646f53350d9c1188cef6d6bdd09a1df8b44.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1342_1b069646f53350d9c1188cef6d6bdd09a1df8b44.txt 2014-05-05 12:47:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1343_8598a32d43af4abe6f3a464af8be7fc020080cf3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1343_8598a32d43af4abe6f3a464af8be7fc020080cf3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1343_8598a32d43af4abe6f3a464af8be7fc020080cf3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1343_8598a32d43af4abe6f3a464af8be7fc020080cf3.patch 2014-05-05 12:47:56.000000000 +0000 @@ -0,0 +1,37 @@ +commit 8598a32d43af4abe6f3a464af8be7fc020080cf3 +Author: David Vrabel +Date: Tue Oct 1 19:00:49 2013 +0100 + + xen/hvc: allow xenboot console to be used again + + commit a9fbf4d591da6cd1d3eaab826c7c15f77fc8f6a3 upstream. + + Commit d0380e6c3c0f6edb986d8798a23acfaf33d5df23 (early_printk: + consolidate random copies of identical code) added in 3.10 introduced + a check for con->index == -1 in early_console_register(). + + Initialize index to -1 for the xenboot console so earlyprintk=xen + works again. + + Signed-off-by: David Vrabel + Cc: Jiri Slaby + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/tty/hvc/hvc_xen.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/hvc/hvc_xen.c 2014-05-05 11:50:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/hvc/hvc_xen.c 2014-05-05 12:47:55.000000000 +0000 +@@ -636,6 +636,7 @@ + .name = "xenboot", + .write = xenboot_write_console, + .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME, ++ .index = -1, + }; + #endif /* CONFIG_EARLY_PRINTK */ + +Index: linux-3.10-3.10.11/dummy/rpi_1343_8598a32d43af4abe6f3a464af8be7fc020080cf3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1343_8598a32d43af4abe6f3a464af8be7fc020080cf3.txt 2014-05-05 12:47:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1344_5b97382398dda31ca38a8c62880a21af03cf6f7f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1344_5b97382398dda31ca38a8c62880a21af03cf6f7f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1344_5b97382398dda31ca38a8c62880a21af03cf6f7f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1344_5b97382398dda31ca38a8c62880a21af03cf6f7f.patch 2014-05-05 12:47:57.000000000 +0000 @@ -0,0 +1,56 @@ +commit 5b97382398dda31ca38a8c62880a21af03cf6f7f +Author: Nicholas Bellinger +Date: Wed Sep 18 12:48:27 2013 -0700 + + ib_srpt: Destroy cm_id before destroying QP. + + commit 0b41d6ca616ddeb3b6c0a80e8770b6f53cd42806 upstream. + + This patch fixes a bug where ib_destroy_cm_id() was incorrectly being called + after srpt_destroy_ch_ib() had destroyed the active QP. + + This would result in the following failed SRP_LOGIN_REQ messages: + + Received SRP_LOGIN_REQ with i_port_id 0x0:0x2590ffff1762bd, t_port_id 0x2c903009f8f40:0x2c903009f8f40 and it_iu_len 260 on port 1 (guid=0xfe80000000000000:0x2c903009f8f41) + Received SRP_LOGIN_REQ with i_port_id 0x0:0x2590ffff1758f9, t_port_id 0x2c903009f8f40:0x2c903009f8f40 and it_iu_len 260 on port 2 (guid=0xfe80000000000000:0x2c903009f8f42) + Received SRP_LOGIN_REQ with i_port_id 0x0:0x2590ffff175941, t_port_id 0x2c903009f8f40:0x2c903009f8f40 and it_iu_len 260 on port 2 (guid=0xfe80000000000000:0x2c90300a3cfb2) + Received SRP_LOGIN_REQ with i_port_id 0x0:0x2590ffff176299, t_port_id 0x2c903009f8f40:0x2c903009f8f40 and it_iu_len 260 on port 1 (guid=0xfe80000000000000:0x2c90300a3cfb1) + mlx4_core 0000:84:00.0: command 0x19 failed: fw status = 0x9 + rejected SRP_LOGIN_REQ because creating a new RDMA channel failed. + Received SRP_LOGIN_REQ with i_port_id 0x0:0x2590ffff176299, t_port_id 0x2c903009f8f40:0x2c903009f8f40 and it_iu_len 260 on port 1 (guid=0xfe80000000000000:0x2c90300a3cfb1) + mlx4_core 0000:84:00.0: command 0x19 failed: fw status = 0x9 + rejected SRP_LOGIN_REQ because creating a new RDMA channel failed. + Received SRP_LOGIN_REQ with i_port_id 0x0:0x2590ffff176299, t_port_id 0x2c903009f8f40:0x2c903009f8f40 and it_iu_len 260 on port 1 (guid=0xfe80000000000000:0x2c90300a3cfb1) + + Reported-by: Navin Ahuja + Signed-off-by: Nicholas Bellinger + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/infiniband/ulp/srpt/ib_srpt.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/infiniband/ulp/srpt/ib_srpt.c 2014-05-05 11:50:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/infiniband/ulp/srpt/ib_srpt.c 2014-05-05 12:47:57.000000000 +0000 +@@ -2358,6 +2358,8 @@ + transport_deregister_session(se_sess); + ch->sess = NULL; + ++ ib_destroy_cm_id(ch->cm_id); ++ + srpt_destroy_ch_ib(ch); + + srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, +@@ -2368,8 +2370,6 @@ + list_del(&ch->list); + spin_unlock_irq(&sdev->spinlock); + +- ib_destroy_cm_id(ch->cm_id); +- + if (ch->release_done) + complete(ch->release_done); + +Index: linux-3.10-3.10.11/dummy/rpi_1344_5b97382398dda31ca38a8c62880a21af03cf6f7f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1344_5b97382398dda31ca38a8c62880a21af03cf6f7f.txt 2014-05-05 12:47:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1345_b07ce93054a72fe89b42096f7603afe3395a95ea.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1345_b07ce93054a72fe89b42096f7603afe3395a95ea.patch --- linux-3.10.11/debian/patches/rpi/rpi_1345_b07ce93054a72fe89b42096f7603afe3395a95ea.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1345_b07ce93054a72fe89b42096f7603afe3395a95ea.patch 2014-05-05 12:47:58.000000000 +0000 @@ -0,0 +1,56 @@ +commit b07ce93054a72fe89b42096f7603afe3395a95ea +Author: Jack Wang +Date: Mon Sep 30 10:09:05 2013 +0200 + + ib_srpt: always set response for task management + + commit c807f64340932e19f0d2ac9b30c8381e1f60663a upstream. + + The SRP specification requires: + + "Response data shall be provided in any SRP_RSP response that is sent in + response to an SRP_TSK_MGMT request (see 6.7). The information in the + RSP_CODE field (see table 24) shall indicate the completion status of + the task management function." + + So fix this to avoid the SRP initiator interprets task management functions + that succeeded as failed. + + Signed-off-by: Jack Wang + Signed-off-by: Nicholas Bellinger + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/infiniband/ulp/srpt/ib_srpt.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/infiniband/ulp/srpt/ib_srpt.c 2014-05-05 12:47:57.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/infiniband/ulp/srpt/ib_srpt.c 2014-05-05 12:47:57.000000000 +0000 +@@ -1588,7 +1588,7 @@ + int resp_data_len; + int resp_len; + +- resp_data_len = (rsp_code == SRP_TSK_MGMT_SUCCESS) ? 0 : 4; ++ resp_data_len = 4; + resp_len = sizeof(*srp_rsp) + resp_data_len; + + srp_rsp = ioctx->ioctx.buf; +@@ -1600,11 +1600,9 @@ + + atomic_xchg(&ch->req_lim_delta, 0)); + srp_rsp->tag = tag; + +- if (rsp_code != SRP_TSK_MGMT_SUCCESS) { +- srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; +- srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); +- srp_rsp->data[3] = rsp_code; +- } ++ srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; ++ srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); ++ srp_rsp->data[3] = rsp_code; + + return resp_len; + } +Index: linux-3.10-3.10.11/dummy/rpi_1345_b07ce93054a72fe89b42096f7603afe3395a95ea.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1345_b07ce93054a72fe89b42096f7603afe3395a95ea.txt 2014-05-05 12:47:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1346_c00095f3c4dcafb0031cbab8abb43787efa7ee64.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1346_c00095f3c4dcafb0031cbab8abb43787efa7ee64.patch --- linux-3.10.11/debian/patches/rpi/rpi_1346_c00095f3c4dcafb0031cbab8abb43787efa7ee64.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1346_c00095f3c4dcafb0031cbab8abb43787efa7ee64.patch 2014-05-05 12:47:59.000000000 +0000 @@ -0,0 +1,38 @@ +commit c00095f3c4dcafb0031cbab8abb43787efa7ee64 +Author: Larry Finger +Date: Wed Sep 18 21:21:35 2013 -0500 + + rtlwifi: Align private space in rtl_priv struct + + commit 60ce314d1750fef843e9db70050e09e49f838b69 upstream. + + The private array at the end of the rtl_priv struct is not aligned. + On ARM architecture, this causes an alignment trap and is fixed by aligning + that array with __align(sizeof(void *)). That should properly align that + space according to the requirements of all architectures. + + Reported-by: Jason Andrews + Tested-by: Jason Andrews + Signed-off-by: Larry Finger + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/wifi.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/rtlwifi/wifi.h 2014-05-05 11:50:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/wifi.h 2014-05-05 12:47:58.000000000 +0000 +@@ -2057,7 +2057,7 @@ + that it points to the data allocated + beyond this structure like: + rtl_pci_priv or rtl_usb_priv */ +- u8 priv[0]; ++ u8 priv[0] __aligned(sizeof(void *)); + }; + + #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) +Index: linux-3.10-3.10.11/dummy/rpi_1346_c00095f3c4dcafb0031cbab8abb43787efa7ee64.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1346_c00095f3c4dcafb0031cbab8abb43787efa7ee64.txt 2014-05-05 12:47:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1347_3e1972928dc7221bbf81c138667aa5d131623dce.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1347_3e1972928dc7221bbf81c138667aa5d131623dce.patch --- linux-3.10.11/debian/patches/rpi/rpi_1347_3e1972928dc7221bbf81c138667aa5d131623dce.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1347_3e1972928dc7221bbf81c138667aa5d131623dce.patch 2014-05-05 12:48:00.000000000 +0000 @@ -0,0 +1,33 @@ +commit 3e1972928dc7221bbf81c138667aa5d131623dce +Author: Christian Lamparter +Date: Tue Sep 24 21:56:46 2013 +0200 + + p54usb: add USB ID for Corega WLUSB2GTST USB adapter + + commit 1e43692cdb7cc445d6347d8a5207d9cef0c71434 upstream. + + Added USB ID for Corega WLUSB2GTST USB adapter. + + Reported-by: Joerg Kalisch + Signed-off-by: Christian Lamparter + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/p54/p54usb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/p54/p54usb.c 2014-05-05 12:41:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/p54/p54usb.c 2014-05-05 12:47:59.000000000 +0000 +@@ -83,6 +83,7 @@ + {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ + {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ ++ {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */ + {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ + {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ + {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ +Index: linux-3.10-3.10.11/dummy/rpi_1347_3e1972928dc7221bbf81c138667aa5d131623dce.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1347_3e1972928dc7221bbf81c138667aa5d131623dce.txt 2014-05-05 12:47:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1348_009dfd4415d898150824d352905fcb80ae1de16e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1348_009dfd4415d898150824d352905fcb80ae1de16e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1348_009dfd4415d898150824d352905fcb80ae1de16e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1348_009dfd4415d898150824d352905fcb80ae1de16e.patch 2014-05-05 12:48:01.000000000 +0000 @@ -0,0 +1,149 @@ +commit 009dfd4415d898150824d352905fcb80ae1de16e +Author: Rafael Aquini +Date: Mon Sep 30 13:45:16 2013 -0700 + + mm: avoid reinserting isolated balloon pages into LRU lists + + commit 117aad1e9e4d97448d1df3f84b08bd65811e6d6a upstream. + + Isolated balloon pages can wrongly end up in LRU lists when + migrate_pages() finishes its round without draining all the isolated + page list. + + The same issue can happen when reclaim_clean_pages_from_list() tries to + reclaim pages from an isolated page list, before migration, in the CMA + path. Such balloon page leak opens a race window against LRU lists + shrinkers that leads us to the following kernel panic: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 + IP: [] shrink_page_list+0x24e/0x897 + PGD 3cda2067 PUD 3d713067 PMD 0 + Oops: 0000 [#1] SMP + CPU: 0 PID: 340 Comm: kswapd0 Not tainted 3.12.0-rc1-22626-g4367597 #87 + Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 + RIP: shrink_page_list+0x24e/0x897 + RSP: 0000:ffff88003da499b8 EFLAGS: 00010286 + RAX: 0000000000000000 RBX: ffff88003e82bd60 RCX: 00000000000657d5 + RDX: 0000000000000000 RSI: 000000000000031f RDI: ffff88003e82bd40 + RBP: ffff88003da49ab0 R08: 0000000000000001 R09: 0000000081121a45 + R10: ffffffff81121a45 R11: ffff88003c4a9a28 R12: ffff88003e82bd40 + R13: ffff88003da0e800 R14: 0000000000000001 R15: ffff88003da49d58 + FS: 0000000000000000(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00000000067d9000 CR3: 000000003ace5000 CR4: 00000000000407b0 + Call Trace: + shrink_inactive_list+0x240/0x3de + shrink_lruvec+0x3e0/0x566 + __shrink_zone+0x94/0x178 + shrink_zone+0x3a/0x82 + balance_pgdat+0x32a/0x4c2 + kswapd+0x2f0/0x372 + kthread+0xa2/0xaa + ret_from_fork+0x7c/0xb0 + Code: 80 7d 8f 01 48 83 95 68 ff ff ff 00 4c 89 e7 e8 5a 7b 00 00 48 85 c0 49 89 c5 75 08 80 7d 8f 00 74 3e eb 31 48 8b 80 18 01 00 00 <48> 8b 74 0d 48 8b 78 30 be 02 00 00 00 ff d2 eb + RIP [] shrink_page_list+0x24e/0x897 + RSP + CR2: 0000000000000028 + ---[ end trace 703d2451af6ffbfd ]--- + Kernel panic - not syncing: Fatal exception + + This patch fixes the issue, by assuring the proper tests are made at + putback_movable_pages() & reclaim_clean_pages_from_list() to avoid + isolated balloon pages being wrongly reinserted in LRU lists. + + [akpm@linux-foundation.org: clarify awkward comment text] + Signed-off-by: Rafael Aquini + Reported-by: Luiz Capitulino + Tested-by: Luiz Capitulino + Cc: Mel Gorman + Cc: Rik van Riel + Cc: Hugh Dickins + Cc: Johannes Weiner + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/balloon_compaction.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/balloon_compaction.h 2014-05-05 11:49:59.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/balloon_compaction.h 2014-05-05 12:48:00.000000000 +0000 +@@ -159,6 +159,26 @@ + } + + /* ++ * isolated_balloon_page - identify an isolated balloon page on private ++ * compaction/migration page lists. ++ * ++ * After a compaction thread isolates a balloon page for migration, it raises ++ * the page refcount to prevent concurrent compaction threads from re-isolating ++ * the same page. For that reason putback_movable_pages(), or other routines ++ * that need to identify isolated balloon pages on private pagelists, cannot ++ * rely on balloon_page_movable() to accomplish the task. ++ */ ++static inline bool isolated_balloon_page(struct page *page) ++{ ++ /* Already isolated balloon pages, by default, have a raised refcount */ ++ if (page_flags_cleared(page) && !page_mapped(page) && ++ page_count(page) >= 2) ++ return __is_movable_balloon_page(page); ++ ++ return false; ++} ++ ++/* + * balloon_page_insert - insert a page into the balloon's page list and make + * the page->mapping assignment accordingly. + * @page : page to be assigned as a 'balloon page' +@@ -242,6 +262,11 @@ + { + return false; + } ++ ++static inline bool isolated_balloon_page(struct page *page) ++{ ++ return false; ++} + + static inline bool balloon_page_isolate(struct page *page) + { +Index: linux-3.10-3.10.11/mm/migrate.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/migrate.c 2014-05-05 11:49:59.000000000 +0000 ++++ linux-3.10-3.10.11/mm/migrate.c 2014-05-05 12:48:00.000000000 +0000 +@@ -103,7 +103,7 @@ + list_del(&page->lru); + dec_zone_page_state(page, NR_ISOLATED_ANON + + page_is_file_cache(page)); +- if (unlikely(balloon_page_movable(page))) ++ if (unlikely(isolated_balloon_page(page))) + balloon_page_putback(page); + else + putback_lru_page(page); +Index: linux-3.10-3.10.11/mm/vmscan.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/vmscan.c 2014-05-05 11:49:59.000000000 +0000 ++++ linux-3.10-3.10.11/mm/vmscan.c 2014-05-05 12:48:00.000000000 +0000 +@@ -48,6 +48,7 @@ + #include + + #include ++#include + + #include "internal.h" + +@@ -978,7 +979,8 @@ + LIST_HEAD(clean_pages); + + list_for_each_entry_safe(page, next, page_list, lru) { +- if (page_is_file_cache(page) && !PageDirty(page)) { ++ if (page_is_file_cache(page) && !PageDirty(page) && ++ !isolated_balloon_page(page)) { + ClearPageActive(page); + list_move(&page->lru, &clean_pages); + } +Index: linux-3.10-3.10.11/dummy/rpi_1348_009dfd4415d898150824d352905fcb80ae1de16e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1348_009dfd4415d898150824d352905fcb80ae1de16e.txt 2014-05-05 12:48:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1349_a0348152bd365caadc105f11da03fc020bcc6226.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1349_a0348152bd365caadc105f11da03fc020bcc6226.patch --- linux-3.10.11/debian/patches/rpi/rpi_1349_a0348152bd365caadc105f11da03fc020bcc6226.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1349_a0348152bd365caadc105f11da03fc020bcc6226.patch 2014-05-05 12:48:01.000000000 +0000 @@ -0,0 +1,46 @@ +commit a0348152bd365caadc105f11da03fc020bcc6226 +Author: Nicholas Bellinger +Date: Thu Oct 3 13:37:21 2013 -0700 + + iscsi-target: Only perform wait_for_tasks when performing shutdown + + commit e255a28598e8e63070322fc89bd34189dd660a89 upstream. + + This patch changes transport_generic_free_cmd() to only wait_for_tasks + when shutdown=true is passed to iscsit_free_cmd(). + + With the advent of >= v3.10 iscsi-target code using se_cmd->cmd_kref, + the extra wait_for_tasks with shutdown=false is unnecessary, and may + end up causing an extra context switch when releasing WRITEs. + + Signed-off-by: Nicholas Bellinger + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/target/iscsi/iscsi_target_util.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/target/iscsi/iscsi_target_util.c 2014-05-05 11:49:58.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/target/iscsi/iscsi_target_util.c 2014-05-05 12:48:01.000000000 +0000 +@@ -734,7 +734,7 @@ + * Fallthrough + */ + case ISCSI_OP_SCSI_TMFUNC: +- rc = transport_generic_free_cmd(&cmd->se_cmd, 1); ++ rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); + if (!rc && shutdown && se_cmd && se_cmd->se_sess) { + __iscsit_free_cmd(cmd, true, shutdown); + target_put_sess_cmd(se_cmd->se_sess, se_cmd); +@@ -750,7 +750,7 @@ + se_cmd = &cmd->se_cmd; + __iscsit_free_cmd(cmd, true, shutdown); + +- rc = transport_generic_free_cmd(&cmd->se_cmd, 1); ++ rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); + if (!rc && shutdown && se_cmd->se_sess) { + __iscsit_free_cmd(cmd, true, shutdown); + target_put_sess_cmd(se_cmd->se_sess, se_cmd); +Index: linux-3.10-3.10.11/dummy/rpi_1349_a0348152bd365caadc105f11da03fc020bcc6226.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1349_a0348152bd365caadc105f11da03fc020bcc6226.txt 2014-05-05 12:48:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1350_acbf720a11a80b0d284f6654bb2acc7404536037.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1350_acbf720a11a80b0d284f6654bb2acc7404536037.patch --- linux-3.10.11/debian/patches/rpi/rpi_1350_acbf720a11a80b0d284f6654bb2acc7404536037.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1350_acbf720a11a80b0d284f6654bb2acc7404536037.patch 2014-05-05 12:48:02.000000000 +0000 @@ -0,0 +1,42 @@ +commit acbf720a11a80b0d284f6654bb2acc7404536037 +Author: Eric W. Biederman +Date: Sat Oct 5 13:15:30 2013 -0700 + + net: Update the sysctl permissions handler to test effective uid/gid + + commit 2433c8f094a008895e66f25bd1773cdb01c91d01 upstream. + + Modify the code to use current_euid(), and in_egroup_p, as in done + in fs/proc/proc_sysctl.c:test_perm() + + Reviewed-by: Eric Sandeen + Reported-by: Eric Sandeen + Signed-off-by: "Eric W. Biederman" + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sysctl_net.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sysctl_net.c 2014-05-05 11:49:58.000000000 +0000 ++++ linux-3.10-3.10.11/net/sysctl_net.c 2014-05-05 12:48:02.000000000 +0000 +@@ -47,12 +47,12 @@ + + /* Allow network administrator to have same access as root. */ + if (ns_capable(net->user_ns, CAP_NET_ADMIN) || +- uid_eq(root_uid, current_uid())) { ++ uid_eq(root_uid, current_euid())) { + int mode = (table->mode >> 6) & 7; + return (mode << 6) | (mode << 3) | mode; + } + /* Allow netns root group to have the same access as the root group */ +- if (gid_eq(root_gid, current_gid())) { ++ if (in_egroup_p(root_gid)) { + int mode = (table->mode >> 3) & 7; + return (mode << 3) | mode; + } +Index: linux-3.10-3.10.11/dummy/rpi_1350_acbf720a11a80b0d284f6654bb2acc7404536037.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1350_acbf720a11a80b0d284f6654bb2acc7404536037.txt 2014-05-05 12:48:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1351_6dcdd5759f76c88ae86f9a98a232199520b6cc22.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1351_6dcdd5759f76c88ae86f9a98a232199520b6cc22.patch --- linux-3.10.11/debian/patches/rpi/rpi_1351_6dcdd5759f76c88ae86f9a98a232199520b6cc22.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1351_6dcdd5759f76c88ae86f9a98a232199520b6cc22.patch 2014-05-05 12:48:03.000000000 +0000 @@ -0,0 +1,157 @@ +commit 6dcdd5759f76c88ae86f9a98a232199520b6cc22 +Author: Frederic Weisbecker +Date: Tue Sep 24 00:50:25 2013 +0200 + + irq: Force hardirq exit's softirq processing on its own stack + + commit ded797547548a5b8e7b92383a41e4c0e6b0ecb7f upstream. + + The commit facd8b80c67a3cf64a467c4a2ac5fb31f2e6745b + ("irq: Sanitize invoke_softirq") converted irq exit + calls of do_softirq() to __do_softirq() on all architectures, + assuming it was only used there for its irq disablement + properties. + + But as a side effect, the softirqs processed in the end + of the hardirq are always called on the inline current + stack that is used by irq_exit() instead of the softirq + stack provided by the archs that override do_softirq(). + + The result is mostly safe if the architecture runs irq_exit() + on a separate irq stack because then softirqs are processed + on that same stack that is near empty at this stage (assuming + hardirq aren't nesting). + + Otherwise irq_exit() runs in the task stack and so does the softirq + too. The interrupted call stack can be randomly deep already and + the softirq can dig through it even further. To add insult to the + injury, this softirq can be interrupted by a new hardirq, maximizing + the chances for a stack overrun as reported in powerpc for example: + + do_IRQ: stack overflow: 1920 + CPU: 0 PID: 1602 Comm: qemu-system-ppc Not tainted 3.10.4-300.1.fc19.ppc64p7 #1 + Call Trace: + [c0000000050a8740] .show_stack+0x130/0x200 (unreliable) + [c0000000050a8810] .dump_stack+0x28/0x3c + [c0000000050a8880] .do_IRQ+0x2b8/0x2c0 + [c0000000050a8930] hardware_interrupt_common+0x154/0x180 + --- Exception: 501 at .cp_start_xmit+0x3a4/0x820 [8139cp] + LR = .cp_start_xmit+0x390/0x820 [8139cp] + [c0000000050a8d40] .dev_hard_start_xmit+0x394/0x640 + [c0000000050a8e00] .sch_direct_xmit+0x110/0x260 + [c0000000050a8ea0] .dev_queue_xmit+0x260/0x630 + [c0000000050a8f40] .br_dev_queue_push_xmit+0xc4/0x130 [bridge] + [c0000000050a8fc0] .br_dev_xmit+0x198/0x270 [bridge] + [c0000000050a9070] .dev_hard_start_xmit+0x394/0x640 + [c0000000050a9130] .dev_queue_xmit+0x428/0x630 + [c0000000050a91d0] .ip_finish_output+0x2a4/0x550 + [c0000000050a9290] .ip_local_out+0x50/0x70 + [c0000000050a9310] .ip_queue_xmit+0x148/0x420 + [c0000000050a93b0] .tcp_transmit_skb+0x4e4/0xaf0 + [c0000000050a94a0] .__tcp_ack_snd_check+0x7c/0xf0 + [c0000000050a9520] .tcp_rcv_established+0x1e8/0x930 + [c0000000050a95f0] .tcp_v4_do_rcv+0x21c/0x570 + [c0000000050a96c0] .tcp_v4_rcv+0x734/0x930 + [c0000000050a97a0] .ip_local_deliver_finish+0x184/0x360 + [c0000000050a9840] .ip_rcv_finish+0x148/0x400 + [c0000000050a98d0] .__netif_receive_skb_core+0x4f8/0xb00 + [c0000000050a99d0] .netif_receive_skb+0x44/0x110 + [c0000000050a9a70] .br_handle_frame_finish+0x2bc/0x3f0 [bridge] + [c0000000050a9b20] .br_nf_pre_routing_finish+0x2ac/0x420 [bridge] + [c0000000050a9bd0] .br_nf_pre_routing+0x4dc/0x7d0 [bridge] + [c0000000050a9c70] .nf_iterate+0x114/0x130 + [c0000000050a9d30] .nf_hook_slow+0xb4/0x1e0 + [c0000000050a9e00] .br_handle_frame+0x290/0x330 [bridge] + [c0000000050a9ea0] .__netif_receive_skb_core+0x34c/0xb00 + [c0000000050a9fa0] .netif_receive_skb+0x44/0x110 + [c0000000050aa040] .napi_gro_receive+0xe8/0x120 + [c0000000050aa0c0] .cp_rx_poll+0x31c/0x590 [8139cp] + [c0000000050aa1d0] .net_rx_action+0x1dc/0x310 + [c0000000050aa2b0] .__do_softirq+0x158/0x330 + [c0000000050aa3b0] .irq_exit+0xc8/0x110 + [c0000000050aa430] .do_IRQ+0xdc/0x2c0 + [c0000000050aa4e0] hardware_interrupt_common+0x154/0x180 + --- Exception: 501 at .bad_range+0x1c/0x110 + LR = .get_page_from_freelist+0x908/0xbb0 + [c0000000050aa7d0] .list_del+0x18/0x50 (unreliable) + [c0000000050aa850] .get_page_from_freelist+0x908/0xbb0 + [c0000000050aa9e0] .__alloc_pages_nodemask+0x21c/0xae0 + [c0000000050aaba0] .alloc_pages_vma+0xd0/0x210 + [c0000000050aac60] .handle_pte_fault+0x814/0xb70 + [c0000000050aad50] .__get_user_pages+0x1a4/0x640 + [c0000000050aae60] .get_user_pages_fast+0xec/0x160 + [c0000000050aaf10] .__gfn_to_pfn_memslot+0x3b0/0x430 [kvm] + [c0000000050aafd0] .kvmppc_gfn_to_pfn+0x64/0x130 [kvm] + [c0000000050ab070] .kvmppc_mmu_map_page+0x94/0x530 [kvm] + [c0000000050ab190] .kvmppc_handle_pagefault+0x174/0x610 [kvm] + [c0000000050ab270] .kvmppc_handle_exit_pr+0x464/0x9b0 [kvm] + [c0000000050ab320] kvm_start_lightweight+0x1ec/0x1fc [kvm] + [c0000000050ab4f0] .kvmppc_vcpu_run_pr+0x168/0x3b0 [kvm] + [c0000000050ab9c0] .kvmppc_vcpu_run+0xc8/0xf0 [kvm] + [c0000000050aba50] .kvm_arch_vcpu_ioctl_run+0x5c/0x1a0 [kvm] + [c0000000050abae0] .kvm_vcpu_ioctl+0x478/0x730 [kvm] + [c0000000050abc90] .do_vfs_ioctl+0x4ec/0x7c0 + [c0000000050abd80] .SyS_ioctl+0xd4/0xf0 + [c0000000050abe30] syscall_exit+0x0/0x98 + + Since this is a regression, this patch proposes a minimalistic + and low-risk solution by blindly forcing the hardirq exit processing of + softirqs on the softirq stack. This way we should reduce significantly + the opportunities for task stack overflow dug by softirqs. + + Longer term solutions may involve extending the hardirq stack coverage to + irq_exit(), etc... + + Reported-by: Benjamin Herrenschmidt + Acked-by: Linus Torvalds + Signed-off-by: Frederic Weisbecker + Cc: Benjamin Herrenschmidt + Cc: Paul Mackerras + Cc: Ingo Molnar + Cc: Thomas Gleixner + Cc: Peter Zijlstra + Cc: H. Peter Anvin + Cc: Linus Torvalds + Cc: Paul Mackerras + Cc: James Hogan + Cc: James E.J. Bottomley + Cc: Helge Deller + Cc: Martin Schwidefsky + Cc: Heiko Carstens + Cc: David S. Miller + Cc: Andrew Morton + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/softirq.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/softirq.c 2014-05-05 11:49:58.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/softirq.c 2014-05-05 12:48:03.000000000 +0000 +@@ -330,10 +330,19 @@ + + static inline void invoke_softirq(void) + { +- if (!force_irqthreads) +- __do_softirq(); +- else ++ if (!force_irqthreads) { ++ /* ++ * We can safely execute softirq on the current stack if ++ * it is the irq stack, because it should be near empty ++ * at this stage. But we have no way to know if the arch ++ * calls irq_exit() on the irq stack. So call softirq ++ * in its own stack to prevent from any overrun on top ++ * of a potentially deep task stack. ++ */ ++ do_softirq(); ++ } else { + wakeup_softirqd(); ++ } + } + + static inline void tick_irq_exit(void) +Index: linux-3.10-3.10.11/dummy/rpi_1351_6dcdd5759f76c88ae86f9a98a232199520b6cc22.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1351_6dcdd5759f76c88ae86f9a98a232199520b6cc22.txt 2014-05-05 12:48:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1352_04283173f26643e0075fbdf95780f548576e30a5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1352_04283173f26643e0075fbdf95780f548576e30a5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1352_04283173f26643e0075fbdf95780f548576e30a5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1352_04283173f26643e0075fbdf95780f548576e30a5.patch 2014-05-05 12:48:04.000000000 +0000 @@ -0,0 +1,40 @@ +commit 04283173f26643e0075fbdf95780f548576e30a5 +Author: Rafał Miłecki +Date: Thu Oct 10 07:56:07 2013 +0200 + + Revert "drm/radeon: add missing hdmi callbacks for rv6xx" + + This reverts commit b2a9484006875ecd7d94582e7bcb72a02682be92. + + Commit 99d79aa2f3b7729e7290e8bda5d0dd8b0240ec62 (backported by + b2a9484006875ecd7d94582e7bcb72a02682be92) was supposed to fix rv6xx_asic + struct. + + In kernel 3.10 we didn't have that struct yet, so the original patch + should never be backported to the 3.10. Accidentally it has applied and + modified different struct (r520_asic) that shouldn't have any HDMI + callbacks at all. + + Signed-off-by: Rafał Miłecki + Reviewed-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_asic.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_asic.c 2014-05-05 12:46:40.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_asic.c 2014-05-05 12:48:03.000000000 +0000 +@@ -892,8 +892,6 @@ + .wait_for_vblank = &avivo_wait_for_vblank, + .set_backlight_level = &atombios_set_backlight_level, + .get_backlight_level = &atombios_get_backlight_level, +- .hdmi_enable = &r600_hdmi_enable, +- .hdmi_setmode = &r600_hdmi_setmode, + }, + .copy = { + .blit = &r100_copy_blit, +Index: linux-3.10-3.10.11/dummy/rpi_1352_04283173f26643e0075fbdf95780f548576e30a5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1352_04283173f26643e0075fbdf95780f548576e30a5.txt 2014-05-05 12:48:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1353_16c72f379e4fdc8b0438f729ecd261428fff4c21.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1353_16c72f379e4fdc8b0438f729ecd261428fff4c21.patch --- linux-3.10.11/debian/patches/rpi/rpi_1353_16c72f379e4fdc8b0438f729ecd261428fff4c21.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1353_16c72f379e4fdc8b0438f729ecd261428fff4c21.patch 2014-05-05 12:48:05.000000000 +0000 @@ -0,0 +1,188 @@ +commit 16c72f379e4fdc8b0438f729ecd261428fff4c21 +Author: Michael Grzeschik +Date: Tue Sep 17 15:56:07 2013 +0200 + + dmaengine: imx-dma: fix lockdep issue between irqhandler and tasklet + + commit 5a276fa6bdf82fd442046969603968c83626ce0b upstream. + + The tasklet and irqhandler are using spin_lock while other routines are + using spin_lock_irqsave/restore. This leads to lockdep issues as + described bellow. This patch is changing the code to use + spinlock_irq_save/restore in both code pathes. + + As imxdma_xfer_desc always gets called with spin_lock_irqsave lock held, + this patch also removes the spare call inside the routine to avoid + double locking. + + [ 403.358162] ================================= + [ 403.362549] [ INFO: inconsistent lock state ] + [ 403.366945] 3.10.0-20130823+ #904 Not tainted + [ 403.371331] --------------------------------- + [ 403.375721] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. + [ 403.381769] swapper/0 [HC0[0]:SC1[1]:HE1:SE0] takes: + [ 403.386762] (&(&imxdma->lock)->rlock){?.-...}, at: [] imxdma_tasklet+0x20/0x134 + [ 403.395201] {IN-HARDIRQ-W} state was registered at: + [ 403.400108] [] mark_lock+0x2a0/0x6b4 + [ 403.404798] [] __lock_acquire+0x650/0x1a64 + [ 403.410004] [] lock_acquire+0x94/0xa8 + [ 403.414773] [] _raw_spin_lock+0x54/0x8c + [ 403.419720] [] dma_irq_handler+0x78/0x254 + [ 403.424845] [] handle_irq_event_percpu+0x38/0x1b4 + [ 403.430670] [] handle_irq_event+0x44/0x64 + [ 403.435789] [] handle_level_irq+0xd8/0xf0 + [ 403.440903] [] generic_handle_irq+0x28/0x38 + [ 403.446194] [] handle_IRQ+0x68/0x8c + [ 403.450789] [] avic_handle_irq+0x3c/0x48 + [ 403.455811] [] __irq_svc+0x44/0x74 + [ 403.460314] [] cpu_startup_entry+0x88/0xf4 + [ 403.465525] [] rest_init+0xb8/0xe0 + [ 403.470045] [] start_kernel+0x28c/0x2d4 + [ 403.474986] [] 0xa0008040 + [ 403.478709] irq event stamp: 50854 + [ 403.482140] hardirqs last enabled at (50854): [] tasklet_action+0x38/0xdc + [ 403.489954] hardirqs last disabled at (50853): [] tasklet_action+0x20/0xdc + [ 403.497761] softirqs last enabled at (50850): [] _local_bh_enable+0x14/0x18 + [ 403.505741] softirqs last disabled at (50851): [] irq_exit+0x88/0xdc + [ 403.513026] + [ 403.513026] other info that might help us debug this: + [ 403.519593] Possible unsafe locking scenario: + [ 403.519593] + [ 403.525548] CPU0 + [ 403.528020] ---- + [ 403.530491] lock(&(&imxdma->lock)->rlock); + [ 403.534828] + [ 403.537474] lock(&(&imxdma->lock)->rlock); + [ 403.541983] + [ 403.541983] *** DEADLOCK *** + [ 403.541983] + [ 403.547951] no locks held by swapper/0. + [ 403.551813] + [ 403.551813] stack backtrace: + [ 403.556222] CPU: 0 PID: 0 Comm: swapper Not tainted 3.10.0-20130823+ #904 + [ 403.563039] Backtrace: + [ 403.565581] [] (dump_backtrace+0x0/0x10c) from [] (show_stack+0x18/0x1c) + [ 403.574054] r6:00000000 r5:c05c51d8 r4:c040bd58 r3:00200000 + [ 403.579872] [] (show_stack+0x0/0x1c) from [] (dump_stack+0x20/0x28) + [ 403.587955] [] (dump_stack+0x0/0x28) from [] (print_usage_bug.part.28+0x224/0x28c) + [ 403.597340] [] (print_usage_bug.part.28+0x0/0x28c) from [] (mark_lock+0x440/0x6b4) + [ 403.606682] r8:c004a41c r7:00000000 r6:c040bd58 r5:c040c040 r4:00000002 + [ 403.613566] [] (mark_lock+0x0/0x6b4) from [] (__lock_acquire+0x6cc/0x1a64) + [ 403.622244] [] (__lock_acquire+0x0/0x1a64) from [] (lock_acquire+0x94/0xa8) + [ 403.631010] [] (lock_acquire+0x0/0xa8) from [] (_raw_spin_lock+0x54/0x8c) + [ 403.639614] [] (_raw_spin_lock+0x0/0x8c) from [] (imxdma_tasklet+0x20/0x134) + [ 403.648434] r6:c3847010 r5:c040e890 r4:c38470d4 + [ 403.653194] [] (imxdma_tasklet+0x0/0x134) from [] (tasklet_action+0x8c/0xdc) + [ 403.662013] r8:c0599160 r7:00000000 r6:00000000 r5:c040e890 r4:c3847114 r3:c019d75c + [ 403.670042] [] (tasklet_action+0x0/0xdc) from [] (__do_softirq+0xe4/0x1f0) + [ 403.678687] r7:00000101 r6:c0402000 r5:c059919c r4:00000001 + [ 403.684498] [] (__do_softirq+0x0/0x1f0) from [] (irq_exit+0x88/0xdc) + [ 403.692652] [] (irq_exit+0x0/0xdc) from [] (handle_IRQ+0x6c/0x8c) + [ 403.700514] r4:00000030 r3:00000110 + [ 403.704192] [] (handle_IRQ+0x0/0x8c) from [] (avic_handle_irq+0x3c/0x48) + [ 403.712664] r5:c0403f28 r4:c0593ebc + [ 403.716343] [] (avic_handle_irq+0x0/0x48) from [] (__irq_svc+0x44/0x74) + [ 403.724733] Exception stack(0xc0403f28 to 0xc0403f70) + [ 403.729841] 3f20: 00000001 00000004 00000000 20000013 c0402000 c04104a8 + [ 403.738078] 3f40: 00000002 c0b69620 a0004000 41069264 a03fb5f4 c0403f7c c0403f40 c0403f70 + [ 403.746301] 3f60: c004b92c c0009e74 20000013 ffffffff + [ 403.751383] r6:ffffffff r5:20000013 r4:c0009e74 r3:c004b92c + [ 403.757210] [] (arch_cpu_idle+0x0/0x4c) from [] (cpu_startup_entry+0x88/0xf4) + [ 403.766161] [] (cpu_startup_entry+0x0/0xf4) from [] (rest_init+0xb8/0xe0) + [ 403.774753] [] (rest_init+0x0/0xe0) from [] (start_kernel+0x28c/0x2d4) + [ 403.783051] r6:c03fc484 r5:ffffffff r4:c040a0e0 + [ 403.787797] [] (start_kernel+0x0/0x2d4) from [] (0xa0008040) + + Signed-off-by: Michael Grzeschik + Signed-off-by: Vinod Koul + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/dma/imx-dma.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/dma/imx-dma.c 2014-05-05 11:49:58.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/dma/imx-dma.c 2014-05-05 12:48:04.000000000 +0000 +@@ -414,17 +414,18 @@ + struct imxdma_engine *imxdma = imxdmac->imxdma; + int chno = imxdmac->channel; + struct imxdma_desc *desc; ++ unsigned long flags; + +- spin_lock(&imxdma->lock); ++ spin_lock_irqsave(&imxdma->lock, flags); + if (list_empty(&imxdmac->ld_active)) { +- spin_unlock(&imxdma->lock); ++ spin_unlock_irqrestore(&imxdma->lock, flags); + goto out; + } + + desc = list_first_entry(&imxdmac->ld_active, + struct imxdma_desc, + node); +- spin_unlock(&imxdma->lock); ++ spin_unlock_irqrestore(&imxdma->lock, flags); + + if (desc->sg) { + u32 tmp; +@@ -496,7 +497,6 @@ + { + struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan); + struct imxdma_engine *imxdma = imxdmac->imxdma; +- unsigned long flags; + int slot = -1; + int i; + +@@ -504,7 +504,6 @@ + switch (d->type) { + case IMXDMA_DESC_INTERLEAVED: + /* Try to get a free 2D slot */ +- spin_lock_irqsave(&imxdma->lock, flags); + for (i = 0; i < IMX_DMA_2D_SLOTS; i++) { + if ((imxdma->slots_2d[i].count > 0) && + ((imxdma->slots_2d[i].xsr != d->x) || +@@ -514,10 +513,8 @@ + slot = i; + break; + } +- if (slot < 0) { +- spin_unlock_irqrestore(&imxdma->lock, flags); ++ if (slot < 0) + return -EBUSY; +- } + + imxdma->slots_2d[slot].xsr = d->x; + imxdma->slots_2d[slot].ysr = d->y; +@@ -526,7 +523,6 @@ + + imxdmac->slot_2d = slot; + imxdmac->enabled_2d = true; +- spin_unlock_irqrestore(&imxdma->lock, flags); + + if (slot == IMX_DMA_2D_SLOT_A) { + d->config_mem &= ~CCR_MSEL_B; +@@ -602,8 +598,9 @@ + struct imxdma_channel *imxdmac = (void *)data; + struct imxdma_engine *imxdma = imxdmac->imxdma; + struct imxdma_desc *desc; ++ unsigned long flags; + +- spin_lock(&imxdma->lock); ++ spin_lock_irqsave(&imxdma->lock, flags); + + if (list_empty(&imxdmac->ld_active)) { + /* Someone might have called terminate all */ +@@ -640,7 +637,7 @@ + __func__, imxdmac->channel); + } + out: +- spin_unlock(&imxdma->lock); ++ spin_unlock_irqrestore(&imxdma->lock, flags); + } + + static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, +Index: linux-3.10-3.10.11/dummy/rpi_1353_16c72f379e4fdc8b0438f729ecd261428fff4c21.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1353_16c72f379e4fdc8b0438f729ecd261428fff4c21.txt 2014-05-05 12:48:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1354_8dac1d15489d284a4ffadaef25650272c4b44bfe.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1354_8dac1d15489d284a4ffadaef25650272c4b44bfe.patch --- linux-3.10.11/debian/patches/rpi/rpi_1354_8dac1d15489d284a4ffadaef25650272c4b44bfe.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1354_8dac1d15489d284a4ffadaef25650272c4b44bfe.patch 2014-05-05 12:48:05.000000000 +0000 @@ -0,0 +1,55 @@ +commit 8dac1d15489d284a4ffadaef25650272c4b44bfe +Author: Michael Grzeschik +Date: Tue Sep 17 15:56:08 2013 +0200 + + dmaengine: imx-dma: fix callback path in tasklet + + commit fcaaba6c7136fe47e5a13352f99a64b019b6d2c5 upstream. + + We need to free the ld_active list head before jumping into the callback + routine. Otherwise the callback could run into issue_pending and change + our ld_active list head we just going to free. This will run the channel + list into an currupted and undefined state. + + Signed-off-by: Michael Grzeschik + Signed-off-by: Vinod Koul + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/dma/imx-dma.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/dma/imx-dma.c 2014-05-05 12:48:04.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/dma/imx-dma.c 2014-05-05 12:48:05.000000000 +0000 +@@ -604,13 +604,11 @@ + + if (list_empty(&imxdmac->ld_active)) { + /* Someone might have called terminate all */ +- goto out; ++ spin_unlock_irqrestore(&imxdma->lock, flags); ++ return; + } + desc = list_first_entry(&imxdmac->ld_active, struct imxdma_desc, node); + +- if (desc->desc.callback) +- desc->desc.callback(desc->desc.callback_param); +- + /* If we are dealing with a cyclic descriptor, keep it on ld_active + * and dont mark the descriptor as complete. + * Only in non-cyclic cases it would be marked as complete +@@ -638,6 +636,10 @@ + } + out: + spin_unlock_irqrestore(&imxdma->lock, flags); ++ ++ if (desc->desc.callback) ++ desc->desc.callback(desc->desc.callback_param); ++ + } + + static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, +Index: linux-3.10-3.10.11/dummy/rpi_1354_8dac1d15489d284a4ffadaef25650272c4b44bfe.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1354_8dac1d15489d284a4ffadaef25650272c4b44bfe.txt 2014-05-05 12:48:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1355_414224fc002fc88c1f79934c12756f40510ff710.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1355_414224fc002fc88c1f79934c12756f40510ff710.patch --- linux-3.10.11/debian/patches/rpi/rpi_1355_414224fc002fc88c1f79934c12756f40510ff710.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1355_414224fc002fc88c1f79934c12756f40510ff710.patch 2014-05-05 12:48:06.000000000 +0000 @@ -0,0 +1,73 @@ +commit 414224fc002fc88c1f79934c12756f40510ff710 +Author: Michael Grzeschik +Date: Tue Sep 17 15:56:06 2013 +0200 + + dmaengine: imx-dma: fix slow path issue in prep_dma_cyclic + + commit edc530fe7ee5a562680615d2e7cd205879c751a7 upstream. + + When perparing cyclic_dma buffers by the sound layer, it will dump the + following lockdep trace. The leading snd_pcm_action_single get called + with read_lock_irq called. To fix this, we change the kcalloc call from + GFP_KERNEL to GFP_ATOMIC. + + WARNING: at kernel/lockdep.c:2740 lockdep_trace_alloc+0xcc/0x114() + DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags)) + Modules linked in: + CPU: 0 PID: 832 Comm: aplay Not tainted 3.11.0-20130823+ #903 + Backtrace: + [] (dump_backtrace+0x0/0x10c) from [] (show_stack+0x18/0x1c) + r6:c004c090 r5:00000009 r4:c2e0bd18 r3:00404000 + [] (show_stack+0x0/0x1c) from [] (dump_stack+0x20/0x28) + [] (dump_stack+0x0/0x28) from [] (warn_slowpath_common+0x54/0x70) + [] (warn_slowpath_common+0x0/0x70) from [] (warn_slowpath_fmt+0x38/0x40) + r8:00004000 r7:a3b90000 r6:000080d0 r5:60000093 r4:c2e0a000 r3:00000009 + [] (warn_slowpath_fmt+0x0/0x40) from [] (lockdep_trace_alloc+0xcc/0x114) + r3:c03955d8 r2:c03907db + [] (lockdep_trace_alloc+0x0/0x114) from [] (__kmalloc+0x34/0x118) + r6:000080d0 r5:c3800120 r4:000080d0 r3:c040a0f8 + [] (__kmalloc+0x0/0x118) from [] (imxdma_prep_dma_cyclic+0x64/0x168) + r7:a3b90000 r6:00000004 r5:c39d8420 r4:c3847150 + [] (imxdma_prep_dma_cyclic+0x0/0x168) from [] (snd_dmaengine_pcm_trigger+0xa8/0x160) + [] (snd_dmaengine_pcm_trigger+0x0/0x160) from [] (soc_pcm_trigger+0x90/0xb4) + r8:c058c7b0 r7:c3b8140c r6:c39da560 r5:00000001 r4:c3b81000 + [] (soc_pcm_trigger+0x0/0xb4) from [] (snd_pcm_do_start+0x2c/0x38) + r7:00000000 r6:00000003 r5:c058c7b0 r4:c3b81000 + [] (snd_pcm_do_start+0x0/0x38) from [] (snd_pcm_action_single+0x40/0x6c) + [] (snd_pcm_action_single+0x0/0x6c) from [] (snd_pcm_action_lock_irq+0x7c/0x9c) + r7:00000003 r6:c3b810f0 r5:c3b810f0 r4:c3b81000 + [] (snd_pcm_action_lock_irq+0x0/0x9c) from [] (snd_pcm_common_ioctl1+0x7f8/0xfd0) + r8:c3b7f888 r7:005407b8 r6:c2c991c0 r5:c3b81000 r4:c3b81000 r3:00004142 + [] (snd_pcm_common_ioctl1+0x0/0xfd0) from [] (snd_pcm_playback_ioctl1+0x464/0x488) + [] (snd_pcm_playback_ioctl1+0x0/0x488) from [] (snd_pcm_playback_ioctl+0x34/0x40) + r8:c3b7f888 r7:00004142 r6:00000004 r5:c2c991c0 r4:005407b8 + [] (snd_pcm_playback_ioctl+0x0/0x40) from [] (vfs_ioctl+0x30/0x44) + [] (vfs_ioctl+0x0/0x44) from [] (do_vfs_ioctl+0x55c/0x5c0) + [] (do_vfs_ioctl+0x0/0x5c0) from [] (SyS_ioctl+0x40/0x68) + [] (SyS_ioctl+0x0/0x68) from [] (ret_fast_syscall+0x0/0x44) + r8:c0009544 r7:00000036 r6:bedeaa58 r5:00000000 r4:000000c0 + + Signed-off-by: Michael Grzeschik + Signed-off-by: Vinod Koul + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/dma/imx-dma.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/dma/imx-dma.c 2014-05-05 12:48:05.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/dma/imx-dma.c 2014-05-05 12:48:06.000000000 +0000 +@@ -861,7 +861,7 @@ + kfree(imxdmac->sg_list); + + imxdmac->sg_list = kcalloc(periods + 1, +- sizeof(struct scatterlist), GFP_KERNEL); ++ sizeof(struct scatterlist), GFP_ATOMIC); + if (!imxdmac->sg_list) + return NULL; + +Index: linux-3.10-3.10.11/dummy/rpi_1355_414224fc002fc88c1f79934c12756f40510ff710.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1355_414224fc002fc88c1f79934c12756f40510ff710.txt 2014-05-05 12:48:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1356_2af8997a301609e2664c3c619865c6e1e518257d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1356_2af8997a301609e2664c3c619865c6e1e518257d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1356_2af8997a301609e2664c3c619865c6e1e518257d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1356_2af8997a301609e2664c3c619865c6e1e518257d.patch 2014-05-05 12:48:07.000000000 +0000 @@ -0,0 +1,184 @@ +commit 2af8997a301609e2664c3c619865c6e1e518257d +Author: Lv Zheng +Date: Fri Sep 13 13:13:23 2013 +0800 + + ACPI / IPMI: Fix atomic context requirement of ipmi_msg_handler() + + commit 06a8566bcf5cf7db9843a82cde7a33c7bf3947d9 upstream. + + This patch fixes the issues indicated by the test results that + ipmi_msg_handler() is invoked in atomic context. + + BUG: scheduling while atomic: kipmi0/18933/0x10000100 + Modules linked in: ipmi_si acpi_ipmi ... + CPU: 3 PID: 18933 Comm: kipmi0 Tainted: G AW 3.10.0-rc7+ #2 + Hardware name: QCI QSSC-S4R/QSSC-S4R, BIOS QSSC-S4R.QCI.01.00.0027.070120100606 07/01/2010 + ffff8838245eea00 ffff88103fc63c98 ffffffff814c4a1e ffff88103fc63ca8 + ffffffff814bfbab ffff88103fc63d28 ffffffff814c73e0 ffff88103933cbd4 + 0000000000000096 ffff88103fc63ce8 ffff88102f618000 ffff881035c01fd8 + Call Trace: + [] dump_stack+0x19/0x1b + [] __schedule_bug+0x46/0x54 + [] __schedule+0x83/0x59c + [] __cond_resched+0x22/0x2d + [] _cond_resched+0x14/0x1d + [] mutex_lock+0x11/0x32 + [] ? __default_send_IPI_dest_field.constprop.0+0x53/0x58 + [] ipmi_msg_handler+0x23/0x166 [ipmi_si] + [] deliver_response+0x55/0x5a + [] handle_new_recv_msgs+0xb67/0xc65 + [] ? read_tsc+0x9/0x19 + [] ? _raw_spin_lock_irq+0xa/0xc + [] ipmi_thread+0x5c/0x146 [ipmi_si] + ... + + Also Tony Camuso says: + + We were getting occasional "Scheduling while atomic" call traces + during boot on some systems. Problem was first seen on a Cisco C210 + but we were able to reproduce it on a Cisco c220m3. Setting + CONFIG_LOCKDEP and LOCKDEP_SUPPORT to 'y' exposed a lockdep around + tx_msg_lock in acpi_ipmi.c struct acpi_ipmi_device. + + ================================= + [ INFO: inconsistent lock state ] + 2.6.32-415.el6.x86_64-debug-splck #1 + --------------------------------- + inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. + ksoftirqd/3/17 [HC0[0]:SC1[1]:HE1:SE0] takes: + (&ipmi_device->tx_msg_lock){+.?...}, at: [] ipmi_msg_handler+0x71/0x126 + {SOFTIRQ-ON-W} state was registered at: + [] __lock_acquire+0x63c/0x1570 + [] lock_acquire+0xa4/0x120 + [] __mutex_lock_common+0x4c/0x400 + [] mutex_lock_nested+0x4a/0x60 + [] acpi_ipmi_space_handler+0x11b/0x234 + [] acpi_ev_address_space_dispatch+0x170/0x1be + + The fix implemented by this change has been tested by Tony: + + Tested the patch in a boot loop with lockdep debug enabled and never + saw the problem in over 400 reboots. + + Reported-and-tested-by: Tony Camuso + Signed-off-by: Lv Zheng + Reviewed-by: Huang Ying + Signed-off-by: Rafael J. Wysocki + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/acpi/acpi_ipmi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/acpi/acpi_ipmi.c 2014-05-05 11:49:57.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/acpi/acpi_ipmi.c 2014-05-05 12:48:07.000000000 +0000 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + MODULE_AUTHOR("Zhao Yakui"); + MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); +@@ -57,7 +58,7 @@ + struct list_head head; + /* the IPMI request message list */ + struct list_head tx_msg_list; +- struct mutex tx_msg_lock; ++ spinlock_t tx_msg_lock; + acpi_handle handle; + struct pnp_dev *pnp_dev; + ipmi_user_t user_interface; +@@ -147,6 +148,7 @@ + struct kernel_ipmi_msg *msg; + struct acpi_ipmi_buffer *buffer; + struct acpi_ipmi_device *device; ++ unsigned long flags; + + msg = &tx_msg->tx_message; + /* +@@ -177,10 +179,10 @@ + + /* Get the msgid */ + device = tx_msg->device; +- mutex_lock(&device->tx_msg_lock); ++ spin_lock_irqsave(&device->tx_msg_lock, flags); + device->curr_msgid++; + tx_msg->tx_msgid = device->curr_msgid; +- mutex_unlock(&device->tx_msg_lock); ++ spin_unlock_irqrestore(&device->tx_msg_lock, flags); + } + + static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, +@@ -242,6 +244,7 @@ + int msg_found = 0; + struct acpi_ipmi_msg *tx_msg; + struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; ++ unsigned long flags; + + if (msg->user != ipmi_device->user_interface) { + dev_warn(&pnp_dev->dev, "Unexpected response is returned. " +@@ -250,7 +253,7 @@ + ipmi_free_recv_msg(msg); + return; + } +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { + if (msg->msgid == tx_msg->tx_msgid) { + msg_found = 1; +@@ -258,7 +261,7 @@ + } + } + +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + if (!msg_found) { + dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " + "returned.\n", msg->msgid); +@@ -378,6 +381,7 @@ + struct acpi_ipmi_device *ipmi_device = handler_context; + int err, rem_time; + acpi_status status; ++ unsigned long flags; + /* + * IPMI opregion message. + * IPMI message is firstly written to the BMC and system software +@@ -395,9 +399,9 @@ + return AE_NO_MEMORY; + + acpi_format_ipmi_msg(tx_msg, address, value); +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + err = ipmi_request_settime(ipmi_device->user_interface, + &tx_msg->addr, + tx_msg->tx_msgid, +@@ -413,9 +417,9 @@ + status = AE_OK; + + end_label: +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_del(&tx_msg->head); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + kfree(tx_msg); + return status; + } +@@ -457,7 +461,7 @@ + + INIT_LIST_HEAD(&ipmi_device->head); + +- mutex_init(&ipmi_device->tx_msg_lock); ++ spin_lock_init(&ipmi_device->tx_msg_lock); + INIT_LIST_HEAD(&ipmi_device->tx_msg_list); + ipmi_install_space_handler(ipmi_device); + +Index: linux-3.10-3.10.11/dummy/rpi_1356_2af8997a301609e2664c3c619865c6e1e518257d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1356_2af8997a301609e2664c3c619865c6e1e518257d.txt 2014-05-05 12:48:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1357_1fe36ec4914c34f63ea93c87ce6997606098628d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1357_1fe36ec4914c34f63ea93c87ce6997606098628d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1357_1fe36ec4914c34f63ea93c87ce6997606098628d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1357_1fe36ec4914c34f63ea93c87ce6997606098628d.patch 2014-05-05 12:48:08.000000000 +0000 @@ -0,0 +1,65 @@ +commit 1fe36ec4914c34f63ea93c87ce6997606098628d +Author: Mark Tinguely +Date: Mon Sep 23 12:18:58 2013 -0500 + + xfs: fix node forward in xfs_node_toosmall + + commit 997def25e4b9cee3b01609e18a52f926bca8bd2b upstream. + + Commit f5ea1100 cleans up the disk to host conversions for + node directory entries, but because a variable is reused in + xfs_node_toosmall() the next node is not correctly found. + If the original node is small enough (<= 3/8 of the node size), + this change may incorrectly cause a node collapse when it should + not. That will cause an assert in xfstest generic/319: + + Assertion failed: first <= last && last < BBTOB(bp->b_length), + file: /root/newest/xfs/fs/xfs/xfs_trans_buf.c, line: 569 + + Keep the original node header to get the correct forward node. + + (When a node is considered for a merge with a sibling, it overwrites the + sibling pointers of the original incore nodehdr with the sibling's + pointers. This leads to loop considering the original node as a merge + candidate with itself in the second pass, and so it incorrectly + determines a merge should occur.) + + [v3: added Dave Chinner's (slightly modified) suggestion to the commit header, + cleaned up whitespace. -bpm] + + Signed-off-by: Mark Tinguely + Reviewed-by: Ben Myers + Signed-off-by: Ben Myers + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/xfs/xfs_da_btree.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/xfs/xfs_da_btree.c 2014-05-05 11:49:57.000000000 +0000 ++++ linux-3.10-3.10.11/fs/xfs/xfs_da_btree.c 2014-05-05 12:48:07.000000000 +0000 +@@ -1223,6 +1223,7 @@ + /* start with smaller blk num */ + forward = nodehdr.forw < nodehdr.back; + for (i = 0; i < 2; forward = !forward, i++) { ++ struct xfs_da3_icnode_hdr thdr; + if (forward) + blkno = nodehdr.forw; + else +@@ -1235,10 +1236,10 @@ + return(error); + + node = bp->b_addr; +- xfs_da3_node_hdr_from_disk(&nodehdr, node); ++ xfs_da3_node_hdr_from_disk(&thdr, node); + xfs_trans_brelse(state->args->trans, bp); + +- if (count - nodehdr.count >= 0) ++ if (count - thdr.count >= 0) + break; /* fits with at least 25% to spare */ + } + if (i >= 2) { +Index: linux-3.10-3.10.11/dummy/rpi_1357_1fe36ec4914c34f63ea93c87ce6997606098628d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1357_1fe36ec4914c34f63ea93c87ce6997606098628d.txt 2014-05-05 12:48:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1358_f60945fd5684f5773efd2d87d383f528056d6285.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1358_f60945fd5684f5773efd2d87d383f528056d6285.patch --- linux-3.10.11/debian/patches/rpi/rpi_1358_f60945fd5684f5773efd2d87d383f528056d6285.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1358_f60945fd5684f5773efd2d87d383f528056d6285.patch 2014-05-05 12:48:09.000000000 +0000 @@ -0,0 +1,54 @@ +commit f60945fd5684f5773efd2d87d383f528056d6285 +Author: Ben Skeggs +Date: Tue Sep 10 12:11:01 2013 +1000 + + drm/nouveau/bios/init: stub opcode 0xaa + + commit 5495e39fb3695182b9f2a72fe4169056cada37a1 upstream. + + Signed-off-by: Ben Skeggs + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/nouveau/core/subdev/bios/init.c 2014-05-05 11:49:56.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/nouveau/core/subdev/bios/init.c 2014-05-05 12:48:08.000000000 +0000 +@@ -580,8 +580,22 @@ + init_reserved(struct nvbios_init *init) + { + u8 opcode = nv_ro08(init->bios, init->offset); +- trace("RESERVED\t0x%02x\n", opcode); +- init->offset += 1; ++ u8 length, i; ++ ++ switch (opcode) { ++ case 0xaa: ++ length = 4; ++ break; ++ default: ++ length = 1; ++ break; ++ } ++ ++ trace("RESERVED 0x%02x\t", opcode); ++ for (i = 1; i < length; i++) ++ cont(" 0x%02x", nv_ro08(init->bios, init->offset + i)); ++ cont("\n"); ++ init->offset += length; + } + + /** +@@ -2136,6 +2150,7 @@ + [0x99] = { init_zm_auxch }, + [0x9a] = { init_i2c_long_if }, + [0xa9] = { init_gpio_ne }, ++ [0xaa] = { init_reserved }, + }; + + #define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0])) +Index: linux-3.10-3.10.11/dummy/rpi_1358_f60945fd5684f5773efd2d87d383f528056d6285.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1358_f60945fd5684f5773efd2d87d383f528056d6285.txt 2014-05-05 12:48:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1359_22c748d6172867030c228d4737fdef0e9713a125.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1359_22c748d6172867030c228d4737fdef0e9713a125.patch --- linux-3.10.11/debian/patches/rpi/rpi_1359_22c748d6172867030c228d4737fdef0e9713a125.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1359_22c748d6172867030c228d4737fdef0e9713a125.patch 2014-05-05 12:48:10.000000000 +0000 @@ -0,0 +1,60 @@ +commit 22c748d6172867030c228d4737fdef0e9713a125 +Author: Takashi Iwai +Date: Mon Sep 30 12:13:44 2013 +0200 + + ALSA: hda - Fix GPIO for Acer Aspire 3830TG + + commit 4a4370442c996be0fd08234a167c8a127c2488bb upstream. + + Acer Aspire 3830TG seems requiring GPIO bit 0 as the primary mute + control. When a machine is booted after Windows 8, the GPIO pin is + turned off and it results in the silent output. + + This patch adds the manual fixup of GPIO bit 0 for this model. + + Reported-by: Christopher + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_conexant.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_conexant.c 2014-05-05 11:49:56.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_conexant.c 2014-05-05 12:48:09.000000000 +0000 +@@ -3225,6 +3225,7 @@ + CXT_PINCFG_LEMOTE_A1205, + CXT_FIXUP_STEREO_DMIC, + CXT_FIXUP_INC_MIC_BOOST, ++ CXT_FIXUP_GPIO1, + }; + + static void cxt_fixup_stereo_dmic(struct hda_codec *codec, +@@ -3303,6 +3304,15 @@ + .type = HDA_FIXUP_FUNC, + .v.func = cxt5066_increase_mic_boost, + }, ++ [CXT_FIXUP_GPIO1] = { ++ .type = HDA_FIXUP_VERBS, ++ .v.verbs = (const struct hda_verb[]) { ++ { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, ++ { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, ++ { 0x01, AC_VERB_SET_GPIO_DATA, 0x01 }, ++ { } ++ }, ++ }, + }; + + static const struct snd_pci_quirk cxt5051_fixups[] = { +@@ -3312,6 +3322,7 @@ + + static const struct snd_pci_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), ++ SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_GPIO1), + SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), +Index: linux-3.10-3.10.11/dummy/rpi_1359_22c748d6172867030c228d4737fdef0e9713a125.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1359_22c748d6172867030c228d4737fdef0e9713a125.txt 2014-05-05 12:48:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1360_bc30c3576d85f7d02f5620cbe8d03f4064c6a73a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1360_bc30c3576d85f7d02f5620cbe8d03f4064c6a73a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1360_bc30c3576d85f7d02f5620cbe8d03f4064c6a73a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1360_bc30c3576d85f7d02f5620cbe8d03f4064c6a73a.patch 2014-05-05 12:48:11.000000000 +0000 @@ -0,0 +1,74 @@ +commit bc30c3576d85f7d02f5620cbe8d03f4064c6a73a +Author: Chris Metcalf +Date: Thu Sep 26 13:24:53 2013 -0400 + + tile: use a more conservative __my_cpu_offset in CONFIG_PREEMPT + + commit f862eefec0b68e099a9fa58d3761ffb10bad97e1 upstream. + + It turns out the kernel relies on barrier() to force a reload of the + percpu offset value. Since we can't easily modify the definition of + barrier() to include "tp" as an output register, we instead provide a + definition of __my_cpu_offset as extended assembly that includes a fake + stack read to hazard against barrier(), forcing gcc to know that it + must reread "tp" and recompute anything based on "tp" after a barrier. + + This fixes observed hangs in the slub allocator when we are looping + on a percpu cmpxchg_double. + + A similar fix for ARMv7 was made in June in change 509eb76ebf97. + + Signed-off-by: Chris Metcalf + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/tile/include/asm/percpu.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/tile/include/asm/percpu.h 2014-05-05 11:49:55.000000000 +0000 ++++ linux-3.10-3.10.11/arch/tile/include/asm/percpu.h 2014-05-05 12:48:10.000000000 +0000 +@@ -15,9 +15,37 @@ + #ifndef _ASM_TILE_PERCPU_H + #define _ASM_TILE_PERCPU_H + +-register unsigned long __my_cpu_offset __asm__("tp"); +-#define __my_cpu_offset __my_cpu_offset +-#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp)) ++register unsigned long my_cpu_offset_reg asm("tp"); ++ ++#ifdef CONFIG_PREEMPT ++/* ++ * For full preemption, we can't just use the register variable ++ * directly, since we need barrier() to hazard against it, causing the ++ * compiler to reload anything computed from a previous "tp" value. ++ * But we also don't want to use volatile asm, since we'd like the ++ * compiler to be able to cache the value across multiple percpu reads. ++ * So we use a fake stack read as a hazard against barrier(). ++ * The 'U' constraint is like 'm' but disallows postincrement. ++ */ ++static inline unsigned long __my_cpu_offset(void) ++{ ++ unsigned long tp; ++ register unsigned long *sp asm("sp"); ++ asm("move %0, tp" : "=r" (tp) : "U" (*sp)); ++ return tp; ++} ++#define __my_cpu_offset __my_cpu_offset() ++#else ++/* ++ * We don't need to hazard against barrier() since "tp" doesn't ever ++ * change with PREEMPT_NONE, and with PREEMPT_VOLUNTARY it only ++ * changes at function call points, at which we are already re-reading ++ * the value of "tp" due to "my_cpu_offset_reg" being a global variable. ++ */ ++#define __my_cpu_offset my_cpu_offset_reg ++#endif ++ ++#define set_my_cpu_offset(tp) (my_cpu_offset_reg = (tp)) + + #include + +Index: linux-3.10-3.10.11/dummy/rpi_1360_bc30c3576d85f7d02f5620cbe8d03f4064c6a73a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1360_bc30c3576d85f7d02f5620cbe8d03f4064c6a73a.txt 2014-05-05 12:48:10.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1361_98e00cd81b76f8b50b881bf3ac532fa1ab42931c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1361_98e00cd81b76f8b50b881bf3ac532fa1ab42931c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1361_98e00cd81b76f8b50b881bf3ac532fa1ab42931c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1361_98e00cd81b76f8b50b881bf3ac532fa1ab42931c.patch 2014-05-05 12:48:12.000000000 +0000 @@ -0,0 +1,47 @@ +commit 98e00cd81b76f8b50b881bf3ac532fa1ab42931c +Author: Martin Schwidefsky +Date: Fri Sep 27 15:24:38 2013 +0200 + + s390: fix system call restart after inferior call + + commit dbbfe487e5f3fc00c9fe5207d63309859704d12f upstream. + + Git commit 616498813b11ffef "s390: system call path micro optimization" + introduced a regression in regard to system call restarting and inferior + function calls via the ptrace interface. The pointer to the system call + table needs to be loaded in sysc_sigpending if do_signal returns with + TIF_SYSCALl set after it restored a system call context. + + Signed-off-by: Martin Schwidefsky + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/s390/kernel/entry.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/s390/kernel/entry.S 2014-05-05 11:49:55.000000000 +0000 ++++ linux-3.10-3.10.11/arch/s390/kernel/entry.S 2014-05-05 12:48:11.000000000 +0000 +@@ -265,6 +265,7 @@ + tm __TI_flags+3(%r12),_TIF_SYSCALL + jno sysc_return + lm %r2,%r7,__PT_R2(%r11) # load svc arguments ++ l %r10,__TI_sysc_table(%r12) # 31 bit system call table + xr %r8,%r8 # svc 0 returns -ENOSYS + clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2) + jnl sysc_nr_ok # invalid svc number -> do svc 0 +Index: linux-3.10-3.10.11/arch/s390/kernel/entry64.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/s390/kernel/entry64.S 2014-05-05 11:49:55.000000000 +0000 ++++ linux-3.10-3.10.11/arch/s390/kernel/entry64.S 2014-05-05 12:48:11.000000000 +0000 +@@ -293,6 +293,7 @@ + tm __TI_flags+7(%r12),_TIF_SYSCALL + jno sysc_return + lmg %r2,%r7,__PT_R2(%r11) # load svc arguments ++ lg %r10,__TI_sysc_table(%r12) # address of system call table + lghi %r8,0 # svc 0 returns -ENOSYS + llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number + cghi %r1,NR_syscalls +Index: linux-3.10-3.10.11/dummy/rpi_1361_98e00cd81b76f8b50b881bf3ac532fa1ab42931c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1361_98e00cd81b76f8b50b881bf3ac532fa1ab42931c.txt 2014-05-05 12:48:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1362_34aa872c2cea9518bba66ab8d88bc0f90dbeb2ba.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1362_34aa872c2cea9518bba66ab8d88bc0f90dbeb2ba.patch --- linux-3.10.11/debian/patches/rpi/rpi_1362_34aa872c2cea9518bba66ab8d88bc0f90dbeb2ba.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1362_34aa872c2cea9518bba66ab8d88bc0f90dbeb2ba.patch 2014-05-05 12:48:12.000000000 +0000 @@ -0,0 +1,71 @@ +commit 34aa872c2cea9518bba66ab8d88bc0f90dbeb2ba +Author: Josef Bacik +Date: Tue Jul 30 16:30:30 2013 -0400 + + Btrfs: change how we queue blocks for backref checking + + commit b6c60c8018c4e9beb2f83fc82c09f9d033766571 upstream. + + Previously we only added blocks to the list to have their backrefs checked if + the level of the block is right above the one we are searching for. This is + because we want to make sure we don't add the entire path up to the root to the + lists to make sure we process things one at a time. This assumes that if any + blocks in the path to the root are going to be not checked (shared in other + words) then they will be in the level right above the current block on up. This + isn't quite right though since we can have blocks higher up the list that are + shared because they are attached to a reloc root. But we won't add this block + to be checked and then later on we will BUG_ON(!upper->checked). So instead + keep track of wether or not we've queued a block to be checked in this current + search, and if we haven't go ahead and queue it to be checked. This patch fixed + the panic I was seeing where we BUG_ON(!upper->checked). Thanks, + + Signed-off-by: Josef Bacik + Signed-off-by: Chris Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/btrfs/relocation.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/btrfs/relocation.c 2014-05-05 11:49:55.000000000 +0000 ++++ linux-3.10-3.10.11/fs/btrfs/relocation.c 2014-05-05 12:48:12.000000000 +0000 +@@ -691,6 +691,7 @@ + int cowonly; + int ret; + int err = 0; ++ bool need_check = true; + + path1 = btrfs_alloc_path(); + path2 = btrfs_alloc_path(); +@@ -914,6 +915,7 @@ + cur->bytenr); + + lower = cur; ++ need_check = true; + for (; level < BTRFS_MAX_LEVEL; level++) { + if (!path2->nodes[level]) { + BUG_ON(btrfs_root_bytenr(&root->root_item) != +@@ -957,14 +959,12 @@ + + /* + * add the block to pending list if we +- * need check its backrefs. only block +- * at 'cur->level + 1' is added to the +- * tail of pending list. this guarantees +- * we check backrefs from lower level +- * blocks to upper level blocks. ++ * need check its backrefs, we only do this once ++ * while walking up a tree as we will catch ++ * anything else later on. + */ +- if (!upper->checked && +- level == cur->level + 1) { ++ if (!upper->checked && need_check) { ++ need_check = false; + list_add_tail(&edge->list[UPPER], + &list); + } else +Index: linux-3.10-3.10.11/dummy/rpi_1362_34aa872c2cea9518bba66ab8d88bc0f90dbeb2ba.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1362_34aa872c2cea9518bba66ab8d88bc0f90dbeb2ba.txt 2014-05-05 12:48:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1363_0ac5762ca876c8554cea6e8a05422d561b98947f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1363_0ac5762ca876c8554cea6e8a05422d561b98947f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1363_0ac5762ca876c8554cea6e8a05422d561b98947f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1363_0ac5762ca876c8554cea6e8a05422d561b98947f.patch 2014-05-05 12:48:13.000000000 +0000 @@ -0,0 +1,42 @@ +commit 0ac5762ca876c8554cea6e8a05422d561b98947f +Author: Josef Bacik +Date: Mon Aug 12 10:56:14 2013 -0400 + + Btrfs: skip subvol entries when checking if we've created a dir already + + commit a05254143cd183b18002cbba7759a1e4629aa762 upstream. + + We have logic to see if we've already created a parent directory by check to see + if an inode inside of that directory has a lower inode number than the one we + are currently processing. The logic is that if there is a lower inode number + then we would have had to made sure the directory was created at that previous + point. The problem is that subvols inode numbers count from the lowest objectid + in the root tree, which may be less than our current progress. So just skip if + our dir item key is a root item. This fixes the original test and the xfstest + version I made that added an extra subvol create. Thanks, + + Reported-by: Emil Karlson + Signed-off-by: Josef Bacik + Signed-off-by: Chris Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/btrfs/send.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/btrfs/send.c 2014-05-05 11:49:54.000000000 +0000 ++++ linux-3.10-3.10.11/fs/btrfs/send.c 2014-05-05 12:48:13.000000000 +0000 +@@ -2524,7 +2524,8 @@ + di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); + btrfs_dir_item_key_to_cpu(eb, di, &di_key); + +- if (di_key.objectid < sctx->send_progress) { ++ if (di_key.type != BTRFS_ROOT_ITEM_KEY && ++ di_key.objectid < sctx->send_progress) { + ret = 1; + goto out; + } +Index: linux-3.10-3.10.11/dummy/rpi_1363_0ac5762ca876c8554cea6e8a05422d561b98947f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1363_0ac5762ca876c8554cea6e8a05422d561b98947f.txt 2014-05-05 12:48:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1364_322d9a97c490b890975e0d61f2b034bc18ea1100.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1364_322d9a97c490b890975e0d61f2b034bc18ea1100.patch --- linux-3.10.11/debian/patches/rpi/rpi_1364_322d9a97c490b890975e0d61f2b034bc18ea1100.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1364_322d9a97c490b890975e0d61f2b034bc18ea1100.patch 2014-05-05 12:48:14.000000000 +0000 @@ -0,0 +1,45 @@ +commit 322d9a97c490b890975e0d61f2b034bc18ea1100 +Author: Josef Bacik +Date: Thu Aug 22 17:03:29 2013 -0400 + + Btrfs: remove ourselves from the cluster list under lock + + commit b8d0c69b9469ffd33df30fee3e990f2d4aa68a09 upstream. + + A user was reporting weird warnings from btrfs_put_delayed_ref() and I noticed + that we were doing this list_del_init() on our head ref outside of + delayed_refs->lock. This is a problem if we have people still on the list, we + could end up modifying old pointers and such. Fix this by removing us from the + list before we do our run_delayed_ref on our head ref. Thanks, + + Signed-off-by: Josef Bacik + Signed-off-by: Chris Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/btrfs/extent-tree.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/btrfs/extent-tree.c 2014-05-05 11:49:54.000000000 +0000 ++++ linux-3.10-3.10.11/fs/btrfs/extent-tree.c 2014-05-05 12:48:14.000000000 +0000 +@@ -2402,6 +2402,8 @@ + default: + WARN_ON(1); + } ++ } else { ++ list_del_init(&locked_ref->cluster); + } + spin_unlock(&delayed_refs->lock); + +@@ -2424,7 +2426,6 @@ + * list before we release it. + */ + if (btrfs_delayed_ref_is_head(ref)) { +- list_del_init(&locked_ref->cluster); + btrfs_delayed_ref_unlock(locked_ref); + locked_ref = NULL; + } +Index: linux-3.10-3.10.11/dummy/rpi_1364_322d9a97c490b890975e0d61f2b034bc18ea1100.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1364_322d9a97c490b890975e0d61f2b034bc18ea1100.txt 2014-05-05 12:48:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1365_a873420aa42b4c96a9ea9900855856bfea8558d2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1365_a873420aa42b4c96a9ea9900855856bfea8558d2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1365_a873420aa42b4c96a9ea9900855856bfea8558d2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1365_a873420aa42b4c96a9ea9900855856bfea8558d2.patch 2014-05-05 12:48:15.000000000 +0000 @@ -0,0 +1,63 @@ +commit a873420aa42b4c96a9ea9900855856bfea8558d2 +Author: Stefan Achatz +Date: Fri Aug 30 14:10:07 2013 +0200 + + HID: roccat: add support for KonePureOptical v2 + + commit a4be0ed39f2b1ea990804ea54e39bc42d17ed5a5 upstream. + + KonePureOptical is a KonePure with different sensor. + + Signed-off-by: Stefan Achatz + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/hid-core.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-core.c 2014-05-05 12:46:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-core.c 2014-05-05 12:48:14.000000000 +0000 +@@ -1755,6 +1755,7 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, +Index: linux-3.10-3.10.11/drivers/hid/hid-ids.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-ids.h 2014-05-05 12:44:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-ids.h 2014-05-05 12:48:14.000000000 +0000 +@@ -705,6 +705,7 @@ + #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced + #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 + #define USB_DEVICE_ID_ROCCAT_KONEPURE 0x2dbe ++#define USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL 0x2db4 + #define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22 + #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 + #define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e +Index: linux-3.10-3.10.11/drivers/hid/hid-roccat-konepure.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/hid-roccat-konepure.c 2014-05-05 11:49:53.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/hid-roccat-konepure.c 2014-05-05 12:48:14.000000000 +0000 +@@ -262,6 +262,7 @@ + + static const struct hid_device_id konepure_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) }, + { } + }; + +@@ -300,5 +301,5 @@ + module_exit(konepure_exit); + + MODULE_AUTHOR("Stefan Achatz"); +-MODULE_DESCRIPTION("USB Roccat KonePure driver"); ++MODULE_DESCRIPTION("USB Roccat KonePure/Optical driver"); + MODULE_LICENSE("GPL v2"); +Index: linux-3.10-3.10.11/dummy/rpi_1365_a873420aa42b4c96a9ea9900855856bfea8558d2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1365_a873420aa42b4c96a9ea9900855856bfea8558d2.txt 2014-05-05 12:48:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1366_1685c9903b259801b4e1c6c0c325f364742f28f4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1366_1685c9903b259801b4e1c6c0c325f364742f28f4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1366_1685c9903b259801b4e1c6c0c325f364742f28f4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1366_1685c9903b259801b4e1c6c0c325f364742f28f4.patch 2014-05-05 12:48:16.000000000 +0000 @@ -0,0 +1,30 @@ +commit 1685c9903b259801b4e1c6c0c325f364742f28f4 +Author: Marcel Holtmann +Date: Sun Sep 1 11:02:46 2013 -0700 + + HID: uhid: add devname module alias + + commit 60cbd53e4bf623fe978e6f23a6da642e730fde3a upstream. + + For simple device node creation, add the devname module alias. + + Signed-off-by: Marcel Holtmann + Reviewed-by: David Herrmann + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/uhid.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/uhid.c 2014-05-05 11:49:53.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/uhid.c 2014-05-05 12:48:15.000000000 +0000 +@@ -659,3 +659,4 @@ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("David Herrmann "); + MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); ++MODULE_ALIAS("devname:" UHID_NAME); +Index: linux-3.10-3.10.11/dummy/rpi_1366_1685c9903b259801b4e1c6c0c325f364742f28f4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1366_1685c9903b259801b4e1c6c0c325f364742f28f4.txt 2014-05-05 12:48:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1367_0e01faab5690ff1674f659abb5ef719be6ef549d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1367_0e01faab5690ff1674f659abb5ef719be6ef549d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1367_0e01faab5690ff1674f659abb5ef719be6ef549d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1367_0e01faab5690ff1674f659abb5ef719be6ef549d.patch 2014-05-05 12:48:17.000000000 +0000 @@ -0,0 +1,68 @@ +commit 0e01faab5690ff1674f659abb5ef719be6ef549d +Author: David Herrmann +Date: Mon Sep 9 18:33:54 2013 +0200 + + HID: uhid: allocate static minor + + commit 19872d20c890073c5207d9e02bb8f14d451a11eb upstream. + + udev has this nice feature of creating "dead" /dev/ device-nodes if + it finds a devnode: modalias. Once the node is accessed, the kernel + automatically loads the module that provides the node. However, this + requires udev to know the major:minor code to use for the node. This + feature was introduced by: + + commit 578454ff7eab61d13a26b568f99a89a2c9edc881 + Author: Kay Sievers + Date: Thu May 20 18:07:20 2010 +0200 + + driver core: add devname module aliases to allow module on-demand auto-loading + + However, uhid uses dynamic minor numbers so this doesn't actually work. We + need to load uhid to know which minor it's going to use. + + Hence, allocate a static minor (just like uinput does) and we're good + to go. + + Reported-by: Tom Gundersen + Signed-off-by: David Herrmann + Signed-off-by: Jiri Kosina + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hid/uhid.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hid/uhid.c 2014-05-05 12:48:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hid/uhid.c 2014-05-05 12:48:16.000000000 +0000 +@@ -640,7 +640,7 @@ + + static struct miscdevice uhid_misc = { + .fops = &uhid_fops, +- .minor = MISC_DYNAMIC_MINOR, ++ .minor = UHID_MINOR, + .name = UHID_NAME, + }; + +@@ -659,4 +659,5 @@ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("David Herrmann "); + MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); ++MODULE_ALIAS_MISCDEV(UHID_MINOR); + MODULE_ALIAS("devname:" UHID_NAME); +Index: linux-3.10-3.10.11/include/linux/miscdevice.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/miscdevice.h 2014-05-05 11:49:53.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/miscdevice.h 2014-05-05 12:48:16.000000000 +0000 +@@ -45,6 +45,7 @@ + #define MAPPER_CTRL_MINOR 236 + #define LOOP_CTRL_MINOR 237 + #define VHOST_NET_MINOR 238 ++#define UHID_MINOR 239 + #define MISC_DYNAMIC_MINOR 255 + + struct device; +Index: linux-3.10-3.10.11/dummy/rpi_1367_0e01faab5690ff1674f659abb5ef719be6ef549d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1367_0e01faab5690ff1674f659abb5ef719be6ef549d.txt 2014-05-05 12:48:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1368_adf0931b2b3ce91cc4096939650f4c4a3f68fef5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1368_adf0931b2b3ce91cc4096939650f4c4a3f68fef5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1368_adf0931b2b3ce91cc4096939650f4c4a3f68fef5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1368_adf0931b2b3ce91cc4096939650f4c4a3f68fef5.patch 2014-05-05 12:48:18.000000000 +0000 @@ -0,0 +1,182 @@ +commit adf0931b2b3ce91cc4096939650f4c4a3f68fef5 +Author: Bjørn Mork +Date: Tue Sep 10 15:06:20 2013 +0200 + + net: qmi_wwan: add new Qualcomm devices + + commit 0470667caa8261beb8a9141102b04a5357dd45b5 upstream. + + Adding the device list from the Windows driver description files + included with a new Qualcomm MDM9615 based device, "Alcatel-sbell + ASB TL131 TDD LTE", from China Mobile. This device is tested + and verified to work. The others are assumed to work based on + using the same Windows driver. + + Many of these devices support multiple QMI/wwan ports, requiring + multiple interface matching entries. All devices are composite, + providing a mix of one or more serial, storage or Android Debug + Brigde functions in addition to the wwan function. + + This device list included an update of one previously known device, + which was incorrectly assumed to have a Gobi 2K layout. This is + corrected. + + Reported-by: 王康 + Signed-off-by: Bjørn Mork + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/usb/qmi_wwan.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/usb/qmi_wwan.c 2014-05-05 11:49:52.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/usb/qmi_wwan.c 2014-05-05 12:48:17.000000000 +0000 +@@ -518,6 +518,135 @@ + + /* 3. Combined interface devices matching on interface number */ + {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ ++ {QMI_FIXED_INTF(0x05c6, 0x7000, 0)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7001, 1)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7002, 1)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7101, 1)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7101, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7101, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7102, 1)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7102, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x7102, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x8000, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x8001, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9000, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9003, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9005, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900a, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900b, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900c, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900c, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900c, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900d, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900f, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900f, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x900f, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9010, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9010, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9011, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9011, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9021, 1)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9022, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9025, 4)}, /* Alcatel-sbell ASB TL131 TDD LTE (China Mobile) */ ++ {QMI_FIXED_INTF(0x05c6, 0x9026, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x902e, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9031, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9032, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9033, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9033, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9033, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9033, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9034, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9034, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9034, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9034, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9034, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9035, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9036, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9037, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9038, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x903b, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x903c, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x903d, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x903e, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9043, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9046, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9046, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9046, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9047, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9047, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9047, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9048, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9048, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9048, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9048, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9048, 8)}, ++ {QMI_FIXED_INTF(0x05c6, 0x904c, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x904c, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x904c, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x904c, 8)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9050, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9052, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9053, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9053, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9054, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9054, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9055, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9055, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9055, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9055, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9055, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9056, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 8)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9062, 9)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9064, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9065, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9065, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9066, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9066, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9067, 1)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9068, 2)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9068, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9068, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9068, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9068, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9068, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9069, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9069, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9069, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9069, 8)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9070, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9070, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9075, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9076, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9076, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9076, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9076, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9076, 8)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9077, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9077, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9077, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9077, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9078, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9079, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9079, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9079, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9079, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9079, 8)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9080, 5)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9080, 6)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9080, 7)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, ++ {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, ++ {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, + {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ + {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ + {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, +@@ -610,7 +739,6 @@ + {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ + {QMI_GOBI_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ + {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ +- {QMI_GOBI_DEVICE(0x05c6, 0x920d)}, /* Gobi 3000 Composite */ + {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ + {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ + {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ +Index: linux-3.10-3.10.11/dummy/rpi_1368_adf0931b2b3ce91cc4096939650f4c4a3f68fef5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1368_adf0931b2b3ce91cc4096939650f4c4a3f68fef5.txt 2014-05-05 12:48:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1369_84c8b3b9e17107a74f07dc5e48264034f1410b97.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1369_84c8b3b9e17107a74f07dc5e48264034f1410b97.patch --- linux-3.10.11/debian/patches/rpi/rpi_1369_84c8b3b9e17107a74f07dc5e48264034f1410b97.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1369_84c8b3b9e17107a74f07dc5e48264034f1410b97.patch 2014-05-05 12:48:18.000000000 +0000 @@ -0,0 +1,44 @@ +commit 84c8b3b9e17107a74f07dc5e48264034f1410b97 +Author: Kent Overstreet +Date: Thu Oct 10 17:31:15 2013 -0700 + + bcache: Fix a null ptr deref regression + + commit 2fe80d3bbf1c8bd9efc5b8154207c8dd104e7306 upstream. + + Commit c0f04d88e46d ("bcache: Fix flushes in writeback mode") was fixing + a reported data corruption bug, but it seems some last minute + refactoring or rebasing introduced a null pointer deref. + + Signed-off-by: Kent Overstreet + Reported-by: Gabriel de Perthuis + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/request.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/request.c 2014-05-05 12:46:10.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/request.c 2014-05-05 12:48:18.000000000 +0000 +@@ -1055,6 +1055,7 @@ + } else { + trace_bcache_writeback(s->orig_bio); + bch_writeback_add(dc, bio_sectors(bio)); ++ s->op.cache_bio = bio; + + if (bio->bi_rw & REQ_FLUSH) { + /* Also need to send a flush to the backing device */ +@@ -1067,8 +1068,6 @@ + flush->bi_private = cl; + + closure_bio_submit(flush, cl, s->d); +- } else { +- s->op.cache_bio = bio; + } + } + out: +Index: linux-3.10-3.10.11/dummy/rpi_1369_84c8b3b9e17107a74f07dc5e48264034f1410b97.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1369_84c8b3b9e17107a74f07dc5e48264034f1410b97.txt 2014-05-05 12:48:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1370_7fc878164dd8bc7812eb774e728f2cc1ffe905ed.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1370_7fc878164dd8bc7812eb774e728f2cc1ffe905ed.patch --- linux-3.10.11/debian/patches/rpi/rpi_1370_7fc878164dd8bc7812eb774e728f2cc1ffe905ed.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1370_7fc878164dd8bc7812eb774e728f2cc1ffe905ed.patch 2014-05-05 12:48:19.000000000 +0000 @@ -0,0 +1,24 @@ +commit 7fc878164dd8bc7812eb774e728f2cc1ffe905ed +Author: Greg Kroah-Hartman +Date: Sun Oct 13 16:08:56 2013 -0700 + + Linux 3.10.16 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:46:46.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:48:18.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 15 ++SUBLEVEL = 16 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1370_7fc878164dd8bc7812eb774e728f2cc1ffe905ed.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1370_7fc878164dd8bc7812eb774e728f2cc1ffe905ed.txt 2014-05-05 12:48:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1371_044dde0ae7ea37140b31c5068c7517b49b141aae.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1371_044dde0ae7ea37140b31c5068c7517b49b141aae.patch --- linux-3.10.11/debian/patches/rpi/rpi_1371_044dde0ae7ea37140b31c5068c7517b49b141aae.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1371_044dde0ae7ea37140b31c5068c7517b49b141aae.patch 2014-05-05 12:48:20.000000000 +0000 @@ -0,0 +1,88 @@ +commit 044dde0ae7ea37140b31c5068c7517b49b141aae +Author: Daniel Mack +Date: Wed Oct 2 17:49:50 2013 +0200 + + ALSA: snd-usb-usx2y: remove bogus frame checks + + commit a9d14bc0b188a822e42787d01e56c06fe9750162 upstream. + + The frame check in i_usX2Y_urb_complete() and + i_usX2Y_usbpcm_urb_complete() is bogus and produces false positives as + described in this LAU thread: + + http://linuxaudio.org/mailarchive/lau/2013/5/20/200177 + + This patch removes the check code entirely. + + Cc: fzu@wemgehoertderstaat.de + Reported-by: Dr Nicholas J Bailey + Suggested-by: Takashi Iwai + Signed-off-by: Daniel Mack + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/usb/usx2y/usbusx2yaudio.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/usb/usx2y/usbusx2yaudio.c 2014-05-05 11:49:51.000000000 +0000 ++++ linux-3.10-3.10.11/sound/usb/usx2y/usbusx2yaudio.c 2014-05-05 12:48:19.000000000 +0000 +@@ -299,19 +299,6 @@ + usX2Y_clients_stop(usX2Y); + } + +-static void usX2Y_error_sequence(struct usX2Ydev *usX2Y, +- struct snd_usX2Y_substream *subs, struct urb *urb) +-{ +- snd_printk(KERN_ERR +-"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" +-"Most probably some urb of usb-frame %i is still missing.\n" +-"Cause could be too long delays in usb-hcd interrupt handling.\n", +- usb_get_current_frame_number(usX2Y->dev), +- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", +- usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame); +- usX2Y_clients_stop(usX2Y); +-} +- + static void i_usX2Y_urb_complete(struct urb *urb) + { + struct snd_usX2Y_substream *subs = urb->context; +@@ -328,12 +315,9 @@ + usX2Y_error_urb_status(usX2Y, subs, urb); + return; + } +- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) +- subs->completed_urb = urb; +- else { +- usX2Y_error_sequence(usX2Y, subs, urb); +- return; +- } ++ ++ subs->completed_urb = urb; ++ + { + struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE], + *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; +Index: linux-3.10-3.10.11/sound/usb/usx2y/usx2yhwdeppcm.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/usb/usx2y/usx2yhwdeppcm.c 2014-05-05 11:49:51.000000000 +0000 ++++ linux-3.10-3.10.11/sound/usb/usx2y/usx2yhwdeppcm.c 2014-05-05 12:48:19.000000000 +0000 +@@ -244,13 +244,8 @@ + usX2Y_error_urb_status(usX2Y, subs, urb); + return; + } +- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) +- subs->completed_urb = urb; +- else { +- usX2Y_error_sequence(usX2Y, subs, urb); +- return; +- } + ++ subs->completed_urb = urb; + capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]; + capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; + playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; +Index: linux-3.10-3.10.11/dummy/rpi_1371_044dde0ae7ea37140b31c5068c7517b49b141aae.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1371_044dde0ae7ea37140b31c5068c7517b49b141aae.txt 2014-05-05 12:48:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1372_43d3dd157aa81407473c416234c94abcd13c4fc8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1372_43d3dd157aa81407473c416234c94abcd13c4fc8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1372_43d3dd157aa81407473c416234c94abcd13c4fc8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1372_43d3dd157aa81407473c416234c94abcd13c4fc8.patch 2014-05-05 12:48:21.000000000 +0000 @@ -0,0 +1,74 @@ +commit 43d3dd157aa81407473c416234c94abcd13c4fc8 +Author: Anssi Hannula +Date: Mon Oct 7 19:24:52 2013 +0300 + + ALSA: hda - hdmi: Fix channel map switch not taking effect + + commit 39edac70e9aedf451fccaa851b273ace9fcca0bd upstream. + + Currently hdmi_setup_audio_infoframe() reprograms the HDA channel + mapping only when the infoframe is not up-to-date or the non-PCM flag + has changed. + + However, when just the channel map has been changed, the infoframe may + still be up-to-date and non-PCM flag may not have changed, so the new + channel map is not actually programmed into the HDA codec. + + Notably, this failing case is also always triggered when the device is + already in a prepared state and a new channel map is configured while + changing only the channel positions (for example, plain + "speaker-test -c2 -m FR,FL"). + + Fix that by always programming the channel map in + hdmi_setup_audio_infoframe(). Tested on Intel HDMI. + + Signed-off-by: Anssi Hannula + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_hdmi.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_hdmi.c 2014-05-05 12:44:28.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_hdmi.c 2014-05-05 12:48:20.000000000 +0000 +@@ -930,6 +930,14 @@ + } + + /* ++ * always configure channel mapping, it may have been changed by the ++ * user in the meantime ++ */ ++ hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca, ++ channels, per_pin->chmap, ++ per_pin->chmap_set); ++ ++ /* + * sizeof(ai) is used instead of sizeof(*hdmi_ai) or + * sizeof(*dp_ai) to avoid partial match/update problems when + * the user switches between HDMI/DP monitors. +@@ -940,20 +948,10 @@ + "pin=%d channels=%d\n", + pin_nid, + channels); +- hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca, +- channels, per_pin->chmap, +- per_pin->chmap_set); + hdmi_stop_infoframe_trans(codec, pin_nid); + hdmi_fill_audio_infoframe(codec, pin_nid, + ai.bytes, sizeof(ai)); + hdmi_start_infoframe_trans(codec, pin_nid); +- } else { +- /* For non-pcm audio switch, setup new channel mapping +- * accordingly */ +- if (per_pin->non_pcm != non_pcm) +- hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca, +- channels, per_pin->chmap, +- per_pin->chmap_set); + } + + per_pin->non_pcm = non_pcm; +Index: linux-3.10-3.10.11/dummy/rpi_1372_43d3dd157aa81407473c416234c94abcd13c4fc8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1372_43d3dd157aa81407473c416234c94abcd13c4fc8.txt 2014-05-05 12:48:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1373_74a8f08dfff48215dabccf8148b7505e00d39c37.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1373_74a8f08dfff48215dabccf8148b7505e00d39c37.patch --- linux-3.10.11/debian/patches/rpi/rpi_1373_74a8f08dfff48215dabccf8148b7505e00d39c37.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1373_74a8f08dfff48215dabccf8148b7505e00d39c37.patch 2014-05-05 12:48:21.000000000 +0000 @@ -0,0 +1,33 @@ +commit 74a8f08dfff48215dabccf8148b7505e00d39c37 +Author: Takashi Iwai +Date: Tue Oct 8 19:57:50 2013 +0200 + + ALSA: hda - Add fixup for ASUS N56VZ + + commit c6cc3d58b4042f5cadae653ff8d3df26af1a0169 upstream. + + ASUS N56VZ needs a fixup for the bass speaker pin, which was already + provided via model=asus-mode4. + + Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=841645 + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_realtek.c 2014-05-05 11:49:50.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c 2014-05-05 12:48:21.000000000 +0000 +@@ -4216,6 +4216,7 @@ + SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), ++ SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4), + SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), +Index: linux-3.10-3.10.11/dummy/rpi_1373_74a8f08dfff48215dabccf8148b7505e00d39c37.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1373_74a8f08dfff48215dabccf8148b7505e00d39c37.txt 2014-05-05 12:48:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1374_09c517435dd6f29c29822b627f653259e97e7294.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1374_09c517435dd6f29c29822b627f653259e97e7294.patch --- linux-3.10.11/debian/patches/rpi/rpi_1374_09c517435dd6f29c29822b627f653259e97e7294.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1374_09c517435dd6f29c29822b627f653259e97e7294.patch 2014-05-05 12:48:22.000000000 +0000 @@ -0,0 +1,60 @@ +commit 09c517435dd6f29c29822b627f653259e97e7294 +Author: David Henningsson +Date: Fri Oct 11 10:18:45 2013 +0200 + + ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model) + + commit 88cfcf86aa3ada84d97195bcad74f4dadb4ae23b upstream. + + The external mic showed up with a precense detect of "always present", + essentially disabling the internal mic. Therefore turn off presence + detection for this pin. + + Note: The external mic seems not yet working, but an internal mic is + certainly better than no mic at all. + + BugLink: https://bugs.launchpad.net/bugs/1227093 + Signed-off-by: David Henningsson + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_realtek.c 2014-05-05 12:48:21.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c 2014-05-05 12:48:22.000000000 +0000 +@@ -3223,6 +3223,7 @@ + ALC269_FIXUP_HP_GPIO_LED, + ALC269_FIXUP_INV_DMIC, + ALC269_FIXUP_LENOVO_DOCK, ++ ALC286_FIXUP_SONY_MIC_NO_PRESENCE, + ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, + ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, +@@ -3420,6 +3421,13 @@ + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode_no_hp_mic, + }, ++ [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ ++ { } ++ }, ++ }, + [ALC269_FIXUP_ASUS_X101_FUNC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_x101_headset_mic, +@@ -3529,6 +3537,7 @@ + SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), ++ SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), + SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), + SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), +Index: linux-3.10-3.10.11/dummy/rpi_1374_09c517435dd6f29c29822b627f653259e97e7294.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1374_09c517435dd6f29c29822b627f653259e97e7294.txt 2014-05-05 12:48:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1375_b7a52f5111bc53ffbfff96330621cbde80df6ba4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1375_b7a52f5111bc53ffbfff96330621cbde80df6ba4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1375_b7a52f5111bc53ffbfff96330621cbde80df6ba4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1375_b7a52f5111bc53ffbfff96330621cbde80df6ba4.patch 2014-05-05 12:48:23.000000000 +0000 @@ -0,0 +1,72 @@ +commit b7a52f5111bc53ffbfff96330621cbde80df6ba4 +Author: Theodore Ts'o +Date: Tue Sep 10 10:52:35 2013 -0400 + + random: run random_int_secret_init() run after all late_initcalls + + commit 47d06e532e95b71c0db3839ebdef3fe8812fca2c upstream. + + The some platforms (e.g., ARM) initializes their clocks as + late_initcalls for some unknown reason. So make sure + random_int_secret_init() is run after all of the late_initcalls are + run. + + Signed-off-by: "Theodore Ts'o" + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/char/random.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/char/random.c 2014-05-05 11:49:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/char/random.c 2014-05-05 12:48:23.000000000 +0000 +@@ -1462,12 +1462,11 @@ + + static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; + +-static int __init random_int_secret_init(void) ++int random_int_secret_init(void) + { + get_random_bytes(random_int_secret, sizeof(random_int_secret)); + return 0; + } +-late_initcall(random_int_secret_init); + + /* + * Get a random word for internal kernel use only. Similar to urandom but +Index: linux-3.10-3.10.11/include/linux/random.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/random.h 2014-05-05 11:49:49.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/random.h 2014-05-05 12:48:23.000000000 +0000 +@@ -17,6 +17,7 @@ + extern void get_random_bytes(void *buf, int nbytes); + extern void get_random_bytes_arch(void *buf, int nbytes); + void generate_random_uuid(unsigned char uuid_out[16]); ++extern int random_int_secret_init(void); + + #ifndef MODULE + extern const struct file_operations random_fops, urandom_fops; +Index: linux-3.10-3.10.11/init/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/init/main.c 2014-05-05 11:49:49.000000000 +0000 ++++ linux-3.10-3.10.11/init/main.c 2014-05-05 12:48:23.000000000 +0000 +@@ -74,6 +74,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -777,6 +778,7 @@ + do_ctors(); + usermodehelper_enable(); + do_initcalls(); ++ random_int_secret_init(); + } + + static void __init do_pre_smp_initcalls(void) +Index: linux-3.10-3.10.11/dummy/rpi_1375_b7a52f5111bc53ffbfff96330621cbde80df6ba4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1375_b7a52f5111bc53ffbfff96330621cbde80df6ba4.txt 2014-05-05 12:48:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1376_670c0d101a57340aff4311c26a9ebb65b1d58f5a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1376_670c0d101a57340aff4311c26a9ebb65b1d58f5a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1376_670c0d101a57340aff4311c26a9ebb65b1d58f5a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1376_670c0d101a57340aff4311c26a9ebb65b1d58f5a.patch 2014-05-05 12:48:24.000000000 +0000 @@ -0,0 +1,40 @@ +commit 670c0d101a57340aff4311c26a9ebb65b1d58f5a +Author: Linus Torvalds +Date: Mon Sep 30 08:35:10 2013 -0700 + + vfs: allow O_PATH file descriptors for fstatfs() + + commit 9d05746e7b16d8565dddbe3200faa1e669d23bbf upstream. + + Olga reported that file descriptors opened with O_PATH do not work with + fstatfs(), found during further development of ksh93's thread support. + + There is no reason to not allow O_PATH file descriptors here (fstatfs is + very much a path operation), so use "fdget_raw()". See commit + 55815f70147d ("vfs: make O_PATH file descriptors usable for 'fstat()'") + for a very similar issue reported for fstat() by the same team. + + Reported-and-tested-by: ольга крыжановская + Acked-by: Al Viro + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/statfs.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/statfs.c 2014-05-05 11:49:48.000000000 +0000 ++++ linux-3.10-3.10.11/fs/statfs.c 2014-05-05 12:48:23.000000000 +0000 +@@ -94,7 +94,7 @@ + + int fd_statfs(int fd, struct kstatfs *st) + { +- struct fd f = fdget(fd); ++ struct fd f = fdget_raw(fd); + int error = -EBADF; + if (f.file) { + error = vfs_statfs(&f.file->f_path, st); +Index: linux-3.10-3.10.11/dummy/rpi_1376_670c0d101a57340aff4311c26a9ebb65b1d58f5a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1376_670c0d101a57340aff4311c26a9ebb65b1d58f5a.txt 2014-05-05 12:48:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1377_fafd39123416e56bf782e323031e6fdd18b61d60.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1377_fafd39123416e56bf782e323031e6fdd18b61d60.patch --- linux-3.10.11/debian/patches/rpi/rpi_1377_fafd39123416e56bf782e323031e6fdd18b61d60.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1377_fafd39123416e56bf782e323031e6fdd18b61d60.patch 2014-05-05 12:48:25.000000000 +0000 @@ -0,0 +1,43 @@ +commit fafd39123416e56bf782e323031e6fdd18b61d60 +Author: Taras Kondratiuk +Date: Mon Oct 7 13:41:59 2013 +0300 + + i2c: omap: Clear ARDY bit twice + + commit 4cdbf7d346e7461c3b93a26707c852e2c9db3753 upstream. + + Initially commit cb527ede1bf6ff2008a025606f25344b8ed7b4ac + "i2c-omap: Double clear of ARDY status in IRQ handler" + added a workaround for undocumented errata ProDB0017052. + But then commit 1d7afc95946487945cc7f5019b41255b72224b70 + "i2c: omap: ack IRQ in parts" refactored code and missed + one of ARDY clearings. So current code violates errata. + It causes often i2c bus timeouts on my Pandaboard. + + This patch adds a second clearing in place. + + Signed-off-by: Grygorii Strashko + Signed-off-by: Taras Kondratiuk + Signed-off-by: Wolfram Sang + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/i2c/busses/i2c-omap.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/i2c/busses/i2c-omap.c 2014-05-05 11:49:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/i2c/busses/i2c-omap.c 2014-05-05 12:48:24.000000000 +0000 +@@ -941,6 +941,9 @@ + /* + * ProDB0017052: Clear ARDY bit twice + */ ++ if (stat & OMAP_I2C_STAT_ARDY) ++ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ARDY); ++ + if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | + OMAP_I2C_STAT_AL)) { + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | +Index: linux-3.10-3.10.11/dummy/rpi_1377_fafd39123416e56bf782e323031e6fdd18b61d60.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1377_fafd39123416e56bf782e323031e6fdd18b61d60.txt 2014-05-05 12:48:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1378_8c279694727d2ec6de4cc9dc96b1d0cfac0f5295.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1378_8c279694727d2ec6de4cc9dc96b1d0cfac0f5295.patch --- linux-3.10.11/debian/patches/rpi/rpi_1378_8c279694727d2ec6de4cc9dc96b1d0cfac0f5295.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1378_8c279694727d2ec6de4cc9dc96b1d0cfac0f5295.patch 2014-05-05 12:48:25.000000000 +0000 @@ -0,0 +1,75 @@ +commit 8c279694727d2ec6de4cc9dc96b1d0cfac0f5295 +Author: Henrik Rydberg +Date: Wed Oct 2 19:15:03 2013 +0200 + + hwmon: (applesmc) Always read until end of data + + commit 25f2bd7f5add608c1d1405938f39c96927b275ca upstream. + + The crash reported and investigated in commit 5f4513 turned out to be + caused by a change to the read interface on newer (2012) SMCs. + + Tests by Chris show that simply reading the data valid line is enough + for the problem to go away. Additional tests show that the newer SMCs + no longer wait for the number of requested bytes, but start sending + data right away. Apparently the number of bytes to read is no longer + specified as before, but instead found out by reading until end of + data. Failure to read until end of data confuses the state machine, + which eventually causes the crash. + + As a remedy, assuming bit0 is the read valid line, make sure there is + nothing more to read before leaving the read function. + + Tested to resolve the original problem, and runtested on MBA3,1, + MBP4,1, MBP8,2, MBP10,1, MBP10,2. The patch seems to have no effect on + machines before 2012. + + Tested-by: Chris Murphy + Signed-off-by: Henrik Rydberg + Signed-off-by: Guenter Roeck + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/hwmon/applesmc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/hwmon/applesmc.c 2014-05-05 12:46:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/hwmon/applesmc.c 2014-05-05 12:48:25.000000000 +0000 +@@ -230,6 +230,7 @@ + + static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) + { ++ u8 status, data = 0; + int i; + + if (send_command(cmd) || send_argument(key)) { +@@ -237,6 +238,7 @@ + return -EIO; + } + ++ /* This has no effect on newer (2012) SMCs */ + if (send_byte(len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: read len fail\n", key); + return -EIO; +@@ -250,6 +252,17 @@ + buffer[i] = inb(APPLESMC_DATA_PORT); + } + ++ /* Read the data port until bit0 is cleared */ ++ for (i = 0; i < 16; i++) { ++ udelay(APPLESMC_MIN_WAIT); ++ status = inb(APPLESMC_CMD_PORT); ++ if (!(status & 0x01)) ++ break; ++ data = inb(APPLESMC_DATA_PORT); ++ } ++ if (i) ++ pr_warn("flushed %d bytes, last value is: %d\n", i, data); ++ + return 0; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1378_8c279694727d2ec6de4cc9dc96b1d0cfac0f5295.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1378_8c279694727d2ec6de4cc9dc96b1d0cfac0f5295.txt 2014-05-05 12:48:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1379_a849b2f4200ab490d7a6d80e7632d28dc80c8f6f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1379_a849b2f4200ab490d7a6d80e7632d28dc80c8f6f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1379_a849b2f4200ab490d7a6d80e7632d28dc80c8f6f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1379_a849b2f4200ab490d7a6d80e7632d28dc80c8f6f.patch 2014-05-05 12:48:26.000000000 +0000 @@ -0,0 +1,43 @@ +commit a849b2f4200ab490d7a6d80e7632d28dc80c8f6f +Author: Josef Bacik +Date: Wed Oct 9 12:24:04 2013 -0400 + + Btrfs: use right root when checking for hash collision + + commit 4871c1588f92c6c13f4713a7009f25f217055807 upstream. + + btrfs_rename was using the root of the old dir instead of the root of the new + dir when checking for a hash collision, so if you tried to move a file into a + subvol it would freak out because it would see the file you are trying to move + in its current root. This fixes the bug where this would fail + + btrfs subvol create test1 + btrfs subvol create test2 + mv test1 test2. + + Thanks to Chris Murphy for catching this, + + Reported-by: Chris Murphy + Signed-off-by: Josef Bacik + Signed-off-by: Chris Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/btrfs/inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/btrfs/inode.c 2014-05-05 11:49:48.000000000 +0000 ++++ linux-3.10-3.10.11/fs/btrfs/inode.c 2014-05-05 12:48:26.000000000 +0000 +@@ -8146,7 +8146,7 @@ + + + /* check for collisions, even if the name isn't there */ +- ret = btrfs_check_dir_item_collision(root, new_dir->i_ino, ++ ret = btrfs_check_dir_item_collision(dest, new_dir->i_ino, + new_dentry->d_name.name, + new_dentry->d_name.len); + +Index: linux-3.10-3.10.11/dummy/rpi_1379_a849b2f4200ab490d7a6d80e7632d28dc80c8f6f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1379_a849b2f4200ab490d7a6d80e7632d28dc80c8f6f.txt 2014-05-05 12:48:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1380_cec073e269a8e8ee653ada869b96c59e8286a606.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1380_cec073e269a8e8ee653ada869b96c59e8286a606.patch --- linux-3.10.11/debian/patches/rpi/rpi_1380_cec073e269a8e8ee653ada869b96c59e8286a606.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1380_cec073e269a8e8ee653ada869b96c59e8286a606.patch 2014-05-05 12:48:27.000000000 +0000 @@ -0,0 +1,44 @@ +commit cec073e269a8e8ee653ada869b96c59e8286a606 +Author: Dave Jones +Date: Thu Oct 10 20:05:35 2013 -0400 + + ext4: fix memory leak in xattr + + commit 6e4ea8e33b2057b85d75175dd89b93f5e26de3bc upstream. + + If we take the 2nd retry path in ext4_expand_extra_isize_ea, we + potentionally return from the function without having freed these + allocations. If we don't do the return, we over-write the previous + allocation pointers, so we leak either way. + + Spotted with Coverity. + + [ Fixed by tytso to set is and bs to NULL after freeing these + pointers, in case in the retry loop we later end up triggering an + error causing a jump to cleanup, at which point we could have a double + free bug. -- Ted ] + + Signed-off-by: Dave Jones + Signed-off-by: "Theodore Ts'o" + Reviewed-by: Eric Sandeen + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/ext4/xattr.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/ext4/xattr.c 2014-05-05 11:49:47.000000000 +0000 ++++ linux-3.10-3.10.11/fs/ext4/xattr.c 2014-05-05 12:48:27.000000000 +0000 +@@ -1350,6 +1350,8 @@ + s_min_extra_isize) { + tried_min_extra_isize++; + new_extra_isize = s_min_extra_isize; ++ kfree(is); is = NULL; ++ kfree(bs); bs = NULL; + goto retry; + } + error = -1; +Index: linux-3.10-3.10.11/dummy/rpi_1380_cec073e269a8e8ee653ada869b96c59e8286a606.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1380_cec073e269a8e8ee653ada869b96c59e8286a606.txt 2014-05-05 12:48:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1381_40ee05de350259890492ceb4f23017470c553217.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1381_40ee05de350259890492ceb4f23017470c553217.patch --- linux-3.10.11/debian/patches/rpi/rpi_1381_40ee05de350259890492ceb4f23017470c553217.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1381_40ee05de350259890492ceb4f23017470c553217.patch 2014-05-05 12:48:28.000000000 +0000 @@ -0,0 +1,38 @@ +commit 40ee05de350259890492ceb4f23017470c553217 +Author: Paul Mackerras +Date: Sat Sep 21 09:53:28 2013 +1000 + + KVM: PPC: Book3S HV: Fix typo in saving DSCR + + commit cfc860253abd73e1681696c08ea268d33285a2c4 upstream. + + This fixes a typo in the code that saves the guest DSCR (Data Stream + Control Register) into the kvm_vcpu_arch struct on guest exit. The + effect of the typo was that the DSCR value was saved in the wrong place, + so changes to the DSCR by the guest didn't persist across guest exit + and entry, and some host kernel memory got corrupted. + + Signed-off-by: Paul Mackerras + Acked-by: Alexander Graf + Signed-off-by: Paolo Bonzini + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/powerpc/kvm/book3s_hv_rmhandlers.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/kvm/book3s_hv_rmhandlers.S 2014-05-05 11:49:47.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/kvm/book3s_hv_rmhandlers.S 2014-05-05 12:48:27.000000000 +0000 +@@ -1054,7 +1054,7 @@ + BEGIN_FTR_SECTION + mfspr r8, SPRN_DSCR + ld r7, HSTATE_DSCR(r13) +- std r8, VCPU_DSCR(r7) ++ std r8, VCPU_DSCR(r9) + mtspr SPRN_DSCR, r7 + END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) + +Index: linux-3.10-3.10.11/dummy/rpi_1381_40ee05de350259890492ceb4f23017470c553217.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1381_40ee05de350259890492ceb4f23017470c553217.txt 2014-05-05 12:48:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1382_77587e89405f5d8225a0e750df254bcc2dcb73e1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1382_77587e89405f5d8225a0e750df254bcc2dcb73e1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1382_77587e89405f5d8225a0e750df254bcc2dcb73e1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1382_77587e89405f5d8225a0e750df254bcc2dcb73e1.patch 2014-05-05 12:48:29.000000000 +0000 @@ -0,0 +1,58 @@ +commit 77587e89405f5d8225a0e750df254bcc2dcb73e1 +Author: Helge Deller +Date: Tue Oct 1 21:54:46 2013 +0200 + + parisc: fix interruption handler to respect pagefault_disable() + + commit 59b33f148cc08fb33cbe823fca1e34f7f023765e upstream. + + Running an "echo t > /proc/sysrq-trigger" crashes the parisc kernel. The + problem is, that in print_worker_info() we try to read the workqueue info via + the probe_kernel_read() functions which use pagefault_disable() to avoid + crashes like this: + probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq)); + probe_kernel_read(&wq, &pwq->wq, sizeof(wq)); + probe_kernel_read(name, wq->name, sizeof(name) - 1); + + The problem here is, that the first probe_kernel_read(&pwq) might return zero + in pwq and as such the following probe_kernel_reads() try to access contents of + the page zero which is read protected and generate a kernel segfault. + + With this patch we fix the interruption handler to call parisc_terminate() + directly only if pagefault_disable() was not called (in which case + preempt_count()==0). Otherwise we hand over to the pagefault handler which + will try to look up the faulting address in the fixup tables. + + Signed-off-by: Helge Deller + Signed-off-by: John David Anglin + Signed-off-by: Helge Deller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/parisc/kernel/traps.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/parisc/kernel/traps.c 2014-05-05 11:49:47.000000000 +0000 ++++ linux-3.10-3.10.11/arch/parisc/kernel/traps.c 2014-05-05 12:48:28.000000000 +0000 +@@ -805,14 +805,14 @@ + else { + + /* +- * The kernel should never fault on its own address space. ++ * The kernel should never fault on its own address space, ++ * unless pagefault_disable() was called before. + */ + +- if (fault_space == 0) ++ if (fault_space == 0 && !in_atomic()) + { + pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); + parisc_terminate("Kernel Fault", regs, code, fault_address); +- + } + } + +Index: linux-3.10-3.10.11/dummy/rpi_1382_77587e89405f5d8225a0e750df254bcc2dcb73e1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1382_77587e89405f5d8225a0e750df254bcc2dcb73e1.txt 2014-05-05 12:48:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1383_1176dcded10fd4de79aaac9bb1bd77a4aabdba61.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1383_1176dcded10fd4de79aaac9bb1bd77a4aabdba61.patch --- linux-3.10.11/debian/patches/rpi/rpi_1383_1176dcded10fd4de79aaac9bb1bd77a4aabdba61.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1383_1176dcded10fd4de79aaac9bb1bd77a4aabdba61.patch 2014-05-05 12:48:30.000000000 +0000 @@ -0,0 +1,32 @@ +commit 1176dcded10fd4de79aaac9bb1bd77a4aabdba61 +Author: Russell King +Date: Tue Aug 6 09:49:14 2013 +0100 + + ARM: Fix the world famous typo with is_gate_vma() + + commit 1d0bbf428924f94867542d49d436cf254b9dbd06 upstream. + + Signed-off-by: Russell King + Signed-off-by: Greg Kroah-Hartman + Cc: Colin Cross + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/kernel/process.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/kernel/process.c 2014-05-05 11:49:47.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/kernel/process.c 2014-05-05 12:48:29.000000000 +0000 +@@ -466,7 +466,7 @@ + { + return in_gate_area(NULL, addr); + } +-#define is_gate_vma(vma) ((vma) = &gate_vma) ++#define is_gate_vma(vma) ((vma) == &gate_vma) + #else + #define is_gate_vma(vma) 0 + #endif +Index: linux-3.10-3.10.11/dummy/rpi_1383_1176dcded10fd4de79aaac9bb1bd77a4aabdba61.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1383_1176dcded10fd4de79aaac9bb1bd77a4aabdba61.txt 2014-05-05 12:48:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1384_8a229aeadcf9cf6616e56b00babc86607a3b3d1d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1384_8a229aeadcf9cf6616e56b00babc86607a3b3d1d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1384_8a229aeadcf9cf6616e56b00babc86607a3b3d1d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1384_8a229aeadcf9cf6616e56b00babc86607a3b3d1d.patch 2014-05-05 12:48:31.000000000 +0000 @@ -0,0 +1,48 @@ +commit 8a229aeadcf9cf6616e56b00babc86607a3b3d1d +Author: Vineet Gupta +Date: Mon Jun 17 18:27:23 2013 +0530 + + ARC: Setup Vector Table Base in early boot + + commit 05b016ecf5e7a8c24409d8e9effb5d2ec9107708 upstream. + + Otherwise early boot exceptions such as instructions errors due to + configuration mismatch between kernel and hardware go off to la-la land, + as opposed to hitting the handler and panic()'ing properly. + + Signed-off-by: Vineet Gupta + Cc: Guenter Roeck + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/kernel/head.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/head.S 2014-05-05 11:49:46.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/head.S 2014-05-05 12:48:30.000000000 +0000 +@@ -27,6 +27,8 @@ + ; Don't clobber r0-r4 yet. It might have bootloader provided info + ;------------------------------------------------------------------- + ++ sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE] ++ + #ifdef CONFIG_SMP + ; Only Boot (Master) proceeds. Others wait in platform dependent way + ; IDENTITY Reg [ 3 2 1 0 ] +Index: linux-3.10-3.10.11/arch/arc/kernel/irq.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/irq.c 2014-05-05 11:49:46.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/irq.c 2014-05-05 12:48:30.000000000 +0000 +@@ -32,8 +32,6 @@ + { + int level_mask = 0; + +- write_aux_reg(AUX_INTR_VEC_BASE, _int_vec_base_lds); +- + /* Disable all IRQs: enable them as devices request */ + write_aux_reg(AUX_IENABLE, 0); + +Index: linux-3.10-3.10.11/dummy/rpi_1384_8a229aeadcf9cf6616e56b00babc86607a3b3d1d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1384_8a229aeadcf9cf6616e56b00babc86607a3b3d1d.txt 2014-05-05 12:48:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1385_98f745546bd27e54fe0bed1e9c900301428de9d5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1385_98f745546bd27e54fe0bed1e9c900301428de9d5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1385_98f745546bd27e54fe0bed1e9c900301428de9d5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1385_98f745546bd27e54fe0bed1e9c900301428de9d5.patch 2014-05-05 12:48:34.000000000 +0000 @@ -0,0 +1,95 @@ +commit 98f745546bd27e54fe0bed1e9c900301428de9d5 +Author: Noam Camus +Date: Thu Sep 12 13:07:39 2013 +0530 + + ARC: SMP failed to boot due to missing IVT setup + + commit c3567f8a359b7917dcffa442301f88ed0a75211f upstream. + + Commit 05b016ecf5e7a "ARC: Setup Vector Table Base in early boot" moved + the Interrupt vector Table setup out of arc_init_IRQ() which is called + for all CPUs, to entry point of boot cpu only, breaking booting of others. + + Fix by adding the same to entry point of non-boot CPUs too. + + read_arc_build_cfg_regs() printing IVT Base Register didn't help the + casue since it prints a synthetic value if zero which is totally bogus, + so fix that to print the exact Register. + + [vgupta: Remove the now stale comment from header of arc_init_IRQ and + also added the commentary for halt-on-reset] + + Cc: Gilad Ben-Yossef + Signed-off-by: Noam Camus + Signed-off-by: Vineet Gupta + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/include/asm/sections.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/include/asm/sections.h 2014-05-05 11:49:46.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/include/asm/sections.h 2014-05-05 12:48:33.000000000 +0000 +@@ -11,7 +11,6 @@ + + #include + +-extern char _int_vec_base_lds[]; + extern char __arc_dccm_base[]; + extern char __dtb_start[]; + +Index: linux-3.10-3.10.11/arch/arc/kernel/head.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/head.S 2014-05-05 12:48:30.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/head.S 2014-05-05 12:48:33.000000000 +0000 +@@ -34,6 +34,9 @@ + ; IDENTITY Reg [ 3 2 1 0 ] + ; (cpu-id) ^^^ => Zero for UP ARC700 + ; => #Core-ID if SMP (Master 0) ++ ; Note that non-boot CPUs might not land here if halt-on-reset and ++ ; instead breath life from @first_lines_of_secondary, but we still ++ ; need to make sure only boot cpu takes this path. + GET_CPU_ID r5 + cmp r5, 0 + jnz arc_platform_smp_wait_to_boot +@@ -98,6 +101,8 @@ + + first_lines_of_secondary: + ++ sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE] ++ + ; setup per-cpu idle task as "current" on this CPU + ld r0, [@secondary_idle_tsk] + SET_CURR_TASK_ON_CPU r0, r1 +Index: linux-3.10-3.10.11/arch/arc/kernel/irq.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/irq.c 2014-05-05 12:48:30.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/irq.c 2014-05-05 12:48:33.000000000 +0000 +@@ -24,7 +24,6 @@ + * -Needed for each CPU (hence not foldable into init_IRQ) + * + * what it does ? +- * -setup Vector Table Base Reg - in case Linux not linked at 0x8000_0000 + * -Disable all IRQs (on CPU side) + * -Optionally, setup the High priority Interrupts as Level 2 IRQs + */ +Index: linux-3.10-3.10.11/arch/arc/kernel/setup.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/setup.c 2014-05-05 11:49:46.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/setup.c 2014-05-05 12:48:33.000000000 +0000 +@@ -47,10 +47,7 @@ + READ_BCR(AUX_IDENTITY, cpu->core); + + cpu->timers = read_aux_reg(ARC_REG_TIMERS_BCR); +- + cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); +- if (cpu->vec_base == 0) +- cpu->vec_base = (unsigned int)_int_vec_base_lds; + + READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); + cpu->uncached_base = uncached_space.start << 24; +Index: linux-3.10-3.10.11/dummy/rpi_1385_98f745546bd27e54fe0bed1e9c900301428de9d5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1385_98f745546bd27e54fe0bed1e9c900301428de9d5.txt 2014-05-05 12:48:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1386_8036c31c84117707d4132cd199d997d7ed41427c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1386_8036c31c84117707d4132cd199d997d7ed41427c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1386_8036c31c84117707d4132cd199d997d7ed41427c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1386_8036c31c84117707d4132cd199d997d7ed41427c.patch 2014-05-05 12:48:34.000000000 +0000 @@ -0,0 +1,44 @@ +commit 8036c31c84117707d4132cd199d997d7ed41427c +Author: Mischa Jonker +Date: Fri Aug 30 11:56:25 2013 +0200 + + ARC: Fix __udelay calculation + + commit 7efd0da2d17360e1cef91507dbe619db0ee2c691 upstream. + + Cast usecs to u64, to ensure that the (usecs * 4295 * HZ) + multiplication is 64 bit. + + Initially, the (usecs * 4295 * HZ) part was done as a 32 bit + multiplication, with the result casted to 64 bit. This led to some bits + falling off, causing a "DMA initialization error" in the stmmac Ethernet + driver, due to a premature timeout. + + Signed-off-by: Mischa Jonker + Signed-off-by: Vineet Gupta + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/include/asm/delay.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/include/asm/delay.h 2014-05-05 11:49:46.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/include/asm/delay.h 2014-05-05 12:48:34.000000000 +0000 +@@ -53,11 +53,10 @@ + { + unsigned long loops; + +- /* (long long) cast ensures 64 bit MPY - real or emulated ++ /* (u64) cast ensures 64 bit MPY - real or emulated + * HZ * 4295 is pre-evaluated by gcc - hence only 2 mpy ops + */ +- loops = ((long long)(usecs * 4295 * HZ) * +- (long long)(loops_per_jiffy)) >> 32; ++ loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; + + __delay(loops); + } +Index: linux-3.10-3.10.11/dummy/rpi_1386_8036c31c84117707d4132cd199d997d7ed41427c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1386_8036c31c84117707d4132cd199d997d7ed41427c.txt 2014-05-05 12:48:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1387_5cd12e7776183668bd92a5f5fe102113d3bb599a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1387_5cd12e7776183668bd92a5f5fe102113d3bb599a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1387_5cd12e7776183668bd92a5f5fe102113d3bb599a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1387_5cd12e7776183668bd92a5f5fe102113d3bb599a.patch 2014-05-05 12:48:35.000000000 +0000 @@ -0,0 +1,40 @@ +commit 5cd12e7776183668bd92a5f5fe102113d3bb599a +Author: Mischa Jonker +Date: Thu Sep 26 15:44:56 2013 +0200 + + ARC: Handle zero-overhead-loop in unaligned access handler + + commit c11eb222fd7d4db91196121dbf854178505d2751 upstream. + + If a load or store is the last instruction in a zero-overhead-loop, and + it's misaligned, the loop would execute only once. + + This fixes that problem. + + Signed-off-by: Mischa Jonker + Signed-off-by: Vineet Gupta + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/kernel/unaligned.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/unaligned.c 2014-05-05 11:49:45.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/unaligned.c 2014-05-05 12:48:35.000000000 +0000 +@@ -233,6 +233,12 @@ + regs->status32 &= ~STATUS_DE_MASK; + } else { + regs->ret += state.instr_len; ++ ++ /* handle zero-overhead-loop */ ++ if ((regs->ret == regs->lp_end) && (regs->lp_count)) { ++ regs->ret = regs->lp_start; ++ regs->lp_count--; ++ } + } + + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1387_5cd12e7776183668bd92a5f5fe102113d3bb599a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1387_5cd12e7776183668bd92a5f5fe102113d3bb599a.txt 2014-05-05 12:48:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1388_a683a93b1ce0b86944a51a1b8f787aa684836edb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1388_a683a93b1ce0b86944a51a1b8f787aa684836edb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1388_a683a93b1ce0b86944a51a1b8f787aa684836edb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1388_a683a93b1ce0b86944a51a1b8f787aa684836edb.patch 2014-05-05 12:48:36.000000000 +0000 @@ -0,0 +1,53 @@ +commit a683a93b1ce0b86944a51a1b8f787aa684836edb +Author: Vineet Gupta +Date: Thu Sep 26 18:50:40 2013 +0530 + + ARC: Fix 32-bit wrap around in access_ok() + + commit 0752adfda15f0eca9859a76da3db1800e129ad43 upstream. + + Anton reported + + | LTP tests syscalls/process_vm_readv01 and process_vm_writev01 fail + | similarly in one testcase test_iov_invalid -> lvec->iov_base. + | Testcase expects errno EFAULT and return code -1, + | but it gets return code 1 and ERRNO is 0 what means success. + + Essentially test case was passing a pointer of -1 which access_ok() + was not catching. It was doing [@addr + @sz <= TASK_SIZE] which would + pass for @addr == -1 + + Fixed that by rewriting as [@addr <= TASK_SIZE - @sz] + + Reported-by: Anton Kolesov + Signed-off-by: Vineet Gupta + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/include/asm/uaccess.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/include/asm/uaccess.h 2014-05-05 11:49:45.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/include/asm/uaccess.h 2014-05-05 12:48:35.000000000 +0000 +@@ -43,7 +43,7 @@ + * Because it essentially checks if buffer end is within limit and @len is + * non-ngeative, which implies that buffer start will be within limit too. + * +- * The reason for rewriting being, for majorit yof cases, @len is generally ++ * The reason for rewriting being, for majority of cases, @len is generally + * compile time constant, causing first sub-expression to be compile time + * subsumed. + * +@@ -53,7 +53,7 @@ + * + */ + #define __user_ok(addr, sz) (((sz) <= TASK_SIZE) && \ +- (((addr)+(sz)) <= get_fs())) ++ ((addr) <= (get_fs() - (sz)))) + #define __access_ok(addr, sz) (unlikely(__kernel_ok) || \ + likely(__user_ok((addr), (sz)))) + +Index: linux-3.10-3.10.11/dummy/rpi_1388_a683a93b1ce0b86944a51a1b8f787aa684836edb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1388_a683a93b1ce0b86944a51a1b8f787aa684836edb.txt 2014-05-05 12:48:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1389_0c06a0a693a5baaeacdb4c9485d5d6d490ea8a23.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1389_0c06a0a693a5baaeacdb4c9485d5d6d490ea8a23.patch --- linux-3.10.11/debian/patches/rpi/rpi_1389_0c06a0a693a5baaeacdb4c9485d5d6d490ea8a23.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1389_0c06a0a693a5baaeacdb4c9485d5d6d490ea8a23.patch 2014-05-05 12:48:37.000000000 +0000 @@ -0,0 +1,89 @@ +commit 0c06a0a693a5baaeacdb4c9485d5d6d490ea8a23 +Author: Vineet Gupta +Date: Wed Sep 25 16:53:32 2013 +0530 + + ARC: Workaround spinlock livelock in SMP SystemC simulation + + commit 6c00350b573c0bd3635436e43e8696951dd6e1b6 upstream. + + Some ARC SMP systems lack native atomic R-M-W (LLOCK/SCOND) insns and + can only use atomic EX insn (reg with mem) to build higher level R-M-W + primitives. This includes a SystemC based SMP simulation model. + + So rwlocks need to use a protecting spinlock for atomic cmp-n-exchange + operation to update reader(s)/writer count. + + The spinlock operation itself looks as follows: + + mov reg, 1 ; 1=locked, 0=unlocked + retry: + EX reg, [lock] ; load existing, store 1, atomically + BREQ reg, 1, rety ; if already locked, retry + + In single-threaded simulation, SystemC alternates between the 2 cores + with "N" insn each based scheduling. Additionally for insn with global + side effect, such as EX writing to shared mem, a core switch is + enforced too. + + Given that, 2 cores doing a repeated EX on same location, Linux often + got into a livelock e.g. when both cores were fiddling with tasklist + lock (gdbserver / hackbench) for read/write respectively as the + sequence diagram below shows: + + core1 core2 + -------- -------- + 1. spin lock [EX r=0, w=1] - LOCKED + 2. rwlock(Read) - LOCKED + 3. spin unlock [ST 0] - UNLOCKED + spin lock [EX r=0,w=1] - LOCKED + -- resched core 1---- + + 5. spin lock [EX r=1] - ALREADY-LOCKED + + -- resched core 2---- + 6. rwlock(Write) - READER-LOCKED + 7. spin unlock [ST 0] + 8. rwlock failed, retry again + + 9. spin lock [EX r=0, w=1] + -- resched core 1---- + + 10 spinlock locked in #9, retry #5 + 11. spin lock [EX gets 1] + -- resched core 2---- + ... + ... + + The fix was to unlock using the EX insn too (step 7), to trigger another + SystemC scheduling pass which would let core1 proceed, eliding the + livelock. + + Signed-off-by: Vineet Gupta + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/include/asm/spinlock.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/include/asm/spinlock.h 2014-05-05 11:49:45.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/include/asm/spinlock.h 2014-05-05 12:48:36.000000000 +0000 +@@ -45,7 +45,14 @@ + + static inline void arch_spin_unlock(arch_spinlock_t *lock) + { +- lock->slock = __ARCH_SPIN_LOCK_UNLOCKED__; ++ unsigned int tmp = __ARCH_SPIN_LOCK_UNLOCKED__; ++ ++ __asm__ __volatile__( ++ " ex %0, [%1] \n" ++ : "+r" (tmp) ++ : "r"(&(lock->slock)) ++ : "memory"); ++ + smp_mb(); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1389_0c06a0a693a5baaeacdb4c9485d5d6d490ea8a23.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1389_0c06a0a693a5baaeacdb4c9485d5d6d490ea8a23.txt 2014-05-05 12:48:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1390_19a420033da02200c424adfa3a7b9eed6e3a6dc2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1390_19a420033da02200c424adfa3a7b9eed6e3a6dc2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1390_19a420033da02200c424adfa3a7b9eed6e3a6dc2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1390_19a420033da02200c424adfa3a7b9eed6e3a6dc2.patch 2014-05-05 12:48:37.000000000 +0000 @@ -0,0 +1,89 @@ +commit 19a420033da02200c424adfa3a7b9eed6e3a6dc2 +Author: Christian Ruppert +Date: Wed Oct 2 11:13:38 2013 +0200 + + ARC: Fix signal frame management for SA_SIGINFO + + commit 10469350e345599dfef3fa78a7c19fb230e674c1 upstream. + + Previously, when a signal was registered with SA_SIGINFO, parameters 2 + and 3 of the signal handler were written to registers r1 and r2 before + the register set was saved. This led to corruption of these two + registers after returning from the signal handler (the wrong values were + restored). + With this patch, registers are now saved before any parameters are + passed, thus maintaining the processor state from before signal entry. + + Signed-off-by: Christian Ruppert + Signed-off-by: Vineet Gupta + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/kernel/signal.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/signal.c 2014-05-05 11:49:45.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/signal.c 2014-05-05 12:48:37.000000000 +0000 +@@ -101,7 +101,6 @@ + { + struct rt_sigframe __user *sf; + unsigned int magic; +- int err; + struct pt_regs *regs = current_pt_regs(); + + /* Always make any pending restarted system calls return -EINTR */ +@@ -119,15 +118,16 @@ + if (!access_ok(VERIFY_READ, sf, sizeof(*sf))) + goto badframe; + +- err = restore_usr_regs(regs, sf); +- err |= __get_user(magic, &sf->sigret_magic); +- if (err) ++ if (__get_user(magic, &sf->sigret_magic)) + goto badframe; + + if (unlikely(is_do_ss_needed(magic))) + if (restore_altstack(&sf->uc.uc_stack)) + goto badframe; + ++ if (restore_usr_regs(regs, sf)) ++ goto badframe; ++ + /* Don't restart from sigreturn */ + syscall_wont_restart(regs); + +@@ -191,6 +191,15 @@ + return 1; + + /* ++ * w/o SA_SIGINFO, struct ucontext is partially populated (only ++ * uc_mcontext/uc_sigmask) for kernel's normal user state preservation ++ * during signal handler execution. This works for SA_SIGINFO as well ++ * although the semantics are now overloaded (the same reg state can be ++ * inspected by userland: but are they allowed to fiddle with it ? ++ */ ++ err |= stash_usr_regs(sf, regs, set); ++ ++ /* + * SA_SIGINFO requires 3 args to signal handler: + * #1: sig-no (common to any handler) + * #2: struct siginfo +@@ -213,14 +222,6 @@ + magic = MAGIC_SIGALTSTK; + } + +- /* +- * w/o SA_SIGINFO, struct ucontext is partially populated (only +- * uc_mcontext/uc_sigmask) for kernel's normal user state preservation +- * during signal handler execution. This works for SA_SIGINFO as well +- * although the semantics are now overloaded (the same reg state can be +- * inspected by userland: but are they allowed to fiddle with it ? +- */ +- err |= stash_usr_regs(sf, regs, set); + err |= __put_user(magic, &sf->sigret_magic); + if (err) + return err; +Index: linux-3.10-3.10.11/dummy/rpi_1390_19a420033da02200c424adfa3a7b9eed6e3a6dc2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1390_19a420033da02200c424adfa3a7b9eed6e3a6dc2.txt 2014-05-05 12:48:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1391_4b3ea63f5af44f93bd28d94a93508bbd3186be89.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1391_4b3ea63f5af44f93bd28d94a93508bbd3186be89.patch --- linux-3.10.11/debian/patches/rpi/rpi_1391_4b3ea63f5af44f93bd28d94a93508bbd3186be89.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1391_4b3ea63f5af44f93bd28d94a93508bbd3186be89.patch 2014-05-05 12:48:38.000000000 +0000 @@ -0,0 +1,50 @@ +commit 4b3ea63f5af44f93bd28d94a93508bbd3186be89 +Author: Vineet Gupta +Date: Thu Oct 10 19:33:57 2013 +0530 + + ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc" + + commit 5b24282846c064ee90d40fcb3a8f63b8e754fd28 upstream. + + ARCompact TRAP_S insn used for breakpoints, commits before exception is + taken (updating architectural PC). So ptregs->ret contains next-PC and + not the breakpoint PC itself. This is different from other restartable + exceptions such as TLB Miss where ptregs->ret has exact faulting PC. + gdb needs to know exact-PC hence ARC ptrace GETREGSET provides for + @stop_pc which returns ptregs->ret vs. EFA depending on the + situation. + + However, writing stop_pc (SETREGSET request), which updates ptregs->ret + doesn't makes sense stop_pc doesn't always correspond to that reg as + described above. + + This was not an issue so far since user_regs->ret / user_regs->stop_pc + had same value and both writing to ptregs->ret was OK, needless, but NOT + broken, hence not observed. + + With gdb "jump", they diverge, and user_regs->ret updating ptregs is + overwritten immediately with stop_pc, which this patch fixes. + + Reported-by: Anton Kolesov + Signed-off-by: Vineet Gupta + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/kernel/ptrace.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/kernel/ptrace.c 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/kernel/ptrace.c 2014-05-05 12:48:38.000000000 +0000 +@@ -92,7 +92,7 @@ + REG_IN_CHUNK(scratch, callee, ptregs); /* pt_regs[bta..orig_r8] */ + REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */ + REG_IGNORE_ONE(efa); /* efa update invalid */ +- REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */ ++ REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */ + + return ret; + } +Index: linux-3.10-3.10.11/dummy/rpi_1391_4b3ea63f5af44f93bd28d94a93508bbd3186be89.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1391_4b3ea63f5af44f93bd28d94a93508bbd3186be89.txt 2014-05-05 12:48:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1392_e2dcd671f79ade2c764034aeab492ce9a7da6194.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1392_e2dcd671f79ade2c764034aeab492ce9a7da6194.patch --- linux-3.10.11/debian/patches/rpi/rpi_1392_e2dcd671f79ade2c764034aeab492ce9a7da6194.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1392_e2dcd671f79ade2c764034aeab492ce9a7da6194.patch 2014-05-05 12:48:39.000000000 +0000 @@ -0,0 +1,37 @@ +commit e2dcd671f79ade2c764034aeab492ce9a7da6194 +Author: Dan Carpenter +Date: Fri Aug 23 11:40:59 2013 +0300 + + watchdog: ts72xx_wdt: locking bug in ioctl + + commit 8612ed0d97abcf1c016d34755b7cf2060de71963 upstream. + + Calling the WDIOC_GETSTATUS & WDIOC_GETBOOTSTATUS and twice will cause a + interruptible deadlock. + + Signed-off-by: Dan Carpenter + Reviewed-by: Guenter Roeck + Signed-off-by: Wim Van Sebroeck + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/watchdog/ts72xx_wdt.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/watchdog/ts72xx_wdt.c 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/watchdog/ts72xx_wdt.c 2014-05-05 12:48:38.000000000 +0000 +@@ -310,7 +310,8 @@ + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: +- return put_user(0, p); ++ error = put_user(0, p); ++ break; + + case WDIOC_KEEPALIVE: + ts72xx_wdt_kick(wdt); +Index: linux-3.10-3.10.11/dummy/rpi_1392_e2dcd671f79ade2c764034aeab492ce9a7da6194.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1392_e2dcd671f79ade2c764034aeab492ce9a7da6194.txt 2014-05-05 12:48:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1393_bb42ad4e4d2c1c10637368c750a5683100f2ddfa.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1393_bb42ad4e4d2c1c10637368c750a5683100f2ddfa.patch --- linux-3.10.11/debian/patches/rpi/rpi_1393_bb42ad4e4d2c1c10637368c750a5683100f2ddfa.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1393_bb42ad4e4d2c1c10637368c750a5683100f2ddfa.patch 2014-05-05 12:48:41.000000000 +0000 @@ -0,0 +1,150 @@ +commit bb42ad4e4d2c1c10637368c750a5683100f2ddfa +Author: Ingo Molnar +Date: Thu Oct 10 10:16:30 2013 +0200 + + compiler/gcc4: Add quirk for 'asm goto' miscompilation bug + + commit 3f0116c3238a96bc18ad4b4acefe4e7be32fa861 upstream. + + Fengguang Wu, Oleg Nesterov and Peter Zijlstra tracked down + a kernel crash to a GCC bug: GCC miscompiles certain 'asm goto' + constructs, as outlined here: + + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 + + Implement a workaround suggested by Jakub Jelinek. + + Reported-and-tested-by: Fengguang Wu + Reported-by: Oleg Nesterov + Reported-by: Peter Zijlstra + Suggested-by: Jakub Jelinek + Reviewed-by: Richard Henderson + Cc: Linus Torvalds + Cc: Andrew Morton + Link: http://lkml.kernel.org/r/20131015062351.GA4666@gmail.com + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/include/asm/jump_label.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/include/asm/jump_label.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/include/asm/jump_label.h 2014-05-05 12:48:39.000000000 +0000 +@@ -16,7 +16,7 @@ + + static __always_inline bool arch_static_branch(struct static_key *key) + { +- asm goto("1:\n\t" ++ asm_volatile_goto("1:\n\t" + JUMP_LABEL_NOP "\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + ".word 1b, %l[l_yes], %c0\n\t" +Index: linux-3.10-3.10.11/arch/mips/include/asm/jump_label.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/mips/include/asm/jump_label.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/mips/include/asm/jump_label.h 2014-05-05 12:48:39.000000000 +0000 +@@ -22,7 +22,7 @@ + + static __always_inline bool arch_static_branch(struct static_key *key) + { +- asm goto("1:\tnop\n\t" ++ asm_volatile_goto("1:\tnop\n\t" + "nop\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + WORD_INSN " 1b, %l[l_yes], %0\n\t" +Index: linux-3.10-3.10.11/arch/powerpc/include/asm/jump_label.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/powerpc/include/asm/jump_label.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/powerpc/include/asm/jump_label.h 2014-05-05 12:48:39.000000000 +0000 +@@ -19,7 +19,7 @@ + + static __always_inline bool arch_static_branch(struct static_key *key) + { +- asm goto("1:\n\t" ++ asm_volatile_goto("1:\n\t" + "nop\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" +Index: linux-3.10-3.10.11/arch/s390/include/asm/jump_label.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/s390/include/asm/jump_label.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/s390/include/asm/jump_label.h 2014-05-05 12:48:39.000000000 +0000 +@@ -15,7 +15,7 @@ + + static __always_inline bool arch_static_branch(struct static_key *key) + { +- asm goto("0: brcl 0,0\n" ++ asm_volatile_goto("0: brcl 0,0\n" + ".pushsection __jump_table, \"aw\"\n" + ASM_ALIGN "\n" + ASM_PTR " 0b, %l[label], %0\n" +Index: linux-3.10-3.10.11/arch/sparc/include/asm/jump_label.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/sparc/include/asm/jump_label.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/sparc/include/asm/jump_label.h 2014-05-05 12:48:39.000000000 +0000 +@@ -9,7 +9,7 @@ + + static __always_inline bool arch_static_branch(struct static_key *key) + { +- asm goto("1:\n\t" ++ asm_volatile_goto("1:\n\t" + "nop\n\t" + "nop\n\t" + ".pushsection __jump_table, \"aw\"\n\t" +Index: linux-3.10-3.10.11/arch/x86/include/asm/cpufeature.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/cpufeature.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/cpufeature.h 2014-05-05 12:48:40.000000000 +0000 +@@ -365,7 +365,7 @@ + static __always_inline __pure bool __static_cpu_has(u16 bit) + { + #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5 +- asm goto("1: jmp %l[t_no]\n" ++ asm_volatile_goto("1: jmp %l[t_no]\n" + "2:\n" + ".section .altinstructions,\"a\"\n" + " .long 1b - .\n" +Index: linux-3.10-3.10.11/arch/x86/include/asm/jump_label.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/jump_label.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/jump_label.h 2014-05-05 12:48:40.000000000 +0000 +@@ -13,7 +13,7 @@ + + static __always_inline bool arch_static_branch(struct static_key *key) + { +- asm goto("1:" ++ asm_volatile_goto("1:" + STATIC_KEY_INITIAL_NOP + ".pushsection __jump_table, \"aw\" \n\t" + _ASM_ALIGN "\n\t" +Index: linux-3.10-3.10.11/include/linux/compiler-gcc4.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/compiler-gcc4.h 2014-05-05 11:49:44.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/compiler-gcc4.h 2014-05-05 12:48:40.000000000 +0000 +@@ -65,6 +65,21 @@ + #define __visible __attribute__((externally_visible)) + #endif + ++/* ++ * GCC 'asm goto' miscompiles certain code sequences: ++ * ++ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 ++ * ++ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. ++ * Fixed in GCC 4.8.2 and later versions. ++ * ++ * (asm goto is automatically volatile - the naming reflects this.) ++ */ ++#if GCC_VERSION <= 40801 ++# define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) ++#else ++# define asm_volatile_goto(x...) do { asm goto(x); } while (0) ++#endif + + #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP + #if GCC_VERSION >= 40400 +Index: linux-3.10-3.10.11/dummy/rpi_1393_bb42ad4e4d2c1c10637368c750a5683100f2ddfa.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1393_bb42ad4e4d2c1c10637368c750a5683100f2ddfa.txt 2014-05-05 12:48:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1394_92a02b07759bb5cbed4a4793019d14247649925c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1394_92a02b07759bb5cbed4a4793019d14247649925c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1394_92a02b07759bb5cbed4a4793019d14247649925c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1394_92a02b07759bb5cbed4a4793019d14247649925c.patch 2014-05-05 12:48:41.000000000 +0000 @@ -0,0 +1,93 @@ +commit 92a02b07759bb5cbed4a4793019d14247649925c +Author: David Henningsson +Date: Mon Oct 7 10:39:59 2013 +0200 + + ALSA: hda - Fix mono speakers and headset mic on Dell Vostro 5470 + + This is a backport for stable. The original commit SHA is + 338cae565c53755de9f87d6a801517940d2d56f7. + + On this machine, DAC on node 0x03 seems to give mono output. + + Also, it needs additional patches for headset mic support. + It supports CTIA style headsets only. + + Alsa-info available at the bug link below. + + BugLink: https://bugs.launchpad.net/bugs/1236228 + Signed-off-by: David Henningsson + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_realtek.c 2014-05-05 12:48:22.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c 2014-05-05 12:48:41.000000000 +0000 +@@ -3200,6 +3200,15 @@ + } + } + ++static void alc290_fixup_mono_speakers(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) ++ /* Remove DAC node 0x03, as it seems to be ++ giving mono output */ ++ snd_hda_override_wcaps(codec, 0x03, 0); ++} ++ + enum { + ALC269_FIXUP_SONY_VAIO, + ALC275_FIXUP_SONY_VAIO_GPIO2, +@@ -3227,6 +3236,8 @@ + ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, + ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, ++ ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, ++ ALC290_FIXUP_MONO_SPEAKERS, + ALC269_FIXUP_HEADSET_MODE, + ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, + ALC269_FIXUP_ASUS_X101_FUNC, +@@ -3413,6 +3424,15 @@ + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC + }, ++ [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC ++ }, + [ALC269_FIXUP_HEADSET_MODE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode, +@@ -3485,6 +3505,12 @@ + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost, + }, ++ [ALC290_FIXUP_MONO_SPEAKERS] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc290_fixup_mono_speakers, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -3519,6 +3545,7 @@ + SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS), + SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), + SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), +Index: linux-3.10-3.10.11/dummy/rpi_1394_92a02b07759bb5cbed4a4793019d14247649925c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1394_92a02b07759bb5cbed4a4793019d14247649925c.txt 2014-05-05 12:48:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1395_ad4c3cc41d6248a80231a6b87f1dab31542f011c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1395_ad4c3cc41d6248a80231a6b87f1dab31542f011c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1395_ad4c3cc41d6248a80231a6b87f1dab31542f011c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1395_ad4c3cc41d6248a80231a6b87f1dab31542f011c.patch 2014-05-05 12:48:42.000000000 +0000 @@ -0,0 +1,98 @@ +commit ad4c3cc41d6248a80231a6b87f1dab31542f011c +Author: Al Viro +Date: Sat Aug 24 12:08:17 2013 -0400 + + cope with potentially long ->d_dname() output for shmem/hugetlb + + commit 118b23022512eb2f41ce42db70dc0568d00be4ba upstream. + + dynamic_dname() is both too much and too little for those - the + output may be well in excess of 64 bytes dynamic_dname() assumes + to be enough (thanks to ashmem feeding really long names to + shmem_file_setup()) and vsnprintf() is an overkill for those + guys. + + Signed-off-by: Al Viro + Cc: Colin Cross + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/dcache.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/dcache.c 2014-05-05 11:49:43.000000000 +0000 ++++ linux-3.10-3.10.11/fs/dcache.c 2014-05-05 12:48:42.000000000 +0000 +@@ -2724,6 +2724,17 @@ + return memcpy(buffer, temp, sz); + } + ++char *simple_dname(struct dentry *dentry, char *buffer, int buflen) ++{ ++ char *end = buffer + buflen; ++ /* these dentries are never renamed, so d_lock is not needed */ ++ if (prepend(&end, &buflen, " (deleted)", 11) || ++ prepend_name(&end, &buflen, &dentry->d_name) || ++ prepend(&end, &buflen, "/", 1)) ++ end = ERR_PTR(-ENAMETOOLONG); ++ return end; ++} ++ + /* + * Write full pathname from the root of the filesystem into the buffer. + */ +Index: linux-3.10-3.10.11/fs/hugetlbfs/inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/hugetlbfs/inode.c 2014-05-05 11:49:43.000000000 +0000 ++++ linux-3.10-3.10.11/fs/hugetlbfs/inode.c 2014-05-05 12:48:42.000000000 +0000 +@@ -916,14 +916,8 @@ + return h - hstates; + } + +-static char *hugetlb_dname(struct dentry *dentry, char *buffer, int buflen) +-{ +- return dynamic_dname(dentry, buffer, buflen, "/%s (deleted)", +- dentry->d_name.name); +-} +- + static struct dentry_operations anon_ops = { +- .d_dname = hugetlb_dname ++ .d_dname = simple_dname + }; + + /* +Index: linux-3.10-3.10.11/include/linux/dcache.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/dcache.h 2014-05-05 11:49:43.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/dcache.h 2014-05-05 12:48:42.000000000 +0000 +@@ -332,6 +332,7 @@ + * helper function for dentry_operations.d_dname() members + */ + extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); ++extern char *simple_dname(struct dentry *, char *, int); + + extern char *__d_path(const struct path *, const struct path *, char *, int); + extern char *d_absolute_path(const struct path *, char *, int); +Index: linux-3.10-3.10.11/mm/shmem.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/shmem.c 2014-05-05 11:49:43.000000000 +0000 ++++ linux-3.10-3.10.11/mm/shmem.c 2014-05-05 12:48:42.000000000 +0000 +@@ -2879,14 +2879,8 @@ + + /* common code */ + +-static char *shmem_dname(struct dentry *dentry, char *buffer, int buflen) +-{ +- return dynamic_dname(dentry, buffer, buflen, "/%s (deleted)", +- dentry->d_name.name); +-} +- + static struct dentry_operations anon_ops = { +- .d_dname = shmem_dname ++ .d_dname = simple_dname + }; + + /** +Index: linux-3.10-3.10.11/dummy/rpi_1395_ad4c3cc41d6248a80231a6b87f1dab31542f011c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1395_ad4c3cc41d6248a80231a6b87f1dab31542f011c.txt 2014-05-05 12:48:42.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1396_27c35c76cdfec3848ef0997605cfc16cb85a290c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1396_27c35c76cdfec3848ef0997605cfc16cb85a290c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1396_27c35c76cdfec3848ef0997605cfc16cb85a290c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1396_27c35c76cdfec3848ef0997605cfc16cb85a290c.patch 2014-05-05 12:48:43.000000000 +0000 @@ -0,0 +1,100 @@ +commit 27c35c76cdfec3848ef0997605cfc16cb85a290c +Author: Chris Wilson +Date: Sun Sep 29 19:15:07 2013 +0100 + + drm/i915: Only apply DPMS to the encoder if enabled + + commit c9976dcf55c8aaa7037427b239f15e5acfc01a3a upstream. + + The current test for an attached enabled encoder fails if we have + multiple connectors aliased to the same encoder - both connectors + believe they own the enabled encoder and so we attempt to both enable + and disable DPMS on the encoder, leading to hilarity and an OOPs: + + [ 354.803064] WARNING: CPU: 0 PID: 482 at + /usr/src/linux/dist/3.11.2/drivers/gpu/drm/i915/intel_display.c:3869 intel_modeset_check_state+0x764/0x770 [i915]() + [ 354.803064] wrong connector dpms state + [ 354.803084] Modules linked in: nfsd auth_rpcgss oid_registry exportfs nfs lockd sunrpc xt_nat iptable_nat nf_nat_ipv4 nf_nat xt_limit xt_LOG xt_tcpudp nf_conntrack_ipv4 nf_defrag_ipv4 ipt_REJECT ipv6 xt_recent xt_conntrack nf_conntrack iptable_filter ip_tables x_tables snd_hda_codec_realtek snd_hda_codec_hdmi x86_pkg_temp_thermal snd_hda_intel coretemp kvm_intel snd_hda_codec i915 kvm snd_hwdep snd_pcm_oss snd_mixer_oss crc32_pclmul snd_pcm crc32c_intel e1000e intel_agp igb ghash_clmulni_intel intel_gtt aesni_intel cfbfillrect aes_x86_64 cfbimgblt lrw cfbcopyarea drm_kms_helper ptp video thermal processor gf128mul snd_page_alloc drm snd_timer glue_helper 8250_pci snd pps_core ablk_helper agpgart cryptd sg soundcore fan i2c_algo_bit sr_mod thermal_sys 8250 i2c_i801 serial_core + hwmon cdrom i2c_core evdev button + [ 354.803086] CPU: 0 PID: 482 Comm: kworker/0:1 Not tainted 3.11.2 #1 + [ 354.803087] Hardware name: Supermicro X10SAE/X10SAE, BIOS 1.00 05/03/2013 [ 354.803091] Workqueue: events console_callback + [ 354.803092] 0000000000000009 ffff88023611db48 ffffffff814048ac ffff88023611db90 + [ 354.803093] ffff88023611db80 ffffffff8103d4e3 ffff880230d82800 ffff880230f9b800 + [ 354.803094] ffff880230f99000 ffff880230f99448 ffff8802351c0e00 ffff88023611dbe0 + [ 354.803094] Call Trace: + [ 354.803098] [] dump_stack+0x54/0x8d + [ 354.803101] [] warn_slowpath_common+0x73/0x90 + [ 354.803103] [] warn_slowpath_fmt+0x47/0x50 + [ 354.803109] [] ? intel_ddi_connector_get_hw_state+0x5e/0x110 [i915] + [ 354.803114] [] intel_modeset_check_state+0x764/0x770 [i915] + [ 354.803117] [] intel_connector_dpms+0x3b/0x60 [i915] + [ 354.803120] [] drm_fb_helper_dpms.isra.11+0x120/0x160 [drm_kms_helper] + [ 354.803122] [] drm_fb_helper_blank+0x3e/0x80 [drm_kms_helper] + [ 354.803123] [] fb_blank+0x52/0xc0 + [ 354.803125] [] fbcon_blank+0x21b/0x2d0 + [ 354.803127] [] ? update_rq_clock.part.74+0x13/0x30 + [ 354.803129] [] ? lock_timer_base.isra.30+0x26/0x50 + [ 354.803130] [] ? internal_add_timer+0x12/0x40 + [ 354.803131] [] ? mod_timer+0xf8/0x1c0 + [ 354.803133] [] do_unblank_screen+0xa1/0x1c0 + [ 354.803134] [] poke_blanked_console+0xc7/0xd0 + [ 354.803136] [] console_callback+0x13f/0x160 + [ 354.803137] [] process_one_work+0x148/0x3d0 + [ 354.803138] [] worker_thread+0x119/0x3a0 + [ 354.803140] [] ? manage_workers.isra.30+0x2a0/0x2a0 + [ 354.803141] [] kthread+0xbb/0xc0 + [ 354.803142] [] ? kthread_create_on_node+0x120/0x120 + [ 354.803144] [] ret_from_fork+0x7c/0xb0 + [ 354.803145] [] ? kthread_create_on_node+0x120/0x120 + + This regression goes back to the big modeset rework and the conversion + to the new dpms helpers which started with: + + commit 5ab432ef4997ce32c9406721b37ef6e97e57dae1 + Author: Daniel Vetter + Date: Sat Jun 30 08:59:56 2012 +0200 + + drm/i915/hdmi: convert to encoder->disable/enable + + Fixes: igt/kms_flip/dpms-off-confusion + Reported-and-tested-by: Wakko Warner + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68030 + Link: http://lkml.kernel.org/r/20130928185023.GA21672@animx.eu.org + Signed-off-by: Chris Wilson + [danvet: Add regression citation, mention the igt testcase this fixes + and slap a cc: stable on the patch.] + Signed-off-by: Daniel Vetter + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_display.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/i915/intel_display.c 2014-05-05 12:46:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/i915/intel_display.c 2014-05-05 12:48:43.000000000 +0000 +@@ -3946,8 +3946,6 @@ + * consider. */ + void intel_connector_dpms(struct drm_connector *connector, int mode) + { +- struct intel_encoder *encoder = intel_attached_encoder(connector); +- + /* All the simple cases only support two dpms states. */ + if (mode != DRM_MODE_DPMS_ON) + mode = DRM_MODE_DPMS_OFF; +@@ -3958,10 +3956,8 @@ + connector->dpms = mode; + + /* Only need to change hw state when actually enabled */ +- if (encoder->base.crtc) +- intel_encoder_dpms(encoder, mode); +- else +- WARN_ON(encoder->connectors_active != false); ++ if (connector->encoder) ++ intel_encoder_dpms(to_intel_encoder(connector->encoder), mode); + + intel_modeset_check_state(connector->dev); + } +Index: linux-3.10-3.10.11/dummy/rpi_1396_27c35c76cdfec3848ef0997605cfc16cb85a290c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1396_27c35c76cdfec3848ef0997605cfc16cb85a290c.txt 2014-05-05 12:48:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1397_4fbde5f0aabcd189d03e4e34a52024e70bdd3a73.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1397_4fbde5f0aabcd189d03e4e34a52024e70bdd3a73.patch --- linux-3.10.11/debian/patches/rpi/rpi_1397_4fbde5f0aabcd189d03e4e34a52024e70bdd3a73.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1397_4fbde5f0aabcd189d03e4e34a52024e70bdd3a73.patch 2014-05-05 12:48:44.000000000 +0000 @@ -0,0 +1,39 @@ +commit 4fbde5f0aabcd189d03e4e34a52024e70bdd3a73 +Author: Dan Carpenter +Date: Mon Jul 1 19:39:34 2013 +0300 + + drm/radeon: forever loop on error in radeon_do_test_moves() + + commit 89cd67b326fa95872cc2b4524cd807128db6071d upstream. + + The error path does this: + + for (--i; i >= 0; --i) { + + which is a forever loop because "i" is unsigned. + + Signed-off-by: Dan Carpenter + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_test.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/radeon_test.c 2014-05-05 11:49:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/radeon_test.c 2014-05-05 12:48:43.000000000 +0000 +@@ -37,8 +37,8 @@ + struct radeon_bo **gtt_obj = NULL; + struct radeon_fence *fence = NULL; + uint64_t gtt_addr, vram_addr; +- unsigned i, n, size; +- int r, ring; ++ unsigned n, size; ++ int i, r, ring; + + switch (flag) { + case RADEON_TEST_COPY_DMA: +Index: linux-3.10-3.10.11/dummy/rpi_1397_4fbde5f0aabcd189d03e4e34a52024e70bdd3a73.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1397_4fbde5f0aabcd189d03e4e34a52024e70bdd3a73.txt 2014-05-05 12:48:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1398_11685f24f1e127ac069bd37cf1b5db559ced1f7e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1398_11685f24f1e127ac069bd37cf1b5db559ced1f7e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1398_11685f24f1e127ac069bd37cf1b5db559ced1f7e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1398_11685f24f1e127ac069bd37cf1b5db559ced1f7e.patch 2014-05-05 12:48:45.000000000 +0000 @@ -0,0 +1,76 @@ +commit 11685f24f1e127ac069bd37cf1b5db559ced1f7e +Author: Alex Deucher +Date: Tue Oct 1 16:40:45 2013 -0400 + + drm/radeon: fix typo in CP DMA register headers + + commit aa3e146d04b6ae37939daeebaec060562b3db559 upstream. + + Wrong bit offset for SRC endian swapping. + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreend.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/evergreend.h 2014-05-05 12:45:42.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreend.h 2014-05-05 12:48:44.000000000 +0000 +@@ -1104,7 +1104,7 @@ + * 6. COMMAND [29:22] | BYTE_COUNT [20:0] + */ + # define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20) +- /* 0 - SRC_ADDR ++ /* 0 - DST_ADDR + * 1 - GDS + */ + # define PACKET3_CP_DMA_ENGINE(x) ((x) << 27) +@@ -1119,7 +1119,7 @@ + # define PACKET3_CP_DMA_CP_SYNC (1 << 31) + /* COMMAND */ + # define PACKET3_CP_DMA_DIS_WC (1 << 21) +-# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) ++# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22) + /* 0 - none + * 1 - 8 in 16 + * 2 - 8 in 32 +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600d.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/r600d.h 2014-05-05 11:49:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/r600d.h 2014-05-05 12:48:44.000000000 +0000 +@@ -1259,7 +1259,7 @@ + */ + # define PACKET3_CP_DMA_CP_SYNC (1 << 31) + /* COMMAND */ +-# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) ++# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22) + /* 0 - none + * 1 - 8 in 16 + * 2 - 8 in 32 +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/sid.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/sid.h 2014-05-05 12:45:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/sid.h 2014-05-05 12:48:44.000000000 +0000 +@@ -928,7 +928,7 @@ + * 6. COMMAND [30:21] | BYTE_COUNT [20:0] + */ + # define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20) +- /* 0 - SRC_ADDR ++ /* 0 - DST_ADDR + * 1 - GDS + */ + # define PACKET3_CP_DMA_ENGINE(x) ((x) << 27) +@@ -943,7 +943,7 @@ + # define PACKET3_CP_DMA_CP_SYNC (1 << 31) + /* COMMAND */ + # define PACKET3_CP_DMA_DIS_WC (1 << 21) +-# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) ++# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22) + /* 0 - none + * 1 - 8 in 16 + * 2 - 8 in 32 +Index: linux-3.10-3.10.11/dummy/rpi_1398_11685f24f1e127ac069bd37cf1b5db559ced1f7e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1398_11685f24f1e127ac069bd37cf1b5db559ced1f7e.txt 2014-05-05 12:48:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1399_7276dd0042b05ae6409274664ed8747f4dcd2a30.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1399_7276dd0042b05ae6409274664ed8747f4dcd2a30.patch --- linux-3.10.11/debian/patches/rpi/rpi_1399_7276dd0042b05ae6409274664ed8747f4dcd2a30.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1399_7276dd0042b05ae6409274664ed8747f4dcd2a30.patch 2014-05-05 12:48:46.000000000 +0000 @@ -0,0 +1,36 @@ +commit 7276dd0042b05ae6409274664ed8747f4dcd2a30 +Author: wojciech kapuscinski +Date: Tue Oct 1 19:54:33 2013 -0400 + + drm/radeon: fix hw contexts for SUMO2 asics + + commit 50b8f5aec04ebec7dbdf2adb17220b9148c99e63 upstream. + + They have 4 rather than 8. + + Fixes: + https://bugs.freedesktop.org/show_bug.cgi?id=63599 + + Signed-off-by: wojciech kapuscinski + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreen.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/evergreen.c 2014-05-05 12:45:42.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/evergreen.c 2014-05-05 12:48:45.000000000 +0000 +@@ -2990,7 +2990,7 @@ + rdev->config.evergreen.sx_max_export_size = 256; + rdev->config.evergreen.sx_max_export_pos_size = 64; + rdev->config.evergreen.sx_max_export_smx_size = 192; +- rdev->config.evergreen.max_hw_contexts = 8; ++ rdev->config.evergreen.max_hw_contexts = 4; + rdev->config.evergreen.sq_num_cf_insts = 2; + + rdev->config.evergreen.sc_prim_fifo_size = 0x40; +Index: linux-3.10-3.10.11/dummy/rpi_1399_7276dd0042b05ae6409274664ed8747f4dcd2a30.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1399_7276dd0042b05ae6409274664ed8747f4dcd2a30.txt 2014-05-05 12:48:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1400_34b2092419a3f73bb69c55247fe71ca4941faad2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1400_34b2092419a3f73bb69c55247fe71ca4941faad2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1400_34b2092419a3f73bb69c55247fe71ca4941faad2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1400_34b2092419a3f73bb69c55247fe71ca4941faad2.patch 2014-05-05 12:48:47.000000000 +0000 @@ -0,0 +1,111 @@ +commit 34b2092419a3f73bb69c55247fe71ca4941faad2 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:09 2013 -0700 + + ipc: move rcu lock out of ipc_addid + + commit dbfcd91f06f0e2d5564b2fd184e9c2a43675f9ab upstream. + + This patchset continues the work that began in the sysv ipc semaphore + scaling series, see + + https://lkml.org/lkml/2013/3/20/546 + + Just like semaphores used to be, sysv shared memory and msg queues also + abuse the ipc lock, unnecessarily holding it for operations such as + permission and security checks. + + This patchset mostly deals with mqueues, and while shared mem can be + done in a very similar way, I want to get these patches out in the open + first. It also does some pending cleanups, mostly focused on the two + level locking we have in ipc code, taking care of ipc_addid() and + ipcctl_pre_down_nolock() - yes there are still functions that need to be + updated as well. + + This patch: + + Make all callers explicitly take and release the RCU read lock. + + This addresses the two level locking seen in newary(), newseg() and + newqueue(). For the last two, explicitly unlock the ipc object and the + rcu lock, instead of calling the custom shm_unlock and msg_unlock + functions. The next patch will deal with the open coded locking for + ->perm.lock + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 11:49:40.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:46.000000000 +0000 +@@ -199,9 +199,7 @@ + return retval; + } + +- /* +- * ipc_addid() locks msq +- */ ++ /* ipc_addid() locks msq upon success. */ + id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); + if (id < 0) { + security_msg_queue_free(msq); +@@ -218,7 +216,8 @@ + INIT_LIST_HEAD(&msq->q_receivers); + INIT_LIST_HEAD(&msq->q_senders); + +- msg_unlock(msq); ++ spin_unlock(&msq->q_perm.lock); ++ rcu_read_unlock(); + + return msq->q_perm.id; + } +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 11:49:40.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:48:46.000000000 +0000 +@@ -535,6 +535,7 @@ + shp->shm_nattch = 0; + shp->shm_file = file; + shp->shm_creator = current; ++ + /* + * shmid gets reported as "inode#" in /proc/pid/maps. + * proc-ps tools use this. Changing this will break them. +@@ -543,7 +544,9 @@ + + ns->shm_tot += numpages; + error = shp->shm_perm.id; +- shm_unlock(shp); ++ ++ spin_unlock(&shp->shm_perm.lock); ++ rcu_read_unlock(); + return error; + + no_id: +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 11:49:40.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:48:46.000000000 +0000 +@@ -246,9 +246,8 @@ + * is returned. The 'new' entry is returned in a locked state on success. + * On failure the entry is not locked and a negative err-code is returned. + * +- * Called with ipc_ids.rw_mutex held as a writer. ++ * Called with writer ipc_ids.rw_mutex held. + */ +- + int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) + { + kuid_t euid; +Index: linux-3.10-3.10.11/dummy/rpi_1400_34b2092419a3f73bb69c55247fe71ca4941faad2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1400_34b2092419a3f73bb69c55247fe71ca4941faad2.txt 2014-05-05 12:48:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1401_9f7b399c9dbc71bd09d5b45242a6fb8fbf2650a3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1401_9f7b399c9dbc71bd09d5b45242a6fb8fbf2650a3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1401_9f7b399c9dbc71bd09d5b45242a6fb8fbf2650a3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1401_9f7b399c9dbc71bd09d5b45242a6fb8fbf2650a3.patch 2014-05-05 12:48:48.000000000 +0000 @@ -0,0 +1,67 @@ +commit 9f7b399c9dbc71bd09d5b45242a6fb8fbf2650a3 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:10 2013 -0700 + + ipc: introduce ipc object locking helpers + + commit 1ca7003ab41152d673d9e359632283d05294f3d6 upstream. + + Simple helpers around the (kern_ipc_perm *)->lock spinlock. + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.h 2014-05-05 11:49:40.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.h 2014-05-05 12:48:47.000000000 +0000 +@@ -159,23 +159,33 @@ + return uid / SEQ_MULTIPLIER != ipcp->seq; + } + +-static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) ++static inline void ipc_lock_object(struct kern_ipc_perm *perm) + { +- rcu_read_lock(); + spin_lock(&perm->lock); + } + +-static inline void ipc_unlock(struct kern_ipc_perm *perm) ++static inline void ipc_unlock_object(struct kern_ipc_perm *perm) + { + spin_unlock(&perm->lock); +- rcu_read_unlock(); + } + +-static inline void ipc_lock_object(struct kern_ipc_perm *perm) ++static inline void ipc_assert_locked_object(struct kern_ipc_perm *perm) + { ++ assert_spin_locked(&perm->lock); ++} ++ ++static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) ++{ ++ rcu_read_lock(); + spin_lock(&perm->lock); + } + ++static inline void ipc_unlock(struct kern_ipc_perm *perm) ++{ ++ spin_unlock(&perm->lock); ++ rcu_read_unlock(); ++} ++ + struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id); + struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id); + int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, +Index: linux-3.10-3.10.11/dummy/rpi_1401_9f7b399c9dbc71bd09d5b45242a6fb8fbf2650a3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1401_9f7b399c9dbc71bd09d5b45242a6fb8fbf2650a3.txt 2014-05-05 12:48:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1402_115d40dbef93b70e6f32732b0fdd5903c1f7fce4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1402_115d40dbef93b70e6f32732b0fdd5903c1f7fce4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1402_115d40dbef93b70e6f32732b0fdd5903c1f7fce4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1402_115d40dbef93b70e6f32732b0fdd5903c1f7fce4.patch 2014-05-05 12:48:49.000000000 +0000 @@ -0,0 +1,143 @@ +commit 115d40dbef93b70e6f32732b0fdd5903c1f7fce4 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:11 2013 -0700 + + ipc: close open coded spin lock calls + + commit cf9d5d78d05bca96df7618dfc3a5ee4414dcae58 upstream. + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:46.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:48.000000000 +0000 +@@ -216,7 +216,7 @@ + INIT_LIST_HEAD(&msq->q_receivers); + INIT_LIST_HEAD(&msq->q_senders); + +- spin_unlock(&msq->q_perm.lock); ++ ipc_unlock_object(&msq->q_perm); + rcu_read_unlock(); + + return msq->q_perm.id; +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 11:49:39.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:48:48.000000000 +0000 +@@ -246,7 +246,7 @@ + * their critical section while the array lock is held. + */ + lock_array: +- spin_lock(&sma->sem_perm.lock); ++ ipc_lock_object(&sma->sem_perm); + for (i = 0; i < sma->sem_nsems; i++) { + struct sem *sem = sma->sem_base + i; + spin_unlock_wait(&sem->lock); +@@ -259,7 +259,7 @@ + static inline void sem_unlock(struct sem_array *sma, int locknum) + { + if (locknum == -1) { +- spin_unlock(&sma->sem_perm.lock); ++ ipc_unlock_object(&sma->sem_perm); + } else { + struct sem *sem = sma->sem_base + locknum; + spin_unlock(&sem->lock); +@@ -872,7 +872,7 @@ + int i; + + /* Free the existing undo structures for this semaphore set. */ +- assert_spin_locked(&sma->sem_perm.lock); ++ ipc_assert_locked_object(&sma->sem_perm); + list_for_each_entry_safe(un, tu, &sma->list_id, list_id) { + list_del(&un->list_id); + spin_lock(&un->ulp->lock); +@@ -1070,7 +1070,7 @@ + + curr = &sma->sem_base[semnum]; + +- assert_spin_locked(&sma->sem_perm.lock); ++ ipc_assert_locked_object(&sma->sem_perm); + list_for_each_entry(un, &sma->list_id, list_id) + un->semadj[semnum] = 0; + +@@ -1199,7 +1199,7 @@ + for (i = 0; i < nsems; i++) + sma->sem_base[i].semval = sem_io[i]; + +- assert_spin_locked(&sma->sem_perm.lock); ++ ipc_assert_locked_object(&sma->sem_perm); + list_for_each_entry(un, &sma->list_id, list_id) { + for (i = 0; i < nsems; i++) + un->semadj[i] = 0; +@@ -1496,7 +1496,7 @@ + new->semid = semid; + assert_spin_locked(&ulp->lock); + list_add_rcu(&new->list_proc, &ulp->list_proc); +- assert_spin_locked(&sma->sem_perm.lock); ++ ipc_assert_locked_object(&sma->sem_perm); + list_add(&new->list_id, &sma->list_id); + un = new; + +@@ -1833,7 +1833,7 @@ + } + + /* remove un from the linked lists */ +- assert_spin_locked(&sma->sem_perm.lock); ++ ipc_assert_locked_object(&sma->sem_perm); + list_del(&un->list_id); + + spin_lock(&ulp->lock); +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:48:46.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:48:48.000000000 +0000 +@@ -141,7 +141,7 @@ + static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp) + { + rcu_read_lock(); +- spin_lock(&ipcp->shm_perm.lock); ++ ipc_lock_object(&ipcp->shm_perm); + } + + static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns, +@@ -545,7 +545,7 @@ + ns->shm_tot += numpages; + error = shp->shm_perm.id; + +- spin_unlock(&shp->shm_perm.lock); ++ ipc_unlock_object(&shp->shm_perm); + rcu_read_unlock(); + return error; + +Index: linux-3.10-3.10.11/ipc/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.h 2014-05-05 12:48:47.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.h 2014-05-05 12:48:48.000000000 +0000 +@@ -177,12 +177,12 @@ + static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) + { + rcu_read_lock(); +- spin_lock(&perm->lock); ++ ipc_lock_object(perm); + } + + static inline void ipc_unlock(struct kern_ipc_perm *perm) + { +- spin_unlock(&perm->lock); ++ ipc_unlock_object(perm); + rcu_read_unlock(); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1402_115d40dbef93b70e6f32732b0fdd5903c1f7fce4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1402_115d40dbef93b70e6f32732b0fdd5903c1f7fce4.txt 2014-05-05 12:48:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1403_ac9bc6e396285ab732dd869c3edb353662134022.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1403_ac9bc6e396285ab732dd869c3edb353662134022.patch --- linux-3.10.11/debian/patches/rpi/rpi_1403_ac9bc6e396285ab732dd869c3edb353662134022.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1403_ac9bc6e396285ab732dd869c3edb353662134022.patch 2014-05-05 12:48:50.000000000 +0000 @@ -0,0 +1,254 @@ +commit ac9bc6e396285ab732dd869c3edb353662134022 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:12 2013 -0700 + + ipc: move locking out of ipcctl_pre_down_nolock + + commit 7b4cc5d8411bd4e9d61d8714f53859740cf830c2 upstream. + + This function currently acquires both the rw_mutex and the rcu lock on + successful lookups, leaving the callers to explicitly unlock them, + creating another two level locking situation. + + Make the callers (including those that still use ipcctl_pre_down()) + explicitly lock and unlock the rwsem and rcu lock. + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:49.000000000 +0000 +@@ -407,31 +407,38 @@ + return -EFAULT; + } + ++ down_write(&msg_ids(ns).rw_mutex); ++ rcu_read_lock(); ++ + ipcp = ipcctl_pre_down(ns, &msg_ids(ns), msqid, cmd, + &msqid64.msg_perm, msqid64.msg_qbytes); +- if (IS_ERR(ipcp)) +- return PTR_ERR(ipcp); ++ if (IS_ERR(ipcp)) { ++ err = PTR_ERR(ipcp); ++ /* the ipc lock is not held upon failure */ ++ goto out_unlock1; ++ } + + msq = container_of(ipcp, struct msg_queue, q_perm); + + err = security_msg_queue_msgctl(msq, cmd); + if (err) +- goto out_unlock; ++ goto out_unlock0; + + switch (cmd) { + case IPC_RMID: ++ /* freeque unlocks the ipc object and rcu */ + freeque(ns, ipcp); + goto out_up; + case IPC_SET: + if (msqid64.msg_qbytes > ns->msg_ctlmnb && + !capable(CAP_SYS_RESOURCE)) { + err = -EPERM; +- goto out_unlock; ++ goto out_unlock0; + } + + err = ipc_update_perm(&msqid64.msg_perm, ipcp); + if (err) +- goto out_unlock; ++ goto out_unlock0; + + msq->q_qbytes = msqid64.msg_qbytes; + +@@ -448,8 +455,11 @@ + default: + err = -EINVAL; + } +-out_unlock: +- msg_unlock(msq); ++ ++out_unlock0: ++ ipc_unlock_object(&msq->q_perm); ++out_unlock1: ++ rcu_read_unlock(); + out_up: + up_write(&msg_ids(ns).rw_mutex); + return err; +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:48:49.000000000 +0000 +@@ -1289,39 +1289,44 @@ + return -EFAULT; + } + ++ down_write(&sem_ids(ns).rw_mutex); ++ rcu_read_lock(); ++ + ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd, + &semid64.sem_perm, 0); +- if (IS_ERR(ipcp)) +- return PTR_ERR(ipcp); ++ if (IS_ERR(ipcp)) { ++ err = PTR_ERR(ipcp); ++ /* the ipc lock is not held upon failure */ ++ goto out_unlock1; ++ } + + sma = container_of(ipcp, struct sem_array, sem_perm); + + err = security_sem_semctl(sma, cmd); +- if (err) { +- rcu_read_unlock(); +- goto out_up; +- } ++ if (err) ++ goto out_unlock1; + +- switch(cmd){ ++ switch (cmd) { + case IPC_RMID: + sem_lock(sma, NULL, -1); ++ /* freeary unlocks the ipc object and rcu */ + freeary(ns, ipcp); + goto out_up; + case IPC_SET: + sem_lock(sma, NULL, -1); + err = ipc_update_perm(&semid64.sem_perm, ipcp); + if (err) +- goto out_unlock; ++ goto out_unlock0; + sma->sem_ctime = get_seconds(); + break; + default: +- rcu_read_unlock(); + err = -EINVAL; +- goto out_up; ++ goto out_unlock1; + } + +-out_unlock: ++out_unlock0: + sem_unlock(sma, -1); ++out_unlock1: + rcu_read_unlock(); + out_up: + up_write(&sem_ids(ns).rw_mutex); +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:48:49.000000000 +0000 +@@ -757,31 +757,42 @@ + return -EFAULT; + } + ++ down_write(&shm_ids(ns).rw_mutex); ++ rcu_read_lock(); ++ + ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd, + &shmid64.shm_perm, 0); +- if (IS_ERR(ipcp)) +- return PTR_ERR(ipcp); ++ if (IS_ERR(ipcp)) { ++ err = PTR_ERR(ipcp); ++ /* the ipc lock is not held upon failure */ ++ goto out_unlock1; ++ } + + shp = container_of(ipcp, struct shmid_kernel, shm_perm); + + err = security_shm_shmctl(shp, cmd); + if (err) +- goto out_unlock; ++ goto out_unlock0; ++ + switch (cmd) { + case IPC_RMID: ++ /* do_shm_rmid unlocks the ipc object and rcu */ + do_shm_rmid(ns, ipcp); + goto out_up; + case IPC_SET: + err = ipc_update_perm(&shmid64.shm_perm, ipcp); + if (err) +- goto out_unlock; ++ goto out_unlock0; + shp->shm_ctim = get_seconds(); + break; + default: + err = -EINVAL; + } +-out_unlock: +- shm_unlock(shp); ++ ++out_unlock0: ++ ipc_unlock_object(&shp->shm_perm); ++out_unlock1: ++ rcu_read_unlock(); + out_up: + up_write(&shm_ids(ns).rw_mutex); + return err; +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:48:46.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:48:49.000000000 +0000 +@@ -746,8 +746,10 @@ + * It must be called without any lock held and + * - retrieves the ipc with the given id in the given table. + * - performs some audit and permission check, depending on the given cmd +- * - returns the ipc with both ipc and rw_mutex locks held in case of success ++ * - returns the ipc with the ipc lock held in case of success + * or an err-code without any lock held otherwise. ++ * ++ * Call holding the both the rw_mutex and the rcu read lock. + */ + struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, + struct ipc_ids *ids, int id, int cmd, +@@ -772,13 +774,10 @@ + int err = -EPERM; + struct kern_ipc_perm *ipcp; + +- down_write(&ids->rw_mutex); +- rcu_read_lock(); +- + ipcp = ipc_obtain_object_check(ids, id); + if (IS_ERR(ipcp)) { + err = PTR_ERR(ipcp); +- goto out_up; ++ goto err; + } + + audit_ipc_obj(ipcp); +@@ -789,16 +788,8 @@ + euid = current_euid(); + if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) || + ns_capable(ns->user_ns, CAP_SYS_ADMIN)) +- return ipcp; +- +-out_up: +- /* +- * Unsuccessful lookup, unlock and return +- * the corresponding error. +- */ +- rcu_read_unlock(); +- up_write(&ids->rw_mutex); +- ++ return ipcp; /* successful lookup */ ++err: + return ERR_PTR(err); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1403_ac9bc6e396285ab732dd869c3edb353662134022.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1403_ac9bc6e396285ab732dd869c3edb353662134022.txt 2014-05-05 12:48:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1404_f880aca02ec5531b5ce62b10dae6311001a34804.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1404_f880aca02ec5531b5ce62b10dae6311001a34804.patch --- linux-3.10.11/debian/patches/rpi/rpi_1404_f880aca02ec5531b5ce62b10dae6311001a34804.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1404_f880aca02ec5531b5ce62b10dae6311001a34804.patch 2014-05-05 12:48:50.000000000 +0000 @@ -0,0 +1,77 @@ +commit f880aca02ec5531b5ce62b10dae6311001a34804 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:13 2013 -0700 + + ipc,msg: shorten critical region in msgctl_down + + commit 15724ecb7e9bab35fc694c666ad563adba820cc3 upstream. + + Instead of holding the ipc lock for the entire function, use the + ipcctl_pre_down_nolock and only acquire the lock for specific commands: + RMID and SET. + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:49.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:50.000000000 +0000 +@@ -410,11 +410,10 @@ + down_write(&msg_ids(ns).rw_mutex); + rcu_read_lock(); + +- ipcp = ipcctl_pre_down(ns, &msg_ids(ns), msqid, cmd, +- &msqid64.msg_perm, msqid64.msg_qbytes); ++ ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd, ++ &msqid64.msg_perm, msqid64.msg_qbytes); + if (IS_ERR(ipcp)) { + err = PTR_ERR(ipcp); +- /* the ipc lock is not held upon failure */ + goto out_unlock1; + } + +@@ -422,10 +421,11 @@ + + err = security_msg_queue_msgctl(msq, cmd); + if (err) +- goto out_unlock0; ++ goto out_unlock1; + + switch (cmd) { + case IPC_RMID: ++ ipc_lock_object(&msq->q_perm); + /* freeque unlocks the ipc object and rcu */ + freeque(ns, ipcp); + goto out_up; +@@ -433,9 +433,10 @@ + if (msqid64.msg_qbytes > ns->msg_ctlmnb && + !capable(CAP_SYS_RESOURCE)) { + err = -EPERM; +- goto out_unlock0; ++ goto out_unlock1; + } + ++ ipc_lock_object(&msq->q_perm); + err = ipc_update_perm(&msqid64.msg_perm, ipcp); + if (err) + goto out_unlock0; +@@ -454,6 +455,7 @@ + break; + default: + err = -EINVAL; ++ goto out_unlock1; + } + + out_unlock0: +Index: linux-3.10-3.10.11/dummy/rpi_1404_f880aca02ec5531b5ce62b10dae6311001a34804.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1404_f880aca02ec5531b5ce62b10dae6311001a34804.txt 2014-05-05 12:48:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1405_f1f7913980afb02f8dee9ee190b29230e69cf7a4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1405_f1f7913980afb02f8dee9ee190b29230e69cf7a4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1405_f1f7913980afb02f8dee9ee190b29230e69cf7a4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1405_f1f7913980afb02f8dee9ee190b29230e69cf7a4.patch 2014-05-05 12:48:51.000000000 +0000 @@ -0,0 +1,120 @@ +commit f1f7913980afb02f8dee9ee190b29230e69cf7a4 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:14 2013 -0700 + + ipc,msg: introduce msgctl_nolock + + commit 2cafed30f150f7314f98717b372df8173516cae0 upstream. + + Similar to semctl, when calling msgctl, the *_INFO and *_STAT commands + can be performed without acquiring the ipc object. + + Add a msgctl_nolock() function and move the logic of *_INFO and *_STAT + out of msgctl(). This change still takes the lock and it will be + properly lockless in the next patch + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:50.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:50.000000000 +0000 +@@ -467,17 +467,11 @@ + return err; + } + +-SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) ++static int msgctl_nolock(struct ipc_namespace *ns, int msqid, ++ int cmd, int version, void __user *buf) + { ++ int err; + struct msg_queue *msq; +- int err, version; +- struct ipc_namespace *ns; +- +- if (msqid < 0 || cmd < 0) +- return -EINVAL; +- +- version = ipc_parse_version(&cmd); +- ns = current->nsproxy->ipc_ns; + + switch (cmd) { + case IPC_INFO: +@@ -488,6 +482,7 @@ + + if (!buf) + return -EFAULT; ++ + /* + * We must not return kernel stack data. + * due to padding, it's not enough +@@ -519,7 +514,8 @@ + return -EFAULT; + return (max_id < 0) ? 0 : max_id; + } +- case MSG_STAT: /* msqid is an index rather than a msg queue id */ ++ ++ case MSG_STAT: + case IPC_STAT: + { + struct msqid64_ds tbuf; +@@ -563,19 +559,42 @@ + return -EFAULT; + return success_return; + } +- case IPC_SET: +- case IPC_RMID: +- err = msgctl_down(ns, msqid, cmd, buf, version); +- return err; ++ + default: +- return -EINVAL; ++ return -EINVAL; + } + ++ return err; + out_unlock: + msg_unlock(msq); + return err; + } + ++SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) ++{ ++ int version; ++ struct ipc_namespace *ns; ++ ++ if (msqid < 0 || cmd < 0) ++ return -EINVAL; ++ ++ version = ipc_parse_version(&cmd); ++ ns = current->nsproxy->ipc_ns; ++ ++ switch (cmd) { ++ case IPC_INFO: ++ case MSG_INFO: ++ case MSG_STAT: /* msqid is an index rather than a msg queue id */ ++ case IPC_STAT: ++ return msgctl_nolock(ns, msqid, cmd, version, buf); ++ case IPC_SET: ++ case IPC_RMID: ++ return msgctl_down(ns, msqid, cmd, buf, version); ++ default: ++ return -EINVAL; ++ } ++} ++ + static int testmsg(struct msg_msg *msg, long type, int mode) + { + switch(mode) +Index: linux-3.10-3.10.11/dummy/rpi_1405_f1f7913980afb02f8dee9ee190b29230e69cf7a4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1405_f1f7913980afb02f8dee9ee190b29230e69cf7a4.txt 2014-05-05 12:48:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1406_15d49ab4814e9b3e6b340ec073a3ce95862643a9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1406_15d49ab4814e9b3e6b340ec073a3ce95862643a9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1406_15d49ab4814e9b3e6b340ec073a3ce95862643a9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1406_15d49ab4814e9b3e6b340ec073a3ce95862643a9.patch 2014-05-05 12:48:52.000000000 +0000 @@ -0,0 +1,59 @@ +commit 15d49ab4814e9b3e6b340ec073a3ce95862643a9 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:15 2013 -0700 + + ipc,msg: introduce lockless functions to obtain the ipc object + + commit a5001a0d9768568de5d613c3b3a5b9c7721299da upstream. + + Add msq_obtain_object() and msq_obtain_object_check(), which will allow + us to get the ipc object without acquiring the lock. Just as with + semaphores, these functions are basically wrappers around + ipc_obtain_object*(). + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:50.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:51.000000000 +0000 +@@ -166,6 +166,27 @@ + return container_of(ipcp, struct msg_queue, q_perm); + } + ++static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id) ++{ ++ struct kern_ipc_perm *ipcp = ipc_obtain_object(&msg_ids(ns), id); ++ ++ if (IS_ERR(ipcp)) ++ return ERR_CAST(ipcp); ++ ++ return container_of(ipcp, struct msg_queue, q_perm); ++} ++ ++static inline struct msg_queue *msq_obtain_object_check(struct ipc_namespace *ns, ++ int id) ++{ ++ struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&msg_ids(ns), id); ++ ++ if (IS_ERR(ipcp)) ++ return ERR_CAST(ipcp); ++ ++ return container_of(ipcp, struct msg_queue, q_perm); ++} ++ + static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s) + { + ipc_rmid(&msg_ids(ns), &s->q_perm); +Index: linux-3.10-3.10.11/dummy/rpi_1406_15d49ab4814e9b3e6b340ec073a3ce95862643a9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1406_15d49ab4814e9b3e6b340ec073a3ce95862643a9.txt 2014-05-05 12:48:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1407_107b413cd33374f8eb3a0075d0237e1076e0a752.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1407_107b413cd33374f8eb3a0075d0237e1076e0a752.patch --- linux-3.10.11/debian/patches/rpi/rpi_1407_107b413cd33374f8eb3a0075d0237e1076e0a752.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1407_107b413cd33374f8eb3a0075d0237e1076e0a752.patch 2014-05-05 12:48:53.000000000 +0000 @@ -0,0 +1,92 @@ +commit 107b413cd33374f8eb3a0075d0237e1076e0a752 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:16 2013 -0700 + + ipc,msg: make msgctl_nolock lockless + + commit ac0ba20ea6f2201a1589d6dc26ad1a4f0f967bb8 upstream. + + While the INFO cmd doesn't take the ipc lock, the STAT commands do + acquire it unnecessarily. We can do the permissions and security checks + only holding the rcu lock. + + This function now mimics semctl_nolock(). + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:51.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:52.000000000 +0000 +@@ -545,17 +545,25 @@ + if (!buf) + return -EFAULT; + ++ memset(&tbuf, 0, sizeof(tbuf)); ++ ++ rcu_read_lock(); + if (cmd == MSG_STAT) { +- msq = msg_lock(ns, msqid); +- if (IS_ERR(msq)) +- return PTR_ERR(msq); ++ msq = msq_obtain_object(ns, msqid); ++ if (IS_ERR(msq)) { ++ err = PTR_ERR(msq); ++ goto out_unlock; ++ } + success_return = msq->q_perm.id; + } else { +- msq = msg_lock_check(ns, msqid); +- if (IS_ERR(msq)) +- return PTR_ERR(msq); ++ msq = msq_obtain_object_check(ns, msqid); ++ if (IS_ERR(msq)) { ++ err = PTR_ERR(msq); ++ goto out_unlock; ++ } + success_return = 0; + } ++ + err = -EACCES; + if (ipcperms(ns, &msq->q_perm, S_IRUGO)) + goto out_unlock; +@@ -564,8 +572,6 @@ + if (err) + goto out_unlock; + +- memset(&tbuf, 0, sizeof(tbuf)); +- + kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); + tbuf.msg_stime = msq->q_stime; + tbuf.msg_rtime = msq->q_rtime; +@@ -575,7 +581,8 @@ + tbuf.msg_qbytes = msq->q_qbytes; + tbuf.msg_lspid = msq->q_lspid; + tbuf.msg_lrpid = msq->q_lrpid; +- msg_unlock(msq); ++ rcu_read_unlock(); ++ + if (copy_msqid_to_user(buf, &tbuf, version)) + return -EFAULT; + return success_return; +@@ -587,7 +594,7 @@ + + return err; + out_unlock: +- msg_unlock(msq); ++ rcu_read_unlock(); + return err; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1407_107b413cd33374f8eb3a0075d0237e1076e0a752.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1407_107b413cd33374f8eb3a0075d0237e1076e0a752.txt 2014-05-05 12:48:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1408_8398fe18b48b6e4ac671898cd9b7327954b4ba5f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1408_8398fe18b48b6e4ac671898cd9b7327954b4ba5f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1408_8398fe18b48b6e4ac671898cd9b7327954b4ba5f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1408_8398fe18b48b6e4ac671898cd9b7327954b4ba5f.patch 2014-05-05 12:48:53.000000000 +0000 @@ -0,0 +1,120 @@ +commit 8398fe18b48b6e4ac671898cd9b7327954b4ba5f +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:17 2013 -0700 + + ipc,msg: shorten critical region in msgsnd + + commit 3dd1f784ed6603d7ab1043e51e6371235edf2313 upstream. + + do_msgsnd() is another function that does too many things with the ipc + object lock acquired. Take it only when needed when actually updating + msq. + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:52.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:53.000000000 +0000 +@@ -698,10 +698,11 @@ + msg->m_type = mtype; + msg->m_ts = msgsz; + +- msq = msg_lock_check(ns, msqid); ++ rcu_read_lock(); ++ msq = msq_obtain_object_check(ns, msqid); + if (IS_ERR(msq)) { + err = PTR_ERR(msq); +- goto out_free; ++ goto out_unlock1; + } + + for (;;) { +@@ -709,11 +710,11 @@ + + err = -EACCES; + if (ipcperms(ns, &msq->q_perm, S_IWUGO)) +- goto out_unlock_free; ++ goto out_unlock1; + + err = security_msg_queue_msgsnd(msq, msg, msgflg); + if (err) +- goto out_unlock_free; ++ goto out_unlock1; + + if (msgsz + msq->q_cbytes <= msq->q_qbytes && + 1 + msq->q_qnum <= msq->q_qbytes) { +@@ -723,32 +724,41 @@ + /* queue full, wait: */ + if (msgflg & IPC_NOWAIT) { + err = -EAGAIN; +- goto out_unlock_free; ++ goto out_unlock1; + } ++ ++ ipc_lock_object(&msq->q_perm); + ss_add(msq, &s); + + if (!ipc_rcu_getref(msq)) { + err = -EIDRM; +- goto out_unlock_free; ++ goto out_unlock0; + } + +- msg_unlock(msq); ++ ipc_unlock_object(&msq->q_perm); ++ rcu_read_unlock(); + schedule(); + +- ipc_lock_by_ptr(&msq->q_perm); ++ rcu_read_lock(); ++ ipc_lock_object(&msq->q_perm); ++ + ipc_rcu_putref(msq); + if (msq->q_perm.deleted) { + err = -EIDRM; +- goto out_unlock_free; ++ goto out_unlock0; + } ++ + ss_del(&s); + + if (signal_pending(current)) { + err = -ERESTARTNOHAND; +- goto out_unlock_free; ++ goto out_unlock0; + } ++ ++ ipc_unlock_object(&msq->q_perm); + } + ++ ipc_lock_object(&msq->q_perm); + msq->q_lspid = task_tgid_vnr(current); + msq->q_stime = get_seconds(); + +@@ -764,9 +774,10 @@ + err = 0; + msg = NULL; + +-out_unlock_free: +- msg_unlock(msq); +-out_free: ++out_unlock0: ++ ipc_unlock_object(&msq->q_perm); ++out_unlock1: ++ rcu_read_unlock(); + if (msg != NULL) + free_msg(msg); + return err; +Index: linux-3.10-3.10.11/dummy/rpi_1408_8398fe18b48b6e4ac671898cd9b7327954b4ba5f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1408_8398fe18b48b6e4ac671898cd9b7327954b4ba5f.txt 2014-05-05 12:48:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1409_7b527fcdfdc6c4edfc6dad3bae254679ed63fc55.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1409_7b527fcdfdc6c4edfc6dad3bae254679ed63fc55.patch --- linux-3.10.11/debian/patches/rpi/rpi_1409_7b527fcdfdc6c4edfc6dad3bae254679ed63fc55.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1409_7b527fcdfdc6c4edfc6dad3bae254679ed63fc55.patch 2014-05-05 12:48:54.000000000 +0000 @@ -0,0 +1,186 @@ +commit 7b527fcdfdc6c4edfc6dad3bae254679ed63fc55 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:18 2013 -0700 + + ipc,msg: shorten critical region in msgrcv + + commit 41a0d523d0f626e9da0dc01de47f1b89058033cf upstream. + + do_msgrcv() is the last msg queue function that abuses the ipc lock Take + it only when needed when actually updating msq. + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Tested-by: Sedat Dilek + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:53.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:54.000000000 +0000 +@@ -886,21 +886,19 @@ + return found ?: ERR_PTR(-EAGAIN); + } + +- +-long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, +- int msgflg, ++long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, + long (*msg_handler)(void __user *, struct msg_msg *, size_t)) + { +- struct msg_queue *msq; +- struct msg_msg *msg; + int mode; ++ struct msg_queue *msq; + struct ipc_namespace *ns; +- struct msg_msg *copy = NULL; ++ struct msg_msg *msg, *copy = NULL; + + ns = current->nsproxy->ipc_ns; + + if (msqid < 0 || (long) bufsz < 0) + return -EINVAL; ++ + if (msgflg & MSG_COPY) { + copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax)); + if (IS_ERR(copy)) +@@ -908,8 +906,10 @@ + } + mode = convert_mode(&msgtyp, msgflg); + +- msq = msg_lock_check(ns, msqid); ++ rcu_read_lock(); ++ msq = msq_obtain_object_check(ns, msqid); + if (IS_ERR(msq)) { ++ rcu_read_unlock(); + free_copy(copy); + return PTR_ERR(msq); + } +@@ -919,10 +919,10 @@ + + msg = ERR_PTR(-EACCES); + if (ipcperms(ns, &msq->q_perm, S_IRUGO)) +- goto out_unlock; ++ goto out_unlock1; + ++ ipc_lock_object(&msq->q_perm); + msg = find_msg(msq, &msgtyp, mode); +- + if (!IS_ERR(msg)) { + /* + * Found a suitable message. +@@ -930,7 +930,7 @@ + */ + if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) { + msg = ERR_PTR(-E2BIG); +- goto out_unlock; ++ goto out_unlock0; + } + /* + * If we are copying, then do not unlink message and do +@@ -938,8 +938,9 @@ + */ + if (msgflg & MSG_COPY) { + msg = copy_msg(msg, copy); +- goto out_unlock; ++ goto out_unlock0; + } ++ + list_del(&msg->m_list); + msq->q_qnum--; + msq->q_rtime = get_seconds(); +@@ -948,14 +949,16 @@ + atomic_sub(msg->m_ts, &ns->msg_bytes); + atomic_dec(&ns->msg_hdrs); + ss_wakeup(&msq->q_senders, 0); +- msg_unlock(msq); +- break; ++ ++ goto out_unlock0; + } ++ + /* No message waiting. Wait for a message */ + if (msgflg & IPC_NOWAIT) { + msg = ERR_PTR(-ENOMSG); +- goto out_unlock; ++ goto out_unlock0; + } ++ + list_add_tail(&msr_d.r_list, &msq->q_receivers); + msr_d.r_tsk = current; + msr_d.r_msgtype = msgtyp; +@@ -966,8 +969,9 @@ + msr_d.r_maxsize = bufsz; + msr_d.r_msg = ERR_PTR(-EAGAIN); + current->state = TASK_INTERRUPTIBLE; +- msg_unlock(msq); + ++ ipc_unlock_object(&msq->q_perm); ++ rcu_read_unlock(); + schedule(); + + /* Lockless receive, part 1: +@@ -978,7 +982,7 @@ + * Prior to destruction, expunge_all(-EIRDM) changes r_msg. + * Thus if r_msg is -EAGAIN, then the queue not yet destroyed. + * rcu_read_lock() prevents preemption between reading r_msg +- * and the spin_lock() inside ipc_lock_by_ptr(). ++ * and acquiring the q_perm.lock in ipc_lock_object(). + */ + rcu_read_lock(); + +@@ -997,32 +1001,34 @@ + * If there is a message or an error then accept it without + * locking. + */ +- if (msg != ERR_PTR(-EAGAIN)) { +- rcu_read_unlock(); +- break; +- } ++ if (msg != ERR_PTR(-EAGAIN)) ++ goto out_unlock1; + + /* Lockless receive, part 3: + * Acquire the queue spinlock. + */ +- ipc_lock_by_ptr(&msq->q_perm); +- rcu_read_unlock(); ++ ipc_lock_object(&msq->q_perm); + + /* Lockless receive, part 4: + * Repeat test after acquiring the spinlock. + */ + msg = (struct msg_msg*)msr_d.r_msg; + if (msg != ERR_PTR(-EAGAIN)) +- goto out_unlock; ++ goto out_unlock0; + + list_del(&msr_d.r_list); + if (signal_pending(current)) { + msg = ERR_PTR(-ERESTARTNOHAND); +-out_unlock: +- msg_unlock(msq); +- break; ++ goto out_unlock0; + } ++ ++ ipc_unlock_object(&msq->q_perm); + } ++ ++out_unlock0: ++ ipc_unlock_object(&msq->q_perm); ++out_unlock1: ++ rcu_read_unlock(); + if (IS_ERR(msg)) { + free_copy(copy); + return PTR_ERR(msg); +Index: linux-3.10-3.10.11/dummy/rpi_1409_7b527fcdfdc6c4edfc6dad3bae254679ed63fc55.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1409_7b527fcdfdc6c4edfc6dad3bae254679ed63fc55.txt 2014-05-05 12:48:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1410_5cd37e921753eeff777a522aa78b0cc5a6ff7596.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1410_5cd37e921753eeff777a522aa78b0cc5a6ff7596.patch --- linux-3.10.11/debian/patches/rpi/rpi_1410_5cd37e921753eeff777a522aa78b0cc5a6ff7596.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1410_5cd37e921753eeff777a522aa78b0cc5a6ff7596.patch 2014-05-05 12:48:55.000000000 +0000 @@ -0,0 +1,73 @@ +commit 5cd37e921753eeff777a522aa78b0cc5a6ff7596 +Author: Davidlohr Bueso +Date: Mon Jul 8 16:01:19 2013 -0700 + + ipc: remove unused functions + + commit 9ad66ae65fc8d3e7e3344310fb0aa835910264fe upstream. + + We can now drop the msg_lock and msg_lock_check functions along with a + bogus comment introduced previously in semctl_down. + + Signed-off-by: Davidlohr Bueso + Cc: Andi Kleen + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:54.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:48:55.000000000 +0000 +@@ -141,31 +141,6 @@ + IPC_MSG_IDS, sysvipc_msg_proc_show); + } + +-/* +- * msg_lock_(check_) routines are called in the paths where the rw_mutex +- * is not held. +- */ +-static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id) +-{ +- struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id); +- +- if (IS_ERR(ipcp)) +- return (struct msg_queue *)ipcp; +- +- return container_of(ipcp, struct msg_queue, q_perm); +-} +- +-static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns, +- int id) +-{ +- struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id); +- +- if (IS_ERR(ipcp)) +- return (struct msg_queue *)ipcp; +- +- return container_of(ipcp, struct msg_queue, q_perm); +-} +- + static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id) + { + struct kern_ipc_perm *ipcp = ipc_obtain_object(&msg_ids(ns), id); +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:48:49.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:48:55.000000000 +0000 +@@ -1296,7 +1296,6 @@ + &semid64.sem_perm, 0); + if (IS_ERR(ipcp)) { + err = PTR_ERR(ipcp); +- /* the ipc lock is not held upon failure */ + goto out_unlock1; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1410_5cd37e921753eeff777a522aa78b0cc5a6ff7596.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1410_5cd37e921753eeff777a522aa78b0cc5a6ff7596.txt 2014-05-05 12:48:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1411_49f7f31ab27de9bcaf2d12e1d0196400dadf6add.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1411_49f7f31ab27de9bcaf2d12e1d0196400dadf6add.patch --- linux-3.10.11/debian/patches/rpi/rpi_1411_49f7f31ab27de9bcaf2d12e1d0196400dadf6add.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1411_49f7f31ab27de9bcaf2d12e1d0196400dadf6add.patch 2014-05-05 12:48:56.000000000 +0000 @@ -0,0 +1,74 @@ +commit 49f7f31ab27de9bcaf2d12e1d0196400dadf6add +Author: Manfred Spraul +Date: Mon Jul 8 16:01:20 2013 -0700 + + ipc/util.c, ipc_rcu_alloc: cacheline align allocation + + commit 196aa0132fc7261f34b10ae1bfb44abc1bc69b3c upstream. + + Enforce that ipc_rcu_alloc returns a cacheline aligned pointer on SMP. + + Rationale: + + The SysV sem code tries to move the main spinlock into a seperate + cacheline (____cacheline_aligned_in_smp). This works only if + ipc_rcu_alloc returns cacheline aligned pointers. vmalloc and kmalloc + return cacheline algined pointers, the implementation of ipc_rcu_alloc + breaks that. + + [akpm@linux-foundation.org: coding-style fixes] + Signed-off-by: Manfred Spraul + Cc: Rik van Riel + Cc: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:48:49.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:48:56.000000000 +0000 +@@ -468,9 +468,7 @@ + struct ipc_rcu { + struct rcu_head rcu; + atomic_t refcount; +- /* "void *" makes sure alignment of following data is sane. */ +- void *data[0]; +-}; ++} ____cacheline_aligned_in_smp; + + /** + * ipc_rcu_alloc - allocate ipc and rcu space +@@ -488,12 +486,14 @@ + if (unlikely(!out)) + return NULL; + atomic_set(&out->refcount, 1); +- return out->data; ++ return out + 1; + } + + int ipc_rcu_getref(void *ptr) + { +- return atomic_inc_not_zero(&container_of(ptr, struct ipc_rcu, data)->refcount); ++ struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1; ++ ++ return atomic_inc_not_zero(&p->refcount); + } + + /** +@@ -507,7 +507,7 @@ + + void ipc_rcu_putref(void *ptr) + { +- struct ipc_rcu *p = container_of(ptr, struct ipc_rcu, data); ++ struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1; + + if (!atomic_dec_and_test(&p->refcount)) + return; +Index: linux-3.10-3.10.11/dummy/rpi_1411_49f7f31ab27de9bcaf2d12e1d0196400dadf6add.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1411_49f7f31ab27de9bcaf2d12e1d0196400dadf6add.txt 2014-05-05 12:48:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1412_0824e44c3f0aa0d5dc3d06910a09b9bbaa53d2f6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1412_0824e44c3f0aa0d5dc3d06910a09b9bbaa53d2f6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1412_0824e44c3f0aa0d5dc3d06910a09b9bbaa53d2f6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1412_0824e44c3f0aa0d5dc3d06910a09b9bbaa53d2f6.patch 2014-05-05 12:48:57.000000000 +0000 @@ -0,0 +1,57 @@ +commit 0824e44c3f0aa0d5dc3d06910a09b9bbaa53d2f6 +Author: Manfred Spraul +Date: Mon Jul 8 16:01:22 2013 -0700 + + ipc/sem.c: cacheline align the semaphore structures + + commit f5c936c0f267ec58641451cf8b8d39b4c207ee4d upstream. + + As now each semaphore has its own spinlock and parallel operations are + possible, give each semaphore its own cacheline. + + On a i3 laptop, this gives up to 28% better performance: + + #semscale 10 | grep "interleave 2" + - before: + Cpus 1, interleave 2 delay 0: 36109234 in 10 secs + Cpus 2, interleave 2 delay 0: 55276317 in 10 secs + Cpus 3, interleave 2 delay 0: 62411025 in 10 secs + Cpus 4, interleave 2 delay 0: 81963928 in 10 secs + + -after: + Cpus 1, interleave 2 delay 0: 35527306 in 10 secs + Cpus 2, interleave 2 delay 0: 70922909 in 10 secs <<< + 28% + Cpus 3, interleave 2 delay 0: 80518538 in 10 secs + Cpus 4, interleave 2 delay 0: 89115148 in 10 secs <<< + 8.7% + + i3, with 2 cores and with hyperthreading enabled. Interleave 2 in order + use first the full cores. HT partially hides the delay from cacheline + trashing, thus the improvement is "only" 8.7% if 4 threads are running. + + Signed-off-by: Manfred Spraul + Cc: Rik van Riel + Cc: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:48:55.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:48:57.000000000 +0000 +@@ -96,7 +96,7 @@ + int sempid; /* pid of last operation */ + spinlock_t lock; /* spinlock for fine-grained semtimedop */ + struct list_head sem_pending; /* pending single-sop operations */ +-}; ++} ____cacheline_aligned_in_smp; + + /* One queue for each sleeping process in the system. */ + struct sem_queue { +Index: linux-3.10-3.10.11/dummy/rpi_1412_0824e44c3f0aa0d5dc3d06910a09b9bbaa53d2f6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1412_0824e44c3f0aa0d5dc3d06910a09b9bbaa53d2f6.txt 2014-05-05 12:48:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1413_ab63bc97faaa8e26cef944eda370cf83ca818ca5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1413_ab63bc97faaa8e26cef944eda370cf83ca818ca5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1413_ab63bc97faaa8e26cef944eda370cf83ca818ca5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1413_ab63bc97faaa8e26cef944eda370cf83ca818ca5.patch 2014-05-05 12:48:58.000000000 +0000 @@ -0,0 +1,412 @@ +commit ab63bc97faaa8e26cef944eda370cf83ca818ca5 +Author: Manfred Spraul +Date: Mon Jul 8 16:01:23 2013 -0700 + + ipc/sem: separate wait-for-zero and alter tasks into seperate queues + + commit 1a82e9e1d0f1b45f47a97c9e2349020536ff8987 upstream. + + Introduce separate queues for operations that do not modify the + semaphore values. Advantages: + + - Simpler logic in check_restart(). + - Faster update_queue(): Right now, all wait-for-zero operations are + always tested, even if the semaphore value is not 0. + - wait-for-zero gets again priority, as in linux <=3.0.9 + + Signed-off-by: Manfred Spraul + Cc: Rik van Riel + Cc: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/sem.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/sem.h 2014-05-05 11:49:35.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/sem.h 2014-05-05 12:48:58.000000000 +0000 +@@ -15,7 +15,10 @@ + time_t sem_otime; /* last semop time */ + time_t sem_ctime; /* last change time */ + struct sem *sem_base; /* ptr to first semaphore in array */ +- struct list_head sem_pending; /* pending operations to be processed */ ++ struct list_head pending_alter; /* pending operations */ ++ /* that alter the array */ ++ struct list_head pending_const; /* pending complex operations */ ++ /* that do not alter semvals */ + struct list_head list_id; /* undo requests on this array */ + int sem_nsems; /* no. of semaphores in array */ + int complex_count; /* pending complex operations */ +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:48:57.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:48:58.000000000 +0000 +@@ -95,7 +95,10 @@ + int semval; /* current value */ + int sempid; /* pid of last operation */ + spinlock_t lock; /* spinlock for fine-grained semtimedop */ +- struct list_head sem_pending; /* pending single-sop operations */ ++ struct list_head pending_alter; /* pending single-sop operations */ ++ /* that alter the semaphore */ ++ struct list_head pending_const; /* pending single-sop operations */ ++ /* that do not alter the semaphore*/ + } ____cacheline_aligned_in_smp; + + /* One queue for each sleeping process in the system. */ +@@ -152,7 +155,7 @@ + /* + * linked list protection: + * sem_undo.id_next, +- * sem_array.sem_pending{,last}, ++ * sem_array.pending{_alter,_cont}, + * sem_array.sem_undo: sem_lock() for read/write + * sem_undo.proc_next: only "current" is allowed to read/write that field. + * +@@ -337,7 +340,7 @@ + * Without the check/retry algorithm a lockless wakeup is possible: + * - queue.status is initialized to -EINTR before blocking. + * - wakeup is performed by +- * * unlinking the queue entry from sma->sem_pending ++ * * unlinking the queue entry from the pending list + * * setting queue.status to IN_WAKEUP + * This is the notification for the blocked thread that a + * result value is imminent. +@@ -418,12 +421,14 @@ + sma->sem_base = (struct sem *) &sma[1]; + + for (i = 0; i < nsems; i++) { +- INIT_LIST_HEAD(&sma->sem_base[i].sem_pending); ++ INIT_LIST_HEAD(&sma->sem_base[i].pending_alter); ++ INIT_LIST_HEAD(&sma->sem_base[i].pending_const); + spin_lock_init(&sma->sem_base[i].lock); + } + + sma->complex_count = 0; +- INIT_LIST_HEAD(&sma->sem_pending); ++ INIT_LIST_HEAD(&sma->pending_alter); ++ INIT_LIST_HEAD(&sma->pending_const); + INIT_LIST_HEAD(&sma->list_id); + sma->sem_nsems = nsems; + sma->sem_ctime = get_seconds(); +@@ -609,60 +614,132 @@ + * update_queue is O(N^2) when it restarts scanning the whole queue of + * waiting operations. Therefore this function checks if the restart is + * really necessary. It is called after a previously waiting operation +- * was completed. ++ * modified the array. ++ * Note that wait-for-zero operations are handled without restart. + */ + static int check_restart(struct sem_array *sma, struct sem_queue *q) + { +- struct sem *curr; +- struct sem_queue *h; +- +- /* if the operation didn't modify the array, then no restart */ +- if (q->alter == 0) +- return 0; +- +- /* pending complex operations are too difficult to analyse */ +- if (sma->complex_count) ++ /* pending complex alter operations are too difficult to analyse */ ++ if (!list_empty(&sma->pending_alter)) + return 1; + + /* we were a sleeping complex operation. Too difficult */ + if (q->nsops > 1) + return 1; + +- curr = sma->sem_base + q->sops[0].sem_num; ++ /* It is impossible that someone waits for the new value: ++ * - complex operations always restart. ++ * - wait-for-zero are handled seperately. ++ * - q is a previously sleeping simple operation that ++ * altered the array. It must be a decrement, because ++ * simple increments never sleep. ++ * - If there are older (higher priority) decrements ++ * in the queue, then they have observed the original ++ * semval value and couldn't proceed. The operation ++ * decremented to value - thus they won't proceed either. ++ */ ++ return 0; ++} + +- /* No-one waits on this queue */ +- if (list_empty(&curr->sem_pending)) +- return 0; ++/** ++ * wake_const_ops(sma, semnum, pt) - Wake up non-alter tasks ++ * @sma: semaphore array. ++ * @semnum: semaphore that was modified. ++ * @pt: list head for the tasks that must be woken up. ++ * ++ * wake_const_ops must be called after a semaphore in a semaphore array ++ * was set to 0. If complex const operations are pending, wake_const_ops must ++ * be called with semnum = -1, as well as with the number of each modified ++ * semaphore. ++ * The tasks that must be woken up are added to @pt. The return code ++ * is stored in q->pid. ++ * The function returns 1 if at least one operation was completed successfully. ++ */ ++static int wake_const_ops(struct sem_array *sma, int semnum, ++ struct list_head *pt) ++{ ++ struct sem_queue *q; ++ struct list_head *walk; ++ struct list_head *pending_list; ++ int semop_completed = 0; ++ ++ if (semnum == -1) ++ pending_list = &sma->pending_const; ++ else ++ pending_list = &sma->sem_base[semnum].pending_const; ++ ++ walk = pending_list->next; ++ while (walk != pending_list) { ++ int error; ++ ++ q = container_of(walk, struct sem_queue, list); ++ walk = walk->next; ++ ++ error = try_atomic_semop(sma, q->sops, q->nsops, ++ q->undo, q->pid); ++ ++ if (error <= 0) { ++ /* operation completed, remove from queue & wakeup */ ++ ++ unlink_queue(sma, q); ++ ++ wake_up_sem_queue_prepare(pt, q, error); ++ if (error == 0) ++ semop_completed = 1; ++ } ++ } ++ return semop_completed; ++} + +- /* the new semaphore value */ +- if (curr->semval) { +- /* It is impossible that someone waits for the new value: +- * - q is a previously sleeping simple operation that +- * altered the array. It must be a decrement, because +- * simple increments never sleep. +- * - The value is not 0, thus wait-for-zero won't proceed. +- * - If there are older (higher priority) decrements +- * in the queue, then they have observed the original +- * semval value and couldn't proceed. The operation +- * decremented to value - thus they won't proceed either. ++/** ++ * do_smart_wakeup_zero(sma, sops, nsops, pt) - wakeup all wait for zero tasks ++ * @sma: semaphore array ++ * @sops: operations that were performed ++ * @nsops: number of operations ++ * @pt: list head of the tasks that must be woken up. ++ * ++ * do_smart_wakeup_zero() checks all required queue for wait-for-zero ++ * operations, based on the actual changes that were performed on the ++ * semaphore array. ++ * The function returns 1 if at least one operation was completed successfully. ++ */ ++static int do_smart_wakeup_zero(struct sem_array *sma, struct sembuf *sops, ++ int nsops, struct list_head *pt) ++{ ++ int i; ++ int semop_completed = 0; ++ int got_zero = 0; ++ ++ /* first: the per-semaphore queues, if known */ ++ if (sops) { ++ for (i = 0; i < nsops; i++) { ++ int num = sops[i].sem_num; ++ ++ if (sma->sem_base[num].semval == 0) { ++ got_zero = 1; ++ semop_completed |= wake_const_ops(sma, num, pt); ++ } ++ } ++ } else { ++ /* ++ * No sops means modified semaphores not known. ++ * Assume all were changed. + */ +- BUG_ON(q->sops[0].sem_op >= 0); +- return 0; ++ for (i = 0; i < sma->sem_nsems; i++) { ++ if (sma->sem_base[i].semval == 0) { ++ got_zero = 1; ++ semop_completed |= wake_const_ops(sma, i, pt); ++ } ++ } + } + /* +- * semval is 0. Check if there are wait-for-zero semops. +- * They must be the first entries in the per-semaphore queue ++ * If one of the modified semaphores got 0, ++ * then check the global queue, too. + */ +- h = list_first_entry(&curr->sem_pending, struct sem_queue, list); +- BUG_ON(h->nsops != 1); +- BUG_ON(h->sops[0].sem_num != q->sops[0].sem_num); ++ if (got_zero) ++ semop_completed |= wake_const_ops(sma, -1, pt); + +- /* Yes, there is a wait-for-zero semop. Restart */ +- if (h->sops[0].sem_op == 0) +- return 1; +- +- /* Again - no-one is waiting for the new value. */ +- return 0; ++ return semop_completed; + } + + +@@ -678,6 +755,8 @@ + * semaphore. + * The tasks that must be woken up are added to @pt. The return code + * is stored in q->pid. ++ * The function internally checks if const operations can now succeed. ++ * + * The function return 1 if at least one semop was completed successfully. + */ + static int update_queue(struct sem_array *sma, int semnum, struct list_head *pt) +@@ -688,9 +767,9 @@ + int semop_completed = 0; + + if (semnum == -1) +- pending_list = &sma->sem_pending; ++ pending_list = &sma->pending_alter; + else +- pending_list = &sma->sem_base[semnum].sem_pending; ++ pending_list = &sma->sem_base[semnum].pending_alter; + + again: + walk = pending_list->next; +@@ -702,13 +781,12 @@ + + /* If we are scanning the single sop, per-semaphore list of + * one semaphore and that semaphore is 0, then it is not +- * necessary to scan the "alter" entries: simple increments ++ * necessary to scan further: simple increments + * that affect only one entry succeed immediately and cannot + * be in the per semaphore pending queue, and decrements + * cannot be successful if the value is already 0. + */ +- if (semnum != -1 && sma->sem_base[semnum].semval == 0 && +- q->alter) ++ if (semnum != -1 && sma->sem_base[semnum].semval == 0) + break; + + error = try_atomic_semop(sma, q->sops, q->nsops, +@@ -724,6 +802,7 @@ + restart = 0; + } else { + semop_completed = 1; ++ do_smart_wakeup_zero(sma, q->sops, q->nsops, pt); + restart = check_restart(sma, q); + } + +@@ -742,8 +821,8 @@ + * @otime: force setting otime + * @pt: list head of the tasks that must be woken up. + * +- * do_smart_update() does the required called to update_queue, based on the +- * actual changes that were performed on the semaphore array. ++ * do_smart_update() does the required calls to update_queue and wakeup_zero, ++ * based on the actual changes that were performed on the semaphore array. + * Note that the function does not do the actual wake-up: the caller is + * responsible for calling wake_up_sem_queue_do(@pt). + * It is safe to perform this call after dropping all locks. +@@ -754,6 +833,8 @@ + int i; + int progress; + ++ otime |= do_smart_wakeup_zero(sma, sops, nsops, pt); ++ + progress = 1; + retry_global: + if (sma->complex_count) { +@@ -813,14 +894,14 @@ + struct sem_queue * q; + + semncnt = 0; +- list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) { ++ list_for_each_entry(q, &sma->sem_base[semnum].pending_alter, list) { + struct sembuf * sops = q->sops; + BUG_ON(sops->sem_num != semnum); + if ((sops->sem_op < 0) && !(sops->sem_flg & IPC_NOWAIT)) + semncnt++; + } + +- list_for_each_entry(q, &sma->sem_pending, list) { ++ list_for_each_entry(q, &sma->pending_alter, list) { + struct sembuf * sops = q->sops; + int nsops = q->nsops; + int i; +@@ -839,14 +920,14 @@ + struct sem_queue * q; + + semzcnt = 0; +- list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) { ++ list_for_each_entry(q, &sma->sem_base[semnum].pending_const, list) { + struct sembuf * sops = q->sops; + BUG_ON(sops->sem_num != semnum); + if ((sops->sem_op == 0) && !(sops->sem_flg & IPC_NOWAIT)) + semzcnt++; + } + +- list_for_each_entry(q, &sma->sem_pending, list) { ++ list_for_each_entry(q, &sma->pending_const, list) { + struct sembuf * sops = q->sops; + int nsops = q->nsops; + int i; +@@ -884,13 +965,22 @@ + + /* Wake up all pending processes and let them fail with EIDRM. */ + INIT_LIST_HEAD(&tasks); +- list_for_each_entry_safe(q, tq, &sma->sem_pending, list) { ++ list_for_each_entry_safe(q, tq, &sma->pending_const, list) { ++ unlink_queue(sma, q); ++ wake_up_sem_queue_prepare(&tasks, q, -EIDRM); ++ } ++ ++ list_for_each_entry_safe(q, tq, &sma->pending_alter, list) { + unlink_queue(sma, q); + wake_up_sem_queue_prepare(&tasks, q, -EIDRM); + } + for (i = 0; i < sma->sem_nsems; i++) { + struct sem *sem = sma->sem_base + i; +- list_for_each_entry_safe(q, tq, &sem->sem_pending, list) { ++ list_for_each_entry_safe(q, tq, &sem->pending_const, list) { ++ unlink_queue(sma, q); ++ wake_up_sem_queue_prepare(&tasks, q, -EIDRM); ++ } ++ list_for_each_entry_safe(q, tq, &sem->pending_alter, list) { + unlink_queue(sma, q); + wake_up_sem_queue_prepare(&tasks, q, -EIDRM); + } +@@ -1658,14 +1748,15 @@ + curr = &sma->sem_base[sops->sem_num]; + + if (alter) +- list_add_tail(&queue.list, &curr->sem_pending); ++ list_add_tail(&queue.list, &curr->pending_alter); + else +- list_add(&queue.list, &curr->sem_pending); ++ list_add_tail(&queue.list, &curr->pending_const); + } else { + if (alter) +- list_add_tail(&queue.list, &sma->sem_pending); ++ list_add_tail(&queue.list, &sma->pending_alter); + else +- list_add(&queue.list, &sma->sem_pending); ++ list_add_tail(&queue.list, &sma->pending_const); ++ + sma->complex_count++; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1413_ab63bc97faaa8e26cef944eda370cf83ca818ca5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1413_ab63bc97faaa8e26cef944eda370cf83ca818ca5.txt 2014-05-05 12:48:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1414_e5639c5288c125607fc45fb727c72a97d01cd868.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1414_e5639c5288c125607fc45fb727c72a97d01cd868.patch --- linux-3.10.11/debian/patches/rpi/rpi_1414_e5639c5288c125607fc45fb727c72a97d01cd868.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1414_e5639c5288c125607fc45fb727c72a97d01cd868.patch 2014-05-05 12:48:59.000000000 +0000 @@ -0,0 +1,208 @@ +commit e5639c5288c125607fc45fb727c72a97d01cd868 +Author: Manfred Spraul +Date: Mon Jul 8 16:01:24 2013 -0700 + + ipc/sem.c: always use only one queue for alter operations + + commit f269f40ad5aeee229ed70044926f44318abe41ef upstream. + + There are two places that can contain alter operations: + - the global queue: sma->pending_alter + - the per-semaphore queues: sma->sem_base[].pending_alter. + + Since one of the queues must be processed first, this causes an odd + priorization of the wakeups: complex operations have priority over + simple ops. + + The patch restores the behavior of linux <=3.0.9: The longest waiting + operation has the highest priority. + + This is done by using only one queue: + - if there are complex ops, then sma->pending_alter is used. + - otherwise, the per-semaphore queues are used. + + As a side effect, do_smart_update_queue() becomes much simpler: no more + goto logic. + + Signed-off-by: Manfred Spraul + Cc: Rik van Riel + Cc: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:48:58.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:48:58.000000000 +0000 +@@ -192,6 +192,53 @@ + IPC_SEM_IDS, sysvipc_sem_proc_show); + } + ++/** ++ * unmerge_queues - unmerge queues, if possible. ++ * @sma: semaphore array ++ * ++ * The function unmerges the wait queues if complex_count is 0. ++ * It must be called prior to dropping the global semaphore array lock. ++ */ ++static void unmerge_queues(struct sem_array *sma) ++{ ++ struct sem_queue *q, *tq; ++ ++ /* complex operations still around? */ ++ if (sma->complex_count) ++ return; ++ /* ++ * We will switch back to simple mode. ++ * Move all pending operation back into the per-semaphore ++ * queues. ++ */ ++ list_for_each_entry_safe(q, tq, &sma->pending_alter, list) { ++ struct sem *curr; ++ curr = &sma->sem_base[q->sops[0].sem_num]; ++ ++ list_add_tail(&q->list, &curr->pending_alter); ++ } ++ INIT_LIST_HEAD(&sma->pending_alter); ++} ++ ++/** ++ * merge_queues - Merge single semop queues into global queue ++ * @sma: semaphore array ++ * ++ * This function merges all per-semaphore queues into the global queue. ++ * It is necessary to achieve FIFO ordering for the pending single-sop ++ * operations when a multi-semop operation must sleep. ++ * Only the alter operations must be moved, the const operations can stay. ++ */ ++static void merge_queues(struct sem_array *sma) ++{ ++ int i; ++ for (i = 0; i < sma->sem_nsems; i++) { ++ struct sem *sem = sma->sem_base + i; ++ ++ list_splice_init(&sem->pending_alter, &sma->pending_alter); ++ } ++} ++ + /* + * If the request contains only one semaphore operation, and there are + * no complex transactions pending, lock only the semaphore involved. +@@ -262,6 +309,7 @@ + static inline void sem_unlock(struct sem_array *sma, int locknum) + { + if (locknum == -1) { ++ unmerge_queues(sma); + ipc_unlock_object(&sma->sem_perm); + } else { + struct sem *sem = sma->sem_base + locknum; +@@ -831,49 +879,38 @@ + int otime, struct list_head *pt) + { + int i; +- int progress; + + otime |= do_smart_wakeup_zero(sma, sops, nsops, pt); + +- progress = 1; +-retry_global: +- if (sma->complex_count) { +- if (update_queue(sma, -1, pt)) { +- progress = 1; +- otime = 1; +- sops = NULL; +- } +- } +- if (!progress) +- goto done; +- +- if (!sops) { +- /* No semops; something special is going on. */ +- for (i = 0; i < sma->sem_nsems; i++) { +- if (update_queue(sma, i, pt)) { +- otime = 1; +- progress = 1; ++ if (!list_empty(&sma->pending_alter)) { ++ /* semaphore array uses the global queue - just process it. */ ++ otime |= update_queue(sma, -1, pt); ++ } else { ++ if (!sops) { ++ /* ++ * No sops, thus the modified semaphores are not ++ * known. Check all. ++ */ ++ for (i = 0; i < sma->sem_nsems; i++) ++ otime |= update_queue(sma, i, pt); ++ } else { ++ /* ++ * Check the semaphores that were increased: ++ * - No complex ops, thus all sleeping ops are ++ * decrease. ++ * - if we decreased the value, then any sleeping ++ * semaphore ops wont be able to run: If the ++ * previous value was too small, then the new ++ * value will be too small, too. ++ */ ++ for (i = 0; i < nsops; i++) { ++ if (sops[i].sem_op > 0) { ++ otime |= update_queue(sma, ++ sops[i].sem_num, pt); ++ } + } + } +- goto done_checkretry; +- } +- +- /* Check the semaphores that were modified. */ +- for (i = 0; i < nsops; i++) { +- if (sops[i].sem_op > 0 || +- (sops[i].sem_op < 0 && +- sma->sem_base[sops[i].sem_num].semval == 0)) +- if (update_queue(sma, sops[i].sem_num, pt)) { +- otime = 1; +- progress = 1; +- } +- } +-done_checkretry: +- if (progress) { +- progress = 0; +- goto retry_global; + } +-done: + if (otime) + sma->sem_otime = get_seconds(); + } +@@ -1747,11 +1784,22 @@ + struct sem *curr; + curr = &sma->sem_base[sops->sem_num]; + +- if (alter) +- list_add_tail(&queue.list, &curr->pending_alter); +- else ++ if (alter) { ++ if (sma->complex_count) { ++ list_add_tail(&queue.list, ++ &sma->pending_alter); ++ } else { ++ ++ list_add_tail(&queue.list, ++ &curr->pending_alter); ++ } ++ } else { + list_add_tail(&queue.list, &curr->pending_const); ++ } + } else { ++ if (!sma->complex_count) ++ merge_queues(sma); ++ + if (alter) + list_add_tail(&queue.list, &sma->pending_alter); + else +Index: linux-3.10-3.10.11/dummy/rpi_1414_e5639c5288c125607fc45fb727c72a97d01cd868.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1414_e5639c5288c125607fc45fb727c72a97d01cd868.txt 2014-05-05 12:48:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1415_bf6830ad689a462a61c7e9191dc44fc45e205165.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1415_bf6830ad689a462a61c7e9191dc44fc45e205165.patch --- linux-3.10.11/debian/patches/rpi/rpi_1415_bf6830ad689a462a61c7e9191dc44fc45e205165.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1415_bf6830ad689a462a61c7e9191dc44fc45e205165.patch 2014-05-05 12:49:00.000000000 +0000 @@ -0,0 +1,127 @@ +commit bf6830ad689a462a61c7e9191dc44fc45e205165 +Author: Manfred Spraul +Date: Mon Jul 8 16:01:25 2013 -0700 + + ipc/sem.c: replace shared sem_otime with per-semaphore value + + commit d12e1e50e47e0900dbbf52237b7e171f4f15ea1e upstream. + + sem_otime contains the time of the last semaphore operation that + completed successfully. Every operation updates this value, thus access + from multiple cpus can cause thrashing. + + Therefore the patch replaces the variable with a per-semaphore variable. + The per-array sem_otime is only calculated when required. + + No performance improvement on a single-socket i3 - only important for + larger systems. + + Signed-off-by: Manfred Spraul + Cc: Rik van Riel + Cc: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/sem.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/sem.h 2014-05-05 12:48:58.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/sem.h 2014-05-05 12:48:59.000000000 +0000 +@@ -12,7 +12,6 @@ + struct sem_array { + struct kern_ipc_perm ____cacheline_aligned_in_smp + sem_perm; /* permissions .. see ipc.h */ +- time_t sem_otime; /* last semop time */ + time_t sem_ctime; /* last change time */ + struct sem *sem_base; /* ptr to first semaphore in array */ + struct list_head pending_alter; /* pending operations */ +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:48:58.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:48:59.000000000 +0000 +@@ -99,6 +99,7 @@ + /* that alter the semaphore */ + struct list_head pending_const; /* pending single-sop operations */ + /* that do not alter the semaphore*/ ++ time_t sem_otime; /* candidate for sem_otime */ + } ____cacheline_aligned_in_smp; + + /* One queue for each sleeping process in the system. */ +@@ -911,8 +912,14 @@ + } + } + } +- if (otime) +- sma->sem_otime = get_seconds(); ++ if (otime) { ++ if (sops == NULL) { ++ sma->sem_base[0].sem_otime = get_seconds(); ++ } else { ++ sma->sem_base[sops[0].sem_num].sem_otime = ++ get_seconds(); ++ } ++ } + } + + +@@ -1058,6 +1065,21 @@ + } + } + ++static time_t get_semotime(struct sem_array *sma) ++{ ++ int i; ++ time_t res; ++ ++ res = sma->sem_base[0].sem_otime; ++ for (i = 1; i < sma->sem_nsems; i++) { ++ time_t to = sma->sem_base[i].sem_otime; ++ ++ if (to > res) ++ res = to; ++ } ++ return res; ++} ++ + static int semctl_nolock(struct ipc_namespace *ns, int semid, + int cmd, int version, void __user *p) + { +@@ -1131,9 +1153,9 @@ + goto out_unlock; + + kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); +- tbuf.sem_otime = sma->sem_otime; +- tbuf.sem_ctime = sma->sem_ctime; +- tbuf.sem_nsems = sma->sem_nsems; ++ tbuf.sem_otime = get_semotime(sma); ++ tbuf.sem_ctime = sma->sem_ctime; ++ tbuf.sem_nsems = sma->sem_nsems; + rcu_read_unlock(); + if (copy_semid_to_user(p, &tbuf, version)) + return -EFAULT; +@@ -2025,6 +2047,9 @@ + { + struct user_namespace *user_ns = seq_user_ns(s); + struct sem_array *sma = it; ++ time_t sem_otime; ++ ++ sem_otime = get_semotime(sma); + + return seq_printf(s, + "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n", +@@ -2036,7 +2061,7 @@ + from_kgid_munged(user_ns, sma->sem_perm.gid), + from_kuid_munged(user_ns, sma->sem_perm.cuid), + from_kgid_munged(user_ns, sma->sem_perm.cgid), +- sma->sem_otime, ++ sem_otime, + sma->sem_ctime); + } + #endif +Index: linux-3.10-3.10.11/dummy/rpi_1415_bf6830ad689a462a61c7e9191dc44fc45e205165.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1415_bf6830ad689a462a61c7e9191dc44fc45e205165.txt 2014-05-05 12:48:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1416_b56e88e25e1d576619343e97fdb6cbe11035cf6d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1416_b56e88e25e1d576619343e97fdb6cbe11035cf6d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1416_b56e88e25e1d576619343e97fdb6cbe11035cf6d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1416_b56e88e25e1d576619343e97fdb6cbe11035cf6d.patch 2014-05-05 12:49:01.000000000 +0000 @@ -0,0 +1,116 @@ +commit b56e88e25e1d576619343e97fdb6cbe11035cf6d +Author: Manfred Spraul +Date: Mon Jul 8 16:01:26 2013 -0700 + + ipc/sem.c: rename try_atomic_semop() to perform_atomic_semop(), docu update + + commit 758a6ba39ef6df4cdc615e5edd7bd86eab81a5f7 upstream. + + Cleanup: Some minor points that I noticed while writing the previous + patches + + 1) The name try_atomic_semop() is misleading: The function performs the + operation (if it is possible). + + 2) Some documentation updates. + + No real code change, a rename and documentation changes. + + Signed-off-by: Manfred Spraul + Cc: Rik van Riel + Cc: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:48:59.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:49:00.000000000 +0000 +@@ -154,12 +154,15 @@ + #define SEMOPM_FAST 64 /* ~ 372 bytes on stack */ + + /* +- * linked list protection: ++ * Locking: + * sem_undo.id_next, ++ * sem_array.complex_count, + * sem_array.pending{_alter,_cont}, +- * sem_array.sem_undo: sem_lock() for read/write ++ * sem_array.sem_undo: global sem_lock() for read/write + * sem_undo.proc_next: only "current" is allowed to read/write that field. + * ++ * sem_array.sem_base[i].pending_{const,alter}: ++ * global or semaphore sem_lock() for read/write + */ + + #define sc_semmsl sem_ctls[0] +@@ -536,12 +539,19 @@ + return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params); + } + +-/* +- * Determine whether a sequence of semaphore operations would succeed +- * all at once. Return 0 if yes, 1 if need to sleep, else return error code. ++/** perform_atomic_semop - Perform (if possible) a semaphore operation ++ * @sma: semaphore array ++ * @sops: array with operations that should be checked ++ * @nsems: number of sops ++ * @un: undo array ++ * @pid: pid that did the change ++ * ++ * Returns 0 if the operation was possible. ++ * Returns 1 if the operation is impossible, the caller must sleep. ++ * Negative values are error codes. + */ + +-static int try_atomic_semop (struct sem_array * sma, struct sembuf * sops, ++static int perform_atomic_semop(struct sem_array *sma, struct sembuf *sops, + int nsops, struct sem_undo *un, int pid) + { + int result, sem_op; +@@ -724,8 +734,8 @@ + q = container_of(walk, struct sem_queue, list); + walk = walk->next; + +- error = try_atomic_semop(sma, q->sops, q->nsops, +- q->undo, q->pid); ++ error = perform_atomic_semop(sma, q->sops, q->nsops, ++ q->undo, q->pid); + + if (error <= 0) { + /* operation completed, remove from queue & wakeup */ +@@ -838,7 +848,7 @@ + if (semnum != -1 && sma->sem_base[semnum].semval == 0) + break; + +- error = try_atomic_semop(sma, q->sops, q->nsops, ++ error = perform_atomic_semop(sma, q->sops, q->nsops, + q->undo, q->pid); + + /* Does q->sleeper still need to sleep? */ +@@ -1686,7 +1696,6 @@ + return error; + } + +- + SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, + unsigned, nsops, const struct timespec __user *, timeout) + { +@@ -1784,7 +1793,8 @@ + if (un && un->semid == -1) + goto out_unlock_free; + +- error = try_atomic_semop (sma, sops, nsops, un, task_tgid_vnr(current)); ++ error = perform_atomic_semop(sma, sops, nsops, un, ++ task_tgid_vnr(current)); + if (error <= 0) { + if (alter && error == 0) + do_smart_update(sma, sops, nsops, 1, &tasks); +Index: linux-3.10-3.10.11/dummy/rpi_1416_b56e88e25e1d576619343e97fdb6cbe11035cf6d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1416_b56e88e25e1d576619343e97fdb6cbe11035cf6d.txt 2014-05-05 12:49:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1417_11ce33923261281f406a99ee345ffc5f53aec2c8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1417_11ce33923261281f406a99ee345ffc5f53aec2c8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1417_11ce33923261281f406a99ee345ffc5f53aec2c8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1417_11ce33923261281f406a99ee345ffc5f53aec2c8.patch 2014-05-05 12:49:02.000000000 +0000 @@ -0,0 +1,94 @@ +commit 11ce33923261281f406a99ee345ffc5f53aec2c8 +Author: Manfred Spraul +Date: Tue Sep 3 16:00:08 2013 +0200 + + ipc/msg.c: Fix lost wakeup in msgsnd(). + + commit bebcb928c820d0ee83aca4b192adc195e43e66a2 upstream. + + The check if the queue is full and adding current to the wait queue of + pending msgsnd() operations (ss_add()) must be atomic. + + Otherwise: + - the thread that performs msgsnd() finds a full queue and decides to + sleep. + - the thread that performs msgrcv() first reads all messages from the + queue and then sleeps, because the queue is empty. + - the msgrcv() calls do not perform any wakeups, because the msgsnd() + task has not yet called ss_add(). + - then the msgsnd()-thread first calls ss_add() and then sleeps. + + Net result: msgsnd() and msgrcv() both sleep forever. + + Observed with msgctl08 from ltp with a preemptible kernel. + + Fix: Call ipc_lock_object() before performing the check. + + The patch also moves security_msg_queue_msgsnd() under ipc_lock_object: + - msgctl(IPC_SET) explicitely mentions that it tries to expunge any + pending operations that are not allowed anymore with the new + permissions. If security_msg_queue_msgsnd() is called without locks, + then there might be races. + - it makes the patch much simpler. + + Reported-and-tested-by: Vineet Gupta + Acked-by: Rik van Riel + Signed-off-by: Manfred Spraul + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:48:55.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:49:01.000000000 +0000 +@@ -680,16 +680,18 @@ + goto out_unlock1; + } + ++ ipc_lock_object(&msq->q_perm); ++ + for (;;) { + struct msg_sender s; + + err = -EACCES; + if (ipcperms(ns, &msq->q_perm, S_IWUGO)) +- goto out_unlock1; ++ goto out_unlock0; + + err = security_msg_queue_msgsnd(msq, msg, msgflg); + if (err) +- goto out_unlock1; ++ goto out_unlock0; + + if (msgsz + msq->q_cbytes <= msq->q_qbytes && + 1 + msq->q_qnum <= msq->q_qbytes) { +@@ -699,10 +701,9 @@ + /* queue full, wait: */ + if (msgflg & IPC_NOWAIT) { + err = -EAGAIN; +- goto out_unlock1; ++ goto out_unlock0; + } + +- ipc_lock_object(&msq->q_perm); + ss_add(msq, &s); + + if (!ipc_rcu_getref(msq)) { +@@ -730,10 +731,7 @@ + goto out_unlock0; + } + +- ipc_unlock_object(&msq->q_perm); + } +- +- ipc_lock_object(&msq->q_perm); + msq->q_lspid = task_tgid_vnr(current); + msq->q_stime = get_seconds(); + +Index: linux-3.10-3.10.11/dummy/rpi_1417_11ce33923261281f406a99ee345ffc5f53aec2c8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1417_11ce33923261281f406a99ee345ffc5f53aec2c8.txt 2014-05-05 12:49:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1418_1b2ad167481aed32347ef7726d14bb2b9f63c4c9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1418_1b2ad167481aed32347ef7726d14bb2b9f63c4c9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1418_1b2ad167481aed32347ef7726d14bb2b9f63c4c9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1418_1b2ad167481aed32347ef7726d14bb2b9f63c4c9.patch 2014-05-05 12:49:03.000000000 +0000 @@ -0,0 +1,84 @@ +commit 1b2ad167481aed32347ef7726d14bb2b9f63c4c9 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:15 2013 -0700 + + ipc,shm: introduce lockless functions to obtain the ipc object + + commit 8b8d52ac382b17a19906b930cd69e2edb0aca8ba upstream. + + This is the third and final patchset that deals with reducing the amount + of contention we impose on the ipc lock (kern_ipc_perm.lock). These + changes mostly deal with shared memory, previous work has already been + done for semaphores and message queues: + + http://lkml.org/lkml/2013/3/20/546 (sems) + http://lkml.org/lkml/2013/5/15/584 (mqueues) + + With these patches applied, a custom shm microbenchmark stressing shmctl + doing IPC_STAT with 4 threads a million times, reduces the execution + time by 50%. A similar run, this time with IPC_SET, reduces the + execution time from 3 mins and 35 secs to 27 seconds. + + Patches 1-8: replaces blindly taking the ipc lock for a smarter + combination of rcu and ipc_obtain_object, only acquiring the spinlock + when updating. + + Patch 9: renames the ids rw_mutex to rwsem, which is what it already was. + + Patch 10: is a trivial mqueue leftover cleanup + + Patch 11: adds a brief lock scheme description, requested by Andrew. + + This patch: + + Add shm_obtain_object() and shm_obtain_object_check(), which will allow us + to get the ipc object without acquiring the lock. Just as with other + forms of ipc, these functions are basically wrappers around + ipc_obtain_object*(). + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:48:49.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:02.000000000 +0000 +@@ -124,6 +124,26 @@ + IPC_SHM_IDS, sysvipc_shm_proc_show); + } + ++static inline struct shmid_kernel *shm_obtain_object(struct ipc_namespace *ns, int id) ++{ ++ struct kern_ipc_perm *ipcp = ipc_obtain_object(&shm_ids(ns), id); ++ ++ if (IS_ERR(ipcp)) ++ return ERR_CAST(ipcp); ++ ++ return container_of(ipcp, struct shmid_kernel, shm_perm); ++} ++ ++static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace *ns, int id) ++{ ++ struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&shm_ids(ns), id); ++ ++ if (IS_ERR(ipcp)) ++ return ERR_CAST(ipcp); ++ ++ return container_of(ipcp, struct shmid_kernel, shm_perm); ++} ++ + /* + * shm_lock_(check_) routines are called in the paths where the rw_mutex + * is not necessarily held. +Index: linux-3.10-3.10.11/dummy/rpi_1418_1b2ad167481aed32347ef7726d14bb2b9f63c4c9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1418_1b2ad167481aed32347ef7726d14bb2b9f63c4c9.txt 2014-05-05 12:49:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1419_b3b7b427fd385e92ce2ea8a847ec977724dc9669.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1419_b3b7b427fd385e92ce2ea8a847ec977724dc9669.patch --- linux-3.10.11/debian/patches/rpi/rpi_1419_b3b7b427fd385e92ce2ea8a847ec977724dc9669.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1419_b3b7b427fd385e92ce2ea8a847ec977724dc9669.patch 2014-05-05 12:49:04.000000000 +0000 @@ -0,0 +1,71 @@ +commit b3b7b427fd385e92ce2ea8a847ec977724dc9669 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:16 2013 -0700 + + ipc,shm: shorten critical region in shmctl_down + + commit 79ccf0f8c8e04e8b9eda6645ba0f63b0915a3075 upstream. + + Instead of holding the ipc lock for the entire function, use the + ipcctl_pre_down_nolock and only acquire the lock for specific commands: + RMID and SET. + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:02.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:03.000000000 +0000 +@@ -780,11 +780,10 @@ + down_write(&shm_ids(ns).rw_mutex); + rcu_read_lock(); + +- ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd, +- &shmid64.shm_perm, 0); ++ ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd, ++ &shmid64.shm_perm, 0); + if (IS_ERR(ipcp)) { + err = PTR_ERR(ipcp); +- /* the ipc lock is not held upon failure */ + goto out_unlock1; + } + +@@ -792,14 +791,16 @@ + + err = security_shm_shmctl(shp, cmd); + if (err) +- goto out_unlock0; ++ goto out_unlock1; + + switch (cmd) { + case IPC_RMID: ++ ipc_lock_object(&shp->shm_perm); + /* do_shm_rmid unlocks the ipc object and rcu */ + do_shm_rmid(ns, ipcp); + goto out_up; + case IPC_SET: ++ ipc_lock_object(&shp->shm_perm); + err = ipc_update_perm(&shmid64.shm_perm, ipcp); + if (err) + goto out_unlock0; +@@ -807,6 +808,7 @@ + break; + default: + err = -EINVAL; ++ goto out_unlock1; + } + + out_unlock0: +Index: linux-3.10-3.10.11/dummy/rpi_1419_b3b7b427fd385e92ce2ea8a847ec977724dc9669.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1419_b3b7b427fd385e92ce2ea8a847ec977724dc9669.txt 2014-05-05 12:49:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1420_60425b7b25c07bbc55f39ce1b178c5bf86e679e4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1420_60425b7b25c07bbc55f39ce1b178c5bf86e679e4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1420_60425b7b25c07bbc55f39ce1b178c5bf86e679e4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1420_60425b7b25c07bbc55f39ce1b178c5bf86e679e4.patch 2014-05-05 12:49:05.000000000 +0000 @@ -0,0 +1,87 @@ +commit 60425b7b25c07bbc55f39ce1b178c5bf86e679e4 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:17 2013 -0700 + + ipc: drop ipcctl_pre_down + + commit 3b1c4ad37741e53804ffe0a30dd01e08b2ab6241 upstream. + + Now that sem, msgque and shm, through *_down(), all use the lockless + variant of ipcctl_pre_down(), go ahead and delete it. + + [akpm@linux-foundation.org: fix function name in kerneldoc, cleanups] + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:48:56.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:49:04.000000000 +0000 +@@ -733,7 +733,7 @@ + } + + /** +- * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd ++ * ipcctl_pre_down_nolock - retrieve an ipc and check permissions for some IPC_XXX cmd + * @ns: the ipc namespace + * @ids: the table of ids where to look for the ipc + * @id: the id of the ipc to retrieve +@@ -746,29 +746,13 @@ + * It must be called without any lock held and + * - retrieves the ipc with the given id in the given table. + * - performs some audit and permission check, depending on the given cmd +- * - returns the ipc with the ipc lock held in case of success +- * or an err-code without any lock held otherwise. ++ * - returns a pointer to the ipc object or otherwise, the corresponding error. + * + * Call holding the both the rw_mutex and the rcu read lock. + */ +-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, +- struct ipc_ids *ids, int id, int cmd, +- struct ipc64_perm *perm, int extra_perm) +-{ +- struct kern_ipc_perm *ipcp; +- +- ipcp = ipcctl_pre_down_nolock(ns, ids, id, cmd, perm, extra_perm); +- if (IS_ERR(ipcp)) +- goto out; +- +- spin_lock(&ipcp->lock); +-out: +- return ipcp; +-} +- + struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, +- struct ipc_ids *ids, int id, int cmd, +- struct ipc64_perm *perm, int extra_perm) ++ struct ipc_ids *ids, int id, int cmd, ++ struct ipc64_perm *perm, int extra_perm) + { + kuid_t euid; + int err = -EPERM; +Index: linux-3.10-3.10.11/ipc/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.h 2014-05-05 12:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.h 2014-05-05 12:49:04.000000000 +0000 +@@ -131,9 +131,6 @@ + struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, + struct ipc_ids *ids, int id, int cmd, + struct ipc64_perm *perm, int extra_perm); +-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, +- struct ipc_ids *ids, int id, int cmd, +- struct ipc64_perm *perm, int extra_perm); + + #ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION + /* On IA-64, we always use the "64-bit version" of the IPC structures. */ +Index: linux-3.10-3.10.11/dummy/rpi_1420_60425b7b25c07bbc55f39ce1b178c5bf86e679e4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1420_60425b7b25c07bbc55f39ce1b178c5bf86e679e4.txt 2014-05-05 12:49:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1421_d6187ddfc90715e95b8c73f49887781b4b2a1ebc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1421_d6187ddfc90715e95b8c73f49887781b4b2a1ebc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1421_d6187ddfc90715e95b8c73f49887781b4b2a1ebc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1421_d6187ddfc90715e95b8c73f49887781b4b2a1ebc.patch 2014-05-05 12:49:05.000000000 +0000 @@ -0,0 +1,121 @@ +commit d6187ddfc90715e95b8c73f49887781b4b2a1ebc +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:18 2013 -0700 + + ipc,shm: introduce shmctl_nolock + + commit 68eccc1dc345539d589ae78ee43b835c1a06a134 upstream. + + Similar to semctl and msgctl, when calling msgctl, the *_INFO and *_STAT + commands can be performed without acquiring the ipc object. + + Add a shmctl_nolock() function and move the logic of *_INFO and *_STAT out + of msgctl(). Since we are just moving functionality, this change still + takes the lock and it will be properly lockless in the next patch. + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:03.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:05.000000000 +0000 +@@ -820,29 +820,24 @@ + return err; + } + +-SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) ++static int shmctl_nolock(struct ipc_namespace *ns, int shmid, ++ int cmd, int version, void __user *buf) + { ++ int err; + struct shmid_kernel *shp; +- int err, version; +- struct ipc_namespace *ns; + +- if (cmd < 0 || shmid < 0) { +- err = -EINVAL; +- goto out; ++ /* preliminary security checks for *_INFO */ ++ if (cmd == IPC_INFO || cmd == SHM_INFO) { ++ err = security_shm_shmctl(NULL, cmd); ++ if (err) ++ return err; + } + +- version = ipc_parse_version(&cmd); +- ns = current->nsproxy->ipc_ns; +- +- switch (cmd) { /* replace with proc interface ? */ ++ switch (cmd) { + case IPC_INFO: + { + struct shminfo64 shminfo; + +- err = security_shm_shmctl(NULL, cmd); +- if (err) +- return err; +- + memset(&shminfo, 0, sizeof(shminfo)); + shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; + shminfo.shmmax = ns->shm_ctlmax; +@@ -864,10 +859,6 @@ + { + struct shm_info shm_info; + +- err = security_shm_shmctl(NULL, cmd); +- if (err) +- return err; +- + memset(&shm_info, 0, sizeof(shm_info)); + down_read(&shm_ids(ns).rw_mutex); + shm_info.used_ids = shm_ids(ns).in_use; +@@ -928,6 +919,36 @@ + err = result; + goto out; + } ++ default: ++ return -EINVAL; ++ } ++ ++out_unlock: ++ shm_unlock(shp); ++out: ++ return err; ++} ++ ++SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) ++{ ++ struct shmid_kernel *shp; ++ int err, version; ++ struct ipc_namespace *ns; ++ ++ if (cmd < 0 || shmid < 0) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ version = ipc_parse_version(&cmd); ++ ns = current->nsproxy->ipc_ns; ++ ++ switch (cmd) { ++ case IPC_INFO: ++ case SHM_INFO: ++ case SHM_STAT: ++ case IPC_STAT: ++ return shmctl_nolock(ns, shmid, cmd, version, buf); + case SHM_LOCK: + case SHM_UNLOCK: + { +Index: linux-3.10-3.10.11/dummy/rpi_1421_d6187ddfc90715e95b8c73f49887781b4b2a1ebc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1421_d6187ddfc90715e95b8c73f49887781b4b2a1ebc.txt 2014-05-05 12:49:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1422_c29c40392a01b9414b02c1b57b042950704cb774.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1422_c29c40392a01b9414b02c1b57b042950704cb774.patch --- linux-3.10.11/debian/patches/rpi/rpi_1422_c29c40392a01b9414b02c1b57b042950704cb774.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1422_c29c40392a01b9414b02c1b57b042950704cb774.patch 2014-05-05 12:49:06.000000000 +0000 @@ -0,0 +1,89 @@ +commit c29c40392a01b9414b02c1b57b042950704cb774 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:20 2013 -0700 + + ipc,shm: make shmctl_nolock lockless + + commit c97cb9ccab8c85428ec21eff690642ad2ce1fa8a upstream. + + While the INFO cmd doesn't take the ipc lock, the STAT commands do acquire + it unnecessarily. We can do the permissions and security checks only + holding the rcu lock. + + [akpm@linux-foundation.org: coding-style fixes] + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:05.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:06.000000000 +0000 +@@ -882,27 +882,31 @@ + struct shmid64_ds tbuf; + int result; + ++ rcu_read_lock(); + if (cmd == SHM_STAT) { +- shp = shm_lock(ns, shmid); ++ shp = shm_obtain_object(ns, shmid); + if (IS_ERR(shp)) { + err = PTR_ERR(shp); +- goto out; ++ goto out_unlock; + } + result = shp->shm_perm.id; + } else { +- shp = shm_lock_check(ns, shmid); ++ shp = shm_obtain_object_check(ns, shmid); + if (IS_ERR(shp)) { + err = PTR_ERR(shp); +- goto out; ++ goto out_unlock; + } + result = 0; + } ++ + err = -EACCES; + if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) + goto out_unlock; ++ + err = security_shm_shmctl(shp, cmd); + if (err) + goto out_unlock; ++ + memset(&tbuf, 0, sizeof(tbuf)); + kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm); + tbuf.shm_segsz = shp->shm_segsz; +@@ -912,8 +916,9 @@ + tbuf.shm_cpid = shp->shm_cprid; + tbuf.shm_lpid = shp->shm_lprid; + tbuf.shm_nattch = shp->shm_nattch; +- shm_unlock(shp); +- if(copy_shmid_to_user (buf, &tbuf, version)) ++ rcu_read_unlock(); ++ ++ if (copy_shmid_to_user(buf, &tbuf, version)) + err = -EFAULT; + else + err = result; +@@ -924,7 +929,7 @@ + } + + out_unlock: +- shm_unlock(shp); ++ rcu_read_unlock(); + out: + return err; + } +Index: linux-3.10-3.10.11/dummy/rpi_1422_c29c40392a01b9414b02c1b57b042950704cb774.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1422_c29c40392a01b9414b02c1b57b042950704cb774.txt 2014-05-05 12:49:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1423_00c88e695ae4c001495d6768d6c91603f34aa6c7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1423_00c88e695ae4c001495d6768d6c91603f34aa6c7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1423_00c88e695ae4c001495d6768d6c91603f34aa6c7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1423_00c88e695ae4c001495d6768d6c91603f34aa6c7.patch 2014-05-05 12:49:07.000000000 +0000 @@ -0,0 +1,138 @@ +commit 00c88e695ae4c001495d6768d6c91603f34aa6c7 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:21 2013 -0700 + + ipc,shm: shorten critical region for shmctl + + commit 2caacaa82a51b78fc0c800e206473874094287ed upstream. + + With the *_INFO, *_STAT, IPC_RMID and IPC_SET commands already optimized, + deal with the remaining SHM_LOCK and SHM_UNLOCK commands. Take the + shm_perm lock after doing the initial auditing and security checks. The + rest of the logic remains unchanged. + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:06.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:07.000000000 +0000 +@@ -940,10 +940,8 @@ + int err, version; + struct ipc_namespace *ns; + +- if (cmd < 0 || shmid < 0) { +- err = -EINVAL; +- goto out; +- } ++ if (cmd < 0 || shmid < 0) ++ return -EINVAL; + + version = ipc_parse_version(&cmd); + ns = current->nsproxy->ipc_ns; +@@ -954,36 +952,40 @@ + case SHM_STAT: + case IPC_STAT: + return shmctl_nolock(ns, shmid, cmd, version, buf); ++ case IPC_RMID: ++ case IPC_SET: ++ return shmctl_down(ns, shmid, cmd, buf, version); + case SHM_LOCK: + case SHM_UNLOCK: + { + struct file *shm_file; + +- shp = shm_lock_check(ns, shmid); ++ rcu_read_lock(); ++ shp = shm_obtain_object_check(ns, shmid); + if (IS_ERR(shp)) { + err = PTR_ERR(shp); +- goto out; ++ goto out_unlock1; + } + + audit_ipc_obj(&(shp->shm_perm)); ++ err = security_shm_shmctl(shp, cmd); ++ if (err) ++ goto out_unlock1; + ++ ipc_lock_object(&shp->shm_perm); + if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { + kuid_t euid = current_euid(); + err = -EPERM; + if (!uid_eq(euid, shp->shm_perm.uid) && + !uid_eq(euid, shp->shm_perm.cuid)) +- goto out_unlock; ++ goto out_unlock0; + if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) +- goto out_unlock; ++ goto out_unlock0; + } + +- err = security_shm_shmctl(shp, cmd); +- if (err) +- goto out_unlock; +- + shm_file = shp->shm_file; + if (is_file_hugepages(shm_file)) +- goto out_unlock; ++ goto out_unlock0; + + if (cmd == SHM_LOCK) { + struct user_struct *user = current_user(); +@@ -992,32 +994,31 @@ + shp->shm_perm.mode |= SHM_LOCKED; + shp->mlock_user = user; + } +- goto out_unlock; ++ goto out_unlock0; + } + + /* SHM_UNLOCK */ + if (!(shp->shm_perm.mode & SHM_LOCKED)) +- goto out_unlock; ++ goto out_unlock0; + shmem_lock(shm_file, 0, shp->mlock_user); + shp->shm_perm.mode &= ~SHM_LOCKED; + shp->mlock_user = NULL; + get_file(shm_file); +- shm_unlock(shp); ++ ipc_unlock_object(&shp->shm_perm); ++ rcu_read_unlock(); + shmem_unlock_mapping(shm_file->f_mapping); ++ + fput(shm_file); +- goto out; +- } +- case IPC_RMID: +- case IPC_SET: +- err = shmctl_down(ns, shmid, cmd, buf, version); + return err; ++ } + default: + return -EINVAL; + } + +-out_unlock: +- shm_unlock(shp); +-out: ++out_unlock0: ++ ipc_unlock_object(&shp->shm_perm); ++out_unlock1: ++ rcu_read_unlock(); + return err; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1423_00c88e695ae4c001495d6768d6c91603f34aa6c7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1423_00c88e695ae4c001495d6768d6c91603f34aa6c7.txt 2014-05-05 12:49:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1424_247ec302b53873fa13bbb413b5df982cb5d7f78f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1424_247ec302b53873fa13bbb413b5df982cb5d7f78f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1424_247ec302b53873fa13bbb413b5df982cb5d7f78f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1424_247ec302b53873fa13bbb413b5df982cb5d7f78f.patch 2014-05-05 12:49:08.000000000 +0000 @@ -0,0 +1,88 @@ +commit 247ec302b53873fa13bbb413b5df982cb5d7f78f +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:22 2013 -0700 + + ipc,shm: cleanup do_shmat pasta + + commit f42569b1388b1408b574a5e93a23a663647d4181 upstream. + + Clean up some of the messy do_shmat() spaghetti code, getting rid of + out_free and out_put_dentry labels. This makes shortening the critical + region of this function in the next patch a little easier to do and read. + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:07.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:08.000000000 +0000 +@@ -1108,16 +1108,21 @@ + + err = -ENOMEM; + sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); +- if (!sfd) +- goto out_put_dentry; ++ if (!sfd) { ++ path_put(&path); ++ goto out_nattch; ++ } + + file = alloc_file(&path, f_mode, + is_file_hugepages(shp->shm_file) ? + &shm_file_operations_huge : + &shm_file_operations); + err = PTR_ERR(file); +- if (IS_ERR(file)) +- goto out_free; ++ if (IS_ERR(file)) { ++ kfree(sfd); ++ path_put(&path); ++ goto out_nattch; ++ } + + file->private_data = sfd; + file->f_mapping = shp->shm_file->f_mapping; +@@ -1143,7 +1148,7 @@ + addr > current->mm->start_stack - size - PAGE_SIZE * 5) + goto invalid; + } +- ++ + addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate); + *raddr = addr; + err = 0; +@@ -1167,19 +1172,12 @@ + else + shm_unlock(shp); + up_write(&shm_ids(ns).rw_mutex); +- +-out: + return err; + + out_unlock: + shm_unlock(shp); +- goto out; +- +-out_free: +- kfree(sfd); +-out_put_dentry: +- path_put(&path); +- goto out_nattch; ++out: ++ return err; + } + + SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) +Index: linux-3.10-3.10.11/dummy/rpi_1424_247ec302b53873fa13bbb413b5df982cb5d7f78f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1424_247ec302b53873fa13bbb413b5df982cb5d7f78f.txt 2014-05-05 12:49:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1425_bd58e2dc27330012ff1774cd54d41d6e7ffcbc36.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1425_bd58e2dc27330012ff1774cd54d41d6e7ffcbc36.patch --- linux-3.10.11/debian/patches/rpi/rpi_1425_bd58e2dc27330012ff1774cd54d41d6e7ffcbc36.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1425_bd58e2dc27330012ff1774cd54d41d6e7ffcbc36.patch 2014-05-05 12:49:09.000000000 +0000 @@ -0,0 +1,80 @@ +commit bd58e2dc27330012ff1774cd54d41d6e7ffcbc36 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:23 2013 -0700 + + ipc,shm: shorten critical region for shmat + + commit c2c737a0461e61a34676bd0bd1bc1a70a1b4e396 upstream. + + Similar to other system calls, acquire the kern_ipc_perm lock after doing + the initial permission and security checks. + + [sasha.levin@oracle.com: dont leave do_shmat with rcu lock held] + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Sasha Levin + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:08.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:08.000000000 +0000 +@@ -19,6 +19,9 @@ + * namespaces support + * OpenVZ, SWsoft Inc. + * Pavel Emelianov ++ * ++ * Better ipc lock (kern_ipc_perm.lock) handling ++ * Davidlohr Bueso , June 2013. + */ + + #include +@@ -1086,10 +1089,11 @@ + * additional creator id... + */ + ns = current->nsproxy->ipc_ns; +- shp = shm_lock_check(ns, shmid); ++ rcu_read_lock(); ++ shp = shm_obtain_object_check(ns, shmid); + if (IS_ERR(shp)) { + err = PTR_ERR(shp); +- goto out; ++ goto out_unlock; + } + + err = -EACCES; +@@ -1100,11 +1104,13 @@ + if (err) + goto out_unlock; + ++ ipc_lock_object(&shp->shm_perm); + path = shp->shm_file->f_path; + path_get(&path); + shp->shm_nattch++; + size = i_size_read(path.dentry->d_inode); +- shm_unlock(shp); ++ ipc_unlock_object(&shp->shm_perm); ++ rcu_read_unlock(); + + err = -ENOMEM; + sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); +@@ -1175,7 +1181,7 @@ + return err; + + out_unlock: +- shm_unlock(shp); ++ rcu_read_unlock(); + out: + return err; + } +Index: linux-3.10-3.10.11/dummy/rpi_1425_bd58e2dc27330012ff1774cd54d41d6e7ffcbc36.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1425_bd58e2dc27330012ff1774cd54d41d6e7ffcbc36.txt 2014-05-05 12:49:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1426_33b74669858f3f1982d83015203264b462d845e7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1426_33b74669858f3f1982d83015203264b462d845e7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1426_33b74669858f3f1982d83015203264b462d845e7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1426_33b74669858f3f1982d83015203264b462d845e7.patch 2014-05-05 12:49:10.000000000 +0000 @@ -0,0 +1,603 @@ +commit 33b74669858f3f1982d83015203264b462d845e7 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:24 2013 -0700 + + ipc: rename ids->rw_mutex + + commit d9a605e40b1376eb02b067d7690580255a0df68f upstream. + + Since in some situations the lock can be shared for readers, we shouldn't + be calling it a mutex, rename it to rwsem. + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/ipc_namespace.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/ipc_namespace.h 2014-05-05 11:49:30.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/ipc_namespace.h 2014-05-05 12:49:09.000000000 +0000 +@@ -22,7 +22,7 @@ + int in_use; + unsigned short seq; + unsigned short seq_max; +- struct rw_semaphore rw_mutex; ++ struct rw_semaphore rwsem; + struct idr ipcs_idr; + int next_id; + }; +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:49:01.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:49:09.000000000 +0000 +@@ -172,7 +172,7 @@ + * @ns: namespace + * @params: ptr to the structure that contains the key and msgflg + * +- * Called with msg_ids.rw_mutex held (writer) ++ * Called with msg_ids.rwsem held (writer) + */ + static int newque(struct ipc_namespace *ns, struct ipc_params *params) + { +@@ -259,8 +259,8 @@ + * removes the message queue from message queue ID IDR, and cleans up all the + * messages associated with this queue. + * +- * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held +- * before freeque() is called. msg_ids.rw_mutex remains locked on exit. ++ * msg_ids.rwsem (writer) and the spinlock for this message queue are held ++ * before freeque() is called. msg_ids.rwsem remains locked on exit. + */ + static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) + { +@@ -282,7 +282,7 @@ + } + + /* +- * Called with msg_ids.rw_mutex and ipcp locked. ++ * Called with msg_ids.rwsem and ipcp locked. + */ + static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) + { +@@ -386,9 +386,9 @@ + } + + /* +- * This function handles some msgctl commands which require the rw_mutex ++ * This function handles some msgctl commands which require the rwsem + * to be held in write mode. +- * NOTE: no locks must be held, the rw_mutex is taken inside this function. ++ * NOTE: no locks must be held, the rwsem is taken inside this function. + */ + static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, + struct msqid_ds __user *buf, int version) +@@ -403,7 +403,7 @@ + return -EFAULT; + } + +- down_write(&msg_ids(ns).rw_mutex); ++ down_write(&msg_ids(ns).rwsem); + rcu_read_lock(); + + ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd, +@@ -459,7 +459,7 @@ + out_unlock1: + rcu_read_unlock(); + out_up: +- up_write(&msg_ids(ns).rw_mutex); ++ up_write(&msg_ids(ns).rwsem); + return err; + } + +@@ -494,7 +494,7 @@ + msginfo.msgmnb = ns->msg_ctlmnb; + msginfo.msgssz = MSGSSZ; + msginfo.msgseg = MSGSEG; +- down_read(&msg_ids(ns).rw_mutex); ++ down_read(&msg_ids(ns).rwsem); + if (cmd == MSG_INFO) { + msginfo.msgpool = msg_ids(ns).in_use; + msginfo.msgmap = atomic_read(&ns->msg_hdrs); +@@ -505,7 +505,7 @@ + msginfo.msgtql = MSGTQL; + } + max_id = ipc_get_maxid(&msg_ids(ns)); +- up_read(&msg_ids(ns).rw_mutex); ++ up_read(&msg_ids(ns).rwsem); + if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) + return -EFAULT; + return (max_id < 0) ? 0 : max_id; +Index: linux-3.10-3.10.11/ipc/namespace.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/namespace.c 2014-05-05 11:49:30.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/namespace.c 2014-05-05 12:49:09.000000000 +0000 +@@ -81,7 +81,7 @@ + int next_id; + int total, in_use; + +- down_write(&ids->rw_mutex); ++ down_write(&ids->rwsem); + + in_use = ids->in_use; + +@@ -93,7 +93,7 @@ + free(ns, perm); + total++; + } +- up_write(&ids->rw_mutex); ++ up_write(&ids->rwsem); + } + + static void free_ipc_ns(struct ipc_namespace *ns) +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:49:00.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:49:09.000000000 +0000 +@@ -322,7 +322,7 @@ + } + + /* +- * sem_lock_(check_) routines are called in the paths where the rw_mutex ++ * sem_lock_(check_) routines are called in the paths where the rwsem + * is not held. + * + * The caller holds the RCU read lock. +@@ -426,7 +426,7 @@ + * @ns: namespace + * @params: ptr to the structure that contains key, semflg and nsems + * +- * Called with sem_ids.rw_mutex held (as a writer) ++ * Called with sem_ids.rwsem held (as a writer) + */ + + static int newary(struct ipc_namespace *ns, struct ipc_params *params) +@@ -492,7 +492,7 @@ + + + /* +- * Called with sem_ids.rw_mutex and ipcp locked. ++ * Called with sem_ids.rwsem and ipcp locked. + */ + static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) + { +@@ -503,7 +503,7 @@ + } + + /* +- * Called with sem_ids.rw_mutex and ipcp locked. ++ * Called with sem_ids.rwsem and ipcp locked. + */ + static inline int sem_more_checks(struct kern_ipc_perm *ipcp, + struct ipc_params *params) +@@ -994,8 +994,8 @@ + return semzcnt; + } + +-/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked +- * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex ++/* Free a semaphore set. freeary() is called with sem_ids.rwsem locked ++ * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem + * remains locked on exit. + */ + static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) +@@ -1116,7 +1116,7 @@ + seminfo.semmnu = SEMMNU; + seminfo.semmap = SEMMAP; + seminfo.semume = SEMUME; +- down_read(&sem_ids(ns).rw_mutex); ++ down_read(&sem_ids(ns).rwsem); + if (cmd == SEM_INFO) { + seminfo.semusz = sem_ids(ns).in_use; + seminfo.semaem = ns->used_sems; +@@ -1125,7 +1125,7 @@ + seminfo.semaem = SEMAEM; + } + max_id = ipc_get_maxid(&sem_ids(ns)); +- up_read(&sem_ids(ns).rw_mutex); ++ up_read(&sem_ids(ns).rwsem); + if (copy_to_user(p, &seminfo, sizeof(struct seminfo))) + return -EFAULT; + return (max_id < 0) ? 0: max_id; +@@ -1431,9 +1431,9 @@ + } + + /* +- * This function handles some semctl commands which require the rw_mutex ++ * This function handles some semctl commands which require the rwsem + * to be held in write mode. +- * NOTE: no locks must be held, the rw_mutex is taken inside this function. ++ * NOTE: no locks must be held, the rwsem is taken inside this function. + */ + static int semctl_down(struct ipc_namespace *ns, int semid, + int cmd, int version, void __user *p) +@@ -1448,7 +1448,7 @@ + return -EFAULT; + } + +- down_write(&sem_ids(ns).rw_mutex); ++ down_write(&sem_ids(ns).rwsem); + rcu_read_lock(); + + ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd, +@@ -1487,7 +1487,7 @@ + out_unlock1: + rcu_read_unlock(); + out_up: +- up_write(&sem_ids(ns).rw_mutex); ++ up_write(&sem_ids(ns).rwsem); + return err; + } + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:08.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:09.000000000 +0000 +@@ -83,8 +83,8 @@ + } + + /* +- * Called with shm_ids.rw_mutex (writer) and the shp structure locked. +- * Only shm_ids.rw_mutex remains locked on exit. ++ * Called with shm_ids.rwsem (writer) and the shp structure locked. ++ * Only shm_ids.rwsem remains locked on exit. + */ + static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) + { +@@ -148,7 +148,7 @@ + } + + /* +- * shm_lock_(check_) routines are called in the paths where the rw_mutex ++ * shm_lock_(check_) routines are called in the paths where the rwsem + * is not necessarily held. + */ + static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id) +@@ -205,7 +205,7 @@ + * @ns: namespace + * @shp: struct to free + * +- * It has to be called with shp and shm_ids.rw_mutex (writer) locked, ++ * It has to be called with shp and shm_ids.rwsem (writer) locked, + * but returns with shp unlocked and freed. + */ + static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) +@@ -253,7 +253,7 @@ + struct shmid_kernel *shp; + struct ipc_namespace *ns = sfd->ns; + +- down_write(&shm_ids(ns).rw_mutex); ++ down_write(&shm_ids(ns).rwsem); + /* remove from the list of attaches of the shm segment */ + shp = shm_lock(ns, sfd->id); + BUG_ON(IS_ERR(shp)); +@@ -264,10 +264,10 @@ + shm_destroy(ns, shp); + else + shm_unlock(shp); +- up_write(&shm_ids(ns).rw_mutex); ++ up_write(&shm_ids(ns).rwsem); + } + +-/* Called with ns->shm_ids(ns).rw_mutex locked */ ++/* Called with ns->shm_ids(ns).rwsem locked */ + static int shm_try_destroy_current(int id, void *p, void *data) + { + struct ipc_namespace *ns = data; +@@ -298,7 +298,7 @@ + return 0; + } + +-/* Called with ns->shm_ids(ns).rw_mutex locked */ ++/* Called with ns->shm_ids(ns).rwsem locked */ + static int shm_try_destroy_orphaned(int id, void *p, void *data) + { + struct ipc_namespace *ns = data; +@@ -309,7 +309,7 @@ + * We want to destroy segments without users and with already + * exit'ed originating process. + * +- * As shp->* are changed under rw_mutex, it's safe to skip shp locking. ++ * As shp->* are changed under rwsem, it's safe to skip shp locking. + */ + if (shp->shm_creator != NULL) + return 0; +@@ -323,10 +323,10 @@ + + void shm_destroy_orphaned(struct ipc_namespace *ns) + { +- down_write(&shm_ids(ns).rw_mutex); ++ down_write(&shm_ids(ns).rwsem); + if (shm_ids(ns).in_use) + idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns); +- up_write(&shm_ids(ns).rw_mutex); ++ up_write(&shm_ids(ns).rwsem); + } + + +@@ -338,10 +338,10 @@ + return; + + /* Destroy all already created segments, but not mapped yet */ +- down_write(&shm_ids(ns).rw_mutex); ++ down_write(&shm_ids(ns).rwsem); + if (shm_ids(ns).in_use) + idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns); +- up_write(&shm_ids(ns).rw_mutex); ++ up_write(&shm_ids(ns).rwsem); + } + + static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +@@ -475,7 +475,7 @@ + * @ns: namespace + * @params: ptr to the structure that contains key, size and shmflg + * +- * Called with shm_ids.rw_mutex held as a writer. ++ * Called with shm_ids.rwsem held as a writer. + */ + + static int newseg(struct ipc_namespace *ns, struct ipc_params *params) +@@ -583,7 +583,7 @@ + } + + /* +- * Called with shm_ids.rw_mutex and ipcp locked. ++ * Called with shm_ids.rwsem and ipcp locked. + */ + static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) + { +@@ -594,7 +594,7 @@ + } + + /* +- * Called with shm_ids.rw_mutex and ipcp locked. ++ * Called with shm_ids.rwsem and ipcp locked. + */ + static inline int shm_more_checks(struct kern_ipc_perm *ipcp, + struct ipc_params *params) +@@ -707,7 +707,7 @@ + + /* + * Calculate and add used RSS and swap pages of a shm. +- * Called with shm_ids.rw_mutex held as a reader ++ * Called with shm_ids.rwsem held as a reader + */ + static void shm_add_rss_swap(struct shmid_kernel *shp, + unsigned long *rss_add, unsigned long *swp_add) +@@ -734,7 +734,7 @@ + } + + /* +- * Called with shm_ids.rw_mutex held as a reader ++ * Called with shm_ids.rwsem held as a reader + */ + static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, + unsigned long *swp) +@@ -763,9 +763,9 @@ + } + + /* +- * This function handles some shmctl commands which require the rw_mutex ++ * This function handles some shmctl commands which require the rwsem + * to be held in write mode. +- * NOTE: no locks must be held, the rw_mutex is taken inside this function. ++ * NOTE: no locks must be held, the rwsem is taken inside this function. + */ + static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, + struct shmid_ds __user *buf, int version) +@@ -780,7 +780,7 @@ + return -EFAULT; + } + +- down_write(&shm_ids(ns).rw_mutex); ++ down_write(&shm_ids(ns).rwsem); + rcu_read_lock(); + + ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd, +@@ -819,7 +819,7 @@ + out_unlock1: + rcu_read_unlock(); + out_up: +- up_write(&shm_ids(ns).rw_mutex); ++ up_write(&shm_ids(ns).rwsem); + return err; + } + +@@ -850,9 +850,9 @@ + if(copy_shminfo_to_user (buf, &shminfo, version)) + return -EFAULT; + +- down_read(&shm_ids(ns).rw_mutex); ++ down_read(&shm_ids(ns).rwsem); + err = ipc_get_maxid(&shm_ids(ns)); +- up_read(&shm_ids(ns).rw_mutex); ++ up_read(&shm_ids(ns).rwsem); + + if(err<0) + err = 0; +@@ -863,14 +863,14 @@ + struct shm_info shm_info; + + memset(&shm_info, 0, sizeof(shm_info)); +- down_read(&shm_ids(ns).rw_mutex); ++ down_read(&shm_ids(ns).rwsem); + shm_info.used_ids = shm_ids(ns).in_use; + shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); + shm_info.shm_tot = ns->shm_tot; + shm_info.swap_attempts = 0; + shm_info.swap_successes = 0; + err = ipc_get_maxid(&shm_ids(ns)); +- up_read(&shm_ids(ns).rw_mutex); ++ up_read(&shm_ids(ns).rwsem); + if (copy_to_user(buf, &shm_info, sizeof(shm_info))) { + err = -EFAULT; + goto out; +@@ -1169,7 +1169,7 @@ + fput(file); + + out_nattch: +- down_write(&shm_ids(ns).rw_mutex); ++ down_write(&shm_ids(ns).rwsem); + shp = shm_lock(ns, shmid); + BUG_ON(IS_ERR(shp)); + shp->shm_nattch--; +@@ -1177,7 +1177,7 @@ + shm_destroy(ns, shp); + else + shm_unlock(shp); +- up_write(&shm_ids(ns).rw_mutex); ++ up_write(&shm_ids(ns).rwsem); + return err; + + out_unlock: +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:49:04.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:49:09.000000000 +0000 +@@ -119,7 +119,7 @@ + + void ipc_init_ids(struct ipc_ids *ids) + { +- init_rwsem(&ids->rw_mutex); ++ init_rwsem(&ids->rwsem); + + ids->in_use = 0; + ids->seq = 0; +@@ -174,7 +174,7 @@ + * @ids: Identifier set + * @key: The key to find + * +- * Requires ipc_ids.rw_mutex locked. ++ * Requires ipc_ids.rwsem locked. + * Returns the LOCKED pointer to the ipc structure if found or NULL + * if not. + * If key is found ipc points to the owning ipc structure +@@ -208,7 +208,7 @@ + * ipc_get_maxid - get the last assigned id + * @ids: IPC identifier set + * +- * Called with ipc_ids.rw_mutex held. ++ * Called with ipc_ids.rwsem held. + */ + + int ipc_get_maxid(struct ipc_ids *ids) +@@ -246,7 +246,7 @@ + * is returned. The 'new' entry is returned in a locked state on success. + * On failure the entry is not locked and a negative err-code is returned. + * +- * Called with writer ipc_ids.rw_mutex held. ++ * Called with writer ipc_ids.rwsem held. + */ + int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) + { +@@ -312,9 +312,9 @@ + { + int err; + +- down_write(&ids->rw_mutex); ++ down_write(&ids->rwsem); + err = ops->getnew(ns, params); +- up_write(&ids->rw_mutex); ++ up_write(&ids->rwsem); + return err; + } + +@@ -331,7 +331,7 @@ + * + * On success, the IPC id is returned. + * +- * It is called with ipc_ids.rw_mutex and ipcp->lock held. ++ * It is called with ipc_ids.rwsem and ipcp->lock held. + */ + static int ipc_check_perms(struct ipc_namespace *ns, + struct kern_ipc_perm *ipcp, +@@ -376,7 +376,7 @@ + * Take the lock as a writer since we are potentially going to add + * a new entry + read locks are not "upgradable" + */ +- down_write(&ids->rw_mutex); ++ down_write(&ids->rwsem); + ipcp = ipc_findkey(ids, params->key); + if (ipcp == NULL) { + /* key not used */ +@@ -402,7 +402,7 @@ + } + ipc_unlock(ipcp); + } +- up_write(&ids->rw_mutex); ++ up_write(&ids->rwsem); + + return err; + } +@@ -413,7 +413,7 @@ + * @ids: IPC identifier set + * @ipcp: ipc perm structure containing the identifier to remove + * +- * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held ++ * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held + * before this function is called, and remain locked on the exit. + */ + +@@ -621,7 +621,7 @@ + } + + /** +- * ipc_lock - Lock an ipc structure without rw_mutex held ++ * ipc_lock - Lock an ipc structure without rwsem held + * @ids: IPC identifier set + * @id: ipc id to look for + * +@@ -748,7 +748,7 @@ + * - performs some audit and permission check, depending on the given cmd + * - returns a pointer to the ipc object or otherwise, the corresponding error. + * +- * Call holding the both the rw_mutex and the rcu read lock. ++ * Call holding the both the rwsem and the rcu read lock. + */ + struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, + struct ipc_ids *ids, int id, int cmd, +@@ -868,7 +868,7 @@ + * Take the lock - this will be released by the corresponding + * call to stop(). + */ +- down_read(&ids->rw_mutex); ++ down_read(&ids->rwsem); + + /* pos < 0 is invalid */ + if (*pos < 0) +@@ -895,7 +895,7 @@ + + ids = &iter->ns->ids[iface->ids]; + /* Release the lock we took in start() */ +- up_read(&ids->rw_mutex); ++ up_read(&ids->rwsem); + } + + static int sysvipc_proc_show(struct seq_file *s, void *it) +Index: linux-3.10-3.10.11/ipc/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.h 2014-05-05 12:49:04.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.h 2014-05-05 12:49:09.000000000 +0000 +@@ -94,10 +94,10 @@ + #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER) + #define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER) + +-/* must be called with ids->rw_mutex acquired for writing */ ++/* must be called with ids->rwsem acquired for writing */ + int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); + +-/* must be called with ids->rw_mutex acquired for reading */ ++/* must be called with ids->rwsem acquired for reading */ + int ipc_get_maxid(struct ipc_ids *); + + /* must be called with both locks acquired. */ +Index: linux-3.10-3.10.11/dummy/rpi_1426_33b74669858f3f1982d83015203264b462d845e7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1426_33b74669858f3f1982d83015203264b462d845e7.txt 2014-05-05 12:49:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1427_c143813735d3246637e4ad60bfd4cf042189b83c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1427_c143813735d3246637e4ad60bfd4cf042189b83c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1427_c143813735d3246637e4ad60bfd4cf042189b83c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1427_c143813735d3246637e4ad60bfd4cf042189b83c.patch 2014-05-05 12:49:11.000000000 +0000 @@ -0,0 +1,49 @@ +commit c143813735d3246637e4ad60bfd4cf042189b83c +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:25 2013 -0700 + + ipc,msg: drop msg_unlock + + commit 4718787d1f626f45ddb239912bc07266b9880044 upstream. + + There is only one user left, drop this function and just call + ipc_unlock_object() and rcu_read_unlock(). + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:49:11.000000000 +0000 +@@ -70,8 +70,6 @@ + + #define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS]) + +-#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) +- + static void freeque(struct ipc_namespace *, struct kern_ipc_perm *); + static int newque(struct ipc_namespace *, struct ipc_params *); + #ifdef CONFIG_PROC_FS +@@ -270,7 +268,8 @@ + expunge_all(msq, -EIDRM); + ss_wakeup(&msq->q_senders, 1); + msg_rmid(ns, msq); +- msg_unlock(msq); ++ ipc_unlock_object(&msq->q_perm); ++ rcu_read_unlock(); + + list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) { + atomic_dec(&ns->msg_hdrs); +Index: linux-3.10-3.10.11/dummy/rpi_1427_c143813735d3246637e4ad60bfd4cf042189b83c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1427_c143813735d3246637e4ad60bfd4cf042189b83c.txt 2014-05-05 12:49:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1428_a5daa172ff0897c52eb4c6da18b092c757264b2f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1428_a5daa172ff0897c52eb4c6da18b092c757264b2f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1428_a5daa172ff0897c52eb4c6da18b092c757264b2f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1428_a5daa172ff0897c52eb4c6da18b092c757264b2f.patch 2014-05-05 12:49:12.000000000 +0000 @@ -0,0 +1,49 @@ +commit a5daa172ff0897c52eb4c6da18b092c757264b2f +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:26 2013 -0700 + + ipc: document general ipc locking scheme + + commit 05603c44a7627793219b0bd9a7b236099dc9cd9d upstream. + + As suggested by Andrew, add a generic initial locking scheme used + throughout all sysv ipc mechanisms. Documenting the ids rwsem, how rcu + can be enough to do the initial checks and when to actually acquire the + kern_ipc_perm.lock spinlock. + + I found that adding it to util.c was generic enough. + + Signed-off-by: Davidlohr Bueso + Tested-by: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:49:11.000000000 +0000 +@@ -15,6 +15,14 @@ + * Jun 2006 - namespaces ssupport + * OpenVZ, SWsoft Inc. + * Pavel Emelianov ++ * ++ * General sysv ipc locking scheme: ++ * when doing ipc id lookups, take the ids->rwsem ++ * rcu_read_lock() ++ * obtain the ipc object (kern_ipc_perm) ++ * perform security, capabilities, auditing and permission checks, etc. ++ * acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object() ++ * perform data updates (ie: SET, RMID, LOCK/UNLOCK commands) + */ + + #include +Index: linux-3.10-3.10.11/dummy/rpi_1428_a5daa172ff0897c52eb4c6da18b092c757264b2f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1428_a5daa172ff0897c52eb4c6da18b092c757264b2f.txt 2014-05-05 12:49:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1429_48ec782ce3e59d6ab14a8c1197c19826e61ac8e5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1429_48ec782ce3e59d6ab14a8c1197c19826e61ac8e5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1429_48ec782ce3e59d6ab14a8c1197c19826e61ac8e5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1429_48ec782ce3e59d6ab14a8c1197c19826e61ac8e5.patch 2014-05-05 12:49:13.000000000 +0000 @@ -0,0 +1,43 @@ +commit 48ec782ce3e59d6ab14a8c1197c19826e61ac8e5 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:28 2013 -0700 + + ipc, shm: guard against non-existant vma in shmdt(2) + + commit 530fcd16d87cd2417c472a581ba5a1e501556c86 upstream. + + When !CONFIG_MMU there's a chance we can derefence a NULL pointer when the + VM area isn't found - check the return value of find_vma(). + + Also, remove the redundant -EINVAL return: retval is set to the proper + return code and *only* changed to 0, when we actually unmap the segments. + + Signed-off-by: Davidlohr Bueso + Cc: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:12.000000000 +0000 +@@ -1288,8 +1288,7 @@ + #else /* CONFIG_MMU */ + /* under NOMMU conditions, the exact address to be destroyed must be + * given */ +- retval = -EINVAL; +- if (vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) { ++ if (vma && vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) { + do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); + retval = 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1429_48ec782ce3e59d6ab14a8c1197c19826e61ac8e5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1429_48ec782ce3e59d6ab14a8c1197c19826e61ac8e5.txt 2014-05-05 12:49:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1430_ffa02e67efa1c1bd32ea07a17d74506e5855a50d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1430_ffa02e67efa1c1bd32ea07a17d74506e5855a50d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1430_ffa02e67efa1c1bd32ea07a17d74506e5855a50d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1430_ffa02e67efa1c1bd32ea07a17d74506e5855a50d.patch 2014-05-05 12:49:14.000000000 +0000 @@ -0,0 +1,82 @@ +commit ffa02e67efa1c1bd32ea07a17d74506e5855a50d +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:29 2013 -0700 + + ipc: drop ipc_lock_by_ptr + + commit 32a2750010981216fb788c5190fb0e646abfab30 upstream. + + After previous cleanups and optimizations, this function is no longer + heavily used and we don't have a good reason to keep it. Update the few + remaining callers and get rid of it. + + Signed-off-by: Davidlohr Bueso + Cc: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/namespace.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/namespace.c 2014-05-05 12:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/namespace.c 2014-05-05 12:49:13.000000000 +0000 +@@ -89,7 +89,8 @@ + perm = idr_find(&ids->ipcs_idr, next_id); + if (perm == NULL) + continue; +- ipc_lock_by_ptr(perm); ++ rcu_read_lock(); ++ ipc_lock_object(perm); + free(ns, perm); + total++; + } +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:49:11.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:49:13.000000000 +0000 +@@ -205,7 +205,8 @@ + continue; + } + +- ipc_lock_by_ptr(ipc); ++ rcu_read_lock(); ++ ipc_lock_object(ipc); + return ipc; + } + +@@ -838,7 +839,8 @@ + ipc = idr_find(&ids->ipcs_idr, pos); + if (ipc != NULL) { + *new_pos = pos + 1; +- ipc_lock_by_ptr(ipc); ++ rcu_read_lock(); ++ ipc_lock_object(ipc); + return ipc; + } + } +Index: linux-3.10-3.10.11/ipc/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.h 2014-05-05 12:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.h 2014-05-05 12:49:13.000000000 +0000 +@@ -171,12 +171,6 @@ + assert_spin_locked(&perm->lock); + } + +-static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) +-{ +- rcu_read_lock(); +- ipc_lock_object(perm); +-} +- + static inline void ipc_unlock(struct kern_ipc_perm *perm) + { + ipc_unlock_object(perm); +Index: linux-3.10-3.10.11/dummy/rpi_1430_ffa02e67efa1c1bd32ea07a17d74506e5855a50d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1430_ffa02e67efa1c1bd32ea07a17d74506e5855a50d.txt 2014-05-05 12:49:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1431_1129a4810a2499dd02a7bfa657053c55c35140a3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1431_1129a4810a2499dd02a7bfa657053c55c35140a3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1431_1129a4810a2499dd02a7bfa657053c55c35140a3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1431_1129a4810a2499dd02a7bfa657053c55c35140a3.patch 2014-05-05 12:49:14.000000000 +0000 @@ -0,0 +1,48 @@ +commit 1129a4810a2499dd02a7bfa657053c55c35140a3 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:30 2013 -0700 + + ipc, shm: drop shm_lock_check + + commit 7a25dd9e042b2b94202a67e5551112f4ac87285a upstream. + + This function was replaced by a the lockless shm_obtain_object_check(), + and no longer has any users. + + Signed-off-by: Davidlohr Bueso + Cc: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:12.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:14.000000000 +0000 +@@ -167,17 +167,6 @@ + ipc_lock_object(&ipcp->shm_perm); + } + +-static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns, +- int id) +-{ +- struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id); +- +- if (IS_ERR(ipcp)) +- return (struct shmid_kernel *)ipcp; +- +- return container_of(ipcp, struct shmid_kernel, shm_perm); +-} +- + static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s) + { + ipc_rmid(&shm_ids(ns), &s->shm_perm); +Index: linux-3.10-3.10.11/dummy/rpi_1431_1129a4810a2499dd02a7bfa657053c55c35140a3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1431_1129a4810a2499dd02a7bfa657053c55c35140a3.txt 2014-05-05 12:49:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1432_c42107e68217f062e4257f0505a8c5b24b6cb9f3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1432_c42107e68217f062e4257f0505a8c5b24b6cb9f3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1432_c42107e68217f062e4257f0505a8c5b24b6cb9f3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1432_c42107e68217f062e4257f0505a8c5b24b6cb9f3.patch 2014-05-05 12:49:15.000000000 +0000 @@ -0,0 +1,64 @@ +commit c42107e68217f062e4257f0505a8c5b24b6cb9f3 +Author: Davidlohr Bueso +Date: Wed Sep 11 14:26:31 2013 -0700 + + ipc: drop ipc_lock_check + + commit 20b8875abcf2daa1dda5cf70bd6369df5e85d4c1 upstream. + + No remaining users, we now use ipc_obtain_object_check(). + + Signed-off-by: Davidlohr Bueso + Cc: Sedat Dilek + Cc: Rik van Riel + Cc: Manfred Spraul + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:49:13.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:49:15.000000000 +0000 +@@ -686,22 +686,6 @@ + return out; + } + +-struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id) +-{ +- struct kern_ipc_perm *out; +- +- out = ipc_lock(ids, id); +- if (IS_ERR(out)) +- return out; +- +- if (ipc_checkid(out, id)) { +- ipc_unlock(out); +- return ERR_PTR(-EIDRM); +- } +- +- return out; +-} +- + /** + * ipcget - Common sys_*get() code + * @ns : namsepace +Index: linux-3.10-3.10.11/ipc/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.h 2014-05-05 12:49:13.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.h 2014-05-05 12:49:15.000000000 +0000 +@@ -177,7 +177,6 @@ + rcu_read_unlock(); + } + +-struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id); + struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id); + int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, + struct ipc_ops *ops, struct ipc_params *params); +Index: linux-3.10-3.10.11/dummy/rpi_1432_c42107e68217f062e4257f0505a8c5b24b6cb9f3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1432_c42107e68217f062e4257f0505a8c5b24b6cb9f3.txt 2014-05-05 12:49:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1433_e84ca333752636c70cf85711aeef2b2abaac816e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1433_e84ca333752636c70cf85711aeef2b2abaac816e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1433_e84ca333752636c70cf85711aeef2b2abaac816e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1433_e84ca333752636c70cf85711aeef2b2abaac816e.patch 2014-05-05 12:49:16.000000000 +0000 @@ -0,0 +1,354 @@ +commit e84ca333752636c70cf85711aeef2b2abaac816e +Author: Davidlohr Bueso +Date: Mon Sep 23 17:04:45 2013 -0700 + + ipc: fix race with LSMs + + commit 53dad6d3a8e5ac1af8bacc6ac2134ae1a8b085f1 upstream. + + Currently, IPC mechanisms do security and auditing related checks under + RCU. However, since security modules can free the security structure, + for example, through selinux_[sem,msg_queue,shm]_free_security(), we can + race if the structure is freed before other tasks are done with it, + creating a use-after-free condition. Manfred illustrates this nicely, + for instance with shared mem and selinux: + + -> do_shmat calls rcu_read_lock() + -> do_shmat calls shm_object_check(). + Checks that the object is still valid - but doesn't acquire any locks. + Then it returns. + -> do_shmat calls security_shm_shmat (e.g. selinux_shm_shmat) + -> selinux_shm_shmat calls ipc_has_perm() + -> ipc_has_perm accesses ipc_perms->security + + shm_close() + -> shm_close acquires rw_mutex & shm_lock + -> shm_close calls shm_destroy + -> shm_destroy calls security_shm_free (e.g. selinux_shm_free_security) + -> selinux_shm_free_security calls ipc_free_security(&shp->shm_perm) + -> ipc_free_security calls kfree(ipc_perms->security) + + This patch delays the freeing of the security structures after all RCU + readers are done. Furthermore it aligns the security life cycle with + that of the rest of IPC - freeing them based on the reference counter. + For situations where we need not free security, the current behavior is + kept. Linus states: + + "... the old behavior was suspect for another reason too: having the + security blob go away from under a user sounds like it could cause + various other problems anyway, so I think the old code was at least + _prone_ to bugs even if it didn't have catastrophic behavior." + + I have tested this patch with IPC testcases from LTP on both my + quad-core laptop and on a 64 core NUMA server. In both cases selinux is + enabled, and tests pass for both voluntary and forced preemption models. + While the mentioned races are theoretical (at least no one as reported + them), I wanted to make sure that this new logic doesn't break anything + we weren't aware of. + + Suggested-by: Linus Torvalds + Signed-off-by: Davidlohr Bueso + Acked-by: Manfred Spraul + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:49:11.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:49:15.000000000 +0000 +@@ -165,6 +165,15 @@ + ipc_rmid(&msg_ids(ns), &s->q_perm); + } + ++static void msg_rcu_free(struct rcu_head *head) ++{ ++ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); ++ struct msg_queue *msq = ipc_rcu_to_struct(p); ++ ++ security_msg_queue_free(msq); ++ ipc_rcu_free(head); ++} ++ + /** + * newque - Create a new msg queue + * @ns: namespace +@@ -189,15 +198,14 @@ + msq->q_perm.security = NULL; + retval = security_msg_queue_alloc(msq); + if (retval) { +- ipc_rcu_putref(msq); ++ ipc_rcu_putref(msq, ipc_rcu_free); + return retval; + } + + /* ipc_addid() locks msq upon success. */ + id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); + if (id < 0) { +- security_msg_queue_free(msq); +- ipc_rcu_putref(msq); ++ ipc_rcu_putref(msq, msg_rcu_free); + return id; + } + +@@ -276,8 +284,7 @@ + free_msg(msg); + } + atomic_sub(msq->q_cbytes, &ns->msg_bytes); +- security_msg_queue_free(msq); +- ipc_rcu_putref(msq); ++ ipc_rcu_putref(msq, msg_rcu_free); + } + + /* +@@ -717,7 +724,7 @@ + rcu_read_lock(); + ipc_lock_object(&msq->q_perm); + +- ipc_rcu_putref(msq); ++ ipc_rcu_putref(msq, ipc_rcu_free); + if (msq->q_perm.deleted) { + err = -EIDRM; + goto out_unlock0; +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:49:15.000000000 +0000 +@@ -243,6 +243,15 @@ + } + } + ++static void sem_rcu_free(struct rcu_head *head) ++{ ++ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); ++ struct sem_array *sma = ipc_rcu_to_struct(p); ++ ++ security_sem_free(sma); ++ ipc_rcu_free(head); ++} ++ + /* + * If the request contains only one semaphore operation, and there are + * no complex transactions pending, lock only the semaphore involved. +@@ -374,12 +383,7 @@ + static inline void sem_lock_and_putref(struct sem_array *sma) + { + sem_lock(sma, NULL, -1); +- ipc_rcu_putref(sma); +-} +- +-static inline void sem_putref(struct sem_array *sma) +-{ +- ipc_rcu_putref(sma); ++ ipc_rcu_putref(sma, ipc_rcu_free); + } + + static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) +@@ -458,14 +462,13 @@ + sma->sem_perm.security = NULL; + retval = security_sem_alloc(sma); + if (retval) { +- ipc_rcu_putref(sma); ++ ipc_rcu_putref(sma, ipc_rcu_free); + return retval; + } + + id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); + if (id < 0) { +- security_sem_free(sma); +- ipc_rcu_putref(sma); ++ ipc_rcu_putref(sma, sem_rcu_free); + return id; + } + ns->used_sems += nsems; +@@ -1047,8 +1050,7 @@ + + wake_up_sem_queue_do(&tasks); + ns->used_sems -= sma->sem_nsems; +- security_sem_free(sma); +- ipc_rcu_putref(sma); ++ ipc_rcu_putref(sma, sem_rcu_free); + } + + static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, int version) +@@ -1292,7 +1294,7 @@ + rcu_read_unlock(); + sem_io = ipc_alloc(sizeof(ushort)*nsems); + if(sem_io == NULL) { +- sem_putref(sma); ++ ipc_rcu_putref(sma, ipc_rcu_free); + return -ENOMEM; + } + +@@ -1328,20 +1330,20 @@ + if(nsems > SEMMSL_FAST) { + sem_io = ipc_alloc(sizeof(ushort)*nsems); + if(sem_io == NULL) { +- sem_putref(sma); ++ ipc_rcu_putref(sma, ipc_rcu_free); + return -ENOMEM; + } + } + + if (copy_from_user (sem_io, p, nsems*sizeof(ushort))) { +- sem_putref(sma); ++ ipc_rcu_putref(sma, ipc_rcu_free); + err = -EFAULT; + goto out_free; + } + + for (i = 0; i < nsems; i++) { + if (sem_io[i] > SEMVMX) { +- sem_putref(sma); ++ ipc_rcu_putref(sma, ipc_rcu_free); + err = -ERANGE; + goto out_free; + } +@@ -1629,7 +1631,7 @@ + /* step 2: allocate new undo structure */ + new = kzalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL); + if (!new) { +- sem_putref(sma); ++ ipc_rcu_putref(sma, ipc_rcu_free); + return ERR_PTR(-ENOMEM); + } + +Index: linux-3.10-3.10.11/ipc/shm.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/shm.c 2014-05-05 12:49:14.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/shm.c 2014-05-05 12:49:15.000000000 +0000 +@@ -167,6 +167,15 @@ + ipc_lock_object(&ipcp->shm_perm); + } + ++static void shm_rcu_free(struct rcu_head *head) ++{ ++ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); ++ struct shmid_kernel *shp = ipc_rcu_to_struct(p); ++ ++ security_shm_free(shp); ++ ipc_rcu_free(head); ++} ++ + static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s) + { + ipc_rmid(&shm_ids(ns), &s->shm_perm); +@@ -208,8 +217,7 @@ + user_shm_unlock(file_inode(shp->shm_file)->i_size, + shp->mlock_user); + fput (shp->shm_file); +- security_shm_free(shp); +- ipc_rcu_putref(shp); ++ ipc_rcu_putref(shp, shm_rcu_free); + } + + /* +@@ -497,7 +505,7 @@ + shp->shm_perm.security = NULL; + error = security_shm_alloc(shp); + if (error) { +- ipc_rcu_putref(shp); ++ ipc_rcu_putref(shp, ipc_rcu_free); + return error; + } + +@@ -566,8 +574,7 @@ + user_shm_unlock(size, shp->mlock_user); + fput(file); + no_file: +- security_shm_free(shp); +- ipc_rcu_putref(shp); ++ ipc_rcu_putref(shp, shm_rcu_free); + return error; + } + +Index: linux-3.10-3.10.11/ipc/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.c 2014-05-05 12:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.c 2014-05-05 12:49:15.000000000 +0000 +@@ -474,11 +474,6 @@ + kfree(ptr); + } + +-struct ipc_rcu { +- struct rcu_head rcu; +- atomic_t refcount; +-} ____cacheline_aligned_in_smp; +- + /** + * ipc_rcu_alloc - allocate ipc and rcu space + * @size: size desired +@@ -505,27 +500,24 @@ + return atomic_inc_not_zero(&p->refcount); + } + +-/** +- * ipc_schedule_free - free ipc + rcu space +- * @head: RCU callback structure for queued work +- */ +-static void ipc_schedule_free(struct rcu_head *head) +-{ +- vfree(container_of(head, struct ipc_rcu, rcu)); +-} +- +-void ipc_rcu_putref(void *ptr) ++void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)) + { + struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1; + + if (!atomic_dec_and_test(&p->refcount)) + return; + +- if (is_vmalloc_addr(ptr)) { +- call_rcu(&p->rcu, ipc_schedule_free); +- } else { +- kfree_rcu(p, rcu); +- } ++ call_rcu(&p->rcu, func); ++} ++ ++void ipc_rcu_free(struct rcu_head *head) ++{ ++ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); ++ ++ if (is_vmalloc_addr(p)) ++ vfree(p); ++ else ++ kfree(p); + } + + /** +Index: linux-3.10-3.10.11/ipc/util.h +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/util.h 2014-05-05 12:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/util.h 2014-05-05 12:49:15.000000000 +0000 +@@ -47,6 +47,13 @@ + static inline void shm_exit_ns(struct ipc_namespace *ns) { } + #endif + ++struct ipc_rcu { ++ struct rcu_head rcu; ++ atomic_t refcount; ++} ____cacheline_aligned_in_smp; ++ ++#define ipc_rcu_to_struct(p) ((void *)(p+1)) ++ + /* + * Structure that holds the parameters needed by the ipc operations + * (see after) +@@ -120,7 +127,8 @@ + */ + void* ipc_rcu_alloc(int size); + int ipc_rcu_getref(void *ptr); +-void ipc_rcu_putref(void *ptr); ++void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)); ++void ipc_rcu_free(struct rcu_head *head); + + struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int); + struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id); +Index: linux-3.10-3.10.11/dummy/rpi_1433_e84ca333752636c70cf85711aeef2b2abaac816e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1433_e84ca333752636c70cf85711aeef2b2abaac816e.txt 2014-05-05 12:49:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1434_184076a9f9306c9bef6843bf4cc7b7e15b8fc7b4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1434_184076a9f9306c9bef6843bf4cc7b7e15b8fc7b4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1434_184076a9f9306c9bef6843bf4cc7b7e15b8fc7b4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1434_184076a9f9306c9bef6843bf4cc7b7e15b8fc7b4.patch 2014-05-05 12:49:17.000000000 +0000 @@ -0,0 +1,252 @@ +commit 184076a9f9306c9bef6843bf4cc7b7e15b8fc7b4 +Author: Manfred Spraul +Date: Mon Sep 30 13:45:04 2013 -0700 + + ipc/sem.c: fix race in sem_lock() + + commit 5e9d527591421ccdb16acb8c23662231135d8686 upstream. + + The exclusion of complex operations in sem_lock() is insufficient: after + acquiring the per-semaphore lock, a simple op must first check that + sem_perm.lock is not locked and only after that test check + complex_count. The current code does it the other way around - and that + creates a race. Details are below. + + The patch is a complete rewrite of sem_lock(), based in part on the code + from Mike Galbraith. It removes all gotos and all loops and thus the + risk of livelocks. + + I have tested the patch (together with the next one) on my i3 laptop and + it didn't cause any problems. + + The bug is probably also present in 3.10 and 3.11, but for these kernels + it might be simpler just to move the test of sma->complex_count after + the spin_is_locked() test. + + Details of the bug: + + Assume: + - sma->complex_count = 0. + - Thread 1: semtimedop(complex op that must sleep) + - Thread 2: semtimedop(simple op). + + Pseudo-Trace: + + Thread 1: sem_lock(): acquire sem_perm.lock + Thread 1: sem_lock(): check for ongoing simple ops + Nothing ongoing, thread 2 is still before sem_lock(). + Thread 1: try_atomic_semop() + <<< preempted. + + Thread 2: sem_lock(): + static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, + int nsops) + { + int locknum; + again: + if (nsops == 1 && !sma->complex_count) { + struct sem *sem = sma->sem_base + sops->sem_num; + + /* Lock just the semaphore we are interested in. */ + spin_lock(&sem->lock); + + /* + * If sma->complex_count was set while we were spinning, + * we may need to look at things we did not lock here. + */ + if (unlikely(sma->complex_count)) { + spin_unlock(&sem->lock); + goto lock_array; + } + <<<<<<<<< + <<< complex_count is still 0. + <<< + <<< Here it is preempted + <<<<<<<<< + + Thread 1: try_atomic_semop() returns, notices that it must sleep. + Thread 1: increases sma->complex_count. + Thread 1: drops sem_perm.lock + Thread 2: + /* + * Another process is holding the global lock on the + * sem_array; we cannot enter our critical section, + * but have to wait for the global lock to be released. + */ + if (unlikely(spin_is_locked(&sma->sem_perm.lock))) { + spin_unlock(&sem->lock); + spin_unlock_wait(&sma->sem_perm.lock); + goto again; + } + <<< sem_perm.lock already dropped, thus no "goto again;" + + locknum = sops->sem_num; + + Signed-off-by: Manfred Spraul + Cc: Mike Galbraith + Cc: Rik van Riel + Cc: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:49:16.000000000 +0000 +@@ -253,70 +253,104 @@ + } + + /* ++ * Wait until all currently ongoing simple ops have completed. ++ * Caller must own sem_perm.lock. ++ * New simple ops cannot start, because simple ops first check ++ * that sem_perm.lock is free. ++ */ ++static void sem_wait_array(struct sem_array *sma) ++{ ++ int i; ++ struct sem *sem; ++ ++ for (i = 0; i < sma->sem_nsems; i++) { ++ sem = sma->sem_base + i; ++ spin_unlock_wait(&sem->lock); ++ } ++} ++ ++/* + * If the request contains only one semaphore operation, and there are + * no complex transactions pending, lock only the semaphore involved. + * Otherwise, lock the entire semaphore array, since we either have + * multiple semaphores in our own semops, or we need to look at + * semaphores from other pending complex operations. +- * +- * Carefully guard against sma->complex_count changing between zero +- * and non-zero while we are spinning for the lock. The value of +- * sma->complex_count cannot change while we are holding the lock, +- * so sem_unlock should be fine. +- * +- * The global lock path checks that all the local locks have been released, +- * checking each local lock once. This means that the local lock paths +- * cannot start their critical sections while the global lock is held. + */ + static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, + int nsops) + { +- int locknum; +- again: +- if (nsops == 1 && !sma->complex_count) { +- struct sem *sem = sma->sem_base + sops->sem_num; ++ struct sem *sem; + +- /* Lock just the semaphore we are interested in. */ +- spin_lock(&sem->lock); ++ if (nsops != 1) { ++ /* Complex operation - acquire a full lock */ ++ ipc_lock_object(&sma->sem_perm); + +- /* +- * If sma->complex_count was set while we were spinning, +- * we may need to look at things we did not lock here. ++ /* And wait until all simple ops that are processed ++ * right now have dropped their locks. + */ +- if (unlikely(sma->complex_count)) { +- spin_unlock(&sem->lock); +- goto lock_array; +- } ++ sem_wait_array(sma); ++ return -1; ++ } ++ ++ /* ++ * Only one semaphore affected - try to optimize locking. ++ * The rules are: ++ * - optimized locking is possible if no complex operation ++ * is either enqueued or processed right now. ++ * - The test for enqueued complex ops is simple: ++ * sma->complex_count != 0 ++ * - Testing for complex ops that are processed right now is ++ * a bit more difficult. Complex ops acquire the full lock ++ * and first wait that the running simple ops have completed. ++ * (see above) ++ * Thus: If we own a simple lock and the global lock is free ++ * and complex_count is now 0, then it will stay 0 and ++ * thus just locking sem->lock is sufficient. ++ */ ++ sem = sma->sem_base + sops->sem_num; + ++ if (sma->complex_count == 0) { + /* +- * Another process is holding the global lock on the +- * sem_array; we cannot enter our critical section, +- * but have to wait for the global lock to be released. ++ * It appears that no complex operation is around. ++ * Acquire the per-semaphore lock. + */ +- if (unlikely(spin_is_locked(&sma->sem_perm.lock))) { +- spin_unlock(&sem->lock); +- spin_unlock_wait(&sma->sem_perm.lock); +- goto again; ++ spin_lock(&sem->lock); ++ ++ /* Then check that the global lock is free */ ++ if (!spin_is_locked(&sma->sem_perm.lock)) { ++ /* spin_is_locked() is not a memory barrier */ ++ smp_mb(); ++ ++ /* Now repeat the test of complex_count: ++ * It can't change anymore until we drop sem->lock. ++ * Thus: if is now 0, then it will stay 0. ++ */ ++ if (sma->complex_count == 0) { ++ /* fast path successful! */ ++ return sops->sem_num; ++ } + } ++ spin_unlock(&sem->lock); ++ } ++ ++ /* slow path: acquire the full lock */ ++ ipc_lock_object(&sma->sem_perm); + +- locknum = sops->sem_num; ++ if (sma->complex_count == 0) { ++ /* False alarm: ++ * There is no complex operation, thus we can switch ++ * back to the fast path. ++ */ ++ spin_lock(&sem->lock); ++ ipc_unlock_object(&sma->sem_perm); ++ return sops->sem_num; + } else { +- int i; +- /* +- * Lock the semaphore array, and wait for all of the +- * individual semaphore locks to go away. The code +- * above ensures no new single-lock holders will enter +- * their critical section while the array lock is held. ++ /* Not a false alarm, thus complete the sequence for a ++ * full lock. + */ +- lock_array: +- ipc_lock_object(&sma->sem_perm); +- for (i = 0; i < sma->sem_nsems; i++) { +- struct sem *sem = sma->sem_base + i; +- spin_unlock_wait(&sem->lock); +- } +- locknum = -1; ++ sem_wait_array(sma); ++ return -1; + } +- return locknum; + } + + static inline void sem_unlock(struct sem_array *sma, int locknum) +Index: linux-3.10-3.10.11/dummy/rpi_1434_184076a9f9306c9bef6843bf4cc7b7e15b8fc7b4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1434_184076a9f9306c9bef6843bf4cc7b7e15b8fc7b4.txt 2014-05-05 12:49:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1435_901f6fedc5340d66e2ca67c70dfee926cb5a1ea0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1435_901f6fedc5340d66e2ca67c70dfee926cb5a1ea0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1435_901f6fedc5340d66e2ca67c70dfee926cb5a1ea0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1435_901f6fedc5340d66e2ca67c70dfee926cb5a1ea0.patch 2014-05-05 12:49:18.000000000 +0000 @@ -0,0 +1,58 @@ +commit 901f6fedc5340d66e2ca67c70dfee926cb5a1ea0 +Author: Manfred Spraul +Date: Mon Sep 30 13:45:06 2013 -0700 + + ipc/sem.c: optimize sem_lock() + + commit 6d07b68ce16ae9535955ba2059dedba5309c3ca1 upstream. + + Operations that need access to the whole array must guarantee that there + are no simple operations ongoing. Right now this is achieved by + spin_unlock_wait(sem->lock) on all semaphores. + + If complex_count is nonzero, then this spin_unlock_wait() is not + necessary, because it was already performed in the past by the thread + that increased complex_count and even though sem_perm.lock was dropped + inbetween, no simple operation could have started, because simple + operations cannot start when complex_count is non-zero. + + Signed-off-by: Manfred Spraul + Cc: Mike Galbraith + Cc: Rik van Riel + Reviewed-by: Davidlohr Bueso + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Mike Galbraith + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:49:16.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:49:17.000000000 +0000 +@@ -257,12 +257,20 @@ + * Caller must own sem_perm.lock. + * New simple ops cannot start, because simple ops first check + * that sem_perm.lock is free. ++ * that a) sem_perm.lock is free and b) complex_count is 0. + */ + static void sem_wait_array(struct sem_array *sma) + { + int i; + struct sem *sem; + ++ if (sma->complex_count) { ++ /* The thread that increased sma->complex_count waited on ++ * all sem->lock locks. Thus we don't need to wait again. ++ */ ++ return; ++ } ++ + for (i = 0; i < sma->sem_nsems; i++) { + sem = sma->sem_base + i; + spin_unlock_wait(&sem->lock); +Index: linux-3.10-3.10.11/dummy/rpi_1435_901f6fedc5340d66e2ca67c70dfee926cb5a1ea0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1435_901f6fedc5340d66e2ca67c70dfee926cb5a1ea0.txt 2014-05-05 12:49:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1436_83aeb6e3449cc54fa8867a0c9cc1b8d2484fa91e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1436_83aeb6e3449cc54fa8867a0c9cc1b8d2484fa91e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1436_83aeb6e3449cc54fa8867a0c9cc1b8d2484fa91e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1436_83aeb6e3449cc54fa8867a0c9cc1b8d2484fa91e.patch 2014-05-05 12:49:18.000000000 +0000 @@ -0,0 +1,49 @@ +commit 83aeb6e3449cc54fa8867a0c9cc1b8d2484fa91e +Author: Manfred Spraul +Date: Mon Sep 30 13:45:07 2013 -0700 + + ipc/sem.c: synchronize the proc interface + + commit d8c633766ad88527f25d9f81a5c2f083d78a2b39 upstream. + + The proc interface is not aware of sem_lock(), it instead calls + ipc_lock_object() directly. This means that simple semop() operations + can run in parallel with the proc interface. Right now, this is + uncritical, because the implementation doesn't do anything that requires + a proper synchronization. + + But it is dangerous and therefore should be fixed. + + Signed-off-by: Manfred Spraul + Cc: Davidlohr Bueso + Cc: Mike Galbraith + Cc: Rik van Riel + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:49:17.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:49:18.000000000 +0000 +@@ -2103,6 +2103,14 @@ + struct sem_array *sma = it; + time_t sem_otime; + ++ /* ++ * The proc interface isn't aware of sem_lock(), it calls ++ * ipc_lock_object() directly (in sysvipc_find_ipc). ++ * In order to stay compatible with sem_lock(), we must wait until ++ * all simple semop() calls have left their critical regions. ++ */ ++ sem_wait_array(sma); ++ + sem_otime = get_semotime(sma); + + return seq_printf(s, +Index: linux-3.10-3.10.11/dummy/rpi_1436_83aeb6e3449cc54fa8867a0c9cc1b8d2484fa91e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1436_83aeb6e3449cc54fa8867a0c9cc1b8d2484fa91e.txt 2014-05-05 12:49:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1437_e556ea0191d648c63fbc4fe24bbfb15ad872a205.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1437_e556ea0191d648c63fbc4fe24bbfb15ad872a205.patch --- linux-3.10.11/debian/patches/rpi/rpi_1437_e556ea0191d648c63fbc4fe24bbfb15ad872a205.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1437_e556ea0191d648c63fbc4fe24bbfb15ad872a205.patch 2014-05-05 12:49:19.000000000 +0000 @@ -0,0 +1,106 @@ +commit e556ea0191d648c63fbc4fe24bbfb15ad872a205 +Author: Manfred Spraul +Date: Mon Sep 30 13:45:25 2013 -0700 + + ipc/sem.c: update sem_otime for all operations + + commit 0e8c665699e953fa58dc1b0b0d09e5dce7343cc7 upstream. + + In commit 0a2b9d4c7967 ("ipc/sem.c: move wake_up_process out of the + spinlock section"), the update of semaphore's sem_otime(last semop time) + was moved to one central position (do_smart_update). + + But since do_smart_update() is only called for operations that modify + the array, this means that wait-for-zero semops do not update sem_otime + anymore. + + The fix is simple: + Non-alter operations must update sem_otime. + + [akpm@linux-foundation.org: coding-style fixes] + Signed-off-by: Manfred Spraul + Reported-by: Jia He + Tested-by: Jia He + Cc: Davidlohr Bueso + Cc: Mike Galbraith + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/sem.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/sem.c 2014-05-05 12:49:18.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/sem.c 2014-05-05 12:49:19.000000000 +0000 +@@ -918,6 +918,24 @@ + } + + /** ++ * set_semotime(sma, sops) - set sem_otime ++ * @sma: semaphore array ++ * @sops: operations that modified the array, may be NULL ++ * ++ * sem_otime is replicated to avoid cache line trashing. ++ * This function sets one instance to the current time. ++ */ ++static void set_semotime(struct sem_array *sma, struct sembuf *sops) ++{ ++ if (sops == NULL) { ++ sma->sem_base[0].sem_otime = get_seconds(); ++ } else { ++ sma->sem_base[sops[0].sem_num].sem_otime = ++ get_seconds(); ++ } ++} ++ ++/** + * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue + * @sma: semaphore array + * @sops: operations that were performed +@@ -967,17 +985,10 @@ + } + } + } +- if (otime) { +- if (sops == NULL) { +- sma->sem_base[0].sem_otime = get_seconds(); +- } else { +- sma->sem_base[sops[0].sem_num].sem_otime = +- get_seconds(); +- } +- } ++ if (otime) ++ set_semotime(sma, sops); + } + +- + /* The following counts are associated to each semaphore: + * semncnt number of tasks waiting on semval being nonzero + * semzcnt number of tasks waiting on semval being zero +@@ -1839,12 +1850,17 @@ + + error = perform_atomic_semop(sma, sops, nsops, un, + task_tgid_vnr(current)); +- if (error <= 0) { +- if (alter && error == 0) ++ if (error == 0) { ++ /* If the operation was successful, then do ++ * the required updates. ++ */ ++ if (alter) + do_smart_update(sma, sops, nsops, 1, &tasks); +- +- goto out_unlock_free; ++ else ++ set_semotime(sma, sops); + } ++ if (error <= 0) ++ goto out_unlock_free; + + /* We need to sleep on this operation, so we put the current + * task into the pending queue and go to sleep. +Index: linux-3.10-3.10.11/dummy/rpi_1437_e556ea0191d648c63fbc4fe24bbfb15ad872a205.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1437_e556ea0191d648c63fbc4fe24bbfb15ad872a205.txt 2014-05-05 12:49:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1438_3232569ecd21ad181bd070acdb27ac5ccd54494c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1438_3232569ecd21ad181bd070acdb27ac5ccd54494c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1438_3232569ecd21ad181bd070acdb27ac5ccd54494c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1438_3232569ecd21ad181bd070acdb27ac5ccd54494c.patch 2014-05-05 12:49:20.000000000 +0000 @@ -0,0 +1,72 @@ +commit 3232569ecd21ad181bd070acdb27ac5ccd54494c +Author: Davidlohr Bueso +Date: Mon Sep 30 13:45:26 2013 -0700 + + ipc,msg: prevent race with rmid in msgsnd,msgrcv + + commit 4271b05a227dc6175b66c3d9941aeab09048aeb2 upstream. + + This fixes a race in both msgrcv() and msgsnd() between finding the msg + and actually dealing with the queue, as another thread can delete shmid + underneath us if we are preempted before acquiring the + kern_ipc_perm.lock. + + Manfred illustrates this nicely: + + Assume a preemptible kernel that is preempted just after + + msq = msq_obtain_object_check(ns, msqid) + + in do_msgrcv(). The only lock that is held is rcu_read_lock(). + + Now the other thread processes IPC_RMID. When the first task is + resumed, then it will happily wait for messages on a deleted queue. + + Fix this by checking for if the queue has been deleted after taking the + lock. + + Signed-off-by: Davidlohr Bueso + Reported-by: Manfred Spraul + Cc: Rik van Riel + Cc: Mike Galbraith + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/ipc/msg.c +=================================================================== +--- linux-3.10-3.10.11.orig/ipc/msg.c 2014-05-05 12:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/ipc/msg.c 2014-05-05 12:49:19.000000000 +0000 +@@ -695,6 +695,12 @@ + if (ipcperms(ns, &msq->q_perm, S_IWUGO)) + goto out_unlock0; + ++ /* raced with RMID? */ ++ if (msq->q_perm.deleted) { ++ err = -EIDRM; ++ goto out_unlock0; ++ } ++ + err = security_msg_queue_msgsnd(msq, msg, msgflg); + if (err) + goto out_unlock0; +@@ -901,6 +907,13 @@ + goto out_unlock1; + + ipc_lock_object(&msq->q_perm); ++ ++ /* raced with RMID? */ ++ if (msq->q_perm.deleted) { ++ msg = ERR_PTR(-EIDRM); ++ goto out_unlock0; ++ } ++ + msg = find_msg(msq, &msgtyp, mode); + if (!IS_ERR(msg)) { + /* +Index: linux-3.10-3.10.11/dummy/rpi_1438_3232569ecd21ad181bd070acdb27ac5ccd54494c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1438_3232569ecd21ad181bd070acdb27ac5ccd54494c.txt 2014-05-05 12:49:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1439_954acd2b6df732230608d260779ef6d545534929.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1439_954acd2b6df732230608d260779ef6d545534929.patch --- linux-3.10.11/debian/patches/rpi/rpi_1439_954acd2b6df732230608d260779ef6d545534929.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1439_954acd2b6df732230608d260779ef6d545534929.patch 2014-05-05 12:49:21.000000000 +0000 @@ -0,0 +1,114 @@ +commit 954acd2b6df732230608d260779ef6d545534929 +Author: Linn Crosetto +Date: Tue Aug 13 15:46:41 2013 -0600 + + x86: avoid remapping data in parse_setup_data() + + commit 30e46b574a1db7d14404e52dca8e1aa5f5155fd2 upstream. + + Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size + larger than early_memremap() is able to handle, which is currently + limited to 256kB. If this occurs it leads to a NULL dereference in + parse_setup_data(). + + To avoid this, remap the setup_data header and allow parsing functions + for individual types to handle their own data remapping. + + Signed-off-by: Linn Crosetto + Link: http://lkml.kernel.org/r/1376430401-67445-1-git-send-email-linn@hp.com + Acked-by: Yinghai Lu + Reviewed-by: Pekka Enberg + Signed-off-by: H. Peter Anvin + Cc: Paul Gortmaker + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/include/asm/e820.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/include/asm/e820.h 2014-05-05 11:49:25.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/include/asm/e820.h 2014-05-05 12:49:20.000000000 +0000 +@@ -29,7 +29,7 @@ + extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, + unsigned long start_addr, unsigned long long end_addr); + struct setup_data; +-extern void parse_e820_ext(struct setup_data *data); ++extern void parse_e820_ext(u64 phys_addr, u32 data_len); + + #if defined(CONFIG_X86_64) || \ + (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) +Index: linux-3.10-3.10.11/arch/x86/kernel/e820.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/e820.c 2014-05-05 11:49:25.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/e820.c 2014-05-05 12:49:20.000000000 +0000 +@@ -658,15 +658,18 @@ + * boot_params.e820_map, others are passed via SETUP_E820_EXT node of + * linked list of struct setup_data, which is parsed here. + */ +-void __init parse_e820_ext(struct setup_data *sdata) ++void __init parse_e820_ext(u64 phys_addr, u32 data_len) + { + int entries; + struct e820entry *extmap; ++ struct setup_data *sdata; + ++ sdata = early_memremap(phys_addr, data_len); + entries = sdata->len / sizeof(struct e820entry); + extmap = (struct e820entry *)(sdata->data); + __append_e820_map(extmap, entries); + sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); ++ early_iounmap(sdata, data_len); + printk(KERN_INFO "e820: extended physical RAM map:\n"); + e820_print_map("extended"); + } +Index: linux-3.10-3.10.11/arch/x86/kernel/setup.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/setup.c 2014-05-05 11:49:25.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/setup.c 2014-05-05 12:49:20.000000000 +0000 +@@ -426,25 +426,23 @@ + static void __init parse_setup_data(void) + { + struct setup_data *data; +- u64 pa_data; ++ u64 pa_data, pa_next; + + pa_data = boot_params.hdr.setup_data; + while (pa_data) { +- u32 data_len, map_len; ++ u32 data_len, map_len, data_type; + + map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK), + (u64)sizeof(struct setup_data)); + data = early_memremap(pa_data, map_len); + data_len = data->len + sizeof(struct setup_data); +- if (data_len > map_len) { +- early_iounmap(data, map_len); +- data = early_memremap(pa_data, data_len); +- map_len = data_len; +- } ++ data_type = data->type; ++ pa_next = data->next; ++ early_iounmap(data, map_len); + +- switch (data->type) { ++ switch (data_type) { + case SETUP_E820_EXT: +- parse_e820_ext(data); ++ parse_e820_ext(pa_data, data_len); + break; + case SETUP_DTB: + add_dtb(pa_data); +@@ -452,8 +450,7 @@ + default: + break; + } +- pa_data = data->next; +- early_iounmap(data, map_len); ++ pa_data = pa_next; + } + } + +Index: linux-3.10-3.10.11/dummy/rpi_1439_954acd2b6df732230608d260779ef6d545534929.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1439_954acd2b6df732230608d260779ef6d545534929.txt 2014-05-05 12:49:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1440_14e9c7db465387ede7f019c42f28c90f99fc2793.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1440_14e9c7db465387ede7f019c42f28c90f99fc2793.patch --- linux-3.10.11/debian/patches/rpi/rpi_1440_14e9c7db465387ede7f019c42f28c90f99fc2793.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1440_14e9c7db465387ede7f019c42f28c90f99fc2793.patch 2014-05-05 12:49:22.000000000 +0000 @@ -0,0 +1,24 @@ +commit 14e9c7db465387ede7f019c42f28c90f99fc2793 +Author: Greg Kroah-Hartman +Date: Fri Oct 18 10:44:19 2013 -0700 + + Linux 3.10.17 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:48:18.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:49:21.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 16 ++SUBLEVEL = 17 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1440_14e9c7db465387ede7f019c42f28c90f99fc2793.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1440_14e9c7db465387ede7f019c42f28c90f99fc2793.txt 2014-05-05 12:49:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1441_5e25ba5003ee5de0ba2be56bfd54d16d4b1b028d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1441_5e25ba5003ee5de0ba2be56bfd54d16d4b1b028d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1441_5e25ba5003ee5de0ba2be56bfd54d16d4b1b028d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1441_5e25ba5003ee5de0ba2be56bfd54d16d4b1b028d.patch 2014-05-05 12:49:23.000000000 +0000 @@ -0,0 +1,282 @@ +commit 5e25ba5003ee5de0ba2be56bfd54d16d4b1b028d +Author: Eric Dumazet +Date: Tue Aug 27 05:46:32 2013 -0700 + + tcp: TSO packets automatic sizing + + [ Upstream commits 6d36824e730f247b602c90e8715a792003e3c5a7, + 02cf4ebd82ff0ac7254b88e466820a290ed8289a, and parts of + 7eec4174ff29cd42f2acfae8112f51c228545d40 ] + + After hearing many people over past years complaining against TSO being + bursty or even buggy, we are proud to present automatic sizing of TSO + packets. + + One part of the problem is that tcp_tso_should_defer() uses an heuristic + relying on upcoming ACKS instead of a timer, but more generally, having + big TSO packets makes little sense for low rates, as it tends to create + micro bursts on the network, and general consensus is to reduce the + buffering amount. + + This patch introduces a per socket sk_pacing_rate, that approximates + the current sending rate, and allows us to size the TSO packets so + that we try to send one packet every ms. + + This field could be set by other transports. + + Patch has no impact for high speed flows, where having large TSO packets + makes sense to reach line rate. + + For other flows, this helps better packet scheduling and ACK clocking. + + This patch increases performance of TCP flows in lossy environments. + + A new sysctl (tcp_min_tso_segs) is added, to specify the + minimal size of a TSO packet (default being 2). + + A follow-up patch will provide a new packet scheduler (FQ), using + sk_pacing_rate as an input to perform optional per flow pacing. + + This explains why we chose to set sk_pacing_rate to twice the current + rate, allowing 'slow start' ramp up. + + sk_pacing_rate = 2 * cwnd * mss / srtt + + v2: Neal Cardwell reported a suspect deferring of last two segments on + initial write of 10 MSS, I had to change tcp_tso_should_defer() to take + into account tp->xmit_size_goal_segs + + Signed-off-by: Eric Dumazet + Cc: Neal Cardwell + Cc: Yuchung Cheng + Cc: Van Jacobson + Cc: Tom Herbert + Acked-by: Yuchung Cheng + Acked-by: Neal Cardwell + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/Documentation/networking/ip-sysctl.txt +=================================================================== +--- linux-3.10-3.10.11.orig/Documentation/networking/ip-sysctl.txt 2014-05-05 11:49:24.000000000 +0000 ++++ linux-3.10-3.10.11/Documentation/networking/ip-sysctl.txt 2014-05-05 12:49:22.000000000 +0000 +@@ -478,6 +478,15 @@ + tcp_timestamps - BOOLEAN + Enable timestamps as defined in RFC1323. + ++tcp_min_tso_segs - INTEGER ++ Minimal number of segments per TSO frame. ++ Since linux-3.12, TCP does an automatic sizing of TSO frames, ++ depending on flow rate, instead of filling 64Kbytes packets. ++ For specific usages, it's possible to force TCP to build big ++ TSO frames. Note that TCP stack might split too big TSO packets ++ if available window is too small. ++ Default: 2 ++ + tcp_tso_win_divisor - INTEGER + This allows control over what percentage of the congestion window + can be consumed by a single TSO frame. +Index: linux-3.10-3.10.11/include/net/sock.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/sock.h 2014-05-05 11:49:24.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/sock.h 2014-05-05 12:49:22.000000000 +0000 +@@ -230,6 +230,7 @@ + * @sk_wmem_queued: persistent queue size + * @sk_forward_alloc: space allocated forward + * @sk_allocation: allocation mode ++ * @sk_pacing_rate: Pacing rate (if supported by transport/packet scheduler) + * @sk_sndbuf: size of send buffer in bytes + * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, + * %SO_OOBINLINE settings, %SO_TIMESTAMPING settings +@@ -355,6 +356,7 @@ + kmemcheck_bitfield_end(flags); + int sk_wmem_queued; + gfp_t sk_allocation; ++ u32 sk_pacing_rate; /* bytes per second */ + netdev_features_t sk_route_caps; + netdev_features_t sk_route_nocaps; + int sk_gso_type; +Index: linux-3.10-3.10.11/include/net/tcp.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/tcp.h 2014-05-05 11:49:24.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/tcp.h 2014-05-05 12:49:22.000000000 +0000 +@@ -287,6 +287,7 @@ + extern int sysctl_tcp_early_retrans; + extern int sysctl_tcp_limit_output_bytes; + extern int sysctl_tcp_challenge_ack_limit; ++extern int sysctl_tcp_min_tso_segs; + + extern atomic_long_t tcp_memory_allocated; + extern struct percpu_counter tcp_sockets_allocated; +Index: linux-3.10-3.10.11/net/core/sock.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/sock.c 2014-05-05 11:49:24.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/sock.c 2014-05-05 12:49:22.000000000 +0000 +@@ -2271,6 +2271,7 @@ + + sk->sk_stamp = ktime_set(-1L, 0); + ++ sk->sk_pacing_rate = ~0U; + /* + * Before updating sk_refcnt, we must commit prior changes to memory + * (Documentation/RCU/rculist_nulls.txt for details) +Index: linux-3.10-3.10.11/net/ipv4/sysctl_net_ipv4.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/sysctl_net_ipv4.c 2014-05-05 11:49:24.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/sysctl_net_ipv4.c 2014-05-05 12:49:22.000000000 +0000 +@@ -29,6 +29,7 @@ + static int zero; + static int one = 1; + static int four = 4; ++static int gso_max_segs = GSO_MAX_SEGS; + static int tcp_retr1_max = 255; + static int ip_local_port_range_min[] = { 1, 1 }; + static int ip_local_port_range_max[] = { 65535, 65535 }; +@@ -753,6 +754,15 @@ + .extra2 = &four, + }, + { ++ .procname = "tcp_min_tso_segs", ++ .data = &sysctl_tcp_min_tso_segs, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = &zero, ++ .extra2 = &gso_max_segs, ++ }, ++ { + .procname = "udp_mem", + .data = &sysctl_udp_mem, + .maxlen = sizeof(sysctl_udp_mem), +Index: linux-3.10-3.10.11/net/ipv4/tcp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp.c 2014-05-05 12:46:52.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp.c 2014-05-05 12:49:22.000000000 +0000 +@@ -282,6 +282,8 @@ + + int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; + ++int sysctl_tcp_min_tso_segs __read_mostly = 2; ++ + struct percpu_counter tcp_orphan_count; + EXPORT_SYMBOL_GPL(tcp_orphan_count); + +@@ -786,12 +788,28 @@ + xmit_size_goal = mss_now; + + if (large_allowed && sk_can_gso(sk)) { +- xmit_size_goal = ((sk->sk_gso_max_size - 1) - +- inet_csk(sk)->icsk_af_ops->net_header_len - +- inet_csk(sk)->icsk_ext_hdr_len - +- tp->tcp_header_len); ++ u32 gso_size, hlen; + +- /* TSQ : try to have two TSO segments in flight */ ++ /* Maybe we should/could use sk->sk_prot->max_header here ? */ ++ hlen = inet_csk(sk)->icsk_af_ops->net_header_len + ++ inet_csk(sk)->icsk_ext_hdr_len + ++ tp->tcp_header_len; ++ ++ /* Goal is to send at least one packet per ms, ++ * not one big TSO packet every 100 ms. ++ * This preserves ACK clocking and is consistent ++ * with tcp_tso_should_defer() heuristic. ++ */ ++ gso_size = sk->sk_pacing_rate / (2 * MSEC_PER_SEC); ++ gso_size = max_t(u32, gso_size, ++ sysctl_tcp_min_tso_segs * mss_now); ++ ++ xmit_size_goal = min_t(u32, gso_size, ++ sk->sk_gso_max_size - 1 - hlen); ++ ++ /* TSQ : try to have at least two segments in flight ++ * (one in NIC TX ring, another in Qdisc) ++ */ + xmit_size_goal = min_t(u32, xmit_size_goal, + sysctl_tcp_limit_output_bytes >> 1); + +Index: linux-3.10-3.10.11/net/ipv4/tcp_input.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_input.c 2014-05-05 12:43:27.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_input.c 2014-05-05 12:49:22.000000000 +0000 +@@ -699,6 +699,34 @@ + } + } + ++/* Set the sk_pacing_rate to allow proper sizing of TSO packets. ++ * Note: TCP stack does not yet implement pacing. ++ * FQ packet scheduler can be used to implement cheap but effective ++ * TCP pacing, to smooth the burst on large writes when packets ++ * in flight is significantly lower than cwnd (or rwin) ++ */ ++static void tcp_update_pacing_rate(struct sock *sk) ++{ ++ const struct tcp_sock *tp = tcp_sk(sk); ++ u64 rate; ++ ++ /* set sk_pacing_rate to 200 % of current rate (mss * cwnd / srtt) */ ++ rate = (u64)tp->mss_cache * 2 * (HZ << 3); ++ ++ rate *= max(tp->snd_cwnd, tp->packets_out); ++ ++ /* Correction for small srtt : minimum srtt being 8 (1 jiffy << 3), ++ * be conservative and assume srtt = 1 (125 us instead of 1.25 ms) ++ * We probably need usec resolution in the future. ++ * Note: This also takes care of possible srtt=0 case, ++ * when tcp_rtt_estimator() was not yet called. ++ */ ++ if (tp->srtt > 8 + 2) ++ do_div(rate, tp->srtt); ++ ++ sk->sk_pacing_rate = min_t(u64, rate, ~0U); ++} ++ + /* Calculate rto without backoff. This is the second half of Van Jacobson's + * routine referred to above. + */ +@@ -3330,7 +3358,7 @@ + u32 ack_seq = TCP_SKB_CB(skb)->seq; + u32 ack = TCP_SKB_CB(skb)->ack_seq; + bool is_dupack = false; +- u32 prior_in_flight; ++ u32 prior_in_flight, prior_cwnd = tp->snd_cwnd, prior_rtt = tp->srtt; + u32 prior_fackets; + int prior_packets = tp->packets_out; + int prior_sacked = tp->sacked_out; +@@ -3438,6 +3466,8 @@ + + if (icsk->icsk_pending == ICSK_TIME_RETRANS) + tcp_schedule_loss_probe(sk); ++ if (tp->srtt != prior_rtt || tp->snd_cwnd != prior_cwnd) ++ tcp_update_pacing_rate(sk); + return 1; + + no_queue: +@@ -5736,6 +5766,8 @@ + } else + tcp_init_metrics(sk); + ++ tcp_update_pacing_rate(sk); ++ + /* Prevent spurious tcp_cwnd_restart() on + * first data packet. + */ +Index: linux-3.10-3.10.11/net/ipv4/tcp_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_output.c 2014-05-05 12:43:29.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_output.c 2014-05-05 12:49:22.000000000 +0000 +@@ -1623,7 +1623,7 @@ + + /* If a full-sized TSO skb can be sent, do it. */ + if (limit >= min_t(unsigned int, sk->sk_gso_max_size, +- sk->sk_gso_max_segs * tp->mss_cache)) ++ tp->xmit_size_goal_segs * tp->mss_cache)) + goto send_now; + + /* Middle in queue won't get any more data, full sendable already? */ +Index: linux-3.10-3.10.11/dummy/rpi_1441_5e25ba5003ee5de0ba2be56bfd54d16d4b1b028d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1441_5e25ba5003ee5de0ba2be56bfd54d16d4b1b028d.txt 2014-05-05 12:49:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1442_0ae5f47eff2e543c3b94eec51c740f38a5071432.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1442_0ae5f47eff2e543c3b94eec51c740f38a5071432.patch --- linux-3.10.11/debian/patches/rpi/rpi_1442_0ae5f47eff2e543c3b94eec51c740f38a5071432.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1442_0ae5f47eff2e543c3b94eec51c740f38a5071432.patch 2014-05-05 12:49:24.000000000 +0000 @@ -0,0 +1,111 @@ +commit 0ae5f47eff2e543c3b94eec51c740f38a5071432 +Author: Eric Dumazet +Date: Fri Sep 27 03:28:54 2013 -0700 + + tcp: TSQ can use a dynamic limit + + [ Upstream commit c9eeec26e32e087359160406f96e0949b3cc6f10 ] + + When TCP Small Queues was added, we used a sysctl to limit amount of + packets queues on Qdisc/device queues for a given TCP flow. + + Problem is this limit is either too big for low rates, or too small + for high rates. + + Now TCP stack has rate estimation in sk->sk_pacing_rate, and TSO + auto sizing, it can better control number of packets in Qdisc/device + queues. + + New limit is two packets or at least 1 to 2 ms worth of packets. + + Low rates flows benefit from this patch by having even smaller + number of packets in queues, allowing for faster recovery, + better RTT estimations. + + High rates flows benefit from this patch by allowing more than 2 packets + in flight as we had reports this was a limiting factor to reach line + rate. [ In particular if TX completion is delayed because of coalescing + parameters ] + + Example for a single flow on 10Gbp link controlled by FQ/pacing + + 14 packets in flight instead of 2 + + $ tc -s -d qd + qdisc fq 8001: dev eth0 root refcnt 32 limit 10000p flow_limit 100p + buckets 1024 quantum 3028 initial_quantum 15140 + Sent 1168459366606 bytes 771822841 pkt (dropped 0, overlimits 0 + requeues 6822476) + rate 9346Mbit 771713pps backlog 953820b 14p requeues 6822476 + 2047 flow, 2046 inactive, 1 throttled, delay 15673 ns + 2372 gc, 0 highprio, 0 retrans, 9739249 throttled, 0 flows_plimit + + Note that sk_pacing_rate is currently set to twice the actual rate, but + this might be refined in the future when a flow is in congestion + avoidance. + + Additional change : skb->destructor should be set to tcp_wfree(). + + A future patch (for linux 3.13+) might remove tcp_limit_output_bytes + + Signed-off-by: Eric Dumazet + Cc: Wei Liu + Cc: Cong Wang + Cc: Yuchung Cheng + Cc: Neal Cardwell + Acked-by: Neal Cardwell + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_output.c 2014-05-05 12:49:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_output.c 2014-05-05 12:49:23.000000000 +0000 +@@ -887,8 +887,7 @@ + + skb_orphan(skb); + skb->sk = sk; +- skb->destructor = (sysctl_tcp_limit_output_bytes > 0) ? +- tcp_wfree : sock_wfree; ++ skb->destructor = tcp_wfree; + atomic_add(skb->truesize, &sk->sk_wmem_alloc); + + /* Build TCP header and checksum it. */ +@@ -1832,7 +1831,6 @@ + while ((skb = tcp_send_head(sk))) { + unsigned int limit; + +- + tso_segs = tcp_init_tso_segs(sk, skb, mss_now); + BUG_ON(!tso_segs); + +@@ -1861,13 +1859,20 @@ + break; + } + +- /* TSQ : sk_wmem_alloc accounts skb truesize, +- * including skb overhead. But thats OK. ++ /* TCP Small Queues : ++ * Control number of packets in qdisc/devices to two packets / or ~1 ms. ++ * This allows for : ++ * - better RTT estimation and ACK scheduling ++ * - faster recovery ++ * - high rates + */ +- if (atomic_read(&sk->sk_wmem_alloc) >= sysctl_tcp_limit_output_bytes) { ++ limit = max(skb->truesize, sk->sk_pacing_rate >> 10); ++ ++ if (atomic_read(&sk->sk_wmem_alloc) > limit) { + set_bit(TSQ_THROTTLED, &tp->tsq_flags); + break; + } ++ + limit = mss_now; + if (tso_segs > 1 && !tcp_urg_mode(tp)) + limit = tcp_mss_split_point(sk, skb, mss_now, +Index: linux-3.10-3.10.11/dummy/rpi_1442_0ae5f47eff2e543c3b94eec51c740f38a5071432.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1442_0ae5f47eff2e543c3b94eec51c740f38a5071432.txt 2014-05-05 12:49:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1443_b81908e15f548e385598beaf17376cd101f36bc8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1443_b81908e15f548e385598beaf17376cd101f36bc8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1443_b81908e15f548e385598beaf17376cd101f36bc8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1443_b81908e15f548e385598beaf17376cd101f36bc8.patch 2014-05-05 12:49:24.000000000 +0000 @@ -0,0 +1,72 @@ +commit b81908e15f548e385598beaf17376cd101f36bc8 +Author: Eric Dumazet +Date: Tue Oct 15 11:54:30 2013 -0700 + + tcp: must unclone packets before mangling them + + [ Upstream commit c52e2421f7368fd36cbe330d2cf41b10452e39a9 ] + + TCP stack should make sure it owns skbs before mangling them. + + We had various crashes using bnx2x, and it turned out gso_size + was cleared right before bnx2x driver was populating TC descriptor + of the _previous_ packet send. TCP stack can sometime retransmit + packets that are still in Qdisc. + + Of course we could make bnx2x driver more robust (using + ACCESS_ONCE(shinfo->gso_size) for example), but the bug is TCP stack. + + We have identified two points where skb_unclone() was needed. + + This patch adds a WARN_ON_ONCE() to warn us if we missed another + fix of this kind. + + Kudos to Neal for finding the root cause of this bug. Its visible + using small MSS. + + Signed-off-by: Eric Dumazet + Signed-off-by: Neal Cardwell + Cc: Yuchung Cheng + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_output.c 2014-05-05 12:49:23.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_output.c 2014-05-05 12:49:24.000000000 +0000 +@@ -976,6 +976,9 @@ + static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb, + unsigned int mss_now) + { ++ /* Make sure we own this skb before messing gso_size/gso_segs */ ++ WARN_ON_ONCE(skb_cloned(skb)); ++ + if (skb->len <= mss_now || !sk_can_gso(sk) || + skb->ip_summed == CHECKSUM_NONE) { + /* Avoid the costly divide in the normal +@@ -1057,9 +1060,7 @@ + if (nsize < 0) + nsize = 0; + +- if (skb_cloned(skb) && +- skb_is_nonlinear(skb) && +- pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) ++ if (skb_unclone(skb, GFP_ATOMIC)) + return -ENOMEM; + + /* Get a new skb... force flag on. */ +@@ -2334,6 +2335,8 @@ + int oldpcount = tcp_skb_pcount(skb); + + if (unlikely(oldpcount > 1)) { ++ if (skb_unclone(skb, GFP_ATOMIC)) ++ return -ENOMEM; + tcp_init_tso_segs(sk, skb, cur_mss); + tcp_adjust_pcount(sk, skb, oldpcount - tcp_skb_pcount(skb)); + } +Index: linux-3.10-3.10.11/dummy/rpi_1443_b81908e15f548e385598beaf17376cd101f36bc8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1443_b81908e15f548e385598beaf17376cd101f36bc8.txt 2014-05-05 12:49:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1444_a50b0399e6899e39e6f74431aaddf12ee92db854.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1444_a50b0399e6899e39e6f74431aaddf12ee92db854.patch --- linux-3.10.11/debian/patches/rpi/rpi_1444_a50b0399e6899e39e6f74431aaddf12ee92db854.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1444_a50b0399e6899e39e6f74431aaddf12ee92db854.patch 2014-05-05 12:49:25.000000000 +0000 @@ -0,0 +1,80 @@ +commit a50b0399e6899e39e6f74431aaddf12ee92db854 +Author: Eric Dumazet +Date: Fri Oct 4 10:31:41 2013 -0700 + + tcp: do not forget FIN in tcp_shifted_skb() + + [ Upstream commit 5e8a402f831dbe7ee831340a91439e46f0d38acd ] + + Yuchung found following problem : + + There are bugs in the SACK processing code, merging part in + tcp_shift_skb_data(), that incorrectly resets or ignores the sacked + skbs FIN flag. When a receiver first SACK the FIN sequence, and later + throw away ofo queue (e.g., sack-reneging), the sender will stop + retransmitting the FIN flag, and hangs forever. + + Following packetdrill test can be used to reproduce the bug. + + $ cat sack-merge-bug.pkt + `sysctl -q net.ipv4.tcp_fack=0` + + // Establish a connection and send 10 MSS. + 0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +.000 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 + +.000 bind(3, ..., ...) = 0 + +.000 listen(3, 1) = 0 + + +.050 < S 0:0(0) win 32792 + +.000 > S. 0:0(0) ack 1 + +.001 < . 1:1(0) ack 1 win 1024 + +.000 accept(3, ..., ...) = 4 + + +.100 write(4, ..., 12000) = 12000 + +.000 shutdown(4, SHUT_WR) = 0 + +.000 > . 1:10001(10000) ack 1 + +.050 < . 1:1(0) ack 2001 win 257 + +.000 > FP. 10001:12001(2000) ack 1 + +.050 < . 1:1(0) ack 2001 win 257 + +.050 < . 1:1(0) ack 2001 win 257 + // SACK reneg + +.050 < . 1:1(0) ack 12001 win 257 + +0 %{ print "unacked: ",tcpi_unacked }% + +5 %{ print "" }% + + First, a typo inverted left/right of one OR operation, then + code forgot to advance end_seq if the merged skb carried FIN. + + Bug was added in 2.6.29 by commit 832d11c5cd076ab + ("tcp: Try to restore large SKBs while SACK processing") + + Signed-off-by: Eric Dumazet + Signed-off-by: Yuchung Cheng + Acked-by: Neal Cardwell + Cc: Ilpo Järvinen + Acked-by: Ilpo Järvinen + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_input.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_input.c 2014-05-05 12:49:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_input.c 2014-05-05 12:49:25.000000000 +0000 +@@ -1292,7 +1292,10 @@ + tp->lost_cnt_hint -= tcp_skb_pcount(prev); + } + +- TCP_SKB_CB(skb)->tcp_flags |= TCP_SKB_CB(prev)->tcp_flags; ++ TCP_SKB_CB(prev)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; ++ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) ++ TCP_SKB_CB(prev)->end_seq++; ++ + if (skb == tcp_highest_sack(sk)) + tcp_advance_highest_sack(sk, skb); + +Index: linux-3.10-3.10.11/dummy/rpi_1444_a50b0399e6899e39e6f74431aaddf12ee92db854.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1444_a50b0399e6899e39e6f74431aaddf12ee92db854.txt 2014-05-05 12:49:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1445_d8ac0f178f98d4e7c23cf9526d789d4869ec6e4c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1445_d8ac0f178f98d4e7c23cf9526d789d4869ec6e4c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1445_d8ac0f178f98d4e7c23cf9526d789d4869ec6e4c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1445_d8ac0f178f98d4e7c23cf9526d789d4869ec6e4c.patch 2014-05-05 12:49:26.000000000 +0000 @@ -0,0 +1,45 @@ +commit d8ac0f178f98d4e7c23cf9526d789d4869ec6e4c +Author: Yuchung Cheng +Date: Sat Oct 12 10:16:27 2013 -0700 + + tcp: fix incorrect ca_state in tail loss probe + + [ Upstream commit 031afe4990a7c9dbff41a3a742c44d3e740ea0a1 ] + + On receiving an ACK that covers the loss probe sequence, TLP + immediately sets the congestion state to Open, even though some packets + are not recovered and retransmisssion are on the way. The later ACks + may trigger a WARN_ON check in step D of tcp_fastretrans_alert(), e.g., + https://bugzilla.redhat.com/show_bug.cgi?id=989251 + + The fix is to follow the similar procedure in recovery by calling + tcp_try_keep_open(). The sender switches to Open state if no packets + are retransmissted. Otherwise it goes to Disorder and let subsequent + ACKs move the state to Recovery or Open. + + Reported-By: Michael Sterrett + Tested-By: Dormando + Signed-off-by: Yuchung Cheng + Acked-by: Neal Cardwell + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/tcp_input.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/tcp_input.c 2014-05-05 12:49:25.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/tcp_input.c 2014-05-05 12:49:26.000000000 +0000 +@@ -3345,7 +3345,7 @@ + tcp_init_cwnd_reduction(sk, true); + tcp_set_ca_state(sk, TCP_CA_CWR); + tcp_end_cwnd_reduction(sk); +- tcp_set_ca_state(sk, TCP_CA_Open); ++ tcp_try_keep_open(sk); + NET_INC_STATS_BH(sock_net(sk), + LINUX_MIB_TCPLOSSPROBERECOVERY); + } +Index: linux-3.10-3.10.11/dummy/rpi_1445_d8ac0f178f98d4e7c23cf9526d789d4869ec6e4c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1445_d8ac0f178f98d4e7c23cf9526d789d4869ec6e4c.txt 2014-05-05 12:49:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1446_53d384ae6a01eadb8d362afaca6a9c0ba72c1126.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1446_53d384ae6a01eadb8d362afaca6a9c0ba72c1126.patch --- linux-3.10.11/debian/patches/rpi/rpi_1446_53d384ae6a01eadb8d362afaca6a9c0ba72c1126.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1446_53d384ae6a01eadb8d362afaca6a9c0ba72c1126.patch 2014-05-05 12:49:27.000000000 +0000 @@ -0,0 +1,49 @@ +commit 53d384ae6a01eadb8d362afaca6a9c0ba72c1126 +Author: Eric Dumazet +Date: Tue Oct 1 21:04:11 2013 -0700 + + net: do not call sock_put() on TIMEWAIT sockets + + [ Upstream commit 80ad1d61e72d626e30ebe8529a0455e660ca4693 ] + + commit 3ab5aee7fe84 ("net: Convert TCP & DCCP hash tables to use RCU / + hlist_nulls") incorrectly used sock_put() on TIMEWAIT sockets. + + We should instead use inet_twsk_put() + + Signed-off-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/inet_hashtables.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/inet_hashtables.c 2014-05-05 11:49:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/inet_hashtables.c 2014-05-05 12:49:26.000000000 +0000 +@@ -287,7 +287,7 @@ + if (unlikely(!INET_TW_MATCH(sk, net, acookie, + saddr, daddr, ports, + dif))) { +- sock_put(sk); ++ inet_twsk_put(inet_twsk(sk)); + goto begintw; + } + goto out; +Index: linux-3.10-3.10.11/net/ipv6/inet6_hashtables.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/inet6_hashtables.c 2014-05-05 11:49:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/inet6_hashtables.c 2014-05-05 12:49:26.000000000 +0000 +@@ -116,7 +116,7 @@ + } + if (unlikely(!INET6_TW_MATCH(sk, net, saddr, daddr, + ports, dif))) { +- sock_put(sk); ++ inet_twsk_put(inet_twsk(sk)); + goto begintw; + } + goto out; +Index: linux-3.10-3.10.11/dummy/rpi_1446_53d384ae6a01eadb8d362afaca6a9c0ba72c1126.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1446_53d384ae6a01eadb8d362afaca6a9c0ba72c1126.txt 2014-05-05 12:49:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1447_bd83cd77073e5c54a88f976d6d6c785a1a80b0c0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1447_bd83cd77073e5c54a88f976d6d6c785a1a80b0c0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1447_bd83cd77073e5c54a88f976d6d6c785a1a80b0c0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1447_bd83cd77073e5c54a88f976d6d6c785a1a80b0c0.patch 2014-05-05 12:49:28.000000000 +0000 @@ -0,0 +1,146 @@ +commit bd83cd77073e5c54a88f976d6d6c785a1a80b0c0 +Author: François CACHEREUL +Date: Wed Oct 2 10:16:02 2013 +0200 + + l2tp: fix kernel panic when using IPv4-mapped IPv6 addresses + + [ Upstream commit e18503f41f9b12132c95d7c31ca6ee5155e44e5c ] + + IPv4 mapped addresses cause kernel panic. + The patch juste check whether the IPv6 address is an IPv4 mapped + address. If so, use IPv4 API instead of IPv6. + + [ 940.026915] general protection fault: 0000 [#1] + [ 940.026915] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core pppox ppp_generic slhc loop psmouse + [ 940.026915] CPU: 0 PID: 3184 Comm: memcheck-amd64- Not tainted 3.11.0+ #1 + [ 940.026915] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 + [ 940.026915] task: ffff880007130e20 ti: ffff88000737e000 task.ti: ffff88000737e000 + [ 940.026915] RIP: 0010:[] [] ip6_xmit+0x276/0x326 + [ 940.026915] RSP: 0018:ffff88000737fd28 EFLAGS: 00010286 + [ 940.026915] RAX: c748521a75ceff48 RBX: ffff880000c30800 RCX: 0000000000000000 + [ 940.026915] RDX: ffff88000075cc4e RSI: 0000000000000028 RDI: ffff8800060e5a40 + [ 940.026915] RBP: ffff8800060e5a40 R08: 0000000000000000 R09: ffff88000075cc90 + [ 940.026915] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88000737fda0 + [ 940.026915] R13: 0000000000000000 R14: 0000000000002000 R15: ffff880005d3b580 + [ 940.026915] FS: 00007f163dc5e800(0000) GS:ffffffff81623000(0000) knlGS:0000000000000000 + [ 940.026915] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [ 940.026915] CR2: 00000004032dc940 CR3: 0000000005c25000 CR4: 00000000000006f0 + [ 940.026915] Stack: + [ 940.026915] ffff88000075cc4e ffffffff81694e90 ffff880000c30b38 0000000000000020 + [ 940.026915] 11000000523c4bac ffff88000737fdb4 0000000000000000 ffff880000c30800 + [ 940.026915] ffff880005d3b580 ffff880000c30b38 ffff8800060e5a40 0000000000000020 + [ 940.026915] Call Trace: + [ 940.026915] [] ? inet6_csk_xmit+0xa4/0xc4 + [ 940.026915] [] ? l2tp_xmit_skb+0x503/0x55a [l2tp_core] + [ 940.026915] [] ? pskb_expand_head+0x161/0x214 + [ 940.026915] [] ? pppol2tp_xmit+0xf2/0x143 [l2tp_ppp] + [ 940.026915] [] ? ppp_channel_push+0x36/0x8b [ppp_generic] + [ 940.026915] [] ? ppp_write+0xaf/0xc5 [ppp_generic] + [ 940.026915] [] ? vfs_write+0xa2/0x106 + [ 940.026915] [] ? SyS_write+0x56/0x8a + [ 940.026915] [] ? system_call_fastpath+0x16/0x1b + [ 940.026915] Code: 00 49 8b 8f d8 00 00 00 66 83 7c 11 02 00 74 60 49 + 8b 47 58 48 83 e0 fe 48 8b 80 18 01 00 00 48 85 c0 74 13 48 8b 80 78 02 + 00 00 <48> ff 40 28 41 8b 57 68 48 01 50 30 48 8b 54 24 08 49 c7 c1 51 + [ 940.026915] RIP [] ip6_xmit+0x276/0x326 + [ 940.026915] RSP + [ 940.057945] ---[ end trace be8aba9a61c8b7f3 ]--- + [ 940.058583] Kernel panic - not syncing: Fatal exception in interrupt + + Signed-off-by: François CACHEREUL + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/l2tp/l2tp_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/l2tp/l2tp_core.c 2014-05-05 11:49:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/l2tp/l2tp_core.c 2014-05-05 12:49:27.000000000 +0000 +@@ -499,6 +499,7 @@ + static inline int l2tp_verify_udp_checksum(struct sock *sk, + struct sk_buff *skb) + { ++ struct l2tp_tunnel *tunnel = (struct l2tp_tunnel *)sk->sk_user_data; + struct udphdr *uh = udp_hdr(skb); + u16 ulen = ntohs(uh->len); + __wsum psum; +@@ -507,7 +508,7 @@ + return 0; + + #if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family == PF_INET6) { ++ if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) { + if (!uh->check) { + LIMIT_NETDEBUG(KERN_INFO "L2TP: IPv6: checksum is 0\n"); + return 1; +@@ -1071,7 +1072,7 @@ + /* Queue the packet to IP for output */ + skb->local_df = 1; + #if IS_ENABLED(CONFIG_IPV6) +- if (skb->sk->sk_family == PF_INET6) ++ if (skb->sk->sk_family == PF_INET6 && !tunnel->v4mapped) + error = inet6_csk_xmit(skb, NULL); + else + #endif +@@ -1198,7 +1199,7 @@ + + /* Calculate UDP checksum if configured to do so */ + #if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family == PF_INET6) ++ if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) + l2tp_xmit_ipv6_csum(sk, skb, udp_len); + else + #endif +@@ -1647,6 +1648,24 @@ + if (cfg != NULL) + tunnel->debug = cfg->debug; + ++#if IS_ENABLED(CONFIG_IPV6) ++ if (sk->sk_family == PF_INET6) { ++ struct ipv6_pinfo *np = inet6_sk(sk); ++ ++ if (ipv6_addr_v4mapped(&np->saddr) && ++ ipv6_addr_v4mapped(&np->daddr)) { ++ struct inet_sock *inet = inet_sk(sk); ++ ++ tunnel->v4mapped = true; ++ inet->inet_saddr = np->saddr.s6_addr32[3]; ++ inet->inet_rcv_saddr = np->rcv_saddr.s6_addr32[3]; ++ inet->inet_daddr = np->daddr.s6_addr32[3]; ++ } else { ++ tunnel->v4mapped = false; ++ } ++ } ++#endif ++ + /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */ + tunnel->encap = encap; + if (encap == L2TP_ENCAPTYPE_UDP) { +@@ -1655,7 +1674,7 @@ + udp_sk(sk)->encap_rcv = l2tp_udp_encap_recv; + udp_sk(sk)->encap_destroy = l2tp_udp_encap_destroy; + #if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family == PF_INET6) ++ if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) + udpv6_encap_enable(); + else + #endif +Index: linux-3.10-3.10.11/net/l2tp/l2tp_core.h +=================================================================== +--- linux-3.10-3.10.11.orig/net/l2tp/l2tp_core.h 2014-05-05 11:49:22.000000000 +0000 ++++ linux-3.10-3.10.11/net/l2tp/l2tp_core.h 2014-05-05 12:49:27.000000000 +0000 +@@ -189,6 +189,9 @@ + struct sock *sock; /* Parent socket */ + int fd; /* Parent fd, if tunnel socket + * was created by userspace */ ++#if IS_ENABLED(CONFIG_IPV6) ++ bool v4mapped; ++#endif + + struct work_struct del_work; + +Index: linux-3.10-3.10.11/dummy/rpi_1447_bd83cd77073e5c54a88f976d6d6c785a1a80b0c0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1447_bd83cd77073e5c54a88f976d6d6c785a1a80b0c0.txt 2014-05-05 12:49:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1448_d980ed627b35d4685a4a27561dc3fc7a09226dab.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1448_d980ed627b35d4685a4a27561dc3fc7a09226dab.patch --- linux-3.10.11/debian/patches/rpi/rpi_1448_d980ed627b35d4685a4a27561dc3fc7a09226dab.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1448_d980ed627b35d4685a4a27561dc3fc7a09226dab.patch 2014-05-05 12:49:29.000000000 +0000 @@ -0,0 +1,77 @@ +commit d980ed627b35d4685a4a27561dc3fc7a09226dab +Author: David S. Miller +Date: Tue Oct 8 15:44:26 2013 -0400 + + l2tp: Fix build warning with ipv6 disabled. + + [ Upstream commit 8d8a51e26a6d415e1470759f2cf5f3ee3ee86196 ] + + net/l2tp/l2tp_core.c: In function ‘l2tp_verify_udp_checksum’: + net/l2tp/l2tp_core.c:499:22: warning: unused variable ‘tunnel’ [-Wunused-variable] + + Create a helper "l2tp_tunnel()" to facilitate this, and as a side + effect get rid of a bunch of unnecessary void pointer casts. + + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/l2tp/l2tp_core.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/l2tp/l2tp_core.c 2014-05-05 12:49:27.000000000 +0000 ++++ linux-3.10-3.10.11/net/l2tp/l2tp_core.c 2014-05-05 12:49:28.000000000 +0000 +@@ -115,6 +115,11 @@ + static void l2tp_session_set_header_len(struct l2tp_session *session, int version); + static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); + ++static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) ++{ ++ return sk->sk_user_data; ++} ++ + static inline struct l2tp_net *l2tp_pernet(struct net *net) + { + BUG_ON(!net); +@@ -499,7 +504,6 @@ + static inline int l2tp_verify_udp_checksum(struct sock *sk, + struct sk_buff *skb) + { +- struct l2tp_tunnel *tunnel = (struct l2tp_tunnel *)sk->sk_user_data; + struct udphdr *uh = udp_hdr(skb); + u16 ulen = ntohs(uh->len); + __wsum psum; +@@ -508,7 +512,7 @@ + return 0; + + #if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) { ++ if (sk->sk_family == PF_INET6 && !l2tp_tunnel(sk)->v4mapped) { + if (!uh->check) { + LIMIT_NETDEBUG(KERN_INFO "L2TP: IPv6: checksum is 0\n"); + return 1; +@@ -1248,10 +1252,9 @@ + */ + static void l2tp_tunnel_destruct(struct sock *sk) + { +- struct l2tp_tunnel *tunnel; ++ struct l2tp_tunnel *tunnel = l2tp_tunnel(sk); + struct l2tp_net *pn; + +- tunnel = sk->sk_user_data; + if (tunnel == NULL) + goto end; + +@@ -1619,7 +1622,7 @@ + } + + /* Check if this socket has already been prepped */ +- tunnel = (struct l2tp_tunnel *)sk->sk_user_data; ++ tunnel = l2tp_tunnel(sk); + if (tunnel != NULL) { + /* This socket has already been prepped */ + err = -EBUSY; +Index: linux-3.10-3.10.11/dummy/rpi_1448_d980ed627b35d4685a4a27561dc3fc7a09226dab.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1448_d980ed627b35d4685a4a27561dc3fc7a09226dab.txt 2014-05-05 12:49:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1449_85cd02136ded01747a7959567aa1626627f1877e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1449_85cd02136ded01747a7959567aa1626627f1877e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1449_85cd02136ded01747a7959567aa1626627f1877e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1449_85cd02136ded01747a7959567aa1626627f1877e.patch 2014-05-05 12:49:30.000000000 +0000 @@ -0,0 +1,45 @@ +commit 85cd02136ded01747a7959567aa1626627f1877e +Author: Sebastian Hesselbarth +Date: Wed Oct 2 12:57:20 2013 +0200 + + net: mv643xx_eth: update statistics timer from timer context only + + [ Upstream commit 041b4ddb84989f06ff1df0ca869b950f1ee3cb1c ] + + Each port driver installs a periodic timer to update port statistics + by calling mib_counters_update. As mib_counters_update is also called + from non-timer context, we should not reschedule the timer there but + rather move it to timer-only context. + + Signed-off-by: Sebastian Hesselbarth + Acked-by: Jason Cooper + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/marvell/mv643xx_eth.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/marvell/mv643xx_eth.c 2014-05-05 11:49:21.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/marvell/mv643xx_eth.c 2014-05-05 12:49:29.000000000 +0000 +@@ -1125,15 +1125,13 @@ + p->rx_discard += rdlp(mp, RX_DISCARD_FRAME_CNT); + p->rx_overrun += rdlp(mp, RX_OVERRUN_FRAME_CNT); + spin_unlock_bh(&mp->mib_counters_lock); +- +- mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); + } + + static void mib_counters_timer_wrapper(unsigned long _mp) + { + struct mv643xx_eth_private *mp = (void *)_mp; +- + mib_counters_update(mp); ++ mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); + } + + +Index: linux-3.10-3.10.11/dummy/rpi_1449_85cd02136ded01747a7959567aa1626627f1877e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1449_85cd02136ded01747a7959567aa1626627f1877e.txt 2014-05-05 12:49:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1450_b24b4a82fc96f74d848275c8f1b33df66cbef061.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1450_b24b4a82fc96f74d848275c8f1b33df66cbef061.patch --- linux-3.10.11/debian/patches/rpi/rpi_1450_b24b4a82fc96f74d848275c8f1b33df66cbef061.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1450_b24b4a82fc96f74d848275c8f1b33df66cbef061.patch 2014-05-05 12:49:31.000000000 +0000 @@ -0,0 +1,45 @@ +commit b24b4a82fc96f74d848275c8f1b33df66cbef061 +Author: Sebastian Hesselbarth +Date: Wed Oct 2 12:57:21 2013 +0200 + + net: mv643xx_eth: fix orphaned statistics timer crash + + [ Upstream commit f564412c935111c583b787bcc18157377b208e2e ] + + The periodic statistics timer gets started at port _probe() time, but + is stopped on _stop() only. In a modular environment, this can cause + the timer to access already deallocated memory, if the module is unloaded + without starting the eth device. To fix this, we add the timer right + before the port is started, instead of at _probe() time. + + Signed-off-by: Sebastian Hesselbarth + Acked-by: Jason Cooper + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/marvell/mv643xx_eth.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/marvell/mv643xx_eth.c 2014-05-05 12:49:29.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/marvell/mv643xx_eth.c 2014-05-05 12:49:30.000000000 +0000 +@@ -2229,6 +2229,7 @@ + mp->int_mask |= INT_TX_END_0 << i; + } + ++ add_timer(&mp->mib_counters_timer); + port_start(mp); + + wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX); +@@ -2737,7 +2738,6 @@ + mp->mib_counters_timer.data = (unsigned long)mp; + mp->mib_counters_timer.function = mib_counters_timer_wrapper; + mp->mib_counters_timer.expires = jiffies + 30 * HZ; +- add_timer(&mp->mib_counters_timer); + + spin_lock_init(&mp->mib_counters_lock); + +Index: linux-3.10-3.10.11/dummy/rpi_1450_b24b4a82fc96f74d848275c8f1b33df66cbef061.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1450_b24b4a82fc96f74d848275c8f1b33df66cbef061.txt 2014-05-05 12:49:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1451_2e8d97ab1f1236d08a8576d5c4b25d3180ff01f6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1451_2e8d97ab1f1236d08a8576d5c4b25d3180ff01f6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1451_2e8d97ab1f1236d08a8576d5c4b25d3180ff01f6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1451_2e8d97ab1f1236d08a8576d5c4b25d3180ff01f6.patch 2014-05-05 12:49:31.000000000 +0000 @@ -0,0 +1,91 @@ +commit 2e8d97ab1f1236d08a8576d5c4b25d3180ff01f6 +Author: Dan Carpenter +Date: Thu Oct 3 00:27:20 2013 +0300 + + net: heap overflow in __audit_sockaddr() + + [ Upstream commit 1661bf364ae9c506bc8795fef70d1532931be1e8 ] + + We need to cap ->msg_namelen or it leads to a buffer overflow when we + to the memcpy() in __audit_sockaddr(). It requires CAP_AUDIT_CONTROL to + exploit this bug. + + The call tree is: + ___sys_recvmsg() + move_addr_to_user() + audit_sockaddr() + __audit_sockaddr() + + Reported-by: Jüri Aedla + Signed-off-by: Dan Carpenter + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/compat.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/compat.c 2014-05-05 11:49:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/compat.c 2014-05-05 12:49:31.000000000 +0000 +@@ -71,6 +71,8 @@ + __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || + __get_user(kmsg->msg_flags, &umsg->msg_flags)) + return -EFAULT; ++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) ++ return -EINVAL; + kmsg->msg_name = compat_ptr(tmp1); + kmsg->msg_iov = compat_ptr(tmp2); + kmsg->msg_control = compat_ptr(tmp3); +Index: linux-3.10-3.10.11/net/socket.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/socket.c 2014-05-05 11:49:20.000000000 +0000 ++++ linux-3.10-3.10.11/net/socket.c 2014-05-05 12:49:31.000000000 +0000 +@@ -1956,6 +1956,16 @@ + unsigned int name_len; + }; + ++static int copy_msghdr_from_user(struct msghdr *kmsg, ++ struct msghdr __user *umsg) ++{ ++ if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) ++ return -EFAULT; ++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) ++ return -EINVAL; ++ return 0; ++} ++ + static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, + struct msghdr *msg_sys, unsigned int flags, + struct used_address *used_address) +@@ -1974,8 +1984,11 @@ + if (MSG_CMSG_COMPAT & flags) { + if (get_compat_msghdr(msg_sys, msg_compat)) + return -EFAULT; +- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) +- return -EFAULT; ++ } else { ++ err = copy_msghdr_from_user(msg_sys, msg); ++ if (err) ++ return err; ++ } + + if (msg_sys->msg_iovlen > UIO_FASTIOV) { + err = -EMSGSIZE; +@@ -2183,8 +2196,11 @@ + if (MSG_CMSG_COMPAT & flags) { + if (get_compat_msghdr(msg_sys, msg_compat)) + return -EFAULT; +- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) +- return -EFAULT; ++ } else { ++ err = copy_msghdr_from_user(msg_sys, msg); ++ if (err) ++ return err; ++ } + + if (msg_sys->msg_iovlen > UIO_FASTIOV) { + err = -EMSGSIZE; +Index: linux-3.10-3.10.11/dummy/rpi_1451_2e8d97ab1f1236d08a8576d5c4b25d3180ff01f6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1451_2e8d97ab1f1236d08a8576d5c4b25d3180ff01f6.txt 2014-05-05 12:49:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1452_df6ae0dc3145f5d3c0b04a59e64cd647469881e4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1452_df6ae0dc3145f5d3c0b04a59e64cd647469881e4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1452_df6ae0dc3145f5d3c0b04a59e64cd647469881e4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1452_df6ae0dc3145f5d3c0b04a59e64cd647469881e4.patch 2014-05-05 12:49:32.000000000 +0000 @@ -0,0 +1,171 @@ +commit df6ae0dc3145f5d3c0b04a59e64cd647469881e4 +Author: Mathias Krause +Date: Mon Sep 30 22:03:06 2013 +0200 + + proc connector: fix info leaks + + [ Upstream commit e727ca82e0e9616ab4844301e6bae60ca7327682 ] + + Initialize event_data for all possible message types to prevent leaking + kernel stack contents to userland (up to 20 bytes). Also set the flags + member of the connector message to 0 to prevent leaking two more stack + bytes this way. + + Signed-off-by: Mathias Krause + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/connector/cn_proc.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/connector/cn_proc.c 2014-05-05 11:49:19.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/connector/cn_proc.c 2014-05-05 12:49:32.000000000 +0000 +@@ -65,6 +65,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -80,6 +81,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + /* If cn_netlink_send() failed, the data is not sent */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } +@@ -96,6 +98,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -106,6 +109,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -122,6 +126,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + ev->what = which_id; + ev->event_data.id.process_pid = task->pid; + ev->event_data.id.process_tgid = task->tgid; +@@ -145,6 +150,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -160,6 +166,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -170,6 +177,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -185,6 +193,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -203,6 +212,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -218,6 +228,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -229,6 +240,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -244,6 +256,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -254,6 +267,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -269,6 +283,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -281,6 +296,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +@@ -304,6 +320,7 @@ + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; ++ memset(&ev->event_data, 0, sizeof(ev->event_data)); + msg->seq = rcvd_seq; + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); +@@ -313,6 +330,7 @@ + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = rcvd_ack + 1; + msg->len = sizeof(*ev); ++ msg->flags = 0; /* not used */ + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1452_df6ae0dc3145f5d3c0b04a59e64cd647469881e4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1452_df6ae0dc3145f5d3c0b04a59e64cd647469881e4.txt 2014-05-05 12:49:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1453_b15e22da6eb11f54ef53bec9b9e9adbc4fba1609.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1453_b15e22da6eb11f54ef53bec9b9e9adbc4fba1609.patch --- linux-3.10.11/debian/patches/rpi/rpi_1453_b15e22da6eb11f54ef53bec9b9e9adbc4fba1609.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1453_b15e22da6eb11f54ef53bec9b9e9adbc4fba1609.patch 2014-05-05 12:49:33.000000000 +0000 @@ -0,0 +1,37 @@ +commit b15e22da6eb11f54ef53bec9b9e9adbc4fba1609 +Author: Jiri Benc +Date: Fri Oct 4 17:04:48 2013 +0200 + + ipv4: fix ineffective source address selection + + [ Upstream commit 0a7e22609067ff524fc7bbd45c6951dd08561667 ] + + When sending out multicast messages, the source address in inet->mc_addr is + ignored and rewritten by an autoselected one. This is caused by a typo in + commit 813b3b5db831 ("ipv4: Use caller's on-stack flowi as-is in output + route lookups"). + + Signed-off-by: Jiri Benc + Acked-by: Eric Dumazet + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/route.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/route.c 2014-05-05 11:49:18.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/route.c 2014-05-05 12:49:32.000000000 +0000 +@@ -2020,7 +2020,7 @@ + RT_SCOPE_LINK); + goto make_route; + } +- if (fl4->saddr) { ++ if (!fl4->saddr) { + if (ipv4_is_multicast(fl4->daddr)) + fl4->saddr = inet_select_addr(dev_out, 0, + fl4->flowi4_scope); +Index: linux-3.10-3.10.11/dummy/rpi_1453_b15e22da6eb11f54ef53bec9b9e9adbc4fba1609.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1453_b15e22da6eb11f54ef53bec9b9e9adbc4fba1609.txt 2014-05-05 12:49:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1454_42fc155b9fe58a8885b76136ebdb7b5e376740b6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1454_42fc155b9fe58a8885b76136ebdb7b5e376740b6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1454_42fc155b9fe58a8885b76136ebdb7b5e376740b6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1454_42fc155b9fe58a8885b76136ebdb7b5e376740b6.patch 2014-05-05 12:49:34.000000000 +0000 @@ -0,0 +1,45 @@ +commit 42fc155b9fe58a8885b76136ebdb7b5e376740b6 +Author: Marc Kleine-Budde +Date: Sat Oct 5 21:25:17 2013 +0200 + + can: dev: fix nlmsg size calculation in can_get_size() + + [ Upstream commit fe119a05f8ca481623a8d02efcc984332e612528 ] + + This patch fixes the calculation of the nlmsg size, by adding the missing + nla_total_size(). + + Signed-off-by: Marc Kleine-Budde + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/can/dev.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/can/dev.c 2014-05-05 11:49:18.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/can/dev.c 2014-05-05 12:49:33.000000000 +0000 +@@ -705,14 +705,14 @@ + size_t size; + + size = nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ +- size += sizeof(struct can_ctrlmode); /* IFLA_CAN_CTRLMODE */ ++ size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */ + size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ +- size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */ +- size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */ ++ size += nla_total_size(sizeof(struct can_bittiming)); /* IFLA_CAN_BITTIMING */ ++ size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ + if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ +- size += sizeof(struct can_berr_counter); ++ size += nla_total_size(sizeof(struct can_berr_counter)); + if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ +- size += sizeof(struct can_bittiming_const); ++ size += nla_total_size(sizeof(struct can_bittiming_const)); + + return size; + } +Index: linux-3.10-3.10.11/dummy/rpi_1454_42fc155b9fe58a8885b76136ebdb7b5e376740b6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1454_42fc155b9fe58a8885b76136ebdb7b5e376740b6.txt 2014-05-05 12:49:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1455_b9396c4c9e7f499b1dd8080e901c88705f2efa99.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1455_b9396c4c9e7f499b1dd8080e901c88705f2efa99.patch --- linux-3.10.11/debian/patches/rpi/rpi_1455_b9396c4c9e7f499b1dd8080e901c88705f2efa99.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1455_b9396c4c9e7f499b1dd8080e901c88705f2efa99.patch 2014-05-05 12:49:34.000000000 +0000 @@ -0,0 +1,62 @@ +commit b9396c4c9e7f499b1dd8080e901c88705f2efa99 +Author: Fabio Estevam +Date: Sat Oct 5 17:56:59 2013 -0300 + + net: secure_seq: Fix warning when CONFIG_IPV6 and CONFIG_INET are not selected + + [ Upstream commit cb03db9d0e964568407fb08ea46cc2b6b7f67587 ] + + net_secret() is only used when CONFIG_IPV6 or CONFIG_INET are selected. + + Building a defconfig with both of these symbols unselected (Using the ARM + at91sam9rl_defconfig, for example) leads to the following build warning: + + $ make at91sam9rl_defconfig + # + # configuration written to .config + # + + $ make net/core/secure_seq.o + scripts/kconfig/conf --silentoldconfig Kconfig + CHK include/config/kernel.release + CHK include/generated/uapi/linux/version.h + CHK include/generated/utsrelease.h + make[1]: `include/generated/mach-types.h' is up to date. + CALL scripts/checksyscalls.sh + CC net/core/secure_seq.o + net/core/secure_seq.c:17:13: warning: 'net_secret_init' defined but not used [-Wunused-function] + + Fix this warning by protecting the definition of net_secret() with these + symbols. + + Reported-by: Olof Johansson + Signed-off-by: Fabio Estevam + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/core/secure_seq.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/core/secure_seq.c 2014-05-05 12:47:14.000000000 +0000 ++++ linux-3.10-3.10.11/net/core/secure_seq.c 2014-05-05 12:49:34.000000000 +0000 +@@ -10,6 +10,7 @@ + + #include + ++#if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_INET) + #define NET_SECRET_SIZE (MD5_MESSAGE_BYTES / 4) + + static u32 net_secret[NET_SECRET_SIZE] ____cacheline_aligned; +@@ -29,6 +30,7 @@ + cmpxchg(&net_secret[--i], 0, tmp); + } + } ++#endif + + #ifdef CONFIG_INET + static u32 seq_scale(u32 seq) +Index: linux-3.10-3.10.11/dummy/rpi_1455_b9396c4c9e7f499b1dd8080e901c88705f2efa99.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1455_b9396c4c9e7f499b1dd8080e901c88705f2efa99.txt 2014-05-05 12:49:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1456_f495ddc46f97dd0054ff2d5d3c7493d59f7511fb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1456_f495ddc46f97dd0054ff2d5d3c7493d59f7511fb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1456_f495ddc46f97dd0054ff2d5d3c7493d59f7511fb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1456_f495ddc46f97dd0054ff2d5d3c7493d59f7511fb.patch 2014-05-05 12:49:35.000000000 +0000 @@ -0,0 +1,131 @@ +commit f495ddc46f97dd0054ff2d5d3c7493d59f7511fb +Author: Paul Durrant +Date: Tue Oct 8 14:22:56 2013 +0100 + + xen-netback: Don't destroy the netdev until the vif is shut down + + [ upstream commit id: 279f438e36c0a70b23b86d2090aeec50155034a9 ] + + Without this patch, if a frontend cycles through states Closing + and Closed (which Windows frontends need to do) then the netdev + will be destroyed and requires re-invocation of hotplug scripts + to restore state before the frontend can move to Connected. Thus + when udev is not in use the backend gets stuck in InitWait. + + With this patch, the netdev is left alone whilst the backend is + still online and is only de-registered and freed just prior to + destroying the vif (which is also nicely symmetrical with the + netdev allocation and registration being done during probe) so + no re-invocation of hotplug scripts is required. + + Signed-off-by: Paul Durrant + Cc: David Vrabel + Cc: Wei Liu + Cc: Ian Campbell + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/xen-netback/common.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/xen-netback/common.h 2014-05-05 11:49:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/xen-netback/common.h 2014-05-05 12:49:35.000000000 +0000 +@@ -115,6 +115,7 @@ + int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn); + void xenvif_disconnect(struct xenvif *vif); ++void xenvif_free(struct xenvif *vif); + + void xenvif_get(struct xenvif *vif); + void xenvif_put(struct xenvif *vif); +Index: linux-3.10-3.10.11/drivers/net/xen-netback/interface.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/xen-netback/interface.c 2014-05-05 11:49:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/xen-netback/interface.c 2014-05-05 12:49:35.000000000 +0000 +@@ -304,6 +304,9 @@ + } + + netdev_dbg(dev, "Successfully created xenvif\n"); ++ ++ __module_get(THIS_MODULE); ++ + return vif; + } + +@@ -369,9 +372,14 @@ + if (vif->irq) + unbind_from_irqhandler(vif->irq, vif); + +- unregister_netdev(vif->dev); +- + xen_netbk_unmap_frontend_rings(vif); ++} ++ ++void xenvif_free(struct xenvif *vif) ++{ ++ unregister_netdev(vif->dev); + + free_netdev(vif->dev); ++ ++ module_put(THIS_MODULE); + } +Index: linux-3.10-3.10.11/drivers/net/xen-netback/xenbus.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/xen-netback/xenbus.c 2014-05-05 11:49:17.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/xen-netback/xenbus.c 2014-05-05 12:49:35.000000000 +0000 +@@ -42,7 +42,7 @@ + if (be->vif) { + kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); +- xenvif_disconnect(be->vif); ++ xenvif_free(be->vif); + be->vif = NULL; + } + kfree(be); +@@ -203,9 +203,18 @@ + { + struct backend_info *be = dev_get_drvdata(&dev->dev); + ++ if (be->vif) ++ xenvif_disconnect(be->vif); ++} ++ ++static void destroy_backend(struct xenbus_device *dev) ++{ ++ struct backend_info *be = dev_get_drvdata(&dev->dev); ++ + if (be->vif) { ++ kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); +- xenvif_disconnect(be->vif); ++ xenvif_free(be->vif); + be->vif = NULL; + } + } +@@ -237,14 +246,11 @@ + case XenbusStateConnected: + if (dev->state == XenbusStateConnected) + break; +- backend_create_xenvif(be); + if (be->vif) + connect(be); + break; + + case XenbusStateClosing: +- if (be->vif) +- kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + disconnect_backend(dev); + xenbus_switch_state(dev, XenbusStateClosing); + break; +@@ -253,6 +259,7 @@ + xenbus_switch_state(dev, XenbusStateClosed); + if (xenbus_dev_is_online(dev)) + break; ++ destroy_backend(dev); + /* fall through if not online */ + case XenbusStateUnknown: + device_unregister(&dev->dev); +Index: linux-3.10-3.10.11/dummy/rpi_1456_f495ddc46f97dd0054ff2d5d3c7493d59f7511fb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1456_f495ddc46f97dd0054ff2d5d3c7493d59f7511fb.txt 2014-05-05 12:49:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1457_4c1f32d2d776b7d87962e902d62f8b6b2b2e1025.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1457_4c1f32d2d776b7d87962e902d62f8b6b2b2e1025.patch --- linux-3.10.11/debian/patches/rpi/rpi_1457_4c1f32d2d776b7d87962e902d62f8b6b2b2e1025.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1457_4c1f32d2d776b7d87962e902d62f8b6b2b2e1025.patch 2014-05-05 12:49:36.000000000 +0000 @@ -0,0 +1,35 @@ +commit 4c1f32d2d776b7d87962e902d62f8b6b2b2e1025 +Author: Marc Kleine-Budde +Date: Mon Oct 7 23:19:58 2013 +0200 + + net: vlan: fix nlmsg size calculation in vlan_get_size() + + [ Upstream commit c33a39c575068c2ea9bffb22fd6de2df19c74b89 ] + + This patch fixes the calculation of the nlmsg size, by adding the missing + nla_total_size(). + + Cc: Patrick McHardy + Signed-off-by: Marc Kleine-Budde + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/8021q/vlan_netlink.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/8021q/vlan_netlink.c 2014-05-05 11:49:17.000000000 +0000 ++++ linux-3.10-3.10.11/net/8021q/vlan_netlink.c 2014-05-05 12:49:36.000000000 +0000 +@@ -171,7 +171,7 @@ + + return nla_total_size(2) + /* IFLA_VLAN_PROTOCOL */ + nla_total_size(2) + /* IFLA_VLAN_ID */ +- sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */ ++ nla_total_size(sizeof(struct ifla_vlan_flags)) + /* IFLA_VLAN_FLAGS */ + vlan_qos_map_size(vlan->nr_ingress_mappings) + + vlan_qos_map_size(vlan->nr_egress_mappings); + } +Index: linux-3.10-3.10.11/dummy/rpi_1457_4c1f32d2d776b7d87962e902d62f8b6b2b2e1025.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1457_4c1f32d2d776b7d87962e902d62f8b6b2b2e1025.txt 2014-05-05 12:49:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1458_a77db44038f976c2734fb3d2b1ed0cb9c3afde75.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1458_a77db44038f976c2734fb3d2b1ed0cb9c3afde75.patch --- linux-3.10.11/debian/patches/rpi/rpi_1458_a77db44038f976c2734fb3d2b1ed0cb9c3afde75.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1458_a77db44038f976c2734fb3d2b1ed0cb9c3afde75.patch 2014-05-05 12:49:37.000000000 +0000 @@ -0,0 +1,129 @@ +commit a77db44038f976c2734fb3d2b1ed0cb9c3afde75 +Author: Christophe Gouault +Date: Tue Oct 8 17:21:22 2013 +0200 + + vti: get rid of nf mark rule in prerouting + + [ Upstream commit 7263a5187f9e9de45fcb51349cf0e031142c19a1 ] + + This patch fixes and improves the use of vti interfaces (while + lightly changing the way of configuring them). + + Currently: + + - it is necessary to identify and mark inbound IPsec + packets destined to each vti interface, via netfilter rules in + the mangle table at prerouting hook. + + - the vti module cannot retrieve the right tunnel in input since + commit b9959fd3: vti tunnels all have an i_key, but the tunnel lookup + is done with flag TUNNEL_NO_KEY, so there no chance to retrieve them. + + - the i_key is used by the outbound processing as a mark to lookup + for the right SP and SA bundle. + + This patch uses the o_key to store the vti mark (instead of i_key) and + enables: + + - to avoid the need for previously marking the inbound skbuffs via a + netfilter rule. + - to properly retrieve the right tunnel in input, only based on the IPsec + packet outer addresses. + - to properly perform an inbound policy check (using the tunnel o_key + as a mark). + - to properly perform an outbound SPD and SAD lookup (using the tunnel + o_key as a mark). + - to keep the current mark of the skbuff. The skbuff mark is neither + used nor changed by the vti interface. Only the vti interface o_key + is used. + + SAs have a wildcard mark. + SPs have a mark equal to the vti interface o_key. + + The vti interface must be created as follows (i_key = 0, o_key = mark): + + ip link add vti1 mode vti local 1.1.1.1 remote 2.2.2.2 okey 1 + + The SPs attached to vti1 must be created as follows (mark = vti1 o_key): + + ip xfrm policy add dir out mark 1 tmpl src 1.1.1.1 dst 2.2.2.2 \ + proto esp mode tunnel + ip xfrm policy add dir in mark 1 tmpl src 2.2.2.2 dst 1.1.1.1 \ + proto esp mode tunnel + + The SAs are created with the default wildcard mark. There is no + distinction between global vs. vti SAs. Just their addresses will + possibly link them to a vti interface: + + ip xfrm state add src 1.1.1.1 dst 2.2.2.2 proto esp spi 1000 mode tunnel \ + enc "cbc(aes)" "azertyuiopqsdfgh" + + ip xfrm state add src 2.2.2.2 dst 1.1.1.1 proto esp spi 2000 mode tunnel \ + enc "cbc(aes)" "sqbdhgqsdjqjsdfh" + + To avoid matching "global" (not vti) SPs in vti interfaces, global SPs + should no use the default wildcard mark, but explicitly match mark 0. + + To avoid a double SPD lookup in input and output (in global and vti SPDs), + the NOPOLICY and NOXFRM options should be set on the vti interfaces: + + echo 1 > /proc/sys/net/ipv4/conf/vti1/disable_policy + echo 1 > /proc/sys/net/ipv4/conf/vti1/disable_xfrm + + The outgoing traffic is steered to vti1 by a route via the vti interface: + + ip route add 192.168.0.0/16 dev vti1 + + The incoming IPsec traffic is steered to vti1 because its outer addresses + match the vti1 tunnel configuration. + + Signed-off-by: Christophe Gouault + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv4/ip_vti.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ip_vti.c 2014-05-05 11:49:16.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ip_vti.c 2014-05-05 12:49:36.000000000 +0000 +@@ -285,8 +285,17 @@ + tunnel = vti_tunnel_lookup(dev_net(skb->dev), iph->saddr, iph->daddr); + if (tunnel != NULL) { + struct pcpu_tstats *tstats; ++ u32 oldmark = skb->mark; ++ int ret; + +- if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) ++ ++ /* temporarily mark the skb with the tunnel o_key, to ++ * only match policies with this mark. ++ */ ++ skb->mark = be32_to_cpu(tunnel->parms.o_key); ++ ret = xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb); ++ skb->mark = oldmark; ++ if (!ret) + return -1; + + tstats = this_cpu_ptr(tunnel->dev->tstats); +@@ -295,7 +304,6 @@ + tstats->rx_bytes += skb->len; + u64_stats_update_end(&tstats->syncp); + +- skb->mark = 0; + secpath_reset(skb); + skb->dev = tunnel->dev; + return 1; +@@ -327,7 +335,7 @@ + + memset(&fl4, 0, sizeof(fl4)); + flowi4_init_output(&fl4, tunnel->parms.link, +- be32_to_cpu(tunnel->parms.i_key), RT_TOS(tos), ++ be32_to_cpu(tunnel->parms.o_key), RT_TOS(tos), + RT_SCOPE_UNIVERSE, + IPPROTO_IPIP, 0, + dst, tiph->saddr, 0, 0); +Index: linux-3.10-3.10.11/dummy/rpi_1458_a77db44038f976c2734fb3d2b1ed0cb9c3afde75.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1458_a77db44038f976c2734fb3d2b1ed0cb9c3afde75.txt 2014-05-05 12:49:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1459_a41536775e712e7b438400f73e927ffe4b21149c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1459_a41536775e712e7b438400f73e927ffe4b21149c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1459_a41536775e712e7b438400f73e927ffe4b21149c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1459_a41536775e712e7b438400f73e927ffe4b21149c.patch 2014-05-05 12:49:38.000000000 +0000 @@ -0,0 +1,205 @@ +commit a41536775e712e7b438400f73e927ffe4b21149c +Author: Eric Dumazet +Date: Thu Oct 10 06:30:09 2013 -0700 + + l2tp: must disable bh before calling l2tp_xmit_skb() + + [ Upstream commit 455cc32bf128e114455d11ad919321ab89a2c312 ] + + François Cachereul made a very nice bug report and suspected + the bh_lock_sock() / bh_unlok_sock() pair used in l2tp_xmit_skb() from + process context was not good. + + This problem was added by commit 6af88da14ee284aaad6e4326da09a89191ab6165 + ("l2tp: Fix locking in l2tp_core.c"). + + l2tp_eth_dev_xmit() runs from BH context, so we must disable BH + from other l2tp_xmit_skb() users. + + [ 452.060011] BUG: soft lockup - CPU#1 stuck for 23s! [accel-pppd:6662] + [ 452.061757] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core pppoe pppox + ppp_generic slhc ipv6 ext3 mbcache jbd virtio_balloon xfs exportfs dm_mod + virtio_blk ata_generic virtio_net floppy ata_piix libata virtio_pci virtio_ring virtio [last unloaded: scsi_wait_scan] + [ 452.064012] CPU 1 + [ 452.080015] BUG: soft lockup - CPU#2 stuck for 23s! [accel-pppd:6643] + [ 452.080015] CPU 2 + [ 452.080015] + [ 452.080015] Pid: 6643, comm: accel-pppd Not tainted 3.2.46.mini #1 Bochs Bochs + [ 452.080015] RIP: 0010:[] [] do_raw_spin_lock+0x17/0x1f + [ 452.080015] RSP: 0018:ffff88007125fc18 EFLAGS: 00000293 + [ 452.080015] RAX: 000000000000aba9 RBX: ffffffff811d0703 RCX: 0000000000000000 + [ 452.080015] RDX: 00000000000000ab RSI: ffff8800711f6896 RDI: ffff8800745c8110 + [ 452.080015] RBP: ffff88007125fc18 R08: 0000000000000020 R09: 0000000000000000 + [ 452.080015] R10: 0000000000000000 R11: 0000000000000280 R12: 0000000000000286 + [ 452.080015] R13: 0000000000000020 R14: 0000000000000240 R15: 0000000000000000 + [ 452.080015] FS: 00007fdc0cc24700(0000) GS:ffff8800b6f00000(0000) knlGS:0000000000000000 + [ 452.080015] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [ 452.080015] CR2: 00007fdb054899b8 CR3: 0000000074404000 CR4: 00000000000006a0 + [ 452.080015] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + [ 452.080015] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + [ 452.080015] Process accel-pppd (pid: 6643, threadinfo ffff88007125e000, task ffff8800b27e6dd0) + [ 452.080015] Stack: + [ 452.080015] ffff88007125fc28 ffffffff81256559 ffff88007125fc98 ffffffffa01b2bd1 + [ 452.080015] ffff88007125fc58 000000000000000c 00000000029490d0 0000009c71dbe25e + [ 452.080015] 000000000000005c 000000080000000e 0000000000000000 ffff880071170600 + [ 452.080015] Call Trace: + [ 452.080015] [] _raw_spin_lock+0xe/0x10 + [ 452.080015] [] l2tp_xmit_skb+0x189/0x4ac [l2tp_core] + [ 452.080015] [] pppol2tp_sendmsg+0x15e/0x19c [l2tp_ppp] + [ 452.080015] [] __sock_sendmsg_nosec+0x22/0x24 + [ 452.080015] [] sock_sendmsg+0xa1/0xb6 + [ 452.080015] [] ? __schedule+0x5c1/0x616 + [ 452.080015] [] ? __dequeue_signal+0xb7/0x10c + [ 452.080015] [] ? fget_light+0x75/0x89 + [ 452.080015] [] ? sockfd_lookup_light+0x20/0x56 + [ 452.080015] [] sys_sendto+0x10c/0x13b + [ 452.080015] [] system_call_fastpath+0x16/0x1b + [ 452.080015] Code: 81 48 89 e5 72 0c 31 c0 48 81 ff 45 66 25 81 0f 92 c0 5d c3 55 b8 00 01 00 00 48 89 e5 f0 66 0f c1 07 0f b6 d4 38 d0 74 06 f3 90 <8a> 07 eb f6 5d c3 90 90 55 48 89 e5 9c 58 0f 1f 44 00 00 5d c3 + [ 452.080015] Call Trace: + [ 452.080015] [] _raw_spin_lock+0xe/0x10 + [ 452.080015] [] l2tp_xmit_skb+0x189/0x4ac [l2tp_core] + [ 452.080015] [] pppol2tp_sendmsg+0x15e/0x19c [l2tp_ppp] + [ 452.080015] [] __sock_sendmsg_nosec+0x22/0x24 + [ 452.080015] [] sock_sendmsg+0xa1/0xb6 + [ 452.080015] [] ? __schedule+0x5c1/0x616 + [ 452.080015] [] ? __dequeue_signal+0xb7/0x10c + [ 452.080015] [] ? fget_light+0x75/0x89 + [ 452.080015] [] ? sockfd_lookup_light+0x20/0x56 + [ 452.080015] [] sys_sendto+0x10c/0x13b + [ 452.080015] [] system_call_fastpath+0x16/0x1b + [ 452.064012] + [ 452.064012] Pid: 6662, comm: accel-pppd Not tainted 3.2.46.mini #1 Bochs Bochs + [ 452.064012] RIP: 0010:[] [] do_raw_spin_lock+0x19/0x1f + [ 452.064012] RSP: 0018:ffff8800b6e83ba0 EFLAGS: 00000297 + [ 452.064012] RAX: 000000000000aaa9 RBX: ffff8800b6e83b40 RCX: 0000000000000002 + [ 452.064012] RDX: 00000000000000aa RSI: 000000000000000a RDI: ffff8800745c8110 + [ 452.064012] RBP: ffff8800b6e83ba0 R08: 000000000000c802 R09: 000000000000001c + [ 452.064012] R10: ffff880071096c4e R11: 0000000000000006 R12: ffff8800b6e83b18 + [ 452.064012] R13: ffffffff8125d51e R14: ffff8800b6e83ba0 R15: ffff880072a589c0 + [ 452.064012] FS: 00007fdc0b81e700(0000) GS:ffff8800b6e80000(0000) knlGS:0000000000000000 + [ 452.064012] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [ 452.064012] CR2: 0000000000625208 CR3: 0000000074404000 CR4: 00000000000006a0 + [ 452.064012] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + [ 452.064012] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + [ 452.064012] Process accel-pppd (pid: 6662, threadinfo ffff88007129a000, task ffff8800744f7410) + [ 452.064012] Stack: + [ 452.064012] ffff8800b6e83bb0 ffffffff81256559 ffff8800b6e83bc0 ffffffff8121c64a + [ 452.064012] ffff8800b6e83bf0 ffffffff8121ec7a ffff880072a589c0 ffff880071096c62 + [ 452.064012] 0000000000000011 ffffffff81430024 ffff8800b6e83c80 ffffffff8121f276 + [ 452.064012] Call Trace: + [ 452.064012] + [ 452.064012] [] _raw_spin_lock+0xe/0x10 + [ 452.064012] [] spin_lock+0x9/0xb + [ 452.064012] [] udp_queue_rcv_skb+0x186/0x269 + [ 452.064012] [] __udp4_lib_rcv+0x297/0x4ae + [ 452.064012] [] ? raw_rcv+0xe9/0xf0 + [ 452.064012] [] udp_rcv+0x1a/0x1c + [ 452.064012] [] ip_local_deliver_finish+0x12b/0x1a5 + [ 452.064012] [] ip_local_deliver+0x53/0x84 + [ 452.064012] [] ip_rcv_finish+0x2bc/0x2f3 + [ 452.064012] [] ip_rcv+0x210/0x269 + [ 452.064012] [] ? kvm_clock_get_cycles+0x9/0xb + [ 452.064012] [] __netif_receive_skb+0x3a5/0x3f7 + [ 452.064012] [] netif_receive_skb+0x57/0x5e + [ 452.064012] [] ? __netdev_alloc_skb+0x1f/0x3b + [ 452.064012] [] virtnet_poll+0x4ba/0x5a4 [virtio_net] + [ 452.064012] [] net_rx_action+0x73/0x184 + [ 452.064012] [] ? l2tp_xmit_skb+0x27a/0x4ac [l2tp_core] + [ 452.064012] [] __do_softirq+0xc3/0x1a8 + [ 452.064012] [] ? ack_APIC_irq+0x10/0x12 + [ 452.064012] [] ? _raw_spin_lock+0xe/0x10 + [ 452.064012] [] call_softirq+0x1c/0x26 + [ 452.064012] [] do_softirq+0x45/0x82 + [ 452.064012] [] irq_exit+0x42/0x9c + [ 452.064012] [] do_IRQ+0x8e/0xa5 + [ 452.064012] [] common_interrupt+0x6e/0x6e + [ 452.064012] + [ 452.064012] [] ? kfree+0x8a/0xa3 + [ 452.064012] [] ? l2tp_xmit_skb+0x27a/0x4ac [l2tp_core] + [ 452.064012] [] ? l2tp_xmit_skb+0x1dd/0x4ac [l2tp_core] + [ 452.064012] [] pppol2tp_sendmsg+0x15e/0x19c [l2tp_ppp] + [ 452.064012] [] __sock_sendmsg_nosec+0x22/0x24 + [ 452.064012] [] sock_sendmsg+0xa1/0xb6 + [ 452.064012] [] ? __schedule+0x5c1/0x616 + [ 452.064012] [] ? __dequeue_signal+0xb7/0x10c + [ 452.064012] [] ? fget_light+0x75/0x89 + [ 452.064012] [] ? sockfd_lookup_light+0x20/0x56 + [ 452.064012] [] sys_sendto+0x10c/0x13b + [ 452.064012] [] system_call_fastpath+0x16/0x1b + [ 452.064012] Code: 89 e5 72 0c 31 c0 48 81 ff 45 66 25 81 0f 92 c0 5d c3 55 b8 00 01 00 00 48 89 e5 f0 66 0f c1 07 0f b6 d4 38 d0 74 06 f3 90 8a 07 f6 5d c3 90 90 55 48 89 e5 9c 58 0f 1f 44 00 00 5d c3 55 48 + [ 452.064012] Call Trace: + [ 452.064012] [] _raw_spin_lock+0xe/0x10 + [ 452.064012] [] spin_lock+0x9/0xb + [ 452.064012] [] udp_queue_rcv_skb+0x186/0x269 + [ 452.064012] [] __udp4_lib_rcv+0x297/0x4ae + [ 452.064012] [] ? raw_rcv+0xe9/0xf0 + [ 452.064012] [] udp_rcv+0x1a/0x1c + [ 452.064012] [] ip_local_deliver_finish+0x12b/0x1a5 + [ 452.064012] [] ip_local_deliver+0x53/0x84 + [ 452.064012] [] ip_rcv_finish+0x2bc/0x2f3 + [ 452.064012] [] ip_rcv+0x210/0x269 + [ 452.064012] [] ? kvm_clock_get_cycles+0x9/0xb + [ 452.064012] [] __netif_receive_skb+0x3a5/0x3f7 + [ 452.064012] [] netif_receive_skb+0x57/0x5e + [ 452.064012] [] ? __netdev_alloc_skb+0x1f/0x3b + [ 452.064012] [] virtnet_poll+0x4ba/0x5a4 [virtio_net] + [ 452.064012] [] net_rx_action+0x73/0x184 + [ 452.064012] [] ? l2tp_xmit_skb+0x27a/0x4ac [l2tp_core] + [ 452.064012] [] __do_softirq+0xc3/0x1a8 + [ 452.064012] [] ? ack_APIC_irq+0x10/0x12 + [ 452.064012] [] ? _raw_spin_lock+0xe/0x10 + [ 452.064012] [] call_softirq+0x1c/0x26 + [ 452.064012] [] do_softirq+0x45/0x82 + [ 452.064012] [] irq_exit+0x42/0x9c + [ 452.064012] [] do_IRQ+0x8e/0xa5 + [ 452.064012] [] common_interrupt+0x6e/0x6e + [ 452.064012] [] ? kfree+0x8a/0xa3 + [ 452.064012] [] ? l2tp_xmit_skb+0x27a/0x4ac [l2tp_core] + [ 452.064012] [] ? l2tp_xmit_skb+0x1dd/0x4ac [l2tp_core] + [ 452.064012] [] pppol2tp_sendmsg+0x15e/0x19c [l2tp_ppp] + [ 452.064012] [] __sock_sendmsg_nosec+0x22/0x24 + [ 452.064012] [] sock_sendmsg+0xa1/0xb6 + [ 452.064012] [] ? __schedule+0x5c1/0x616 + [ 452.064012] [] ? __dequeue_signal+0xb7/0x10c + [ 452.064012] [] ? fget_light+0x75/0x89 + [ 452.064012] [] ? sockfd_lookup_light+0x20/0x56 + [ 452.064012] [] sys_sendto+0x10c/0x13b + [ 452.064012] [] system_call_fastpath+0x16/0x1b + + Reported-by: François Cachereul + Tested-by: François Cachereul + Signed-off-by: Eric Dumazet + Cc: James Chapman + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/l2tp/l2tp_ppp.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/l2tp/l2tp_ppp.c 2014-05-05 11:49:16.000000000 +0000 ++++ linux-3.10-3.10.11/net/l2tp/l2tp_ppp.c 2014-05-05 12:49:37.000000000 +0000 +@@ -353,7 +353,9 @@ + goto error_put_sess_tun; + } + ++ local_bh_disable(); + l2tp_xmit_skb(session, skb, session->hdr_len); ++ local_bh_enable(); + + sock_put(ps->tunnel_sock); + sock_put(sk); +@@ -422,7 +424,9 @@ + skb->data[0] = ppph[0]; + skb->data[1] = ppph[1]; + ++ local_bh_disable(); + l2tp_xmit_skb(session, skb, session->hdr_len); ++ local_bh_enable(); + + sock_put(sk_tun); + sock_put(sk); +Index: linux-3.10-3.10.11/dummy/rpi_1459_a41536775e712e7b438400f73e927ffe4b21149c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1459_a41536775e712e7b438400f73e927ffe4b21149c.txt 2014-05-05 12:49:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1460_3a26736015acfc8745db623efa7f57bc982ed516.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1460_3a26736015acfc8745db623efa7f57bc982ed516.patch --- linux-3.10.11/debian/patches/rpi/rpi_1460_3a26736015acfc8745db623efa7f57bc982ed516.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1460_3a26736015acfc8745db623efa7f57bc982ed516.patch 2014-05-05 12:49:39.000000000 +0000 @@ -0,0 +1,34 @@ +commit 3a26736015acfc8745db623efa7f57bc982ed516 +Author: Salva Peiró +Date: Fri Oct 11 12:50:03 2013 +0300 + + farsync: fix info leak in ioctl + + [ Upstream commit 96b340406724d87e4621284ebac5e059d67b2194 ] + + The fst_get_iface() code fails to initialize the two padding bytes of + struct sync_serial_settings after the ->loopback member. Add an explicit + memset(0) before filling the structure to avoid the info leak. + + Signed-off-by: Dan Carpenter + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wan/farsync.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wan/farsync.c 2014-05-05 11:49:16.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wan/farsync.c 2014-05-05 12:49:38.000000000 +0000 +@@ -1972,6 +1972,7 @@ + } + + i = port->index; ++ memset(&sync, 0, sizeof(sync)); + sync.clock_rate = FST_RDL(card, portConfig[i].lineSpeed); + /* Lucky card and linux use same encoding here */ + sync.clock_type = FST_RDB(card, portConfig[i].internalClock) == +Index: linux-3.10-3.10.11/dummy/rpi_1460_3a26736015acfc8745db623efa7f57bc982ed516.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1460_3a26736015acfc8745db623efa7f57bc982ed516.txt 2014-05-05 12:49:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1461_39283085a92262f9446b95d36df9724902b7579a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1461_39283085a92262f9446b95d36df9724902b7579a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1461_39283085a92262f9446b95d36df9724902b7579a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1461_39283085a92262f9446b95d36df9724902b7579a.patch 2014-05-05 12:49:39.000000000 +0000 @@ -0,0 +1,34 @@ +commit 39283085a92262f9446b95d36df9724902b7579a +Author: Mathias Krause +Date: Mon Sep 30 22:05:40 2013 +0200 + + unix_diag: fix info leak + + [ Upstream commit 6865d1e834be84ddd5808d93d5035b492346c64a ] + + When filling the netlink message we miss to wipe the pad field, + therefore leak one byte of heap memory to userland. Fix this by + setting pad to 0. + + Signed-off-by: Mathias Krause + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/unix/diag.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/unix/diag.c 2014-05-05 11:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/net/unix/diag.c 2014-05-05 12:49:39.000000000 +0000 +@@ -124,6 +124,7 @@ + rep->udiag_family = AF_UNIX; + rep->udiag_type = sk->sk_type; + rep->udiag_state = sk->sk_state; ++ rep->pad = 0; + rep->udiag_ino = sk_ino; + sock_diag_save_cookie(sk, rep->udiag_cookie); + +Index: linux-3.10-3.10.11/dummy/rpi_1461_39283085a92262f9446b95d36df9724902b7579a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1461_39283085a92262f9446b95d36df9724902b7579a.txt 2014-05-05 12:49:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1462_69b9c5ea567e5c9b202b3e5bcac3c2eb72270e0b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1462_69b9c5ea567e5c9b202b3e5bcac3c2eb72270e0b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1462_69b9c5ea567e5c9b202b3e5bcac3c2eb72270e0b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1462_69b9c5ea567e5c9b202b3e5bcac3c2eb72270e0b.patch 2014-05-05 12:49:40.000000000 +0000 @@ -0,0 +1,49 @@ +commit 69b9c5ea567e5c9b202b3e5bcac3c2eb72270e0b +Author: Mathias Krause +Date: Mon Sep 30 22:03:07 2013 +0200 + + connector: use nlmsg_len() to check message length + + [ Upstream commit 162b2bedc084d2d908a04c93383ba02348b648b0 ] + + The current code tests the length of the whole netlink message to be + at least as long to fit a cn_msg. This is wrong as nlmsg_len includes + the length of the netlink message header. Use nlmsg_len() instead to + fix this "off-by-NLMSG_HDRLEN" size check. + + Signed-off-by: Mathias Krause + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/connector/connector.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/connector/connector.c 2014-05-05 11:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/connector/connector.c 2014-05-05 12:49:40.000000000 +0000 +@@ -157,17 +157,18 @@ + static void cn_rx_skb(struct sk_buff *__skb) + { + struct nlmsghdr *nlh; +- int err; + struct sk_buff *skb; ++ int len, err; + + skb = skb_get(__skb); + + if (skb->len >= NLMSG_HDRLEN) { + nlh = nlmsg_hdr(skb); ++ len = nlmsg_len(nlh); + +- if (nlh->nlmsg_len < sizeof(struct cn_msg) || ++ if (len < (int)sizeof(struct cn_msg) || + skb->len < nlh->nlmsg_len || +- nlh->nlmsg_len > CONNECTOR_MAX_MSG_SIZE) { ++ len > CONNECTOR_MAX_MSG_SIZE) { + kfree_skb(skb); + return; + } +Index: linux-3.10-3.10.11/dummy/rpi_1462_69b9c5ea567e5c9b202b3e5bcac3c2eb72270e0b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1462_69b9c5ea567e5c9b202b3e5bcac3c2eb72270e0b.txt 2014-05-05 12:49:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1463_608be70366c3abaa402ba9d6a8427b1b979633cf.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1463_608be70366c3abaa402ba9d6a8427b1b979633cf.patch --- linux-3.10.11/debian/patches/rpi/rpi_1463_608be70366c3abaa402ba9d6a8427b1b979633cf.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1463_608be70366c3abaa402ba9d6a8427b1b979633cf.patch 2014-05-05 12:49:41.000000000 +0000 @@ -0,0 +1,54 @@ +commit 608be70366c3abaa402ba9d6a8427b1b979633cf +Author: Eric Dumazet +Date: Sat Oct 12 14:08:34 2013 -0700 + + bnx2x: record rx queue for LRO packets + + [ Upstream commit 60e66fee56b2256dcb1dc2ea1b2ddcb6e273857d ] + + RPS support is kind of broken on bnx2x, because only non LRO packets + get proper rx queue information. This triggers reorders, as it seems + bnx2x like to generate a non LRO packet for segment including TCP PUSH + flag : (this might be pure coincidence, but all the reorders I've + seen involve segments with a PUSH) + + 11:13:34.335847 IP A > B: . 415808:447136(31328) ack 1 win 457 + 11:13:34.335992 IP A > B: . 447136:448560(1424) ack 1 win 457 + 11:13:34.336391 IP A > B: . 448560:479888(31328) ack 1 win 457 + 11:13:34.336425 IP A > B: P 511216:512640(1424) ack 1 win 457 + 11:13:34.336423 IP A > B: . 479888:511216(31328) ack 1 win 457 + 11:13:34.336924 IP A > B: . 512640:543968(31328) ack 1 win 457 + 11:13:34.336963 IP A > B: . 543968:575296(31328) ack 1 win 457 + + We must call skb_record_rx_queue() to properly give to RPS (and more + generally for TX queue selection on forward path) the receive queue + information. + + Similar fix is needed for skb_mark_napi_id(), but will be handled + in a separate patch to ease stable backports. + + Signed-off-by: Eric Dumazet + Cc: Willem de Bruijn + Cc: Eilon Greenstein + Acked-by: Dmitry Kravkov + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c 2014-05-05 11:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c 2014-05-05 12:49:41.000000000 +0000 +@@ -670,6 +670,7 @@ + } + } + #endif ++ skb_record_rx_queue(skb, fp->rx_queue); + napi_gro_receive(&fp->napi, skb); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1463_608be70366c3abaa402ba9d6a8427b1b979633cf.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1463_608be70366c3abaa402ba9d6a8427b1b979633cf.txt 2014-05-05 12:49:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1464_f02721718c7dcd4cb949fb0c0689e19a66c8c6ef.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1464_f02721718c7dcd4cb949fb0c0689e19a66c8c6ef.patch --- linux-3.10.11/debian/patches/rpi/rpi_1464_f02721718c7dcd4cb949fb0c0689e19a66c8c6ef.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1464_f02721718c7dcd4cb949fb0c0689e19a66c8c6ef.patch 2014-05-05 12:49:42.000000000 +0000 @@ -0,0 +1,60 @@ +commit f02721718c7dcd4cb949fb0c0689e19a66c8c6ef +Author: Jason Wang +Date: Tue Oct 15 11:18:58 2013 +0800 + + virtio-net: don't respond to cpu hotplug notifier if we're not ready + + [ Upstream commit 3ab098df35f8b98b6553edc2e40234af512ba877 ] + + We're trying to re-configure the affinity unconditionally in cpu hotplug + callback. This may lead the issue during resuming from s3/s4 since + + - virt queues haven't been allocated at that time. + - it's unnecessary since thaw method will re-configure the affinity. + + Fix this issue by checking the config_enable and do nothing is we're not ready. + + The bug were introduced by commit 8de4b2f3ae90c8fc0f17eeaab87d5a951b66ee17 + (virtio-net: reset virtqueue affinity when doing cpu hotplug). + + Acked-by: Michael S. Tsirkin + Cc: Rusty Russell + Cc: Michael S. Tsirkin + Cc: Wanlong Gao + Reviewed-by: Wanlong Gao + Signed-off-by: Jason Wang + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/virtio_net.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/virtio_net.c 2014-05-05 11:49:15.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/virtio_net.c 2014-05-05 12:49:41.000000000 +0000 +@@ -1097,6 +1097,11 @@ + { + struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb); + ++ mutex_lock(&vi->config_lock); ++ ++ if (!vi->config_enable) ++ goto done; ++ + switch(action & ~CPU_TASKS_FROZEN) { + case CPU_ONLINE: + case CPU_DOWN_FAILED: +@@ -1109,6 +1114,9 @@ + default: + break; + } ++ ++done: ++ mutex_unlock(&vi->config_lock); + return NOTIFY_OK; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1464_f02721718c7dcd4cb949fb0c0689e19a66c8c6ef.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1464_f02721718c7dcd4cb949fb0c0689e19a66c8c6ef.txt 2014-05-05 12:49:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1465_413054e740f1efb2cb765323bc73ad01f986c4e1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1465_413054e740f1efb2cb765323bc73ad01f986c4e1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1465_413054e740f1efb2cb765323bc73ad01f986c4e1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1465_413054e740f1efb2cb765323bc73ad01f986c4e1.patch 2014-05-05 12:49:43.000000000 +0000 @@ -0,0 +1,59 @@ +commit 413054e740f1efb2cb765323bc73ad01f986c4e1 +Author: Jason Wang +Date: Thu Jul 4 11:22:57 2013 +0930 + + virtio-net: fix the race between channels setting and refill + + [ Upstream commit 9b9cd8024a2882e896c65222aa421d461354e3f2 ] + + Commit 55257d72bd1c51f25106350f4983ec19f62ed1fa (virtio-net: fill only rx queues + which are being used) tries to refill on demand when changing the number of + channels by call try_refill_recv() directly, this may race: + + - the refill work who may do the refill in the same time + - the try_refill_recv() called in bh since napi was not disabled + + Which may led guest complain during setting channels: + + virtio_net virtio0: input.1:id 0 is not a head! + + Solve this issue by scheduling a refill work which can guarantee the + serialization of refill. + + Signed-off-by: Jason Wang + Cc: Sasha Levin + Cc: Rusty Russell + Cc: Michael S. Tsirkin + Signed-off-by: Rusty Russell + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/virtio_net.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/virtio_net.c 2014-05-05 12:49:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/virtio_net.c 2014-05-05 12:49:43.000000000 +0000 +@@ -902,7 +902,6 @@ + struct scatterlist sg; + struct virtio_net_ctrl_mq s; + struct net_device *dev = vi->dev; +- int i; + + if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ)) + return 0; +@@ -916,10 +915,8 @@ + queue_pairs); + return -EINVAL; + } else { +- for (i = vi->curr_queue_pairs; i < queue_pairs; i++) +- if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) +- schedule_delayed_work(&vi->refill, 0); + vi->curr_queue_pairs = queue_pairs; ++ schedule_delayed_work(&vi->refill, 0); + } + + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1465_413054e740f1efb2cb765323bc73ad01f986c4e1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1465_413054e740f1efb2cb765323bc73ad01f986c4e1.txt 2014-05-05 12:49:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1466_30983d3c66572348f078fe2e2d55638d73c3e486.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1466_30983d3c66572348f078fe2e2d55638d73c3e486.patch --- linux-3.10.11/debian/patches/rpi/rpi_1466_30983d3c66572348f078fe2e2d55638d73c3e486.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1466_30983d3c66572348f078fe2e2d55638d73c3e486.patch 2014-05-05 12:49:44.000000000 +0000 @@ -0,0 +1,54 @@ +commit 30983d3c66572348f078fe2e2d55638d73c3e486 +Author: Jason Wang +Date: Tue Oct 15 11:18:59 2013 +0800 + + virtio-net: refill only when device is up during setting queues + + [ Upstream commit 35ed159bfd96a7547ec277ed8b550c7cbd9841b6 ] + + We used to schedule the refill work unconditionally after changing the + number of queues. This may lead an issue if the device is not + up. Since we only try to cancel the work in ndo_stop(), this may cause + the refill work still work after removing the device. Fix this by only + schedule the work when device is up. + + The bug were introduce by commit 9b9cd8024a2882e896c65222aa421d461354e3f2. + (virtio-net: fix the race between channels setting and refill) + + Signed-off-by: Jason Wang + Cc: Rusty Russell + Cc: Michael S. Tsirkin + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/virtio_net.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/virtio_net.c 2014-05-05 12:49:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/virtio_net.c 2014-05-05 12:49:44.000000000 +0000 +@@ -916,7 +916,9 @@ + return -EINVAL; + } else { + vi->curr_queue_pairs = queue_pairs; +- schedule_delayed_work(&vi->refill, 0); ++ /* virtnet_open() will refill when device is going to up. */ ++ if (dev->flags & IFF_UP) ++ schedule_delayed_work(&vi->refill, 0); + } + + return 0; +@@ -1714,7 +1716,9 @@ + vi->config_enable = true; + mutex_unlock(&vi->config_lock); + ++ rtnl_lock(); + virtnet_set_queues(vi, vi->curr_queue_pairs); ++ rtnl_unlock(); + + return 0; + } +Index: linux-3.10-3.10.11/dummy/rpi_1466_30983d3c66572348f078fe2e2d55638d73c3e486.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1466_30983d3c66572348f078fe2e2d55638d73c3e486.txt 2014-05-05 12:49:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1467_d14db2327635ac00aa7332bf26759d13ff39e2a5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1467_d14db2327635ac00aa7332bf26759d13ff39e2a5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1467_d14db2327635ac00aa7332bf26759d13ff39e2a5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1467_d14db2327635ac00aa7332bf26759d13ff39e2a5.patch 2014-05-05 12:49:45.000000000 +0000 @@ -0,0 +1,43 @@ +commit d14db2327635ac00aa7332bf26759d13ff39e2a5 +Author: Vlad Yasevich +Date: Tue Oct 15 14:57:45 2013 -0400 + + bridge: Correctly clamp MAX forward_delay when enabling STP + + [ Upstream commit 4b6c7879d84ad06a2ac5b964808ed599187a188d ] + + Commit be4f154d5ef0ca147ab6bcd38857a774133f5450 + bridge: Clamp forward_delay when enabling STP + had a typo when attempting to clamp maximum forward delay. + + It is possible to set bridge_forward_delay to be higher then + permitted maximum when STP is off. When turning STP on, the + higher then allowed delay has to be clamed down to max value. + + Signed-off-by: Vlad Yasevich + CC: Herbert Xu + CC: Stephen Hemminger + Reviewed-by: Veaceslav Falico + Acked-by: Herbert Xu + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/bridge/br_stp_if.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/bridge/br_stp_if.c 2014-05-05 12:47:04.000000000 +0000 ++++ linux-3.10-3.10.11/net/bridge/br_stp_if.c 2014-05-05 12:49:44.000000000 +0000 +@@ -134,7 +134,7 @@ + + if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) + __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); +- else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY) ++ else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY) + __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); + + if (r == 0) { +Index: linux-3.10-3.10.11/dummy/rpi_1467_d14db2327635ac00aa7332bf26759d13ff39e2a5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1467_d14db2327635ac00aa7332bf26759d13ff39e2a5.txt 2014-05-05 12:49:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1468_c9446ff691aca0ca902f31f7a9830ac725841759.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1468_c9446ff691aca0ca902f31f7a9830ac725841759.patch --- linux-3.10.11/debian/patches/rpi/rpi_1468_c9446ff691aca0ca902f31f7a9830ac725841759.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1468_c9446ff691aca0ca902f31f7a9830ac725841759.patch 2014-05-05 12:49:46.000000000 +0000 @@ -0,0 +1,49 @@ +commit c9446ff691aca0ca902f31f7a9830ac725841759 +Author: Vlad Yasevich +Date: Tue Oct 15 22:01:29 2013 -0400 + + net: dst: provide accessor function to dst->xfrm + + [ Upstream commit e87b3998d795123b4139bc3f25490dd236f68212 ] + + dst->xfrm is conditionally defined. Provide accessor funtion that + is always available. + + Signed-off-by: Vlad Yasevich + Acked-by: Neil Horman + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/dst.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/dst.h 2014-05-05 11:49:13.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/dst.h 2014-05-05 12:49:45.000000000 +0000 +@@ -477,10 +477,22 @@ + { + return dst_orig; + } ++ ++static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) ++{ ++ return NULL; ++} ++ + #else + extern struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, + const struct flowi *fl, struct sock *sk, + int flags); ++ ++/* skb attached with this dst needs transformation if dst->xfrm is valid */ ++static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) ++{ ++ return dst->xfrm; ++} + #endif + + #endif /* _NET_DST_H */ +Index: linux-3.10-3.10.11/dummy/rpi_1468_c9446ff691aca0ca902f31f7a9830ac725841759.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1468_c9446ff691aca0ca902f31f7a9830ac725841759.txt 2014-05-05 12:49:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1469_935be1dc2cafe04f1421e236f75d17878920631b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1469_935be1dc2cafe04f1421e236f75d17878920631b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1469_935be1dc2cafe04f1421e236f75d17878920631b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1469_935be1dc2cafe04f1421e236f75d17878920631b.patch 2014-05-05 12:49:46.000000000 +0000 @@ -0,0 +1,42 @@ +commit 935be1dc2cafe04f1421e236f75d17878920631b +Author: Fan Du +Date: Tue Oct 15 22:01:30 2013 -0400 + + sctp: Use software crc32 checksum when xfrm transform will happen. + + [ Upstream commit 27127a82561a2a3ed955ce207048e1b066a80a2a ] + + igb/ixgbe have hardware sctp checksum support, when this feature is enabled + and also IPsec is armed to protect sctp traffic, ugly things happened as + xfrm_output checks CHECKSUM_PARTIAL to do checksum operation(sum every thing + up and pack the 16bits result in the checksum field). The result is fail + establishment of sctp communication. + + Signed-off-by: Fan Du + Cc: Neil Horman + Cc: Steffen Klassert + Signed-off-by: Vlad Yasevich + Acked-by: Neil Horman + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sctp/output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sctp/output.c 2014-05-05 11:49:13.000000000 +0000 ++++ linux-3.10-3.10.11/net/sctp/output.c 2014-05-05 12:49:46.000000000 +0000 +@@ -547,7 +547,8 @@ + * by CRC32-C as described in . + */ + if (!sctp_checksum_disable) { +- if (!(dst->dev->features & NETIF_F_SCTP_CSUM)) { ++ if (!(dst->dev->features & NETIF_F_SCTP_CSUM) || ++ (dst_xfrm(dst) != NULL)) { + __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); + + /* 3) Put the resultant value into the checksum field in the +Index: linux-3.10-3.10.11/dummy/rpi_1469_935be1dc2cafe04f1421e236f75d17878920631b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1469_935be1dc2cafe04f1421e236f75d17878920631b.txt 2014-05-05 12:49:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1470_c69ee66768490b30127bc496921a3603c9366a10.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1470_c69ee66768490b30127bc496921a3603c9366a10.patch --- linux-3.10.11/debian/patches/rpi/rpi_1470_c69ee66768490b30127bc496921a3603c9366a10.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1470_c69ee66768490b30127bc496921a3603c9366a10.patch 2014-05-05 12:49:47.000000000 +0000 @@ -0,0 +1,41 @@ +commit c69ee66768490b30127bc496921a3603c9366a10 +Author: Vlad Yasevich +Date: Tue Oct 15 22:01:31 2013 -0400 + + sctp: Perform software checksum if packet has to be fragmented. + + [ Upstream commit d2dbbba77e95dff4b4f901fee236fef6d9552072 ] + + IP/IPv6 fragmentation knows how to compute only TCP/UDP checksum. + This causes problems if SCTP packets has to be fragmented and + ipsummed has been set to PARTIAL due to checksum offload support. + This condition can happen when retransmitting after MTU discover, + or when INIT or other control chunks are larger then MTU. + Check for the rare fragmentation condition in SCTP and use software + checksum calculation in this case. + + CC: Fan Du + Signed-off-by: Vlad Yasevich + Acked-by: Neil Horman + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/sctp/output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/sctp/output.c 2014-05-05 12:49:46.000000000 +0000 ++++ linux-3.10-3.10.11/net/sctp/output.c 2014-05-05 12:49:47.000000000 +0000 +@@ -548,7 +548,7 @@ + */ + if (!sctp_checksum_disable) { + if (!(dst->dev->features & NETIF_F_SCTP_CSUM) || +- (dst_xfrm(dst) != NULL)) { ++ (dst_xfrm(dst) != NULL) || packet->ipfragok) { + __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); + + /* 3) Put the resultant value into the checksum field in the +Index: linux-3.10-3.10.11/dummy/rpi_1470_c69ee66768490b30127bc496921a3603c9366a10.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1470_c69ee66768490b30127bc496921a3603c9366a10.txt 2014-05-05 12:49:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1471_8ffb77d881734108a750acb7fb2625643f924bc5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1471_8ffb77d881734108a750acb7fb2625643f924bc5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1471_8ffb77d881734108a750acb7fb2625643f924bc5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1471_8ffb77d881734108a750acb7fb2625643f924bc5.patch 2014-05-05 12:49:48.000000000 +0000 @@ -0,0 +1,34 @@ +commit 8ffb77d881734108a750acb7fb2625643f924bc5 +Author: Salva Peiró +Date: Wed Oct 16 12:46:50 2013 +0200 + + wanxl: fix info leak in ioctl + + [ Upstream commit 2b13d06c9584b4eb773f1e80bbaedab9a1c344e1 ] + + The wanxl_ioctl() code fails to initialize the two padding bytes of + struct sync_serial_settings after the ->loopback member. Add an explicit + memset(0) before filling the structure to avoid the info leak. + + Signed-off-by: Salva Peiró + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wan/wanxl.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wan/wanxl.c 2014-05-05 11:49:12.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wan/wanxl.c 2014-05-05 12:49:47.000000000 +0000 +@@ -355,6 +355,7 @@ + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } ++ memset(&line, 0, sizeof(line)); + line.clock_type = get_status(port)->clocking; + line.clock_rate = 0; + line.loopback = 0; +Index: linux-3.10-3.10.11/dummy/rpi_1471_8ffb77d881734108a750acb7fb2625643f924bc5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1471_8ffb77d881734108a750acb7fb2625643f924bc5.txt 2014-05-05 12:49:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1472_a8410b48a2d992411a8befbab05de5e886b4ac3e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1472_a8410b48a2d992411a8befbab05de5e886b4ac3e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1472_a8410b48a2d992411a8befbab05de5e886b4ac3e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1472_a8410b48a2d992411a8befbab05de5e886b4ac3e.patch 2014-05-05 12:49:49.000000000 +0000 @@ -0,0 +1,44 @@ +commit a8410b48a2d992411a8befbab05de5e886b4ac3e +Author: Vasundhara Volam +Date: Thu Oct 17 11:47:14 2013 +0530 + + be2net: pass if_id for v1 and V2 versions of TX_CREATE cmd + + [ Upstream commit 0fb88d61bc60779dde88b0fc268da17eb81d0412 ] + + It is a required field for all TX_CREATE cmd versions > 0. + This fixes a driver initialization failure, caused by recent SH-R Firmwares + (versions > 10.0.639.0) failing the TX_CREATE cmd when if_id field is + not passed. + + Signed-off-by: Sathya Perla + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/emulex/benet/be_cmds.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/emulex/benet/be_cmds.c 2014-05-05 11:49:12.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/emulex/benet/be_cmds.c 2014-05-05 12:49:48.000000000 +0000 +@@ -1150,7 +1150,6 @@ + + if (lancer_chip(adapter)) { + req->hdr.version = 1; +- req->if_id = cpu_to_le16(adapter->if_handle); + } else if (BEx_chip(adapter)) { + if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) + req->hdr.version = 2; +@@ -1158,6 +1157,8 @@ + req->hdr.version = 2; + } + ++ if (req->hdr.version > 0) ++ req->if_id = cpu_to_le16(adapter->if_handle); + req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); + req->ulp_num = BE_ULP1_NUM; + req->type = BE_ETH_TX_RING_TYPE_STANDARD; +Index: linux-3.10-3.10.11/dummy/rpi_1472_a8410b48a2d992411a8befbab05de5e886b4ac3e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1472_a8410b48a2d992411a8befbab05de5e886b4ac3e.txt 2014-05-05 12:49:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1473_a769ad65ce0dea53fdf907008e5f6c93fe06168f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1473_a769ad65ce0dea53fdf907008e5f6c93fe06168f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1473_a769ad65ce0dea53fdf907008e5f6c93fe06168f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1473_a769ad65ce0dea53fdf907008e5f6c93fe06168f.patch 2014-05-05 12:49:49.000000000 +0000 @@ -0,0 +1,91 @@ +commit a769ad65ce0dea53fdf907008e5f6c93fe06168f +Author: Daniel Borkmann +Date: Thu Oct 17 22:51:31 2013 +0200 + + net: unix: inherit SOCK_PASS{CRED, SEC} flags from socket to fix race + + [ Upstream commit 90c6bd34f884cd9cee21f1d152baf6c18bcac949 ] + + In the case of credentials passing in unix stream sockets (dgram + sockets seem not affected), we get a rather sparse race after + commit 16e5726 ("af_unix: dont send SCM_CREDENTIALS by default"). + + We have a stream server on receiver side that requests credential + passing from senders (e.g. nc -U). Since we need to set SO_PASSCRED + on each spawned/accepted socket on server side to 1 first (as it's + not inherited), it can happen that in the time between accept() and + setsockopt() we get interrupted, the sender is being scheduled and + continues with passing data to our receiver. At that time SO_PASSCRED + is neither set on sender nor receiver side, hence in cmsg's + SCM_CREDENTIALS we get eventually pid:0, uid:65534, gid:65534 + (== overflow{u,g}id) instead of what we actually would like to see. + + On the sender side, here nc -U, the tests in maybe_add_creds() + invoked through unix_stream_sendmsg() would fail, as at that exact + time, as mentioned, the sender has neither SO_PASSCRED on his side + nor sees it on the server side, and we have a valid 'other' socket + in place. Thus, sender believes it would just look like a normal + connection, not needing/requesting SO_PASSCRED at that time. + + As reverting 16e5726 would not be an option due to the significant + performance regression reported when having creds always passed, + one way/trade-off to prevent that would be to set SO_PASSCRED on + the listener socket and allow inheriting these flags to the spawned + socket on server side in accept(). It seems also logical to do so + if we'd tell the listener socket to pass those flags onwards, and + would fix the race. + + Before, strace: + + recvmsg(4, {msg_name(0)=NULL, msg_iov(1)=[{"blub\n", 4096}], + msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_SOCKET, + cmsg_type=SCM_CREDENTIALS{pid=0, uid=65534, gid=65534}}, + msg_flags=0}, 0) = 5 + + After, strace: + + recvmsg(4, {msg_name(0)=NULL, msg_iov(1)=[{"blub\n", 4096}], + msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_SOCKET, + cmsg_type=SCM_CREDENTIALS{pid=11580, uid=1000, gid=1000}}, + msg_flags=0}, 0) = 5 + + Signed-off-by: Daniel Borkmann + Cc: Eric Dumazet + Cc: Eric W. Biederman + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/unix/af_unix.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/unix/af_unix.c 2014-05-05 11:49:12.000000000 +0000 ++++ linux-3.10-3.10.11/net/unix/af_unix.c 2014-05-05 12:49:49.000000000 +0000 +@@ -1245,6 +1245,15 @@ + return 0; + } + ++static void unix_sock_inherit_flags(const struct socket *old, ++ struct socket *new) ++{ ++ if (test_bit(SOCK_PASSCRED, &old->flags)) ++ set_bit(SOCK_PASSCRED, &new->flags); ++ if (test_bit(SOCK_PASSSEC, &old->flags)) ++ set_bit(SOCK_PASSSEC, &new->flags); ++} ++ + static int unix_accept(struct socket *sock, struct socket *newsock, int flags) + { + struct sock *sk = sock->sk; +@@ -1279,6 +1288,7 @@ + /* attach accepted sock to socket */ + unix_state_lock(tsk); + newsock->state = SS_CONNECTED; ++ unix_sock_inherit_flags(sock, newsock); + sock_graft(tsk, newsock); + unix_state_unlock(tsk); + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1473_a769ad65ce0dea53fdf907008e5f6c93fe06168f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1473_a769ad65ce0dea53fdf907008e5f6c93fe06168f.txt 2014-05-05 12:49:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1474_872095cb74f0acd64d89e578a65df877870f198d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1474_872095cb74f0acd64d89e578a65df877870f198d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1474_872095cb74f0acd64d89e578a65df877870f198d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1474_872095cb74f0acd64d89e578a65df877870f198d.patch 2014-05-05 12:49:50.000000000 +0000 @@ -0,0 +1,58 @@ +commit 872095cb74f0acd64d89e578a65df877870f198d +Author: Seif Mazareeb +Date: Thu Oct 17 20:33:21 2013 -0700 + + net: fix cipso packet validation when !NETLABEL + + [ Upstream commit f2e5ddcc0d12f9c4c7b254358ad245c9dddce13b ] + + When CONFIG_NETLABEL is disabled, the cipso_v4_validate() function could loop + forever in the main loop if opt[opt_iter +1] == 0, this will causing a kernel + crash in an SMP system, since the CPU executing this function will + stall /not respond to IPIs. + + This problem can be reproduced by running the IP Stack Integrity Checker + (http://isic.sourceforge.net) using the following command on a Linux machine + connected to DUT: + + "icmpsic -s rand -d -r 123456" + wait (1-2 min) + + Signed-off-by: Seif Mazareeb + Acked-by: Paul Moore + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/cipso_ipv4.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/cipso_ipv4.h 2014-05-05 11:49:11.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/cipso_ipv4.h 2014-05-05 12:49:50.000000000 +0000 +@@ -290,6 +290,7 @@ + unsigned char err_offset = 0; + u8 opt_len = opt[1]; + u8 opt_iter; ++ u8 tag_len; + + if (opt_len < 8) { + err_offset = 1; +@@ -302,11 +303,12 @@ + } + + for (opt_iter = 6; opt_iter < opt_len;) { +- if (opt[opt_iter + 1] > (opt_len - opt_iter)) { ++ tag_len = opt[opt_iter + 1]; ++ if ((tag_len == 0) || (opt[opt_iter + 1] > (opt_len - opt_iter))) { + err_offset = opt_iter + 1; + goto out; + } +- opt_iter += opt[opt_iter + 1]; ++ opt_iter += tag_len; + } + + out: +Index: linux-3.10-3.10.11/dummy/rpi_1474_872095cb74f0acd64d89e578a65df877870f198d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1474_872095cb74f0acd64d89e578a65df877870f198d.txt 2014-05-05 12:49:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1475_b90cd7b9d0baab2e8176d9cca5f18a592ef16063.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1475_b90cd7b9d0baab2e8176d9cca5f18a592ef16063.patch --- linux-3.10.11/debian/patches/rpi/rpi_1475_b90cd7b9d0baab2e8176d9cca5f18a592ef16063.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1475_b90cd7b9d0baab2e8176d9cca5f18a592ef16063.patch 2014-05-05 12:49:51.000000000 +0000 @@ -0,0 +1,82 @@ +commit b90cd7b9d0baab2e8176d9cca5f18a592ef16063 +Author: Hannes Frederic Sowa +Date: Tue Oct 22 00:07:47 2013 +0200 + + inet: fix possible memory corruption with UDP_CORK and UFO + + [ This is a simplified -stable version of a set of upstream commits. ] + + This is a replacement patch only for stable which does fix the problems + handled by the following two commits in -net: + + "ip_output: do skb ufo init for peeked non ufo skb as well" (e93b7d748be887cd7639b113ba7d7ef792a7efb9) + "ip6_output: do skb ufo init for peeked non ufo skb as well" (c547dbf55d5f8cf615ccc0e7265e98db27d3fb8b) + + Three frames are written on a corked udp socket for which the output + netdevice has UFO enabled. If the first and third frame are smaller than + the mtu and the second one is bigger, we enqueue the second frame with + skb_append_datato_frags without initializing the gso fields. This leads + to the third frame appended regulary and thus constructing an invalid skb. + + This fixes the problem by always using skb_append_datato_frags as soon + as the first frag got enqueued to the skb without marking the packet + as SKB_GSO_UDP. + + The problem with only two frames for ipv6 was fixed by "ipv6: udp + packets following an UFO enqueued packet need also be handled by UFO" + (2811ebac2521ceac84f2bdae402455baa6a7fb47). + + Signed-off-by: Hannes Frederic Sowa + Cc: Jiri Pirko + Cc: Eric Dumazet + Cc: David Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/linux/skbuff.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/skbuff.h 2014-05-05 11:49:11.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/skbuff.h 2014-05-05 12:49:51.000000000 +0000 +@@ -1308,6 +1308,11 @@ + return len + skb_headlen(skb); + } + ++static inline bool skb_has_frags(const struct sk_buff *skb) ++{ ++ return skb_shinfo(skb)->nr_frags; ++} ++ + /** + * __skb_fill_page_desc - initialise a paged fragment in an skb + * @skb: buffer containing fragment to be initialised +Index: linux-3.10-3.10.11/net/ipv4/ip_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv4/ip_output.c 2014-05-05 12:47:10.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv4/ip_output.c 2014-05-05 12:49:51.000000000 +0000 +@@ -844,7 +844,7 @@ + csummode = CHECKSUM_PARTIAL; + + cork->length += length; +- if (((length > mtu) || (skb && skb_is_gso(skb))) && ++ if (((length > mtu) || (skb && skb_has_frags(skb))) && + (sk->sk_protocol == IPPROTO_UDP) && + (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { + err = ip_ufo_append_data(sk, queue, getfrag, from, length, +Index: linux-3.10-3.10.11/net/ipv6/ip6_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_output.c 2014-05-05 12:47:12.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_output.c 2014-05-05 12:49:51.000000000 +0000 +@@ -1250,7 +1250,7 @@ + skb = skb_peek_tail(&sk->sk_write_queue); + cork->length += length; + if (((length > mtu) || +- (skb && skb_is_gso(skb))) && ++ (skb && skb_has_frags(skb))) && + (sk->sk_protocol == IPPROTO_UDP) && + (rt->dst.dev->features & NETIF_F_UFO)) { + err = ip6_ufo_append_data(sk, getfrag, from, length, +Index: linux-3.10-3.10.11/dummy/rpi_1475_b90cd7b9d0baab2e8176d9cca5f18a592ef16063.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1475_b90cd7b9d0baab2e8176d9cca5f18a592ef16063.txt 2014-05-05 12:49:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1476_208a6152b633a33722cc53bca47c46b79e88a2ad.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1476_208a6152b633a33722cc53bca47c46b79e88a2ad.patch --- linux-3.10.11/debian/patches/rpi/rpi_1476_208a6152b633a33722cc53bca47c46b79e88a2ad.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1476_208a6152b633a33722cc53bca47c46b79e88a2ad.patch 2014-05-05 12:49:52.000000000 +0000 @@ -0,0 +1,57 @@ +commit 208a6152b633a33722cc53bca47c46b79e88a2ad +Author: Julian Anastasov +Date: Sun Oct 20 15:43:03 2013 +0300 + + ipv6: always prefer rt6i_gateway if present + + [ Upstream commit 96dc809514fb2328605198a0602b67554d8cce7b ] + + In v3.9 6fd6ce2056de2709 ("ipv6: Do not depend on rt->n in + ip6_finish_output2()." changed the behaviour of ip6_finish_output2() + such that the recently introduced rt6_nexthop() is used + instead of an assigned neighbor. + + As rt6_nexthop() prefers rt6i_gateway only for gatewayed + routes this causes a problem for users like IPVS, xt_TEE and + RAW(hdrincl) if they want to use different address for routing + compared to the destination address. + + Another case is when redirect can create RTF_DYNAMIC + route without RTF_GATEWAY flag, we ignore the rt6i_gateway + in rt6_nexthop(). + + Fix the above problems by considering the rt6i_gateway if + present, so that traffic routed to address on local subnet is + not wrongly diverted to the destination address. + + Thanks to Simon Horman and Phil Oester for spotting the + problematic commit. + + Thanks to Hannes Frederic Sowa for his review and help in testing. + + Reported-by: Phil Oester + Reported-by: Mark Brooks + Signed-off-by: Julian Anastasov + Acked-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/ip6_route.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/ip6_route.h 2014-05-05 11:49:10.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/ip6_route.h 2014-05-05 12:49:52.000000000 +0000 +@@ -196,7 +196,7 @@ + + static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, struct in6_addr *dest) + { +- if (rt->rt6i_flags & RTF_GATEWAY) ++ if (rt->rt6i_flags & RTF_GATEWAY || !ipv6_addr_any(&rt->rt6i_gateway)) + return &rt->rt6i_gateway; + return dest; + } +Index: linux-3.10-3.10.11/dummy/rpi_1476_208a6152b633a33722cc53bca47c46b79e88a2ad.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1476_208a6152b633a33722cc53bca47c46b79e88a2ad.txt 2014-05-05 12:49:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1477_044d6efb797bfa1131bfb510102505ba41bfec52.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1477_044d6efb797bfa1131bfb510102505ba41bfec52.patch --- linux-3.10.11/debian/patches/rpi/rpi_1477_044d6efb797bfa1131bfb510102505ba41bfec52.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1477_044d6efb797bfa1131bfb510102505ba41bfec52.patch 2014-05-05 12:49:53.000000000 +0000 @@ -0,0 +1,107 @@ +commit 044d6efb797bfa1131bfb510102505ba41bfec52 +Author: Julian Anastasov +Date: Sun Oct 20 15:43:04 2013 +0300 + + ipv6: fill rt6i_gateway with nexthop address + + [ Upstream commit 550bab42f83308c9d6ab04a980cc4333cef1c8fa ] + + Make sure rt6i_gateway contains nexthop information in + all routes returned from lookup or when routes are directly + attached to skb for generated ICMP packets. + + The effect of this patch should be a faster version of + rt6_nexthop() and the consideration of local addresses as + nexthop. + + Signed-off-by: Julian Anastasov + Acked-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/net/ip6_route.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/net/ip6_route.h 2014-05-05 12:49:52.000000000 +0000 ++++ linux-3.10-3.10.11/include/net/ip6_route.h 2014-05-05 12:49:52.000000000 +0000 +@@ -194,11 +194,9 @@ + skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); + } + +-static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, struct in6_addr *dest) ++static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt) + { +- if (rt->rt6i_flags & RTF_GATEWAY || !ipv6_addr_any(&rt->rt6i_gateway)) +- return &rt->rt6i_gateway; +- return dest; ++ return &rt->rt6i_gateway; + } + + #endif +Index: linux-3.10-3.10.11/net/ipv6/ip6_output.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/ip6_output.c 2014-05-05 12:49:51.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/ip6_output.c 2014-05-05 12:49:52.000000000 +0000 +@@ -130,7 +130,7 @@ + } + + rcu_read_lock_bh(); +- nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr); ++ nexthop = rt6_nexthop((struct rt6_info *)dst); + neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); + if (unlikely(!neigh)) + neigh = __neigh_create(&nd_tbl, nexthop, dst->dev, false); +@@ -898,7 +898,7 @@ + */ + rt = (struct rt6_info *) *dst; + rcu_read_lock_bh(); +- n = __ipv6_neigh_lookup_noref(rt->dst.dev, rt6_nexthop(rt, &fl6->daddr)); ++ n = __ipv6_neigh_lookup_noref(rt->dst.dev, rt6_nexthop(rt)); + err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0; + rcu_read_unlock_bh(); + +Index: linux-3.10-3.10.11/net/ipv6/route.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/route.c 2014-05-05 11:49:10.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/route.c 2014-05-05 12:49:52.000000000 +0000 +@@ -848,7 +848,6 @@ + if (ort->rt6i_dst.plen != 128 && + ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) + rt->rt6i_flags |= RTF_ANYCAST; +- rt->rt6i_gateway = *daddr; + } + + rt->rt6i_flags |= RTF_CACHE; +@@ -1245,6 +1244,7 @@ + rt->dst.flags |= DST_HOST; + rt->dst.output = ip6_output; + atomic_set(&rt->dst.__refcnt, 1); ++ rt->rt6i_gateway = fl6->daddr; + rt->rt6i_dst.addr = fl6->daddr; + rt->rt6i_dst.plen = 128; + rt->rt6i_idev = idev; +@@ -1801,7 +1801,10 @@ + in6_dev_hold(rt->rt6i_idev); + rt->dst.lastuse = jiffies; + +- rt->rt6i_gateway = ort->rt6i_gateway; ++ if (ort->rt6i_flags & RTF_GATEWAY) ++ rt->rt6i_gateway = ort->rt6i_gateway; ++ else ++ rt->rt6i_gateway = *dest; + rt->rt6i_flags = ort->rt6i_flags; + if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == + (RTF_DEFAULT | RTF_ADDRCONF)) +@@ -2088,6 +2091,7 @@ + else + rt->rt6i_flags |= RTF_LOCAL; + ++ rt->rt6i_gateway = *addr; + rt->rt6i_dst.addr = *addr; + rt->rt6i_dst.plen = 128; + rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL); +Index: linux-3.10-3.10.11/dummy/rpi_1477_044d6efb797bfa1131bfb510102505ba41bfec52.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1477_044d6efb797bfa1131bfb510102505ba41bfec52.txt 2014-05-05 12:49:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1478_2332d212926aaa92d4164482f6f7583c0f796647.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1478_2332d212926aaa92d4164482f6f7583c0f796647.patch --- linux-3.10.11/debian/patches/rpi/rpi_1478_2332d212926aaa92d4164482f6f7583c0f796647.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1478_2332d212926aaa92d4164482f6f7583c0f796647.patch 2014-05-05 12:49:54.000000000 +0000 @@ -0,0 +1,39 @@ +commit 2332d212926aaa92d4164482f6f7583c0f796647 +Author: Julian Anastasov +Date: Sun Oct 20 15:43:05 2013 +0300 + + netfilter: nf_conntrack: fix rt6i_gateway checks for H.323 helper + + [ Upstream commit 56e42441ed54b092d6c7411138ce60d049e7c731 ] + + Now when rt6_nexthop() can return nexthop address we can use it + for proper nexthop comparison of directly connected destinations. + For more information refer to commit bbb5823cf742a7 + ("netfilter: nf_conntrack: fix rt_gateway checks for H.323 helper"). + + Signed-off-by: Julian Anastasov + Acked-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/netfilter/nf_conntrack_h323_main.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/netfilter/nf_conntrack_h323_main.c 2014-05-05 11:49:10.000000000 +0000 ++++ linux-3.10-3.10.11/net/netfilter/nf_conntrack_h323_main.c 2014-05-05 12:49:53.000000000 +0000 +@@ -778,8 +778,8 @@ + flowi6_to_flowi(&fl1), false)) { + if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, + flowi6_to_flowi(&fl2), false)) { +- if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway, +- sizeof(rt1->rt6i_gateway)) && ++ if (ipv6_addr_equal(rt6_nexthop(rt1), ++ rt6_nexthop(rt2)) && + rt1->dst.dev == rt2->dst.dev) + ret = 1; + dst_release(&rt2->dst); +Index: linux-3.10-3.10.11/dummy/rpi_1478_2332d212926aaa92d4164482f6f7583c0f796647.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1478_2332d212926aaa92d4164482f6f7583c0f796647.txt 2014-05-05 12:49:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1479_8df627daa0bde7de4236ab68ef2dded12ab624c8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1479_8df627daa0bde7de4236ab68ef2dded12ab624c8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1479_8df627daa0bde7de4236ab68ef2dded12ab624c8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1479_8df627daa0bde7de4236ab68ef2dded12ab624c8.patch 2014-05-05 12:49:55.000000000 +0000 @@ -0,0 +1,86 @@ +commit 8df627daa0bde7de4236ab68ef2dded12ab624c8 +Author: Hannes Frederic Sowa +Date: Mon Oct 21 06:17:15 2013 +0200 + + ipv6: probe routes asynchronous in rt6_probe + + [ Upstream commit c2f17e827b419918c856131f592df9521e1a38e3 ] + + Routes need to be probed asynchronous otherwise the call stack gets + exhausted when the kernel attemps to deliver another skb inline, like + e.g. xt_TEE does, and we probe at the same time. + + We update neigh->updated still at once, otherwise we would send to + many probes. + + Cc: Julian Anastasov + Signed-off-by: Hannes Frederic Sowa + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/ipv6/route.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/ipv6/route.c 2014-05-05 12:49:52.000000000 +0000 ++++ linux-3.10-3.10.11/net/ipv6/route.c 2014-05-05 12:49:54.000000000 +0000 +@@ -473,6 +473,24 @@ + } + + #ifdef CONFIG_IPV6_ROUTER_PREF ++struct __rt6_probe_work { ++ struct work_struct work; ++ struct in6_addr target; ++ struct net_device *dev; ++}; ++ ++static void rt6_probe_deferred(struct work_struct *w) ++{ ++ struct in6_addr mcaddr; ++ struct __rt6_probe_work *work = ++ container_of(w, struct __rt6_probe_work, work); ++ ++ addrconf_addr_solict_mult(&work->target, &mcaddr); ++ ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL); ++ dev_put(work->dev); ++ kfree(w); ++} ++ + static void rt6_probe(struct rt6_info *rt) + { + struct neighbour *neigh; +@@ -496,17 +514,23 @@ + + if (!neigh || + time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { +- struct in6_addr mcaddr; +- struct in6_addr *target; ++ struct __rt6_probe_work *work; + +- if (neigh) { ++ work = kmalloc(sizeof(*work), GFP_ATOMIC); ++ ++ if (neigh && work) + neigh->updated = jiffies; ++ ++ if (neigh) + write_unlock(&neigh->lock); +- } + +- target = (struct in6_addr *)&rt->rt6i_gateway; +- addrconf_addr_solict_mult(target, &mcaddr); +- ndisc_send_ns(rt->dst.dev, NULL, target, &mcaddr, NULL); ++ if (work) { ++ INIT_WORK(&work->work, rt6_probe_deferred); ++ work->target = rt->rt6i_gateway; ++ dev_hold(rt->dst.dev); ++ work->dev = rt->dst.dev; ++ schedule_work(&work->work); ++ } + } else { + out: + write_unlock(&neigh->lock); +Index: linux-3.10-3.10.11/dummy/rpi_1479_8df627daa0bde7de4236ab68ef2dded12ab624c8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1479_8df627daa0bde7de4236ab68ef2dded12ab624c8.txt 2014-05-05 12:49:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1480_9babd8ab0192070535fe1bab8b86d1c7b1e71943.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1480_9babd8ab0192070535fe1bab8b86d1c7b1e71943.patch --- linux-3.10.11/debian/patches/rpi/rpi_1480_9babd8ab0192070535fe1bab8b86d1c7b1e71943.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1480_9babd8ab0192070535fe1bab8b86d1c7b1e71943.patch 2014-05-05 12:49:55.000000000 +0000 @@ -0,0 +1,46 @@ +commit 9babd8ab0192070535fe1bab8b86d1c7b1e71943 +Author: Mariusz Ceier +Date: Mon Oct 21 19:45:04 2013 +0200 + + davinci_emac.c: Fix IFF_ALLMULTI setup + + [ Upstream commit d69e0f7ea95fef8059251325a79c004bac01f018 ] + + When IFF_ALLMULTI flag is set on interface and IFF_PROMISC isn't, + emac_dev_mcast_set should only enable RX of multicasts and reset + MACHASH registers. + + It does this, but afterwards it either sets up multicast MACs + filtering or disables RX of multicasts and resets MACHASH registers + again, rendering IFF_ALLMULTI flag useless. + + This patch fixes emac_dev_mcast_set, so that multicast MACs filtering and + disabling of RX of multicasts are skipped when IFF_ALLMULTI flag is set. + + Tested with kernel 2.6.37. + + Signed-off-by: Mariusz Ceier + Acked-by: Mugunthan V N + Signed-off-by: David S. Miller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/ethernet/ti/davinci_emac.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/ethernet/ti/davinci_emac.c 2014-05-05 11:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/ethernet/ti/davinci_emac.c 2014-05-05 12:49:55.000000000 +0000 +@@ -876,8 +876,7 @@ + netdev_mc_count(ndev) > EMAC_DEF_MAX_MULTICAST_ADDRESSES) { + mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST); + emac_add_mcast(priv, EMAC_ALL_MULTI_SET, NULL); +- } +- if (!netdev_mc_empty(ndev)) { ++ } else if (!netdev_mc_empty(ndev)) { + struct netdev_hw_addr *ha; + + mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST); +Index: linux-3.10-3.10.11/dummy/rpi_1480_9babd8ab0192070535fe1bab8b86d1c7b1e71943.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1480_9babd8ab0192070535fe1bab8b86d1c7b1e71943.txt 2014-05-05 12:49:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1481_4a402463a7a4a4243c9c66600fd01ae800f959e3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1481_4a402463a7a4a4243c9c66600fd01ae800f959e3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1481_4a402463a7a4a4243c9c66600fd01ae800f959e3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1481_4a402463a7a4a4243c9c66600fd01ae800f959e3.patch 2014-05-05 12:49:56.000000000 +0000 @@ -0,0 +1,56 @@ +commit 4a402463a7a4a4243c9c66600fd01ae800f959e3 +Author: AKASHI Takahiro +Date: Wed Oct 9 15:58:29 2013 +0100 + + ARM: 7851/1: check for number of arguments in syscall_get/set_arguments() + + commit 3c1532df5c1b54b5f6246cdef94eeb73a39fe43a upstream. + + In ftrace_syscall_enter(), + syscall_get_arguments(..., 0, n, ...) + if (i == 0) { ...; n--;} + memcpy(..., n * sizeof(args[0])); + If 'number of arguments(n)' is zero and 'argument index(i)' is also zero in + syscall_get_arguments(), none of arguments should be copied by memcpy(). + Otherwise 'n--' can be a big positive number and unexpected amount of data + will be copied. Tracing system calls which take no argument, say sync(void), + may hit this case and eventually make the system corrupted. + This patch fixes the issue both in syscall_get_arguments() and + syscall_set_arguments(). + + Acked-by: Will Deacon + Signed-off-by: AKASHI Takahiro + Signed-off-by: Will Deacon + Signed-off-by: Russell King + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/include/asm/syscall.h +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/include/asm/syscall.h 2014-05-05 11:49:09.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/include/asm/syscall.h 2014-05-05 12:49:56.000000000 +0000 +@@ -57,6 +57,9 @@ + unsigned int i, unsigned int n, + unsigned long *args) + { ++ if (n == 0) ++ return; ++ + if (i + n > SYSCALL_MAX_ARGS) { + unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i; + unsigned int n_bad = n + i - SYSCALL_MAX_ARGS; +@@ -81,6 +84,9 @@ + unsigned int i, unsigned int n, + const unsigned long *args) + { ++ if (n == 0) ++ return; ++ + if (i + n > SYSCALL_MAX_ARGS) { + pr_warning("%s called with max args %d, handling only %d\n", + __func__, i + n, SYSCALL_MAX_ARGS); +Index: linux-3.10-3.10.11/dummy/rpi_1481_4a402463a7a4a4243c9c66600fd01ae800f959e3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1481_4a402463a7a4a4243c9c66600fd01ae800f959e3.txt 2014-05-05 12:49:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1482_77fc96c899a5c926dd8ba6f340f1e04933e7bfd2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1482_77fc96c899a5c926dd8ba6f340f1e04933e7bfd2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1482_77fc96c899a5c926dd8ba6f340f1e04933e7bfd2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1482_77fc96c899a5c926dd8ba6f340f1e04933e7bfd2.patch 2014-05-05 12:49:57.000000000 +0000 @@ -0,0 +1,81 @@ +commit 77fc96c899a5c926dd8ba6f340f1e04933e7bfd2 +Author: Linus Walleij +Date: Mon Oct 7 15:19:53 2013 +0200 + + ARM: integrator: deactivate timer0 on the Integrator/CP + + commit 29114fd7db2fc82a34da8340d29b8fa413e03dca upstream. + + This fixes a long-standing Integrator/CP regression from + commit 870e2928cf3368ca9b06bc925d0027b0a56bcd8e + "ARM: integrator-cp: convert use CLKSRC_OF for timer init" + + When this code was introduced, the both aliases pointing the + system to use timer1 as primary (clocksource) and timer2 + as secondary (clockevent) was ignored, and the system would + simply use the first two timers found as clocksource and + clockevent. + + However this made the system timeline accelerate by a + factor x25, as it turns out that the way the clocking + actually works (totally undocumented and found after some + trial-and-error) is that timer0 runs @ 25MHz and timer1 + and timer2 runs @ 1MHz. Presumably this divider setting + is a boot-on default and configurable albeit the way to + configure it is not documented. + + So as a quick fix to the problem, let's mark timer0 as + disabled, so the code will chose timer1 and timer2 as it + used to. + + This also deletes the two aliases for the primary and + secondary timer as they have been superceded by the + auto-selection + + Cc: Rob Herring + Cc: Russell King + Signed-off-by: Linus Walleij + Signed-off-by: Olof Johansson + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arm/boot/dts/integratorcp.dts +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/boot/dts/integratorcp.dts 2014-05-05 11:49:08.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/boot/dts/integratorcp.dts 2014-05-05 12:49:56.000000000 +0000 +@@ -9,11 +9,6 @@ + model = "ARM Integrator/CP"; + compatible = "arm,integrator-cp"; + +- aliases { +- arm,timer-primary = &timer2; +- arm,timer-secondary = &timer1; +- }; +- + chosen { + bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; + }; +@@ -24,14 +19,18 @@ + }; + + timer0: timer@13000000 { ++ /* TIMER0 runs @ 25MHz */ + compatible = "arm,integrator-cp-timer"; ++ status = "disabled"; + }; + + timer1: timer@13000100 { ++ /* TIMER1 runs @ 1MHz */ + compatible = "arm,integrator-cp-timer"; + }; + + timer2: timer@13000200 { ++ /* TIMER2 runs @ 1MHz */ + compatible = "arm,integrator-cp-timer"; + }; + +Index: linux-3.10-3.10.11/dummy/rpi_1482_77fc96c899a5c926dd8ba6f340f1e04933e7bfd2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1482_77fc96c899a5c926dd8ba6f340f1e04933e7bfd2.txt 2014-05-05 12:49:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1483_5e2672132dbdb79a7d70711ca5c4bd1fa770b7bd.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1483_5e2672132dbdb79a7d70711ca5c4bd1fa770b7bd.patch --- linux-3.10.11/debian/patches/rpi/rpi_1483_5e2672132dbdb79a7d70711ca5c4bd1fa770b7bd.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1483_5e2672132dbdb79a7d70711ca5c4bd1fa770b7bd.patch 2014-05-05 12:49:58.000000000 +0000 @@ -0,0 +1,47 @@ +commit 5e2672132dbdb79a7d70711ca5c4bd1fa770b7bd +Author: Mika Westerberg +Date: Tue Oct 1 17:35:43 2013 +0300 + + gpio/lynxpoint: check if the interrupt is enabled in IRQ handler + + commit 03d152d5582abc8a1c19cb107164c3724bbd4be4 upstream. + + Checking LP_INT_STAT is not enough in the interrupt handler because its + contents get updated regardless of whether the pin has interrupt enabled or + not. This causes the driver to loop forever for GPIOs that are pulled up. + + Fix this by checking the interrupt enable bit for the pin as well. + + Signed-off-by: Mika Westerberg + Acked-by: Mathias Nyman + Signed-off-by: Linus Walleij + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpio/gpio-lynxpoint.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpio/gpio-lynxpoint.c 2014-05-05 11:49:08.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpio/gpio-lynxpoint.c 2014-05-05 12:49:57.000000000 +0000 +@@ -248,14 +248,15 @@ + struct lp_gpio *lg = irq_data_get_irq_handler_data(data); + struct irq_chip *chip = irq_data_get_irq_chip(data); + u32 base, pin, mask; +- unsigned long reg, pending; ++ unsigned long reg, ena, pending; + unsigned virq; + + /* check from GPIO controller which pin triggered the interrupt */ + for (base = 0; base < lg->chip.ngpio; base += 32) { + reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); ++ ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); + +- while ((pending = inl(reg))) { ++ while ((pending = (inl(reg) & inl(ena)))) { + pin = __ffs(pending); + mask = BIT(pin); + /* Clear before handling so we don't lose an edge */ +Index: linux-3.10-3.10.11/dummy/rpi_1483_5e2672132dbdb79a7d70711ca5c4bd1fa770b7bd.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1483_5e2672132dbdb79a7d70711ca5c4bd1fa770b7bd.txt 2014-05-05 12:49:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1484_2d99b6dd66b5778d92fc411b48037084528e1ae2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1484_2d99b6dd66b5778d92fc411b48037084528e1ae2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1484_2d99b6dd66b5778d92fc411b48037084528e1ae2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1484_2d99b6dd66b5778d92fc411b48037084528e1ae2.patch 2014-05-05 12:49:58.000000000 +0000 @@ -0,0 +1,91 @@ +commit 2d99b6dd66b5778d92fc411b48037084528e1ae2 +Author: Mikulas Patocka +Date: Wed Oct 16 03:17:47 2013 +0100 + + dm snapshot: fix data corruption + + commit e9c6a182649f4259db704ae15a91ac820e63b0ca upstream. + + This patch fixes a particular type of data corruption that has been + encountered when loading a snapshot's metadata from disk. + + When we allocate a new chunk in persistent_prepare, we increment + ps->next_free and we make sure that it doesn't point to a metadata area + by further incrementing it if necessary. + + When we load metadata from disk on device activation, ps->next_free is + positioned after the last used data chunk. However, if this last used + data chunk is followed by a metadata area, ps->next_free is positioned + erroneously to the metadata area. A newly-allocated chunk is placed at + the same location as the metadata area, resulting in data or metadata + corruption. + + This patch changes the code so that ps->next_free skips the metadata + area when metadata are loaded in function read_exceptions. + + The patch also moves a piece of code from persistent_prepare_exception + to a separate function skip_metadata to avoid code duplication. + + CVE-2013-4299 + + Signed-off-by: Mikulas Patocka + Cc: Mike Snitzer + Signed-off-by: Alasdair G Kergon + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/dm-snap-persistent.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/dm-snap-persistent.c 2014-05-05 12:46:33.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/dm-snap-persistent.c 2014-05-05 12:49:58.000000000 +0000 +@@ -269,6 +269,14 @@ + return NUM_SNAPSHOT_HDR_CHUNKS + ((ps->exceptions_per_area + 1) * area); + } + ++static void skip_metadata(struct pstore *ps) ++{ ++ uint32_t stride = ps->exceptions_per_area + 1; ++ chunk_t next_free = ps->next_free; ++ if (sector_div(next_free, stride) == NUM_SNAPSHOT_HDR_CHUNKS) ++ ps->next_free++; ++} ++ + /* + * Read or write a metadata area. Remembering to skip the first + * chunk which holds the header. +@@ -502,6 +510,8 @@ + + ps->current_area--; + ++ skip_metadata(ps); ++ + return 0; + } + +@@ -616,8 +626,6 @@ + struct dm_exception *e) + { + struct pstore *ps = get_info(store); +- uint32_t stride; +- chunk_t next_free; + sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); + + /* Is there enough room ? */ +@@ -630,10 +638,8 @@ + * Move onto the next free pending, making sure to take + * into account the location of the metadata chunks. + */ +- stride = (ps->exceptions_per_area + 1); +- next_free = ++ps->next_free; +- if (sector_div(next_free, stride) == 1) +- ps->next_free++; ++ ps->next_free++; ++ skip_metadata(ps); + + atomic_inc(&ps->pending_count); + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1484_2d99b6dd66b5778d92fc411b48037084528e1ae2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1484_2d99b6dd66b5778d92fc411b48037084528e1ae2.txt 2014-05-05 12:49:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1485_fe0051d83cb951fbeab6712633ca2e31de22ee11.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1485_fe0051d83cb951fbeab6712633ca2e31de22ee11.patch --- linux-3.10.11/debian/patches/rpi/rpi_1485_fe0051d83cb951fbeab6712633ca2e31de22ee11.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1485_fe0051d83cb951fbeab6712633ca2e31de22ee11.patch 2014-05-05 12:49:59.000000000 +0000 @@ -0,0 +1,37 @@ +commit fe0051d83cb951fbeab6712633ca2e31de22ee11 +Author: James Ralston +Date: Tue Sep 24 16:47:55 2013 -0700 + + i2c: ismt: initialize DMA buffer + + commit bf4169100c909667ede6af67668b3ecce6928343 upstream. + + This patch adds code to initialize the DMA buffer to compensate for + possible hardware data corruption. + + Signed-off-by: James Ralston + [wsa: changed to use 'sizeof'] + Signed-off-by: Wolfram Sang + Cc: Jean Delvare + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/i2c/busses/i2c-ismt.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/i2c/busses/i2c-ismt.c 2014-05-05 11:49:08.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/i2c/busses/i2c-ismt.c 2014-05-05 12:49:59.000000000 +0000 +@@ -393,6 +393,9 @@ + + desc = &priv->hw[priv->head]; + ++ /* Initialize the DMA buffer */ ++ memset(priv->dma_buffer, 0, sizeof(priv->dma_buffer)); ++ + /* Initialize the descriptor */ + memset(desc, 0, sizeof(struct ismt_desc)); + desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write); +Index: linux-3.10-3.10.11/dummy/rpi_1485_fe0051d83cb951fbeab6712633ca2e31de22ee11.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1485_fe0051d83cb951fbeab6712633ca2e31de22ee11.txt 2014-05-05 12:49:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1486_7ed008638ee15991b79d8867d382e141fee89a69.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1486_7ed008638ee15991b79d8867d382e141fee89a69.patch --- linux-3.10.11/debian/patches/rpi/rpi_1486_7ed008638ee15991b79d8867d382e141fee89a69.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1486_7ed008638ee15991b79d8867d382e141fee89a69.patch 2014-05-05 12:50:00.000000000 +0000 @@ -0,0 +1,60 @@ +commit 7ed008638ee15991b79d8867d382e141fee89a69 +Author: Hugh Dickins +Date: Wed Oct 16 13:47:08 2013 -0700 + + mm: fix BUG in __split_huge_page_pmd + + commit 750e8165f5e87b6a142be953640eabb13a9d350a upstream. + + Occasionally we hit the BUG_ON(pmd_trans_huge(*pmd)) at the end of + __split_huge_page_pmd(): seen when doing madvise(,,MADV_DONTNEED). + + It's invalid: we don't always have down_write of mmap_sem there: a racing + do_huge_pmd_wp_page() might have copied-on-write to another huge page + before our split_huge_page() got the anon_vma lock. + + Forget the BUG_ON, just go back and try again if this happens. + + Signed-off-by: Hugh Dickins + Acked-by: Kirill A. Shutemov + Cc: Andrea Arcangeli + Cc: Naoya Horiguchi + Cc: David Rientjes + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/huge_memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/huge_memory.c 2014-05-05 12:45:03.000000000 +0000 ++++ linux-3.10-3.10.11/mm/huge_memory.c 2014-05-05 12:49:59.000000000 +0000 +@@ -2699,6 +2699,7 @@ + + mmun_start = haddr; + mmun_end = haddr + HPAGE_PMD_SIZE; ++again: + mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); + spin_lock(&mm->page_table_lock); + if (unlikely(!pmd_trans_huge(*pmd))) { +@@ -2721,7 +2722,14 @@ + split_huge_page(page); + + put_page(page); +- BUG_ON(pmd_trans_huge(*pmd)); ++ ++ /* ++ * We don't always have down_write of mmap_sem here: a racing ++ * do_huge_pmd_wp_page() might have copied-on-write to another ++ * huge page before our split_huge_page() got the anon_vma lock. ++ */ ++ if (unlikely(pmd_trans_huge(*pmd))) ++ goto again; + } + + void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address, +Index: linux-3.10-3.10.11/dummy/rpi_1486_7ed008638ee15991b79d8867d382e141fee89a69.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1486_7ed008638ee15991b79d8867d382e141fee89a69.txt 2014-05-05 12:49:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1487_1f931f65de9d04daf024eeb4dd6a8fe93b7a8e91.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1487_1f931f65de9d04daf024eeb4dd6a8fe93b7a8e91.patch --- linux-3.10.11/debian/patches/rpi/rpi_1487_1f931f65de9d04daf024eeb4dd6a8fe93b7a8e91.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1487_1f931f65de9d04daf024eeb4dd6a8fe93b7a8e91.patch 2014-05-05 12:50:01.000000000 +0000 @@ -0,0 +1,43 @@ +commit 1f931f65de9d04daf024eeb4dd6a8fe93b7a8e91 +Author: Takashi Iwai +Date: Mon Oct 14 16:02:15 2013 +0200 + + ALSA: us122l: Fix pcm_usb_stream mmapping regression + + commit ac536a848a1643e4b87e8fbd376a63091afc2ccc upstream. + + The pcm_usb_stream plugin requires the mremap explicitly for the read + buffer, as it expands itself once after reading the required size. + But the commit [314e51b9: mm: kill vma flag VM_RESERVED and + mm->reserved_vm counter] converted blindly to a combination of + VM_DONTEXPAND | VM_DONTDUMP like other normal drivers, and this + resulted in the failure of mremap(). + + For fixing this regression, we need to remove VM_DONTEXPAND for the + read-buffer mmap. + + Reported-and-tested-by: James Miller + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/usb/usx2y/us122l.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/usb/usx2y/us122l.c 2014-05-05 11:49:07.000000000 +0000 ++++ linux-3.10-3.10.11/sound/usb/usx2y/us122l.c 2014-05-05 12:50:00.000000000 +0000 +@@ -262,7 +262,9 @@ + } + + area->vm_ops = &usb_stream_hwdep_vm_ops; +- area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; ++ area->vm_flags |= VM_DONTDUMP; ++ if (!read) ++ area->vm_flags |= VM_DONTEXPAND; + area->vm_private_data = us122l; + atomic_inc(&us122l->mmap_count); + out: +Index: linux-3.10-3.10.11/dummy/rpi_1487_1f931f65de9d04daf024eeb4dd6a8fe93b7a8e91.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1487_1f931f65de9d04daf024eeb4dd6a8fe93b7a8e91.txt 2014-05-05 12:50:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1488_1c4bd2b14d14f524c51839c64aa3f79a81622562.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1488_1c4bd2b14d14f524c51839c64aa3f79a81622562.patch --- linux-3.10.11/debian/patches/rpi/rpi_1488_1c4bd2b14d14f524c51839c64aa3f79a81622562.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1488_1c4bd2b14d14f524c51839c64aa3f79a81622562.patch 2014-05-05 12:50:02.000000000 +0000 @@ -0,0 +1,45 @@ +commit 1c4bd2b14d14f524c51839c64aa3f79a81622562 +Author: David Henningsson +Date: Mon Oct 14 10:16:22 2013 +0200 + + ALSA: hda - Fix inverted internal mic not indicated on some machines + + commit ccb041571b73888785ef7828a276e380125891a4 upstream. + + The create_bind_cap_vol_ctl does not create any control indicating + that an inverted dmic is present. Therefore, create multiple + capture volumes in this scenario, so we always have some indication + that the internal mic is inverted. + + This happens on the Lenovo Ideapad U310 as well as the Lenovo Yoga 13 + (both are based on the CX20590 codec), but the fix is generic and + could be needed for other codecs/machines too. + + Thanks to Szymon Acedański for the pointer and a draft patch. + + BugLink: https://bugs.launchpad.net/bugs/1239392 + BugLink: https://bugs.launchpad.net/bugs/1227491 + Reported-by: Szymon Acedański + Signed-off-by: David Henningsson + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/hda_generic.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/hda_generic.c 2014-05-05 11:49:07.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/hda_generic.c 2014-05-05 12:50:01.000000000 +0000 +@@ -3474,7 +3474,7 @@ + if (!multi) + err = create_single_cap_vol_ctl(codec, n, vol, sw, + inv_dmic); +- else if (!multi_cap_vol) ++ else if (!multi_cap_vol && !inv_dmic) + err = create_bind_cap_vol_ctl(codec, n, vol, sw); + else + err = create_multi_cap_vol_ctl(codec); +Index: linux-3.10-3.10.11/dummy/rpi_1488_1c4bd2b14d14f524c51839c64aa3f79a81622562.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1488_1c4bd2b14d14f524c51839c64aa3f79a81622562.txt 2014-05-05 12:50:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1489_71c908a0e5c0bbc2e8ad5f9578b9529a1e6ec8aa.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1489_71c908a0e5c0bbc2e8ad5f9578b9529a1e6ec8aa.patch --- linux-3.10.11/debian/patches/rpi/rpi_1489_71c908a0e5c0bbc2e8ad5f9578b9529a1e6ec8aa.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1489_71c908a0e5c0bbc2e8ad5f9578b9529a1e6ec8aa.patch 2014-05-05 12:50:02.000000000 +0000 @@ -0,0 +1,96 @@ +commit 71c908a0e5c0bbc2e8ad5f9578b9529a1e6ec8aa +Author: Fengguang Wu +Date: Wed Oct 16 13:47:03 2013 -0700 + + writeback: fix negative bdi max pause + + commit e3b6c655b91e01a1dade056cfa358581b47a5351 upstream. + + Toralf runs trinity on UML/i386. After some time it hangs and the last + message line is + + BUG: soft lockup - CPU#0 stuck for 22s! [trinity-child0:1521] + + It's found that pages_dirtied becomes very large. More than 1000000000 + pages in this case: + + period = HZ * pages_dirtied / task_ratelimit; + BUG_ON(pages_dirtied > 2000000000); + BUG_ON(pages_dirtied > 1000000000); <--------- + + UML debug printf shows that we got negative pause here: + + ick: pause : -984 + ick: pages_dirtied : 0 + ick: task_ratelimit: 0 + + pause: + + if (pause < 0) { + + extern int printf(char *, ...); + + printf("ick : pause : %li\n", pause); + + printf("ick: pages_dirtied : %lu\n", pages_dirtied); + + printf("ick: task_ratelimit: %lu\n", task_ratelimit); + + BUG_ON(1); + + } + trace_balance_dirty_pages(bdi, + + Since pause is bounded by [min_pause, max_pause] where min_pause is also + bounded by max_pause. It's suspected and demonstrated that the + max_pause calculation goes wrong: + + ick: pause : -717 + ick: min_pause : -177 + ick: max_pause : -717 + ick: pages_dirtied : 14 + ick: task_ratelimit: 0 + + The problem lies in the two "long = unsigned long" assignments in + bdi_max_pause() which might go negative if the highest bit is 1, and the + min_t(long, ...) check failed to protect it falling under 0. Fix all of + them by using "unsigned long" throughout the function. + + Signed-off-by: Fengguang Wu + Reported-by: Toralf Förster + Tested-by: Toralf Förster + Reviewed-by: Jan Kara + Cc: Richard Weinberger + Cc: Geert Uytterhoeven + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/page-writeback.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/page-writeback.c 2014-05-05 11:49:06.000000000 +0000 ++++ linux-3.10-3.10.11/mm/page-writeback.c 2014-05-05 12:50:02.000000000 +0000 +@@ -1104,11 +1104,11 @@ + return 1; + } + +-static long bdi_max_pause(struct backing_dev_info *bdi, +- unsigned long bdi_dirty) ++static unsigned long bdi_max_pause(struct backing_dev_info *bdi, ++ unsigned long bdi_dirty) + { +- long bw = bdi->avg_write_bandwidth; +- long t; ++ unsigned long bw = bdi->avg_write_bandwidth; ++ unsigned long t; + + /* + * Limit pause time for small memory systems. If sleeping for too long +@@ -1120,7 +1120,7 @@ + t = bdi_dirty / (1 + bw / roundup_pow_of_two(1 + HZ / 8)); + t++; + +- return min_t(long, t, MAX_PAUSE); ++ return min_t(unsigned long, t, MAX_PAUSE); + } + + static long bdi_min_pause(struct backing_dev_info *bdi, +Index: linux-3.10-3.10.11/dummy/rpi_1489_71c908a0e5c0bbc2e8ad5f9578b9529a1e6ec8aa.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1489_71c908a0e5c0bbc2e8ad5f9578b9529a1e6ec8aa.txt 2014-05-05 12:50:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1490_add8ec07b2a000af11be64a89b99afc8c90797e5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1490_add8ec07b2a000af11be64a89b99afc8c90797e5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1490_add8ec07b2a000af11be64a89b99afc8c90797e5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1490_add8ec07b2a000af11be64a89b99afc8c90797e5.patch 2014-05-05 12:50:03.000000000 +0000 @@ -0,0 +1,57 @@ +commit add8ec07b2a000af11be64a89b99afc8c90797e5 +Author: Johannes Berg +Date: Fri Oct 11 14:47:05 2013 +0200 + + wireless: radiotap: fix parsing buffer overrun + + commit f5563318ff1bde15b10e736e97ffce13be08bc1a upstream. + + When parsing an invalid radiotap header, the parser can overrun + the buffer that is passed in because it doesn't correctly check + 1) the minimum radiotap header size + 2) the space for extended bitmaps + + The first issue doesn't affect any in-kernel user as they all + check the minimum size before calling the radiotap function. + The second issue could potentially affect the kernel if an skb + is passed in that consists only of the radiotap header with a + lot of extended bitmaps that extend past the SKB. In that case + a read-only buffer overrun by at most 4 bytes is possible. + + Fix this by adding the appropriate checks to the parser. + + Reported-by: Evan Huus + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/wireless/radiotap.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/wireless/radiotap.c 2014-05-05 11:49:06.000000000 +0000 ++++ linux-3.10-3.10.11/net/wireless/radiotap.c 2014-05-05 12:50:03.000000000 +0000 +@@ -97,6 +97,10 @@ + struct ieee80211_radiotap_header *radiotap_header, + int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns) + { ++ /* check the radiotap header can actually be present */ ++ if (max_length < sizeof(struct ieee80211_radiotap_header)) ++ return -EINVAL; ++ + /* Linux only supports version 0 radiotap format */ + if (radiotap_header->it_version) + return -EINVAL; +@@ -131,7 +135,8 @@ + */ + + if ((unsigned long)iterator->_arg - +- (unsigned long)iterator->_rtheader > ++ (unsigned long)iterator->_rtheader + ++ sizeof(uint32_t) > + (unsigned long)iterator->_max_length) + return -EINVAL; + } +Index: linux-3.10-3.10.11/dummy/rpi_1490_add8ec07b2a000af11be64a89b99afc8c90797e5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1490_add8ec07b2a000af11be64a89b99afc8c90797e5.txt 2014-05-05 12:50:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1491_bfddde1b4056f5b7d0d365606000df3442b82cd0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1491_bfddde1b4056f5b7d0d365606000df3442b82cd0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1491_bfddde1b4056f5b7d0d365606000df3442b82cd0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1491_bfddde1b4056f5b7d0d365606000df3442b82cd0.patch 2014-05-05 12:50:04.000000000 +0000 @@ -0,0 +1,45 @@ +commit bfddde1b4056f5b7d0d365606000df3442b82cd0 +Author: Roel Kluin +Date: Mon Oct 14 23:21:15 2013 +0200 + + serial: vt8500: add missing braces + + commit d969de8d83401683420638c8107dcfedb2146f37 upstream. + + Due to missing braces on an if statement, in presence of a device_node a + port was always assigned -1, regardless of any alias entries in the + device tree. Conversely, if device_node was NULL, an unitialized port + ended up being used. + + This patch adds the missing braces, fixing the issues. + + Signed-off-by: Roel Kluin + Acked-by: Tony Prisk + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/tty/serial/vt8500_serial.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/tty/serial/vt8500_serial.c 2014-05-05 11:49:05.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/tty/serial/vt8500_serial.c 2014-05-05 12:50:03.000000000 +0000 +@@ -559,12 +559,13 @@ + if (!mmres || !irqres) + return -ENODEV; + +- if (np) ++ if (np) { + port = of_alias_get_id(np, "serial"); + if (port >= VT8500_MAX_PORTS) + port = -1; +- else ++ } else { + port = -1; ++ } + + if (port < 0) { + /* calculate the port id */ +Index: linux-3.10-3.10.11/dummy/rpi_1491_bfddde1b4056f5b7d0d365606000df3442b82cd0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1491_bfddde1b4056f5b7d0d365606000df3442b82cd0.txt 2014-05-05 12:50:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1492_e81e74f12005c5303cc26558b1b5c4294a0be4e0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1492_e81e74f12005c5303cc26558b1b5c4294a0be4e0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1492_e81e74f12005c5303cc26558b1b5c4294a0be4e0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1492_e81e74f12005c5303cc26558b1b5c4294a0be4e0.patch 2014-05-05 12:50:05.000000000 +0000 @@ -0,0 +1,32 @@ +commit e81e74f12005c5303cc26558b1b5c4294a0be4e0 +Author: Diego Elio Pettenò +Date: Tue Oct 8 20:03:37 2013 +0100 + + USB: serial: ti_usb_3410_5052: add Abbott strip port ID to combined table as well. + + commit c9d09dc7ad106492c17c587b6eeb99fe3f43e522 upstream. + + Without this change, the USB cable for Freestyle Option and compatible + glucometers will not be detected by the driver. + + Signed-off-by: Diego Elio Pettenò + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/ti_usb_3410_5052.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/ti_usb_3410_5052.c 2014-05-05 12:41:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/ti_usb_3410_5052.c 2014-05-05 12:50:04.000000000 +0000 +@@ -203,6 +203,7 @@ + { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, ++ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, + { } + }; +Index: linux-3.10-3.10.11/dummy/rpi_1492_e81e74f12005c5303cc26558b1b5c4294a0be4e0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1492_e81e74f12005c5303cc26558b1b5c4294a0be4e0.txt 2014-05-05 12:50:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1493_961e551e0f2e2acf2adc7465544ef25c5852a0ac.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1493_961e551e0f2e2acf2adc7465544ef25c5852a0ac.patch --- linux-3.10.11/debian/patches/rpi/rpi_1493_961e551e0f2e2acf2adc7465544ef25c5852a0ac.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1493_961e551e0f2e2acf2adc7465544ef25c5852a0ac.patch 2014-05-05 12:50:06.000000000 +0000 @@ -0,0 +1,43 @@ +commit 961e551e0f2e2acf2adc7465544ef25c5852a0ac +Author: Greg Kroah-Hartman +Date: Sat Oct 5 18:14:18 2013 -0700 + + USB: serial: option: add support for Inovia SEW858 device + + commit f4c19b8e165cff1a6607c21f8809441d61cab7ec upstream. + + This patch adds the device id for the Inovia SEW858 device to the option driver. + + Reported-by: Pavel Parkhomenko + Tested-by: Pavel Parkhomenko + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/option.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/option.c 2014-05-05 12:47:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/option.c 2014-05-05 12:50:05.000000000 +0000 +@@ -451,6 +451,10 @@ + #define CHANGHONG_VENDOR_ID 0x2077 + #define CHANGHONG_PRODUCT_CH690 0x7001 + ++/* Inovia */ ++#define INOVIA_VENDOR_ID 0x20a6 ++#define INOVIA_SEW858 0x1105 ++ + /* some devices interfaces need special handling due to a number of reasons */ + enum option_blacklist_reason { + OPTION_BLACKLIST_NONE = 0, +@@ -1345,6 +1349,7 @@ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ ++ { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +Index: linux-3.10-3.10.11/dummy/rpi_1493_961e551e0f2e2acf2adc7465544ef25c5852a0ac.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1493_961e551e0f2e2acf2adc7465544ef25c5852a0ac.txt 2014-05-05 12:50:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1494_adc6b15872611b75ae523d6784074d2ed84b1c4e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1494_adc6b15872611b75ae523d6784074d2ed84b1c4e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1494_adc6b15872611b75ae523d6784074d2ed84b1c4e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1494_adc6b15872611b75ae523d6784074d2ed84b1c4e.patch 2014-05-05 12:50:06.000000000 +0000 @@ -0,0 +1,37 @@ +commit adc6b15872611b75ae523d6784074d2ed84b1c4e +Author: Enrico Mioso +Date: Tue Oct 15 15:06:47 2013 +0200 + + usb: serial: option: blacklist Olivetti Olicard200 + + commit fd8573f5828873343903215f203f14dc82de397c upstream. + + Interface 6 of this device speaks QMI as per tests done by us. + Credits go to Antonella for providing the hardware. + + Signed-off-by: Enrico Mioso + Signed-off-by: Antonella Pellizzari + Tested-by: Dan Williams + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/option.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/option.c 2014-05-05 12:50:05.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/option.c 2014-05-05 12:50:06.000000000 +0000 +@@ -1261,7 +1261,9 @@ + + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, +- { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200) }, ++ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200), ++ .driver_info = (kernel_ulong_t)&net_intf6_blacklist ++ }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ + { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, +Index: linux-3.10-3.10.11/dummy/rpi_1494_adc6b15872611b75ae523d6784074d2ed84b1c4e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1494_adc6b15872611b75ae523d6784074d2ed84b1c4e.txt 2014-05-05 12:50:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1495_4e77f7f1261f65cff06918bc5e66d02a418fc842.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1495_4e77f7f1261f65cff06918bc5e66d02a418fc842.patch --- linux-3.10.11/debian/patches/rpi/rpi_1495_4e77f7f1261f65cff06918bc5e66d02a418fc842.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1495_4e77f7f1261f65cff06918bc5e66d02a418fc842.patch 2014-05-05 12:50:07.000000000 +0000 @@ -0,0 +1,24 @@ +commit 4e77f7f1261f65cff06918bc5e66d02a418fc842 +Author: Greg Kroah-Hartman +Date: Mon Nov 4 04:31:29 2013 -0800 + + Linux 3.10.18 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:49:21.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:50:06.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 17 ++SUBLEVEL = 18 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1495_4e77f7f1261f65cff06918bc5e66d02a418fc842.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1495_4e77f7f1261f65cff06918bc5e66d02a418fc842.txt 2014-05-05 12:50:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1496_b910ef250be4f872e383c62d1dfc40641b6f1c5b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1496_b910ef250be4f872e383c62d1dfc40641b6f1c5b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1496_b910ef250be4f872e383c62d1dfc40641b6f1c5b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1496_b910ef250be4f872e383c62d1dfc40641b6f1c5b.patch 2014-05-05 12:50:08.000000000 +0000 @@ -0,0 +1,74 @@ +commit b910ef250be4f872e383c62d1dfc40641b6f1c5b +Author: Oliver Neukum +Date: Mon Oct 14 15:24:55 2013 +0200 + + usb-storage: add quirk for mandatory READ_CAPACITY_16 + + commit 32c37fc30c52508711ea6a108cfd5855b8a07176 upstream. + + Some USB drive enclosures do not correctly report an + overflow condition if they hold a drive with a capacity + over 2TB and are confronted with a READ_CAPACITY_10. + They answer with their capacity modulo 2TB. + The generic layer cannot cope with that. It must be told + to use READ_CAPACITY_16 from the beginning. + + Signed-off-by: Oliver Neukum + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/storage/scsiglue.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/storage/scsiglue.c 2014-05-05 11:49:04.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/storage/scsiglue.c 2014-05-05 12:50:07.000000000 +0000 +@@ -211,8 +211,11 @@ + /* + * Many devices do not respond properly to READ_CAPACITY_16. + * Tell the SCSI layer to try READ_CAPACITY_10 first. ++ * However some USB 3.0 drive enclosures return capacity ++ * modulo 2TB. Those must use READ_CAPACITY_16 + */ +- sdev->try_rc_10_first = 1; ++ if (!(us->fflags & US_FL_NEEDS_CAP16)) ++ sdev->try_rc_10_first = 1; + + /* assume SPC3 or latter devices support sense size > 18 */ + if (sdev->scsi_level > SCSI_SPC_2) +Index: linux-3.10-3.10.11/drivers/usb/storage/unusual_devs.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/storage/unusual_devs.h 2014-05-05 11:49:04.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/storage/unusual_devs.h 2014-05-05 12:50:07.000000000 +0000 +@@ -1925,6 +1925,13 @@ + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + ++/* Reported by Oliver Neukum */ ++UNUSUAL_DEV( 0x174c, 0x55aa, 0x0100, 0x0100, ++ "ASMedia", ++ "AS2105", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NEEDS_CAP16), ++ + /* Reported by Jesse Feddema */ + UNUSUAL_DEV( 0x177f, 0x0400, 0x0000, 0x0000, + "Yarvik", +Index: linux-3.10-3.10.11/include/linux/usb_usual.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/usb_usual.h 2014-05-05 11:49:04.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/usb_usual.h 2014-05-05 12:50:07.000000000 +0000 +@@ -66,7 +66,9 @@ + US_FLAG(INITIAL_READ10, 0x00100000) \ + /* Initial READ(10) (and others) must be retried */ \ + US_FLAG(WRITE_CACHE, 0x00200000) \ +- /* Write Cache status is not available */ ++ /* Write Cache status is not available */ \ ++ US_FLAG(NEEDS_CAP16, 0x00400000) ++ /* cannot handle READ_CAPACITY_10 */ + + #define US_FLAG(name, value) US_FL_##name = value , + enum { US_DO_ALL_FLAGS }; +Index: linux-3.10-3.10.11/dummy/rpi_1496_b910ef250be4f872e383c62d1dfc40641b6f1c5b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1496_b910ef250be4f872e383c62d1dfc40641b6f1c5b.txt 2014-05-05 12:50:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1497_75094c77c2e413cf85ca797f9f352ecc4c3533ad.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1497_75094c77c2e413cf85ca797f9f352ecc4c3533ad.patch --- linux-3.10.11/debian/patches/rpi/rpi_1497_75094c77c2e413cf85ca797f9f352ecc4c3533ad.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1497_75094c77c2e413cf85ca797f9f352ecc4c3533ad.patch 2014-05-05 12:50:09.000000000 +0000 @@ -0,0 +1,247 @@ +commit 75094c77c2e413cf85ca797f9f352ecc4c3533ad +Author: Fangxiaozhi (Franko) +Date: Fri Oct 11 03:48:21 2013 +0000 + + USB: support new huawei devices in option.c + + commit d544db293a44a2a3b09feab7dbd59668b692de71 upstream. + + Add new supporting declarations to option.c, to support Huawei new + devices with new bInterfaceSubClass value. + + Signed-off-by: fangxiaozhi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/option.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/option.c 2014-05-05 12:50:06.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/option.c 2014-05-05 12:50:08.000000000 +0000 +@@ -693,6 +693,222 @@ + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x01) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x02) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x03) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x04) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x05) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x06) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x0F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x10) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x12) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x13) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x14) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x15) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x17) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x18) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x19) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x1A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x1B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x1C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x31) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x32) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x33) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x34) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x35) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x36) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x3F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x48) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x49) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x4A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x4B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x4C) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x61) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x62) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x63) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x64) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x65) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x66) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6D) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6E) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x78) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x79) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7A) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7B) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7C) }, + + + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, +Index: linux-3.10-3.10.11/dummy/rpi_1497_75094c77c2e413cf85ca797f9f352ecc4c3533ad.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1497_75094c77c2e413cf85ca797f9f352ecc4c3533ad.txt 2014-05-05 12:50:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1498_ac1acaf7b6cb48562f6466e4f793d0f24a5726d8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1498_ac1acaf7b6cb48562f6466e4f793d0f24a5726d8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1498_ac1acaf7b6cb48562f6466e4f793d0f24a5726d8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1498_ac1acaf7b6cb48562f6466e4f793d0f24a5726d8.patch 2014-05-05 12:50:10.000000000 +0000 @@ -0,0 +1,33 @@ +commit ac1acaf7b6cb48562f6466e4f793d0f24a5726d8 +Author: Oliver Neukum +Date: Mon Oct 14 16:22:40 2013 +0200 + + USB: quirks.c: add one device that cannot deal with suspension + + commit 4294bca7b423d1a5aa24307e3d112a04075e3763 upstream. + + The device is not responsive when resumed, unless it is reset. + + Signed-off-by: Oliver Neukum + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/core/quirks.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/quirks.c 2014-05-05 11:49:03.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/quirks.c 2014-05-05 12:50:09.000000000 +0000 +@@ -130,6 +130,9 @@ + /* Broadcom BCM92035DGROM BT dongle */ + { USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* MAYA44USB sound device */ ++ { USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, +Index: linux-3.10-3.10.11/dummy/rpi_1498_ac1acaf7b6cb48562f6466e4f793d0f24a5726d8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1498_ac1acaf7b6cb48562f6466e4f793d0f24a5726d8.txt 2014-05-05 12:50:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1499_59fa93ea76e2de29910bab0a49dbb14f56b79aea.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1499_59fa93ea76e2de29910bab0a49dbb14f56b79aea.patch --- linux-3.10.11/debian/patches/rpi/rpi_1499_59fa93ea76e2de29910bab0a49dbb14f56b79aea.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1499_59fa93ea76e2de29910bab0a49dbb14f56b79aea.patch 2014-05-05 12:50:10.000000000 +0000 @@ -0,0 +1,33 @@ +commit 59fa93ea76e2de29910bab0a49dbb14f56b79aea +Author: Oliver Neukum +Date: Wed Oct 16 12:26:07 2013 +0200 + + USB: quirks: add touchscreen that is dazzeled by remote wakeup + + commit 614ced91fc6fbb5a1cdd12f0f1b6c9197d9f1350 upstream. + + The device descriptors are messed up after remote wakeup + + Signed-off-by: Oliver Neukum + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/core/quirks.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/quirks.c 2014-05-05 12:50:09.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/quirks.c 2014-05-05 12:50:10.000000000 +0000 +@@ -97,6 +97,9 @@ + /* Alcor Micro Corp. Hub */ + { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* MicroTouch Systems touchscreen */ ++ { USB_DEVICE(0x0596, 0x051e), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* appletouch */ + { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, + +Index: linux-3.10-3.10.11/dummy/rpi_1499_59fa93ea76e2de29910bab0a49dbb14f56b79aea.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1499_59fa93ea76e2de29910bab0a49dbb14f56b79aea.txt 2014-05-05 12:50:10.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1500_a73e47ff525d2a69d61767a5928ba00937f77e1b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1500_a73e47ff525d2a69d61767a5928ba00937f77e1b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1500_a73e47ff525d2a69d61767a5928ba00937f77e1b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1500_a73e47ff525d2a69d61767a5928ba00937f77e1b.patch 2014-05-05 12:50:11.000000000 +0000 @@ -0,0 +1,45 @@ +commit a73e47ff525d2a69d61767a5928ba00937f77e1b +Author: Алексей Крамаренко +Date: Fri Nov 1 17:26:38 2013 +0400 + + USB: serial: ftdi_sio: add id for Z3X Box device + + commit e1466ad5b1aeda303f9282463d55798d2eda218c upstream. + + Custom VID/PID for Z3X Box device, popular tool for cellphone flashing. + + Signed-off-by: Alexey E. Kramarenko + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/usb/serial/ftdi_sio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/ftdi_sio.c 2014-05-05 11:49:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/ftdi_sio.c 2014-05-05 12:50:11.000000000 +0000 +@@ -906,6 +906,7 @@ + { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) }, + /* Crucible Devices */ + { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, + { }, /* Optional parameter entry */ + { } /* Terminating entry */ + }; +Index: linux-3.10-3.10.11/drivers/usb/serial/ftdi_sio_ids.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/serial/ftdi_sio_ids.h 2014-05-05 11:49:02.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/serial/ftdi_sio_ids.h 2014-05-05 12:50:11.000000000 +0000 +@@ -1307,3 +1307,9 @@ + * Manufacturer: Crucible Technologies + */ + #define FTDI_CT_COMET_PID 0x8e08 ++ ++/* ++ * Product: Z3X Box ++ * Manufacturer: Smart GSM Team ++ */ ++#define FTDI_Z3X_PID 0x0011 +Index: linux-3.10-3.10.11/dummy/rpi_1500_a73e47ff525d2a69d61767a5928ba00937f77e1b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1500_a73e47ff525d2a69d61767a5928ba00937f77e1b.txt 2014-05-05 12:50:11.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1501_40f3a9e5aea1753ececbcbbfe483b0c05788b001.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1501_40f3a9e5aea1753ececbcbbfe483b0c05788b001.patch --- linux-3.10.11/debian/patches/rpi/rpi_1501_40f3a9e5aea1753ececbcbbfe483b0c05788b001.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1501_40f3a9e5aea1753ececbcbbfe483b0c05788b001.patch 2014-05-05 12:50:12.000000000 +0000 @@ -0,0 +1,35 @@ +commit 40f3a9e5aea1753ececbcbbfe483b0c05788b001 +Author: Russ Anderson +Date: Mon Oct 14 11:17:34 2013 -0500 + + x86: Update UV3 hub revision ID + + commit dd3c9c4b603c664fedc12facf180db0f1794aafe upstream. + + The UV3 hub revision ID is different than expected. The first + revision was supposed to start at 1 but instead will start at 0. + + Signed-off-by: Russ Anderson + Link: http://lkml.kernel.org/r/20131014161733.GA6274@sgi.com + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/x86/kernel/apic/x2apic_uv_x.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/x86/kernel/apic/x2apic_uv_x.c 2014-05-05 11:49:02.000000000 +0000 ++++ linux-3.10-3.10.11/arch/x86/kernel/apic/x2apic_uv_x.c 2014-05-05 12:50:12.000000000 +0000 +@@ -98,7 +98,7 @@ + break; + case UV3_HUB_PART_NUMBER: + case UV3_HUB_PART_NUMBER_X: +- uv_min_hub_revision_id += UV3_HUB_REVISION_BASE - 1; ++ uv_min_hub_revision_id += UV3_HUB_REVISION_BASE; + break; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1501_40f3a9e5aea1753ececbcbbfe483b0c05788b001.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1501_40f3a9e5aea1753ececbcbbfe483b0c05788b001.txt 2014-05-05 12:50:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1502_f606b358df6e174cd57f0509e5f5299bd4a73854.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1502_f606b358df6e174cd57f0509e5f5299bd4a73854.patch --- linux-3.10.11/debian/patches/rpi/rpi_1502_f606b358df6e174cd57f0509e5f5299bd4a73854.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1502_f606b358df6e174cd57f0509e5f5299bd4a73854.patch 2014-05-05 12:50:13.000000000 +0000 @@ -0,0 +1,50 @@ +commit f606b358df6e174cd57f0509e5f5299bd4a73854 +Author: Dirk Brandewie +Date: Tue Oct 15 11:06:14 2013 -0700 + + cpufreq / intel_pstate: Fix max_perf_pct on resume + + commit 52e0a509e5d6f902ec26bc2a8bb02b137dc453be upstream. + + If the system is suspended while max_perf_pct is less than 100 percent + or no_turbo set policy->{min,max} will be set incorrectly with scaled + values which turn the scaled values into hard limits. + + References: https://bugzilla.kernel.org/show_bug.cgi?id=61241 + Reported-by: Patrick Bartels + Signed-off-by: Dirk Brandewie + Signed-off-by: Rafael J. Wysocki + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/cpufreq/intel_pstate.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/cpufreq/intel_pstate.c 2014-05-05 11:49:01.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/cpufreq/intel_pstate.c 2014-05-05 12:50:12.000000000 +0000 +@@ -629,8 +629,8 @@ + + static int __cpuinit intel_pstate_cpu_init(struct cpufreq_policy *policy) + { +- int rc, min_pstate, max_pstate; + struct cpudata *cpu; ++ int rc; + + rc = intel_pstate_init_cpu(policy->cpu); + if (rc) +@@ -644,9 +644,8 @@ + else + policy->policy = CPUFREQ_POLICY_POWERSAVE; + +- intel_pstate_get_min_max(cpu, &min_pstate, &max_pstate); +- policy->min = min_pstate * 100000; +- policy->max = max_pstate * 100000; ++ policy->min = cpu->pstate.min_pstate * 100000; ++ policy->max = cpu->pstate.turbo_pstate * 100000; + + /* cpuinfo and default policy values */ + policy->cpuinfo.min_freq = cpu->pstate.min_pstate * 100000; +Index: linux-3.10-3.10.11/dummy/rpi_1502_f606b358df6e174cd57f0509e5f5299bd4a73854.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1502_f606b358df6e174cd57f0509e5f5299bd4a73854.txt 2014-05-05 12:50:12.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1503_955a23e181561a792d6e4c1572848b7ba306499f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1503_955a23e181561a792d6e4c1572848b7ba306499f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1503_955a23e181561a792d6e4c1572848b7ba306499f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1503_955a23e181561a792d6e4c1572848b7ba306499f.patch 2014-05-05 12:50:14.000000000 +0000 @@ -0,0 +1,31 @@ +commit 955a23e181561a792d6e4c1572848b7ba306499f +Author: Kent Overstreet +Date: Tue Oct 22 15:35:50 2013 -0700 + + bcache: Fixed incorrect order of arguments to bio_alloc_bioset() + + commit d4eddd42f592a0cf06818fae694a3d271f842e4d upstream. + + Signed-off-by: Kent Overstreet + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/bcache/request.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/bcache/request.c 2014-05-05 12:48:18.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/bcache/request.c 2014-05-05 12:50:13.000000000 +0000 +@@ -1059,7 +1059,7 @@ + + if (bio->bi_rw & REQ_FLUSH) { + /* Also need to send a flush to the backing device */ +- struct bio *flush = bio_alloc_bioset(0, GFP_NOIO, ++ struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0, + dc->disk.bio_split); + + flush->bi_rw = WRITE_FLUSH; +Index: linux-3.10-3.10.11/dummy/rpi_1503_955a23e181561a792d6e4c1572848b7ba306499f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1503_955a23e181561a792d6e4c1572848b7ba306499f.txt 2014-05-05 12:50:13.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1504_5be794dc4bb66266acc91eb589ace48e82a6c77e.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1504_5be794dc4bb66266acc91eb589ace48e82a6c77e.patch --- linux-3.10.11/debian/patches/rpi/rpi_1504_5be794dc4bb66266acc91eb589ace48e82a6c77e.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1504_5be794dc4bb66266acc91eb589ace48e82a6c77e.patch 2014-05-05 12:50:14.000000000 +0000 @@ -0,0 +1,79 @@ +commit 5be794dc4bb66266acc91eb589ace48e82a6c77e +Author: Anjana V Kumar +Date: Sat Oct 12 10:59:17 2013 +0800 + + cgroup: fix to break the while loop in cgroup_attach_task() correctly + + commit ea84753c98a7ac6b74e530b64c444a912b3835ca upstream. + + Both Anjana and Eunki reported a stall in the while_each_thread loop + in cgroup_attach_task(). + + It's because, when we attach a single thread to a cgroup, if the cgroup + is exiting or is already in that cgroup, we won't break the loop. + + If the task is already in the cgroup, the bug can lead to another thread + being attached to the cgroup unexpectedly: + + # echo 5207 > tasks + # cat tasks + 5207 + # echo 5207 > tasks + # cat tasks + 5207 + 5215 + + What's worse, if the task to be attached isn't the leader of the thread + group, we might never exit the loop, hence cpu stall. Thanks for Oleg's + analysis. + + This bug was introduced by commit 081aa458c38ba576bdd4265fc807fa95b48b9e79 + ("cgroup: consolidate cgroup_attach_task() and cgroup_attach_proc()") + + [ lizf: - fixed the first continue, pointed out by Oleg, + - rewrote changelog. ] + + Reported-by: Eunki Kim + Reported-by: Anjana V Kumar + Signed-off-by: Anjana V Kumar + Signed-off-by: Li Zefan + Signed-off-by: Tejun Heo + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/cgroup.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/cgroup.c 2014-05-05 11:49:01.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/cgroup.c 2014-05-05 12:50:14.000000000 +0000 +@@ -1995,7 +1995,7 @@ + + /* @tsk either already exited or can't exit until the end */ + if (tsk->flags & PF_EXITING) +- continue; ++ goto next; + + /* as per above, nr_threads may decrease, but not increase. */ + BUG_ON(i >= group_size); +@@ -2003,7 +2003,7 @@ + ent.cgrp = task_cgroup_from_root(tsk, root); + /* nothing to do if this task is already in the cgroup */ + if (ent.cgrp == cgrp) +- continue; ++ goto next; + /* + * saying GFP_ATOMIC has no effect here because we did prealloc + * earlier, but it's good form to communicate our expectations. +@@ -2011,7 +2011,7 @@ + retval = flex_array_put(group, i, &ent, GFP_ATOMIC); + BUG_ON(retval != 0); + i++; +- ++ next: + if (!threadgroup) + break; + } while_each_thread(leader, tsk); +Index: linux-3.10-3.10.11/dummy/rpi_1504_5be794dc4bb66266acc91eb589ace48e82a6c77e.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1504_5be794dc4bb66266acc91eb589ace48e82a6c77e.txt 2014-05-05 12:50:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1505_715a606d73f63e94259e6251565e6e12e3271d0f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1505_715a606d73f63e94259e6251565e6e12e3271d0f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1505_715a606d73f63e94259e6251565e6e12e3271d0f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1505_715a606d73f63e94259e6251565e6e12e3271d0f.patch 2014-05-05 12:50:15.000000000 +0000 @@ -0,0 +1,92 @@ +commit 715a606d73f63e94259e6251565e6e12e3271d0f +Author: Emmanuel Grumbach +Date: Mon Sep 16 11:12:07 2013 +0300 + + mac80211: correctly close cancelled scans + + commit a754055a1296fcbe6f32de3a5eaca6efb2fd1865 upstream. + + __ieee80211_scan_completed is called from a worker. This + means that the following flow is possible. + + * driver calls ieee80211_scan_completed + * mac80211 cancels the scan (that is already complete) + * __ieee80211_scan_completed runs + + When scan_work will finally run, it will see that the scan + hasn't been aborted and might even trigger another scan on + another band. This leads to a situation where cfg80211's + scan is not done and no further scan can be issued. + + Fix this by setting a new flag when a HW scan is being + cancelled so that no other scan will be triggered. + + Signed-off-by: Emmanuel Grumbach + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/mac80211/ieee80211_i.h +=================================================================== +--- linux-3.10-3.10.11.orig/net/mac80211/ieee80211_i.h 2014-05-05 11:49:00.000000000 +0000 ++++ linux-3.10-3.10.11/net/mac80211/ieee80211_i.h 2014-05-05 12:50:15.000000000 +0000 +@@ -842,6 +842,8 @@ + * that the scan completed. + * @SCAN_ABORTED: Set for our scan work function when the driver reported + * a scan complete for an aborted scan. ++ * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being ++ * cancelled. + */ + enum { + SCAN_SW_SCANNING, +@@ -849,6 +851,7 @@ + SCAN_ONCHANNEL_SCANNING, + SCAN_COMPLETED, + SCAN_ABORTED, ++ SCAN_HW_CANCELLED, + }; + + /** +Index: linux-3.10-3.10.11/net/mac80211/scan.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/mac80211/scan.c 2014-05-05 11:49:00.000000000 +0000 ++++ linux-3.10-3.10.11/net/mac80211/scan.c 2014-05-05 12:50:15.000000000 +0000 +@@ -202,6 +202,9 @@ + enum ieee80211_band band; + int i, ielen, n_chans; + ++ if (test_bit(SCAN_HW_CANCELLED, &local->scanning)) ++ return false; ++ + do { + if (local->hw_scan_band == IEEE80211_NUM_BANDS) + return false; +@@ -878,7 +881,23 @@ + if (!local->scan_req) + goto out; + ++ /* ++ * We have a scan running and the driver already reported completion, ++ * but the worker hasn't run yet or is stuck on the mutex - mark it as ++ * cancelled. ++ */ ++ if (test_bit(SCAN_HW_SCANNING, &local->scanning) && ++ test_bit(SCAN_COMPLETED, &local->scanning)) { ++ set_bit(SCAN_HW_CANCELLED, &local->scanning); ++ goto out; ++ } ++ + if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { ++ /* ++ * Make sure that __ieee80211_scan_completed doesn't trigger a ++ * scan on another band. ++ */ ++ set_bit(SCAN_HW_CANCELLED, &local->scanning); + if (local->ops->cancel_hw_scan) + drv_cancel_hw_scan(local, + rcu_dereference_protected(local->scan_sdata, +Index: linux-3.10-3.10.11/dummy/rpi_1505_715a606d73f63e94259e6251565e6e12e3271d0f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1505_715a606d73f63e94259e6251565e6e12e3271d0f.txt 2014-05-05 12:50:15.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1506_d7da0fc72d073181e65970edad0a9461542e02c6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1506_d7da0fc72d073181e65970edad0a9461542e02c6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1506_d7da0fc72d073181e65970edad0a9461542e02c6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1506_d7da0fc72d073181e65970edad0a9461542e02c6.patch 2014-05-05 12:50:16.000000000 +0000 @@ -0,0 +1,43 @@ +commit d7da0fc72d073181e65970edad0a9461542e02c6 +Author: Felix Fietkau +Date: Tue Sep 17 11:15:43 2013 +0200 + + mac80211: drop spoofed packets in ad-hoc mode + + commit 6329b8d917adc077caa60c2447385554130853a3 upstream. + + If an Ad-Hoc node receives packets with the Cell ID or its own MAC + address as source address, it hits a WARN_ON in sta_info_insert_check() + With many packets, this can massively spam the logs. One way that this + can easily happen is through having Cisco APs in the area with rouge AP + detection and countermeasures enabled. + Such Cisco APs will regularly send fake beacons, disassoc and deauth + packets that trigger these warnings. + + To fix this issue, drop such spoofed packets early in the rx path. + + Reported-by: Thomas Huehn + Signed-off-by: Felix Fietkau + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/mac80211/rx.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/mac80211/rx.c 2014-05-05 11:49:00.000000000 +0000 ++++ linux-3.10-3.10.11/net/mac80211/rx.c 2014-05-05 12:50:16.000000000 +0000 +@@ -3002,6 +3002,9 @@ + case NL80211_IFTYPE_ADHOC: + if (!bssid) + return 0; ++ if (ether_addr_equal(sdata->vif.addr, hdr->addr2) || ++ ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2)) ++ return 0; + if (ieee80211_is_beacon(hdr->frame_control)) { + return 1; + } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { +Index: linux-3.10-3.10.11/dummy/rpi_1506_d7da0fc72d073181e65970edad0a9461542e02c6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1506_d7da0fc72d073181e65970edad0a9461542e02c6.txt 2014-05-05 12:50:16.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1507_8d4f150d4e8d52a761e424f9f640c57cd118105f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1507_8d4f150d4e8d52a761e424f9f640c57cd118105f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1507_8d4f150d4e8d52a761e424f9f640c57cd118105f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1507_8d4f150d4e8d52a761e424f9f640c57cd118105f.patch 2014-05-05 12:50:17.000000000 +0000 @@ -0,0 +1,47 @@ +commit 8d4f150d4e8d52a761e424f9f640c57cd118105f +Author: Felix Fietkau +Date: Sun Sep 29 21:39:33 2013 +0200 + + mac80211: use sta_info_get_bss() for nl80211 tx and client probing + + commit 03bb7f42765ce596604f03d179f3137d7df05bba upstream. + + This allows calls for clients in AP_VLANs (e.g. for 4-addr) to succeed + + Signed-off-by: Felix Fietkau + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/mac80211/cfg.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/mac80211/cfg.c 2014-05-05 11:49:00.000000000 +0000 ++++ linux-3.10-3.10.11/net/mac80211/cfg.c 2014-05-05 12:50:17.000000000 +0000 +@@ -3315,7 +3315,7 @@ + return -EINVAL; + } + band = chanctx_conf->def.chan->band; +- sta = sta_info_get(sdata, peer); ++ sta = sta_info_get_bss(sdata, peer); + if (sta) { + qos = test_sta_flag(sta, WLAN_STA_WME); + } else { +Index: linux-3.10-3.10.11/net/mac80211/tx.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/mac80211/tx.c 2014-05-05 11:49:00.000000000 +0000 ++++ linux-3.10-3.10.11/net/mac80211/tx.c 2014-05-05 12:50:17.000000000 +0000 +@@ -1100,7 +1100,8 @@ + tx->sta = rcu_dereference(sdata->u.vlan.sta); + if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) + return TX_DROP; +- } else if (info->flags & IEEE80211_TX_CTL_INJECTED || ++ } else if (info->flags & (IEEE80211_TX_CTL_INJECTED | ++ IEEE80211_TX_INTFL_NL80211_FRAME_TX) || + tx->sdata->control_port_protocol == tx->skb->protocol) { + tx->sta = sta_info_get_bss(sdata, hdr->addr1); + } +Index: linux-3.10-3.10.11/dummy/rpi_1507_8d4f150d4e8d52a761e424f9f640c57cd118105f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1507_8d4f150d4e8d52a761e424f9f640c57cd118105f.txt 2014-05-05 12:50:17.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1508_31da12cec6d7882acb2bd968566b1cfbbcae695a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1508_31da12cec6d7882acb2bd968566b1cfbbcae695a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1508_31da12cec6d7882acb2bd968566b1cfbbcae695a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1508_31da12cec6d7882acb2bd968566b1cfbbcae695a.patch 2014-05-05 12:50:19.000000000 +0000 @@ -0,0 +1,40 @@ +commit 31da12cec6d7882acb2bd968566b1cfbbcae695a +Author: Felix Fietkau +Date: Sun Sep 29 21:39:34 2013 +0200 + + mac80211: update sta->last_rx on acked tx frames + + commit 0c5b93290b2f3c7a376567c03ae8d385b0e99851 upstream. + + When clients are idle for too long, hostapd sends nullfunc frames for + probing. When those are acked by the client, the idle time needs to be + updated. + + To make this work (and to avoid unnecessary probing), update sta->last_rx + whenever an ACK was received for a tx packet. Only do this if the flag + IEEE80211_HW_REPORTS_TX_ACK_STATUS is set. + + Signed-off-by: Felix Fietkau + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/mac80211/status.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/mac80211/status.c 2014-05-05 11:48:59.000000000 +0000 ++++ linux-3.10-3.10.11/net/mac80211/status.c 2014-05-05 12:50:18.000000000 +0000 +@@ -180,6 +180,9 @@ + struct ieee80211_local *local = sta->local; + struct ieee80211_sub_if_data *sdata = sta->sdata; + ++ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) ++ sta->last_rx = jiffies; ++ + if (ieee80211_is_data_qos(mgmt->frame_control)) { + struct ieee80211_hdr *hdr = (void *) skb->data; + u8 *qc = ieee80211_get_qos_ctl(hdr); +Index: linux-3.10-3.10.11/dummy/rpi_1508_31da12cec6d7882acb2bd968566b1cfbbcae695a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1508_31da12cec6d7882acb2bd968566b1cfbbcae695a.txt 2014-05-05 12:50:18.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1509_0b1621f62382e9b6f97b35861e9ade1a979b95b8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1509_0b1621f62382e9b6f97b35861e9ade1a979b95b8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1509_0b1621f62382e9b6f97b35861e9ade1a979b95b8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1509_0b1621f62382e9b6f97b35861e9ade1a979b95b8.patch 2014-05-05 12:50:19.000000000 +0000 @@ -0,0 +1,39 @@ +commit 0b1621f62382e9b6f97b35861e9ade1a979b95b8 +Author: Johannes Berg +Date: Fri Oct 11 15:47:06 2013 +0200 + + mac80211: fix crash if bitrate calculation goes wrong + + commit d86aa4f8ca58898ec6a94c0635da20b948171ed7 upstream. + + If a frame's timestamp is calculated, and the bitrate + calculation goes wrong and returns zero, the system + will attempt to divide by zero and crash. Catch this + case and print the rate information that the driver + reported when this happens. + + Reported-by: Thomas Lindroth + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/mac80211/util.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/mac80211/util.c 2014-05-05 11:48:59.000000000 +0000 ++++ linux-3.10-3.10.11/net/mac80211/util.c 2014-05-05 12:50:19.000000000 +0000 +@@ -2174,6 +2174,10 @@ + } + + rate = cfg80211_calculate_bitrate(&ri); ++ if (WARN_ONCE(!rate, ++ "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n", ++ status->flag, status->rate_idx, status->vht_nss)) ++ return 0; + + /* rewind from end of MPDU */ + if (status->flag & RX_FLAG_MACTIME_END) +Index: linux-3.10-3.10.11/dummy/rpi_1509_0b1621f62382e9b6f97b35861e9ade1a979b95b8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1509_0b1621f62382e9b6f97b35861e9ade1a979b95b8.txt 2014-05-05 12:50:19.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1510_fc756d89ff073a9c7fb8e4788fa63705d3d8f2a2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1510_fc756d89ff073a9c7fb8e4788fa63705d3d8f2a2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1510_fc756d89ff073a9c7fb8e4788fa63705d3d8f2a2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1510_fc756d89ff073a9c7fb8e4788fa63705d3d8f2a2.patch 2014-05-05 12:50:20.000000000 +0000 @@ -0,0 +1,72 @@ +commit fc756d89ff073a9c7fb8e4788fa63705d3d8f2a2 +Author: Felix Fietkau +Date: Sat Oct 5 14:09:30 2013 +0200 + + ath9k: fix tx queue scheduling after channel changes + + commit ec30326ea773900da210c495e14cfeb532550ba2 upstream. + + Otherwise, if queues are full during a scan, tx scheduling does not + resume after switching back to the home channel. + + Signed-off-by: Felix Fietkau + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/ath/ath9k/main.c 2014-05-05 11:48:59.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/ath/ath9k/main.c 2014-05-05 12:50:20.000000000 +0000 +@@ -209,6 +209,7 @@ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + unsigned long flags; ++ int i; + + if (ath_startrecv(sc) != 0) { + ath_err(common, "Unable to restart recv logic\n"); +@@ -236,6 +237,15 @@ + } + work: + ath_restart_work(sc); ++ ++ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { ++ if (!ATH_TXQ_SETUP(sc, i)) ++ continue; ++ ++ spin_lock_bh(&sc->tx.txq[i].axq_lock); ++ ath_txq_schedule(sc, &sc->tx.txq[i]); ++ spin_unlock_bh(&sc->tx.txq[i].axq_lock); ++ } + } + + if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) +@@ -543,21 +553,10 @@ + + static int ath_reset(struct ath_softc *sc) + { +- int i, r; ++ int r; + + ath9k_ps_wakeup(sc); +- + r = ath_reset_internal(sc, NULL); +- +- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { +- if (!ATH_TXQ_SETUP(sc, i)) +- continue; +- +- spin_lock_bh(&sc->tx.txq[i].axq_lock); +- ath_txq_schedule(sc, &sc->tx.txq[i]); +- spin_unlock_bh(&sc->tx.txq[i].axq_lock); +- } +- + ath9k_ps_restore(sc); + + return r; +Index: linux-3.10-3.10.11/dummy/rpi_1510_fc756d89ff073a9c7fb8e4788fa63705d3d8f2a2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1510_fc756d89ff073a9c7fb8e4788fa63705d3d8f2a2.txt 2014-05-05 12:50:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1511_e83301f88258e3f204392cf59b0ffd706a051a26.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1511_e83301f88258e3f204392cf59b0ffd706a051a26.patch --- linux-3.10.11/debian/patches/rpi/rpi_1511_e83301f88258e3f204392cf59b0ffd706a051a26.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1511_e83301f88258e3f204392cf59b0ffd706a051a26.patch 2014-05-05 12:50:21.000000000 +0000 @@ -0,0 +1,46 @@ +commit e83301f88258e3f204392cf59b0ffd706a051a26 +Author: Bruno Randolf +Date: Thu Sep 26 16:55:28 2013 +0100 + + cfg80211: fix warning when using WEXT for IBSS + + commit f478f33a93f9353dcd1fe55445343d76b1c3f84a upstream. + + Fix kernel warning when using WEXT for configuring ad-hoc mode, + e.g. "iwconfig wlan0 essid test channel 1" + + WARNING: at net/wireless/chan.c:373 cfg80211_chandef_usable+0x50/0x21c [cfg80211]() + + The warning is caused by an uninitialized variable center_freq1. + + Signed-off-by: Bruno Randolf + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/net/wireless/ibss.c +=================================================================== +--- linux-3.10-3.10.11.orig/net/wireless/ibss.c 2014-05-05 11:48:58.000000000 +0000 ++++ linux-3.10-3.10.11/net/wireless/ibss.c 2014-05-05 12:50:20.000000000 +0000 +@@ -269,6 +269,8 @@ + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + wdev->wext.ibss.chandef.chan = chan; ++ wdev->wext.ibss.chandef.center_freq1 = ++ chan->center_freq; + break; + } + +@@ -353,6 +355,7 @@ + if (chan) { + wdev->wext.ibss.chandef.chan = chan; + wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; ++ wdev->wext.ibss.chandef.center_freq1 = freq; + wdev->wext.ibss.channel_fixed = true; + } else { + /* cfg80211_ibss_wext_join will pick one if needed */ +Index: linux-3.10-3.10.11/dummy/rpi_1511_e83301f88258e3f204392cf59b0ffd706a051a26.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1511_e83301f88258e3f204392cf59b0ffd706a051a26.txt 2014-05-05 12:50:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1512_6f2c0ed7835fd30d6c137198cf1dc964f061f132.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1512_6f2c0ed7835fd30d6c137198cf1dc964f061f132.patch --- linux-3.10.11/debian/patches/rpi/rpi_1512_6f2c0ed7835fd30d6c137198cf1dc964f061f132.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1512_6f2c0ed7835fd30d6c137198cf1dc964f061f132.patch 2014-05-05 12:50:22.000000000 +0000 @@ -0,0 +1,58 @@ +commit 6f2c0ed7835fd30d6c137198cf1dc964f061f132 +Author: Amitkumar Karwar +Date: Fri Sep 27 10:55:38 2013 -0700 + + mwifiex: fix SDIO interrupt lost issue + + commit 453b0c3f6910672f79da354077af728d92f95c5b upstream. + + 601216e "mwifiex: process RX packets in SDIO IRQ thread directly" + introduced a command timeout issue which can be reproduced easily on + an AM33xx platform using a test application written by Daniel Mack: + + https://gist.github.com/zonque/6579314 + + mwifiex_main_process() is called from both the SDIO handler and + the workqueue. In case an interrupt occurs right after the + int_status check, but before updating the mwifiex_processing flag, + this interrupt gets lost, resulting in a command timeout and + consequently a card reset. + + Let main_proc_lock protect both int_status and mwifiex_processing + flag. This fixes the interrupt lost issue. + + Reported-by: Sven Neumann + Reported-by: Andreas Fenkart + Tested-by: Daniel Mack + Reviewed-by: Dylan Reid + Signed-off-by: Amitkumar Karwar + Signed-off-by: Bing Zhao + Signed-off-by: Paul Stewart + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/mwifiex/main.c 2014-05-05 12:46:47.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/mwifiex/main.c 2014-05-05 12:50:21.000000000 +0000 +@@ -270,10 +270,12 @@ + } + } while (true); + +- if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter)) ++ spin_lock_irqsave(&adapter->main_proc_lock, flags); ++ if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter)) { ++ spin_unlock_irqrestore(&adapter->main_proc_lock, flags); + goto process_start; ++ } + +- spin_lock_irqsave(&adapter->main_proc_lock, flags); + adapter->mwifiex_processing = false; + spin_unlock_irqrestore(&adapter->main_proc_lock, flags); + +Index: linux-3.10-3.10.11/dummy/rpi_1512_6f2c0ed7835fd30d6c137198cf1dc964f061f132.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1512_6f2c0ed7835fd30d6c137198cf1dc964f061f132.txt 2014-05-05 12:50:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1513_3af669ca9923d504d5476bcfe04eaf4bbde03515.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1513_3af669ca9923d504d5476bcfe04eaf4bbde03515.patch --- linux-3.10.11/debian/patches/rpi/rpi_1513_3af669ca9923d504d5476bcfe04eaf4bbde03515.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1513_3af669ca9923d504d5476bcfe04eaf4bbde03515.patch 2014-05-05 12:50:23.000000000 +0000 @@ -0,0 +1,37 @@ +commit 3af669ca9923d504d5476bcfe04eaf4bbde03515 +Author: Mark Cave-Ayland +Date: Tue Oct 8 10:18:20 2013 -0500 + + rtlwifi: rtl8192cu: Fix error in pointer arithmetic + + commit 9473ca6e920a3b9ca902753ce52833657f9221cc upstream. + + An error in calculating the offset in an skb causes the driver to read + essential device info from the wrong locations. The main effect is that + automatic gain calculations are nonsense. + + Signed-off-by: Mark Cave-Ayland + Signed-off-by: Larry Finger + Signed-off-by: John W. Linville + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c 2014-05-05 11:48:58.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c 2014-05-05 12:50:22.000000000 +0000 +@@ -343,7 +343,8 @@ + (bool)GET_RX_DESC_PAGGR(pdesc)); + rx_status->mactime = GET_RX_DESC_TSFL(pdesc); + if (phystatus) { +- p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); ++ p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + ++ stats->rx_bufshift); + rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, + p_drvinfo); + } +Index: linux-3.10-3.10.11/dummy/rpi_1513_3af669ca9923d504d5476bcfe04eaf4bbde03515.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1513_3af669ca9923d504d5476bcfe04eaf4bbde03515.txt 2014-05-05 12:50:22.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1514_fa2025dc177d9bef300b48289b689a5d667f5ae9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1514_fa2025dc177d9bef300b48289b689a5d667f5ae9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1514_fa2025dc177d9bef300b48289b689a5d667f5ae9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1514_fa2025dc177d9bef300b48289b689a5d667f5ae9.patch 2014-05-05 12:50:24.000000000 +0000 @@ -0,0 +1,99 @@ +commit fa2025dc177d9bef300b48289b689a5d667f5ae9 +Author: Emmanuel Grumbach +Date: Tue Sep 24 19:34:26 2013 +0300 + + iwlwifi: pcie: add SKUs for 6000, 6005 and 6235 series + + commit 08a5dd3842f2ac61c6d69661d2d96022df8ae359 upstream. + + Add some new PCI IDs to the table for 6000, 6005 and 6235 series. + + Signed-off-by: Emmanuel Grumbach + Signed-off-by: Johannes Berg + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-6000.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/iwlwifi/iwl-6000.c 2014-05-05 12:41:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-6000.c 2014-05-05 12:50:23.000000000 +0000 +@@ -268,6 +268,12 @@ + .ht_params = &iwl6000_ht_params, + }; + ++const struct iwl_cfg iwl6035_2agn_sff_cfg = { ++ .name = "Intel(R) Centrino(R) Ultimate-N 6235 AGN", ++ IWL_DEVICE_6035, ++ .ht_params = &iwl6000_ht_params, ++}; ++ + const struct iwl_cfg iwl1030_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", + IWL_DEVICE_6030, +Index: linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-config.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/iwlwifi/iwl-config.h 2014-05-05 11:48:57.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/iwl-config.h 2014-05-05 12:50:23.000000000 +0000 +@@ -316,6 +316,7 @@ + extern const struct iwl_cfg iwl2000_2bgn_d_cfg; + extern const struct iwl_cfg iwl2030_2bgn_cfg; + extern const struct iwl_cfg iwl6035_2agn_cfg; ++extern const struct iwl_cfg iwl6035_2agn_sff_cfg; + extern const struct iwl_cfg iwl105_bgn_cfg; + extern const struct iwl_cfg iwl105_bgn_d_cfg; + extern const struct iwl_cfg iwl135_bgn_cfg; +Index: linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/pcie/drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/wireless/iwlwifi/pcie/drv.c 2014-05-05 11:48:57.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/wireless/iwlwifi/pcie/drv.c 2014-05-05 12:50:23.000000000 +0000 +@@ -138,13 +138,16 @@ + + /* 6x00 Series */ + {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, ++ {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, ++ {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, ++ {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, + +@@ -152,12 +155,16 @@ + {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, ++ {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, ++ {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, ++ {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */ + {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */ +@@ -239,8 +246,11 @@ + + /* 6x35 Series */ + {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, ++ {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, + +Index: linux-3.10-3.10.11/dummy/rpi_1514_fa2025dc177d9bef300b48289b689a5d667f5ae9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1514_fa2025dc177d9bef300b48289b689a5d667f5ae9.txt 2014-05-05 12:50:23.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1515_4ac4eb6520aa52f77be36780bbe5b17ca3bce983.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1515_4ac4eb6520aa52f77be36780bbe5b17ca3bce983.patch --- linux-3.10.11/debian/patches/rpi/rpi_1515_4ac4eb6520aa52f77be36780bbe5b17ca3bce983.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1515_4ac4eb6520aa52f77be36780bbe5b17ca3bce983.patch 2014-05-05 12:50:24.000000000 +0000 @@ -0,0 +1,42 @@ +commit 4ac4eb6520aa52f77be36780bbe5b17ca3bce983 +Author: Dave Kleikamp +Date: Fri Sep 6 21:49:56 2013 -0500 + + jfs: fix error path in ialloc + + commit 8660998608cfa1077e560034db81885af8e1e885 upstream. + + If insert_inode_locked() fails, we shouldn't be calling + unlock_new_inode(). + + Signed-off-by: Dave Kleikamp + Tested-by: Michael L. Semon + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/jfs/jfs_inode.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/jfs/jfs_inode.c 2014-05-05 11:48:57.000000000 +0000 ++++ linux-3.10-3.10.11/fs/jfs/jfs_inode.c 2014-05-05 12:50:24.000000000 +0000 +@@ -95,7 +95,7 @@ + + if (insert_inode_locked(inode) < 0) { + rc = -EINVAL; +- goto fail_unlock; ++ goto fail_put; + } + + inode_init_owner(inode, parent, mode); +@@ -156,7 +156,6 @@ + fail_drop: + dquot_drop(inode); + inode->i_flags |= S_NOQUOTA; +-fail_unlock: + clear_nlink(inode); + unlock_new_inode(inode); + fail_put: +Index: linux-3.10-3.10.11/dummy/rpi_1515_4ac4eb6520aa52f77be36780bbe5b17ca3bce983.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1515_4ac4eb6520aa52f77be36780bbe5b17ca3bce983.txt 2014-05-05 12:50:24.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1516_1a64b62db0883ba42db1c3860a8aa25aa398e020.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1516_1a64b62db0883ba42db1c3860a8aa25aa398e020.patch --- linux-3.10.11/debian/patches/rpi/rpi_1516_1a64b62db0883ba42db1c3860a8aa25aa398e020.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1516_1a64b62db0883ba42db1c3860a8aa25aa398e020.patch 2014-05-05 12:50:25.000000000 +0000 @@ -0,0 +1,46 @@ +commit 1a64b62db0883ba42db1c3860a8aa25aa398e020 +Author: Marc Kleine-Budde +Date: Wed Oct 9 12:19:19 2013 +0200 + + can: at91-can: fix device to driver data mapping for platform devices + + commit 5abbeea553c8260ed4e2ac4aae962aff800b6c6d upstream. + + In commit: + + 3078cde7 can: at91_can: add dt support + + device tree support was added to the at91_can driver. In this commit the + mapping of device to driver data was mixed up. This results in the sam9x5 + parameters being used for the sam9263 and the workaround for the broken mailbox + 0 on the sam9263 not being activated. + + This patch fixes the broken platform_device_id table. + + Cc: Ludovic Desroches + Signed-off-by: Marc Kleine-Budde + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/can/at91_can.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/can/at91_can.c 2014-05-05 11:48:56.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/can/at91_can.c 2014-05-05 12:50:25.000000000 +0000 +@@ -1409,10 +1409,10 @@ + + static const struct platform_device_id at91_can_id_table[] = { + { +- .name = "at91_can", ++ .name = "at91sam9x5_can", + .driver_data = (kernel_ulong_t)&at91_at91sam9x5_data, + }, { +- .name = "at91sam9x5_can", ++ .name = "at91_can", + .driver_data = (kernel_ulong_t)&at91_at91sam9263_data, + }, { + /* sentinel */ +Index: linux-3.10-3.10.11/dummy/rpi_1516_1a64b62db0883ba42db1c3860a8aa25aa398e020.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1516_1a64b62db0883ba42db1c3860a8aa25aa398e020.txt 2014-05-05 12:50:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1517_e350ff50bcd46d650d56015a1416c622d057ec90.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1517_e350ff50bcd46d650d56015a1416c622d057ec90.patch --- linux-3.10.11/debian/patches/rpi/rpi_1517_e350ff50bcd46d650d56015a1416c622d057ec90.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1517_e350ff50bcd46d650d56015a1416c622d057ec90.patch 2014-05-05 12:50:26.000000000 +0000 @@ -0,0 +1,39 @@ +commit e350ff50bcd46d650d56015a1416c622d057ec90 +Author: Marc Kleine-Budde +Date: Thu Oct 3 23:51:55 2013 +0200 + + can: flexcan: fix mx28 detection by rearanging OF match table + + commit e358784297992b012e8071764d996191dd2b1a54 upstream. + + The current implemetation of of_match_device() relies that the of_device_id + table in the driver is sorted from most specific to least specific compatible. + + Without this patch the mx28 is detected as the less specific p1010. This leads + to a p1010 specific workaround is activated on the mx28, which is not needed. + + Signed-off-by: Marc Kleine-Budde + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/can/flexcan.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/can/flexcan.c 2014-05-05 11:48:56.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/can/flexcan.c 2014-05-05 12:50:25.000000000 +0000 +@@ -983,9 +983,9 @@ + } + + static const struct of_device_id flexcan_of_match[] = { +- { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, +- { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, + { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, ++ { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, ++ { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, flexcan_of_match); +Index: linux-3.10-3.10.11/dummy/rpi_1517_e350ff50bcd46d650d56015a1416c622d057ec90.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1517_e350ff50bcd46d650d56015a1416c622d057ec90.txt 2014-05-05 12:50:25.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1518_d60241f65bdc363f1be2b099bd98ff13a96c1f0d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1518_d60241f65bdc363f1be2b099bd98ff13a96c1f0d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1518_d60241f65bdc363f1be2b099bd98ff13a96c1f0d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1518_d60241f65bdc363f1be2b099bd98ff13a96c1f0d.patch 2014-05-05 12:50:27.000000000 +0000 @@ -0,0 +1,76 @@ +commit d60241f65bdc363f1be2b099bd98ff13a96c1f0d +Author: Marc Kleine-Budde +Date: Fri Oct 4 10:52:36 2013 +0200 + + can: flexcan: flexcan_chip_start: fix regression, mark one MB for TX and abort pending TX + + commit d5a7b406c529e4595ce03dc8f6dcf7fa36f106fa upstream. + + In patch + + 0d1862e can: flexcan: fix flexcan_chip_start() on imx6 + + the loop in flexcan_chip_start() that iterates over all mailboxes after the + soft reset of the CAN core was removed. This loop put all mailboxes (even the + ones marked as reserved 1...7) into EMPTY/INACTIVE mode. On mailboxes 8...63, + this aborts any pending TX messages. + + After a cold boot there is random garbage in the mailboxes, which leads to + spontaneous transmit of CAN frames during first activation. Further if the + interface was disabled with a pending message (usually due to an error + condition on the CAN bus), this message is retransmitted after enabling the + interface again. + + This patch fixes the regression by: + 1) Limiting the maximum number of used mailboxes to 8, 0...7 are used by the RX + FIFO, 8 is used by TX. + 2) Marking the TX mailbox as EMPTY/INACTIVE, so that any pending TX of that + mailbox is aborted. + + Cc: Lothar Waßmann + Signed-off-by: Marc Kleine-Budde + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/net/can/flexcan.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/net/can/flexcan.c 2014-05-05 12:50:25.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/net/can/flexcan.c 2014-05-05 12:50:26.000000000 +0000 +@@ -63,7 +63,7 @@ + #define FLEXCAN_MCR_BCC BIT(16) + #define FLEXCAN_MCR_LPRIO_EN BIT(13) + #define FLEXCAN_MCR_AEN BIT(12) +-#define FLEXCAN_MCR_MAXMB(x) ((x) & 0xf) ++#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f) + #define FLEXCAN_MCR_IDAM_A (0 << 8) + #define FLEXCAN_MCR_IDAM_B (1 << 8) + #define FLEXCAN_MCR_IDAM_C (2 << 8) +@@ -745,9 +745,11 @@ + * + */ + reg_mcr = flexcan_read(®s->mcr); ++ reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); + reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | + FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | +- FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS; ++ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS | ++ FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID); + netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); + flexcan_write(reg_mcr, ®s->mcr); + +@@ -792,6 +794,10 @@ + ®s->cantxfg[i].can_ctrl); + } + ++ /* Abort any pending TX, mark Mailbox as INACTIVE */ ++ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), ++ ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); ++ + /* acceptance mask/acceptance code (accept everything) */ + flexcan_write(0x0, ®s->rxgmask); + flexcan_write(0x0, ®s->rx14mask); +Index: linux-3.10-3.10.11/dummy/rpi_1518_d60241f65bdc363f1be2b099bd98ff13a96c1f0d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1518_d60241f65bdc363f1be2b099bd98ff13a96c1f0d.txt 2014-05-05 12:50:26.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1519_da0d4136d107d926273c227fdeaf805159044f66.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1519_da0d4136d107d926273c227fdeaf805159044f66.patch --- linux-3.10.11/debian/patches/rpi/rpi_1519_da0d4136d107d926273c227fdeaf805159044f66.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1519_da0d4136d107d926273c227fdeaf805159044f66.patch 2014-05-05 12:50:27.000000000 +0000 @@ -0,0 +1,73 @@ +commit da0d4136d107d926273c227fdeaf805159044f66 +Author: Aaron Lu +Date: Thu Oct 10 13:22:36 2013 +0800 + + SCSI: sd: call blk_pm_runtime_init before add_disk + + commit 10c580e4239df5c3344ca00322eca86ab2de880b upstream. + + Sujit has found a race condition that would make q->nr_pending + unbalanced, it occurs as Sujit explained: + + " + sd_probe_async() -> + add_disk() -> + disk_add_event() -> + schedule(disk_events_workfn) + sd_revalidate_disk() + blk_pm_runtime_init() + return; + + Let's say the disk_events_workfn() calls sd_check_events() which tries + to send test_unit_ready() and because of sd_revalidate_disk() trying to + send another commands the test_unit_ready() might be re-queued as the + tagged command queuing is disabled. + + So the race condition is - + + Thread 1 | Thread 2 + sd_revalidate_disk() | sd_check_events() + ...nr_pending = 0 as q->dev = NULL| scsi_queue_insert() + blk_runtime_pm_init() | blk_pm_requeue_request() -> + | nr_pending = -1 since + | q->dev != NULL + " + + The problem is, the test_unit_ready request doesn't get counted the + first time it is queued, so the later decrement of q->nr_pending in + blk_pm_requeue_request makes it unbalanced. + + Fix this by calling blk_pm_runtime_init before add_disk so that all + requests initiated there will all be counted. + + Signed-off-by: Aaron Lu + Reported-and-tested-by: Sujit Reddy Thumma + Signed-off-by: James Bottomley + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/scsi/sd.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/sd.c 2014-05-05 12:43:43.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/sd.c 2014-05-05 12:50:27.000000000 +0000 +@@ -2843,6 +2843,7 @@ + gd->events |= DISK_EVENT_MEDIA_CHANGE; + } + ++ blk_pm_runtime_init(sdp->request_queue, dev); + add_disk(gd); + if (sdkp->capacity) + sd_dif_config_host(sdkp); +@@ -2851,7 +2852,6 @@ + + sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", + sdp->removable ? "removable " : ""); +- blk_pm_runtime_init(sdp->request_queue, dev); + scsi_autopm_put_device(sdp); + put_device(&sdkp->dev); + } +Index: linux-3.10-3.10.11/dummy/rpi_1519_da0d4136d107d926273c227fdeaf805159044f66.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1519_da0d4136d107d926273c227fdeaf805159044f66.txt 2014-05-05 12:50:27.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1520_4053771449476d9c323bd00c0c87bbd390588e55.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1520_4053771449476d9c323bd00c0c87bbd390588e55.patch --- linux-3.10.11/debian/patches/rpi/rpi_1520_4053771449476d9c323bd00c0c87bbd390588e55.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1520_4053771449476d9c323bd00c0c87bbd390588e55.patch 2014-05-05 12:50:28.000000000 +0000 @@ -0,0 +1,43 @@ +commit 4053771449476d9c323bd00c0c87bbd390588e55 +Author: Geyslan G. Bem +Date: Fri Oct 11 16:49:16 2013 -0300 + + ecryptfs: Fix memory leakage in keystore.c + + commit 3edc8376c06133e3386265a824869cad03a4efd4 upstream. + + In 'decrypt_pki_encrypted_session_key' function: + + Initializes 'payload' pointer and releases it on exit. + + Signed-off-by: Geyslan G. Bem + Signed-off-by: Tyler Hicks + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/ecryptfs/keystore.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/ecryptfs/keystore.c 2014-05-05 11:48:55.000000000 +0000 ++++ linux-3.10-3.10.11/fs/ecryptfs/keystore.c 2014-05-05 12:50:28.000000000 +0000 +@@ -1149,7 +1149,7 @@ + struct ecryptfs_msg_ctx *msg_ctx; + struct ecryptfs_message *msg = NULL; + char *auth_tok_sig; +- char *payload; ++ char *payload = NULL; + size_t payload_len = 0; + int rc; + +@@ -1203,6 +1203,7 @@ + } + out: + kfree(msg); ++ kfree(payload); + return rc; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1520_4053771449476d9c323bd00c0c87bbd390588e55.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1520_4053771449476d9c323bd00c0c87bbd390588e55.txt 2014-05-05 12:50:28.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1521_7e44a92662ce582268c4f35e68aad1f632ada8f8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1521_7e44a92662ce582268c4f35e68aad1f632ada8f8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1521_7e44a92662ce582268c4f35e68aad1f632ada8f8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1521_7e44a92662ce582268c4f35e68aad1f632ada8f8.patch 2014-05-05 12:50:29.000000000 +0000 @@ -0,0 +1,56 @@ +commit 7e44a92662ce582268c4f35e68aad1f632ada8f8 +Author: Shaohua Li +Date: Sat Oct 19 14:50:28 2013 +0800 + + raid5: set bio bi_vcnt 0 for discard request + + commit 37c61ff31e9b5e3fcf3cc6579f5c68f6ad40c4b1 upstream. + + SCSI layer will add new payload for discard request. If two bios are merged + to one, the second bio has bi_vcnt 1 which is set in raid5. This will confuse + SCSI and cause oops. + + Suitable for backport to 3.7+ + + Reported-by: Jes Sorensen + Signed-off-by: Shaohua Li + Signed-off-by: NeilBrown + Acked-by: Martin K. Petersen + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/raid5.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/raid5.c 2014-05-05 11:48:55.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/raid5.c 2014-05-05 12:50:29.000000000 +0000 +@@ -668,6 +668,12 @@ + bi->bi_io_vec[0].bv_len = STRIPE_SIZE; + bi->bi_io_vec[0].bv_offset = 0; + bi->bi_size = STRIPE_SIZE; ++ /* ++ * If this is discard request, set bi_vcnt 0. We don't ++ * want to confuse SCSI because SCSI will replace payload ++ */ ++ if (rw & REQ_DISCARD) ++ bi->bi_vcnt = 0; + if (rrdev) + set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); + +@@ -706,6 +712,12 @@ + rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; + rbi->bi_io_vec[0].bv_offset = 0; + rbi->bi_size = STRIPE_SIZE; ++ /* ++ * If this is discard request, set bi_vcnt 0. We don't ++ * want to confuse SCSI because SCSI will replace payload ++ */ ++ if (rw & REQ_DISCARD) ++ rbi->bi_vcnt = 0; + if (conf->mddev->gendisk) + trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), + rbi, disk_devt(conf->mddev->gendisk), +Index: linux-3.10-3.10.11/dummy/rpi_1521_7e44a92662ce582268c4f35e68aad1f632ada8f8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1521_7e44a92662ce582268c4f35e68aad1f632ada8f8.txt 2014-05-05 12:50:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1522_01e608d7276508fcafb76f2092db89885e62ef66.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1522_01e608d7276508fcafb76f2092db89885e62ef66.patch --- linux-3.10.11/debian/patches/rpi/rpi_1522_01e608d7276508fcafb76f2092db89885e62ef66.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1522_01e608d7276508fcafb76f2092db89885e62ef66.patch 2014-05-05 12:50:30.000000000 +0000 @@ -0,0 +1,44 @@ +commit 01e608d7276508fcafb76f2092db89885e62ef66 +Author: Shaohua Li +Date: Sat Oct 19 14:51:42 2013 +0800 + + raid5: avoid finding "discard" stripe + + commit d47648fcf0611812286f68131b40251c6fa54f5e upstream. + + SCSI discard will damage discard stripe bio setting, eg, some fields are + changed. If the stripe is reused very soon, we have wrong bios setting. We + remove discard stripe from hash list, so next time the strip will be fully + initialized. + + Suitable for backport to 3.7+. + + Signed-off-by: Shaohua Li + Signed-off-by: NeilBrown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/raid5.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/raid5.c 2014-05-05 12:50:29.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/raid5.c 2014-05-05 12:50:29.000000000 +0000 +@@ -2812,6 +2812,14 @@ + } + /* now that discard is done we can proceed with any sync */ + clear_bit(STRIPE_DISCARD, &sh->state); ++ /* ++ * SCSI discard will change some bio fields and the stripe has ++ * no updated data, so remove it from hash list and the stripe ++ * will be reinitialized ++ */ ++ spin_lock_irq(&conf->device_lock); ++ remove_hash(sh); ++ spin_unlock_irq(&conf->device_lock); + if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) + set_bit(STRIPE_HANDLE, &sh->state); + +Index: linux-3.10-3.10.11/dummy/rpi_1522_01e608d7276508fcafb76f2092db89885e62ef66.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1522_01e608d7276508fcafb76f2092db89885e62ef66.txt 2014-05-05 12:50:29.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1523_1946436e87d13b44bbf69a37cb7fe07477bb5117.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1523_1946436e87d13b44bbf69a37cb7fe07477bb5117.patch --- linux-3.10.11/debian/patches/rpi/rpi_1523_1946436e87d13b44bbf69a37cb7fe07477bb5117.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1523_1946436e87d13b44bbf69a37cb7fe07477bb5117.patch 2014-05-05 12:50:31.000000000 +0000 @@ -0,0 +1,52 @@ +commit 1946436e87d13b44bbf69a37cb7fe07477bb5117 +Author: Gwendal Grignou +Date: Fri Aug 7 16:17:49 2009 -0700 + + libata: make ata_eh_qc_retry() bump scmd->allowed on bogus failures + + commit f13e220161e738c2710b9904dcb3cf8bb0bcce61 upstream. + + libata EH decrements scmd->retries when the command failed for reasons + unrelated to the command itself so that, for example, commands aborted + due to suspend / resume cycle don't get penalized; however, + decrementing scmd->retries isn't enough for ATA passthrough commands. + + Without this fix, ATA passthrough commands are not resend to the + drive, and no error is signalled to the caller because: + + - allowed retry count is 1 + - ata_eh_qc_complete fill the sense data, so result is valid + - sense data is filled with untouched ATA registers. + + Signed-off-by: Gwendal Grignou + Signed-off-by: Tejun Heo + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/ata/libata-eh.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ata/libata-eh.c 2014-05-05 11:48:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ata/libata-eh.c 2014-05-05 12:50:30.000000000 +0000 +@@ -1322,14 +1322,14 @@ + * should be retried. To be used from EH. + * + * SCSI midlayer limits the number of retries to scmd->allowed. +- * scmd->retries is decremented for commands which get retried ++ * scmd->allowed is incremented for commands which get retried + * due to unrelated failures (qc->err_mask is zero). + */ + void ata_eh_qc_retry(struct ata_queued_cmd *qc) + { + struct scsi_cmnd *scmd = qc->scsicmd; +- if (!qc->err_mask && scmd->retries) +- scmd->retries--; ++ if (!qc->err_mask) ++ scmd->allowed++; + __ata_eh_qc_complete(qc); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1523_1946436e87d13b44bbf69a37cb7fe07477bb5117.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1523_1946436e87d13b44bbf69a37cb7fe07477bb5117.txt 2014-05-05 12:50:30.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1524_0465496671f4769e0f4f00481ce5bc5598c5caa2.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1524_0465496671f4769e0f4f00481ce5bc5598c5caa2.patch --- linux-3.10.11/debian/patches/rpi/rpi_1524_0465496671f4769e0f4f00481ce5bc5598c5caa2.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1524_0465496671f4769e0f4f00481ce5bc5598c5caa2.patch 2014-05-05 12:50:32.000000000 +0000 @@ -0,0 +1,113 @@ +commit 0465496671f4769e0f4f00481ce5bc5598c5caa2 +Author: Bian Yu +Date: Sat Oct 12 01:10:03 2013 -0400 + + md: avoid deadlock when md_set_badblocks. + + commit 905b0297a9533d7a6ee00a01a990456636877dd6 upstream. + + When operate harddisk and hit errors, md_set_badblocks is called after + scsi_restart_operations which already disabled the irq. but md_set_badblocks + will call write_sequnlock_irq and enable irq. so softirq can preempt the + current thread and that may cause a deadlock. I think this situation should + use write_sequnlock_irqsave/irqrestore instead. + + I met the situation and the call trace is below: + [ 638.919974] BUG: spinlock recursion on CPU#0, scsi_eh_13/1010 + [ 638.921923] lock: 0xffff8800d4d51fc8, .magic: dead4ead, .owner: scsi_eh_13/1010, .owner_cpu: 0 + [ 638.923890] CPU: 0 PID: 1010 Comm: scsi_eh_13 Not tainted 3.12.0-rc5+ #37 + [ 638.925844] Hardware name: To be filled by O.E.M. To be filled by O.E.M./MAHOBAY, BIOS 4.6.5 03/05/2013 + [ 638.927816] ffff880037ad4640 ffff880118c03d50 ffffffff8172ff85 0000000000000007 + [ 638.929829] ffff8800d4d51fc8 ffff880118c03d70 ffffffff81730030 ffff8800d4d51fc8 + [ 638.931848] ffffffff81a72eb0 ffff880118c03d90 ffffffff81730056 ffff8800d4d51fc8 + [ 638.933884] Call Trace: + [ 638.935867] [] dump_stack+0x55/0x76 + [ 638.937878] [] spin_dump+0x8a/0x8f + [ 638.939861] [] spin_bug+0x21/0x26 + [ 638.941836] [] do_raw_spin_lock+0xa4/0xc0 + [ 638.943801] [] _raw_spin_lock+0x66/0x80 + [ 638.945747] [] ? scsi_device_unbusy+0x9d/0xd0 + [ 638.947672] [] ? _raw_spin_unlock+0x2b/0x50 + [ 638.949595] [] scsi_device_unbusy+0x9d/0xd0 + [ 638.951504] [] scsi_finish_command+0x37/0xe0 + [ 638.953388] [] scsi_softirq_done+0xa8/0x140 + [ 638.955248] [] blk_done_softirq+0x7b/0x90 + [ 638.957116] [] __do_softirq+0xfd/0x330 + [ 638.958987] [] ? __lock_release+0x6f/0x100 + [ 638.960861] [] call_softirq+0x1c/0x30 + [ 638.962724] [] do_softirq+0x8d/0xc0 + [ 638.964565] [] irq_exit+0x10e/0x150 + [ 638.966390] [] smp_apic_timer_interrupt+0x4a/0x60 + [ 638.968223] [] apic_timer_interrupt+0x6f/0x80 + [ 638.970079] [] ? __lock_release+0x6f/0x100 + [ 638.971899] [] ? _raw_spin_unlock_irq+0x3a/0x50 + [ 638.973691] [] ? _raw_spin_unlock_irq+0x30/0x50 + [ 638.975475] [] md_set_badblocks+0x1f3/0x4a0 + [ 638.977243] [] rdev_set_badblocks+0x27/0x80 + [ 638.978988] [] raid5_end_read_request+0x36b/0x4e0 [raid456] + [ 638.980723] [] bio_endio+0x1d/0x40 + [ 638.982463] [] req_bio_endio.isra.65+0x83/0xa0 + [ 638.984214] [] blk_update_request+0x7f/0x350 + [ 638.985967] [] blk_update_bidi_request+0x31/0x90 + [ 638.987710] [] __blk_end_bidi_request+0x20/0x50 + [ 638.989439] [] __blk_end_request_all+0x1f/0x30 + [ 638.991149] [] blk_peek_request+0x106/0x250 + [ 638.992861] [] ? scsi_kill_request.isra.32+0xe9/0x130 + [ 638.994561] [] scsi_request_fn+0x4a/0x3d0 + [ 638.996251] [] __blk_run_queue+0x37/0x50 + [ 638.997900] [] blk_run_queue+0x2f/0x50 + [ 638.999553] [] scsi_run_queue+0xe0/0x1c0 + [ 639.001185] [] scsi_run_host_queues+0x21/0x40 + [ 639.002798] [] scsi_restart_operations+0x177/0x200 + [ 639.004391] [] scsi_error_handler+0xc9/0xe0 + [ 639.005996] [] ? scsi_unjam_host+0xd0/0xd0 + [ 639.007600] [] kthread+0xdb/0xe0 + [ 639.009205] [] ? flush_kthread_worker+0x170/0x170 + [ 639.010821] [] ret_from_fork+0x7c/0xb0 + [ 639.012437] [] ? flush_kthread_worker+0x170/0x170 + + This bug was introduce in commit 2e8ac30312973dd20e68073653 + (the first time rdev_set_badblock was call from interrupt context), + so this patch is appropriate for 3.5 and subsequent kernels. + + Signed-off-by: Bian Yu + Reviewed-by: Jianpeng Ma + Signed-off-by: NeilBrown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/md.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/md.c 2014-05-05 11:48:54.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/md.c 2014-05-05 12:50:31.000000000 +0000 +@@ -8072,6 +8072,7 @@ + u64 *p; + int lo, hi; + int rv = 1; ++ unsigned long flags; + + if (bb->shift < 0) + /* badblocks are disabled */ +@@ -8086,7 +8087,7 @@ + sectors = next - s; + } + +- write_seqlock_irq(&bb->lock); ++ write_seqlock_irqsave(&bb->lock, flags); + + p = bb->page; + lo = 0; +@@ -8202,7 +8203,7 @@ + bb->changed = 1; + if (!acknowledged) + bb->unacked_exist = 1; +- write_sequnlock_irq(&bb->lock); ++ write_sequnlock_irqrestore(&bb->lock, flags); + + return rv; + } +Index: linux-3.10-3.10.11/dummy/rpi_1524_0465496671f4769e0f4f00481ce5bc5598c5caa2.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1524_0465496671f4769e0f4f00481ce5bc5598c5caa2.txt 2014-05-05 12:50:31.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1525_ed840bec21c6f2f99ca34e974a5905e4f2116c1b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1525_ed840bec21c6f2f99ca34e974a5905e4f2116c1b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1525_ed840bec21c6f2f99ca34e974a5905e4f2116c1b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1525_ed840bec21c6f2f99ca34e974a5905e4f2116c1b.patch 2014-05-05 12:50:33.000000000 +0000 @@ -0,0 +1,60 @@ +commit ed840bec21c6f2f99ca34e974a5905e4f2116c1b +Author: Lukasz Dorau +Date: Thu Oct 24 12:55:17 2013 +1100 + + md: Fix skipping recovery for read-only arrays. + + commit 61e4947c99c4494336254ec540c50186d186150b upstream. + + Since: + commit 7ceb17e87bde79d285a8b988cfed9eaeebe60b86 + md: Allow devices to be re-added to a read-only array. + + spares are activated on a read-only array. In case of raid1 and raid10 + personalities it causes that not-in-sync devices are marked in-sync + without checking if recovery has been finished. + + If a read-only array is degraded and one of its devices is not in-sync + (because the array has been only partially recovered) recovery will be skipped. + + This patch adds checking if recovery has been finished before marking a device + in-sync for raid1 and raid10 personalities. In case of raid5 personality + such condition is already present (at raid5.c:6029). + + Bug was introduced in 3.10 and causes data corruption. + + Signed-off-by: Pawel Baldysiak + Signed-off-by: Lukasz Dorau + Signed-off-by: NeilBrown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/md/raid1.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/raid1.c 2014-05-05 11:48:53.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/raid1.c 2014-05-05 12:50:32.000000000 +0000 +@@ -1479,6 +1479,7 @@ + } + } + if (rdev ++ && rdev->recovery_offset == MaxSector + && !test_bit(Faulty, &rdev->flags) + && !test_and_set_bit(In_sync, &rdev->flags)) { + count++; +Index: linux-3.10-3.10.11/drivers/md/raid10.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/md/raid10.c 2014-05-05 11:48:53.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/md/raid10.c 2014-05-05 12:50:32.000000000 +0000 +@@ -1762,6 +1762,7 @@ + } + sysfs_notify_dirent_safe(tmp->replacement->sysfs_state); + } else if (tmp->rdev ++ && tmp->rdev->recovery_offset == MaxSector + && !test_bit(Faulty, &tmp->rdev->flags) + && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { + count++; +Index: linux-3.10-3.10.11/dummy/rpi_1525_ed840bec21c6f2f99ca34e974a5905e4f2116c1b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1525_ed840bec21c6f2f99ca34e974a5905e4f2116c1b.txt 2014-05-05 12:50:32.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1526_f21abb623ac78e2e9248057282d0de4e9b82e616.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1526_f21abb623ac78e2e9248057282d0de4e9b82e616.patch --- linux-3.10.11/debian/patches/rpi/rpi_1526_f21abb623ac78e2e9248057282d0de4e9b82e616.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1526_f21abb623ac78e2e9248057282d0de4e9b82e616.patch 2014-05-05 12:50:34.000000000 +0000 @@ -0,0 +1,52 @@ +commit f21abb623ac78e2e9248057282d0de4e9b82e616 +Author: Wei Yongjun +Date: Fri Oct 25 21:53:33 2013 +0800 + + target/pscsi: fix return value check + + commit 58932e96e438cd78f75e765d7b87ef39d3533d15 upstream. + + In case of error, the function scsi_host_lookup() returns NULL + pointer not ERR_PTR(). The IS_ERR() test in the return value check + should be replaced with NULL test. + + Signed-off-by: Wei Yongjun + Signed-off-by: Nicholas Bellinger + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/target/target_core_pscsi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/target/target_core_pscsi.c 2014-05-05 11:48:53.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/target/target_core_pscsi.c 2014-05-05 12:50:33.000000000 +0000 +@@ -134,10 +134,10 @@ + * pSCSI Host ID and enable for phba mode + */ + sh = scsi_host_lookup(phv->phv_host_id); +- if (IS_ERR(sh)) { ++ if (!sh) { + pr_err("pSCSI: Unable to locate SCSI Host for" + " phv_host_id: %d\n", phv->phv_host_id); +- return PTR_ERR(sh); ++ return -EINVAL; + } + + phv->phv_lld_host = sh; +@@ -515,10 +515,10 @@ + sh = phv->phv_lld_host; + } else { + sh = scsi_host_lookup(pdv->pdv_host_id); +- if (IS_ERR(sh)) { ++ if (!sh) { + pr_err("pSCSI: Unable to locate" + " pdv_host_id: %d\n", pdv->pdv_host_id); +- return PTR_ERR(sh); ++ return -EINVAL; + } + } + } else { +Index: linux-3.10-3.10.11/dummy/rpi_1526_f21abb623ac78e2e9248057282d0de4e9b82e616.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1526_f21abb623ac78e2e9248057282d0de4e9b82e616.txt 2014-05-05 12:50:33.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1527_722b78bc8a42b6910c291266e87abe2e63dc750f.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1527_722b78bc8a42b6910c291266e87abe2e63dc750f.patch --- linux-3.10.11/debian/patches/rpi/rpi_1527_722b78bc8a42b6910c291266e87abe2e63dc750f.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1527_722b78bc8a42b6910c291266e87abe2e63dc750f.patch 2014-05-05 12:50:35.000000000 +0000 @@ -0,0 +1,46 @@ +commit 722b78bc8a42b6910c291266e87abe2e63dc750f +Author: Nicholas Bellinger +Date: Fri Oct 25 10:44:15 2013 -0700 + + vhost/scsi: Fix incorrect usage of get_user_pages_fast write parameter + + commit 60a01f558af9c48b0bb31f303c479e32721add3f upstream. + + This patch addresses a long-standing bug where the get_user_pages_fast() + write parameter used for setting the underlying page table entry permission + bits was incorrectly set to write=1 for data_direction=DMA_TO_DEVICE, and + passed into get_user_pages_fast() via vhost_scsi_map_iov_to_sgl(). + + However, this parameter is intended to signal WRITEs to pinned userspace + PTEs for the virtio-scsi DMA_FROM_DEVICE -> READ payload case, and *not* + for the virtio-scsi DMA_TO_DEVICE -> WRITE payload case. + + This bug would manifest itself as random process segmentation faults on + KVM host after repeated vhost starts + stops and/or with lots of vhost + endpoints + LUNs. + + Cc: Stefan Hajnoczi + Cc: Michael S. Tsirkin + Cc: Asias He + Signed-off-by: Nicholas Bellinger + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/vhost/scsi.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/vhost/scsi.c 2014-05-05 11:48:53.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/vhost/scsi.c 2014-05-05 12:50:34.000000000 +0000 +@@ -1017,7 +1017,7 @@ + if (data_direction != DMA_NONE) { + ret = vhost_scsi_map_iov_to_sgl(tv_cmd, + &vq->iov[data_first], data_num, +- data_direction == DMA_TO_DEVICE); ++ data_direction == DMA_FROM_DEVICE); + if (unlikely(ret)) { + vq_err(vq, "Failed to map iov to sgl\n"); + goto err_free; +Index: linux-3.10-3.10.11/dummy/rpi_1527_722b78bc8a42b6910c291266e87abe2e63dc750f.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1527_722b78bc8a42b6910c291266e87abe2e63dc750f.txt 2014-05-05 12:50:34.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1528_b5b02b140665d016236918cb88b88f6249050605.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1528_b5b02b140665d016236918cb88b88f6249050605.patch --- linux-3.10.11/debian/patches/rpi/rpi_1528_b5b02b140665d016236918cb88b88f6249050605.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1528_b5b02b140665d016236918cb88b88f6249050605.patch 2014-05-05 12:50:35.000000000 +0000 @@ -0,0 +1,165 @@ +commit b5b02b140665d016236918cb88b88f6249050605 +Author: Thomas Gleixner +Date: Tue Sep 24 21:50:23 2013 +0200 + + clockevents: Sanitize ticks to nsec conversion + + commit 97b9410643475d6557d2517c2aff9fd2221141a9 upstream. + + Marc Kleine-Budde pointed out, that commit 77cc982 "clocksource: use + clockevents_config_and_register() where possible" caused a regression + for some of the converted subarchs. + + The reason is, that the clockevents core code converts the minimal + hardware tick delta to a nanosecond value for core internal + usage. This conversion is affected by integer math rounding loss, so + the backwards conversion to hardware ticks will likely result in a + value which is less than the configured hardware limitation. The + affected subarchs used their own workaround (SIGH!) which got lost in + the conversion. + + The solution for the issue at hand is simple: adding evt->mult - 1 to + the shifted value before the integer divison in the core conversion + function takes care of it. But this only works for the case where for + the scaled math mult/shift pair "mult <= 1 << shift" is true. For the + case where "mult > 1 << shift" we can apply the rounding add only for + the minimum delta value to make sure that the backward conversion is + not less than the given hardware limit. For the upper bound we need to + omit the rounding add, because the backwards conversion is always + larger than the original latch value. That would violate the upper + bound of the hardware device. + + Though looking closer at the details of that function reveals another + bogosity: The upper bounds check is broken as well. Checking for a + resulting "clc" value greater than KTIME_MAX after the conversion is + pointless. The conversion does: + + u64 clc = (latch << evt->shift) / evt->mult; + + So there is no sanity check for (latch << evt->shift) exceeding the + 64bit boundary. The latch argument is "unsigned long", so on a 64bit + arch the handed in argument could easily lead to an unnoticed shift + overflow. With the above rounding fix applied the calculation before + the divison is: + + u64 clc = (latch << evt->shift) + evt->mult - 1; + + So we need to make sure, that neither the shift nor the rounding add + is overflowing the u64 boundary. + + [ukl: move assignment to rnd after eventually changing mult, fix build + issue and correct comment with the right math] + + Signed-off-by: Thomas Gleixner + Cc: Russell King - ARM Linux + Cc: Marc Kleine-Budde + Cc: nicolas.ferre@atmel.com + Cc: Marc Pignat + Cc: john.stultz@linaro.org + Cc: kernel@pengutronix.de + Cc: Ronald Wahl + Cc: LAK + Cc: Ludovic Desroches + Link: http://lkml.kernel.org/r/1380052223-24139-1-git-send-email-u.kleine-koenig@pengutronix.de + Signed-off-by: Uwe Kleine-König + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/kernel/time/clockevents.c +=================================================================== +--- linux-3.10-3.10.11.orig/kernel/time/clockevents.c 2014-05-05 11:48:52.000000000 +0000 ++++ linux-3.10-3.10.11/kernel/time/clockevents.c 2014-05-05 12:50:35.000000000 +0000 +@@ -30,29 +30,64 @@ + /* Protection for the above */ + static DEFINE_RAW_SPINLOCK(clockevents_lock); + +-/** +- * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds +- * @latch: value to convert +- * @evt: pointer to clock event device descriptor +- * +- * Math helper, returns latch value converted to nanoseconds (bound checked) +- */ +-u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) ++static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt, ++ bool ismax) + { + u64 clc = (u64) latch << evt->shift; ++ u64 rnd; + + if (unlikely(!evt->mult)) { + evt->mult = 1; + WARN_ON(1); + } ++ rnd = (u64) evt->mult - 1; ++ ++ /* ++ * Upper bound sanity check. If the backwards conversion is ++ * not equal latch, we know that the above shift overflowed. ++ */ ++ if ((clc >> evt->shift) != (u64)latch) ++ clc = ~0ULL; ++ ++ /* ++ * Scaled math oddities: ++ * ++ * For mult <= (1 << shift) we can safely add mult - 1 to ++ * prevent integer rounding loss. So the backwards conversion ++ * from nsec to device ticks will be correct. ++ * ++ * For mult > (1 << shift), i.e. device frequency is > 1GHz we ++ * need to be careful. Adding mult - 1 will result in a value ++ * which when converted back to device ticks can be larger ++ * than latch by up to (mult - 1) >> shift. For the min_delta ++ * calculation we still want to apply this in order to stay ++ * above the minimum device ticks limit. For the upper limit ++ * we would end up with a latch value larger than the upper ++ * limit of the device, so we omit the add to stay below the ++ * device upper boundary. ++ * ++ * Also omit the add if it would overflow the u64 boundary. ++ */ ++ if ((~0ULL - clc > rnd) && ++ (!ismax || evt->mult <= (1U << evt->shift))) ++ clc += rnd; + + do_div(clc, evt->mult); +- if (clc < 1000) +- clc = 1000; +- if (clc > KTIME_MAX) +- clc = KTIME_MAX; + +- return clc; ++ /* Deltas less than 1usec are pointless noise */ ++ return clc > 1000 ? clc : 1000; ++} ++ ++/** ++ * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds ++ * @latch: value to convert ++ * @evt: pointer to clock event device descriptor ++ * ++ * Math helper, returns latch value converted to nanoseconds (bound checked) ++ */ ++u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt) ++{ ++ return cev_delta2ns(latch, evt, false); + } + EXPORT_SYMBOL_GPL(clockevent_delta2ns); + +@@ -317,8 +352,8 @@ + sec = 600; + + clockevents_calc_mult_shift(dev, freq, sec); +- dev->min_delta_ns = clockevent_delta2ns(dev->min_delta_ticks, dev); +- dev->max_delta_ns = clockevent_delta2ns(dev->max_delta_ticks, dev); ++ dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false); ++ dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true); + } + + /** +Index: linux-3.10-3.10.11/dummy/rpi_1528_b5b02b140665d016236918cb88b88f6249050605.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1528_b5b02b140665d016236918cb88b88f6249050605.txt 2014-05-05 12:50:35.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1529_daa73ffb82d3e6135de12ca879c373bbd5a9f41b.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1529_daa73ffb82d3e6135de12ca879c373bbd5a9f41b.patch --- linux-3.10.11/debian/patches/rpi/rpi_1529_daa73ffb82d3e6135de12ca879c373bbd5a9f41b.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1529_daa73ffb82d3e6135de12ca879c373bbd5a9f41b.patch 2014-05-05 12:50:36.000000000 +0000 @@ -0,0 +1,73 @@ +commit daa73ffb82d3e6135de12ca879c373bbd5a9f41b +Author: Helge Deller +Date: Sat Oct 26 23:19:25 2013 +0200 + + parisc: Do not crash 64bit SMP kernels on machines with >= 4GB RAM + + commit 54e181e073fc1415e41917d725ebdbd7de956455 upstream. + + Since the beginning of the parisc-linux port, sometimes 64bit SMP kernels were + not able to bring up other CPUs than the monarch CPU and instead crashed the + kernel. The reason was unclear, esp. since it involved various machines (e.g. + J5600, J6750 and SuperDome). Testing showed, that those crashes didn't happened + when less than 4GB were installed, or if a 32bit Linux kernel was booted. + + In the end, the fix for those SMP problems is trivial: + During the early phase of the initialization of the CPUs, including the monarch + CPU, the PDC_PSW firmware function to enable WIDE (=64bit) mode is called. + It's documented that this firmware function may clobber various registers, and + one one of those possibly clobbered registers is %cr30 which holds the task + thread info pointer. + + Now, if %cr30 would always have been clobbered, then this bug would have been + detected much earlier. But lots of testing finally showed, that - at least for + %cr30 - on some machines only the upper 32bits of the 64bit register suddenly + turned zero after the firmware call. + + So, after finding the root cause, the explanation for the various crashes + became clear: + - On 32bit SMP Linux kernels all upper 32bit were zero, so we didn't faced this + problem. + - Monarch CPUs in 64bit mode always booted sucessfully, because the inital task + thread info pointer was below 4GB. + - Secondary CPUs booted sucessfully on machines with less than 4GB RAM because + the upper 32bit were zero anyay. + - Secondary CPus failed to boot if we had more than 4GB RAM and the task thread + info pointer was located above the 4GB boundary. + + Finally, the patch to fix this problem is trivial by saving the %cr30 register + before the firmware call and restoring it afterwards. + + Signed-off-by: Helge Deller + Signed-off-by: John David Anglin + Signed-off-by: Helge Deller + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/parisc/kernel/head.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/parisc/kernel/head.S 2014-05-05 11:48:52.000000000 +0000 ++++ linux-3.10-3.10.11/arch/parisc/kernel/head.S 2014-05-05 12:50:36.000000000 +0000 +@@ -195,6 +195,8 @@ + ldw MEM_PDC_HI(%r0),%r6 + depd %r6, 31, 32, %r3 /* move to upper word */ + ++ mfctl %cr30,%r6 /* PCX-W2 firmware bug */ ++ + ldo PDC_PSW(%r0),%arg0 /* 21 */ + ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */ + ldo PDC_PSW_WIDE_BIT(%r0),%arg2 /* 2 */ +@@ -203,6 +205,8 @@ + copy %r0,%arg3 + + stext_pdc_ret: ++ mtctl %r6,%cr30 /* restore task thread info */ ++ + /* restore rfi target address*/ + ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10 + tophys_r1 %r10 +Index: linux-3.10-3.10.11/dummy/rpi_1529_daa73ffb82d3e6135de12ca879c373bbd5a9f41b.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1529_daa73ffb82d3e6135de12ca879c373bbd5a9f41b.txt 2014-05-05 12:50:36.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1530_27b840ea211f8a36fadabaa07ef94fb1b45730c3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1530_27b840ea211f8a36fadabaa07ef94fb1b45730c3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1530_27b840ea211f8a36fadabaa07ef94fb1b45730c3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1530_27b840ea211f8a36fadabaa07ef94fb1b45730c3.patch 2014-05-05 12:50:37.000000000 +0000 @@ -0,0 +1,88 @@ +commit 27b840ea211f8a36fadabaa07ef94fb1b45730c3 +Author: Ming Lei +Date: Sat Nov 2 09:11:33 2013 +1030 + + scripts/kallsyms: filter symbols not in kernel address space + + commit f6537f2f0eba4eba3354e48dbe3047db6d8b6254 upstream. + + This patch uses CONFIG_PAGE_OFFSET to filter symbols which + are not in kernel address space because these symbols are + generally for generating code purpose and can't be run at + kernel mode, so we needn't keep them in /proc/kallsyms. + + For example, on ARM there are some symbols which may be + linked in relocatable code section, then perf can't parse + symbols any more from /proc/kallsyms, this patch fixes the + problem (introduced b9b32bf70f2fb710b07c94e13afbc729afe221da) + + Cc: Russell King + Cc: linux-arm-kernel@lists.infradead.org + Cc: Michal Marek + Signed-off-by: Ming Lei + Signed-off-by: Rusty Russell + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/scripts/kallsyms.c +=================================================================== +--- linux-3.10-3.10.11.orig/scripts/kallsyms.c 2014-05-05 11:48:52.000000000 +0000 ++++ linux-3.10-3.10.11/scripts/kallsyms.c 2014-05-05 12:50:37.000000000 +0000 +@@ -55,6 +55,7 @@ + static unsigned int table_size, table_cnt; + static int all_symbols = 0; + static char symbol_prefix_char = '\0'; ++static unsigned long long kernel_start_addr = 0; + + int token_profit[0x10000]; + +@@ -65,7 +66,10 @@ + + static void usage(void) + { +- fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=] < in.map > out.S\n"); ++ fprintf(stderr, "Usage: kallsyms [--all-symbols] " ++ "[--symbol-prefix=] " ++ "[--page-offset=] " ++ "< in.map > out.S\n"); + exit(1); + } + +@@ -194,6 +198,9 @@ + int i; + int offset = 1; + ++ if (s->addr < kernel_start_addr) ++ return 0; ++ + /* skip prefix char */ + if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char) + offset++; +@@ -646,6 +653,9 @@ + if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\'')) + p++; + symbol_prefix_char = *p; ++ } else if (strncmp(argv[i], "--page-offset=", 14) == 0) { ++ const char *p = &argv[i][14]; ++ kernel_start_addr = strtoull(p, NULL, 16); + } else + usage(); + } +Index: linux-3.10-3.10.11/scripts/link-vmlinux.sh +=================================================================== +--- linux-3.10-3.10.11.orig/scripts/link-vmlinux.sh 2014-05-05 11:48:52.000000000 +0000 ++++ linux-3.10-3.10.11/scripts/link-vmlinux.sh 2014-05-05 12:50:37.000000000 +0000 +@@ -82,6 +82,8 @@ + kallsymopt="${kallsymopt} --all-symbols" + fi + ++ kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET" ++ + local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ + ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" + +Index: linux-3.10-3.10.11/dummy/rpi_1530_27b840ea211f8a36fadabaa07ef94fb1b45730c3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1530_27b840ea211f8a36fadabaa07ef94fb1b45730c3.txt 2014-05-05 12:50:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1531_40a894023d9a4c58379eb4f2ac12e40a2fe014d3.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1531_40a894023d9a4c58379eb4f2ac12e40a2fe014d3.patch --- linux-3.10.11/debian/patches/rpi/rpi_1531_40a894023d9a4c58379eb4f2ac12e40a2fe014d3.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1531_40a894023d9a4c58379eb4f2ac12e40a2fe014d3.patch 2014-05-05 12:50:38.000000000 +0000 @@ -0,0 +1,68 @@ +commit 40a894023d9a4c58379eb4f2ac12e40a2fe014d3 +Author: Vineet Gupta +Date: Sat Nov 2 17:47:49 2013 +0530 + + ARC: Incorrect mm reference used in vmalloc fault handler + + commit 9c41f4eeb9d51f3ece20428d35a3ea32cf3b5622 upstream. + + A vmalloc fault needs to sync up PGD/PTE entry from init_mm to current + task's "active_mm". ARC vmalloc fault handler however was using mm. + + A vmalloc fault for non user task context (actually pre-userland, from + init thread's open for /dev/console) caused the handler to deref NULL mm + (for mm->pgd) + + The reasons it worked so far is amazing: + + 1. By default (!SMP), vmalloc fault handler uses a cached value of PGD. + In SMP that MMU register is repurposed hence need for mm pointer deref. + + 2. In pre-3.12 SMP kernel, the problem triggering vmalloc didn't exist in + pre-userland code path - it was introduced with commit 20bafb3d23d108bc + "n_tty: Move buffers into n_tty_data" + + Signed-off-by: Vineet Gupta + Cc: Gilad Ben-Yossef + Cc: Noam Camus + Cc: Peter Hurley + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/arc/mm/fault.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arc/mm/fault.c 2014-05-05 11:48:51.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arc/mm/fault.c 2014-05-05 12:50:37.000000000 +0000 +@@ -16,7 +16,7 @@ + #include + #include + +-static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) ++static int handle_vmalloc_fault(unsigned long address) + { + /* + * Synchronize this task's top level page-table +@@ -26,7 +26,7 @@ + pud_t *pud, *pud_k; + pmd_t *pmd, *pmd_k; + +- pgd = pgd_offset_fast(mm, address); ++ pgd = pgd_offset_fast(current->active_mm, address); + pgd_k = pgd_offset_k(address); + + if (!pgd_present(*pgd_k)) +@@ -72,7 +72,7 @@ + * nothing more. + */ + if (address >= VMALLOC_START && address <= VMALLOC_END) { +- ret = handle_vmalloc_fault(mm, address); ++ ret = handle_vmalloc_fault(address); + if (unlikely(ret)) + goto bad_area_nosemaphore; + else +Index: linux-3.10-3.10.11/dummy/rpi_1531_40a894023d9a4c58379eb4f2ac12e40a2fe014d3.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1531_40a894023d9a4c58379eb4f2ac12e40a2fe014d3.txt 2014-05-05 12:50:37.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1532_8fde18bd74c8f30094bc47edf2c9ed19478661de.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1532_8fde18bd74c8f30094bc47edf2c9ed19478661de.patch --- linux-3.10.11/debian/patches/rpi/rpi_1532_8fde18bd74c8f30094bc47edf2c9ed19478661de.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1532_8fde18bd74c8f30094bc47edf2c9ed19478661de.patch 2014-05-05 12:50:39.000000000 +0000 @@ -0,0 +1,44 @@ +commit 8fde18bd74c8f30094bc47edf2c9ed19478661de +Author: Takashi Iwai +Date: Fri Oct 25 23:43:10 2013 +0200 + + ALSA: hda - Add missing initial vmaster hook at build_controls callback + + commit b63eae0a6c84839275a4638a7baa391be965cd0e upstream. + + The generic parser has a support of vmaster hook, but this is + initialized only in the init callback with the check of the presence + of the corresponding kctl. However, since kctl is NULL at the very + first init callback that is called before build_controls callback, the + vmaster hook sync is skipped there. Eventually this leads to the + uninitialized state depending on the hook implementation. + + This patch adds a simple workaround, just calling the sync function + explicitly at build_controls callback. + + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/hda_generic.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/hda_generic.c 2014-05-05 12:50:01.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/hda_generic.c 2014-05-05 12:50:38.000000000 +0000 +@@ -4383,9 +4383,11 @@ + true, &spec->vmaster_mute.sw_kctl); + if (err < 0) + return err; +- if (spec->vmaster_mute.hook) ++ if (spec->vmaster_mute.hook) { + snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, + spec->vmaster_mute_enum); ++ snd_hda_sync_vmaster_hook(&spec->vmaster_mute); ++ } + } + + free_kctls(spec); /* no longer needed */ +Index: linux-3.10-3.10.11/dummy/rpi_1532_8fde18bd74c8f30094bc47edf2c9ed19478661de.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1532_8fde18bd74c8f30094bc47edf2c9ed19478661de.txt 2014-05-05 12:50:38.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1533_c9e32ffdbe042276914daac9cdc737b8896eace6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1533_c9e32ffdbe042276914daac9cdc737b8896eace6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1533_c9e32ffdbe042276914daac9cdc737b8896eace6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1533_c9e32ffdbe042276914daac9cdc737b8896eace6.patch 2014-05-05 12:50:39.000000000 +0000 @@ -0,0 +1,40 @@ +commit c9e32ffdbe042276914daac9cdc737b8896eace6 +Author: Takashi Iwai +Date: Thu Oct 24 01:20:24 2013 +0200 + + ALSA: hda - Fix unbalanced runtime PM refcount after S3/S4 + + commit e6bbe666673ab044a3d39ddb74e4d9a401cf1d6f upstream. + + When a machine goes to S3/S4 after power-save is enabled, the runtime + PM refcount might be incorrectly decreased because the power-down + triggered soon after resume assumes that the controller was already + powered up, and issues the pm_notify down. + + This patch fixes the incorrect pm_notify call simply by checking the + current value properly. + + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/hda_codec.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/hda_codec.c 2014-05-05 11:48:51.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/hda_codec.c 2014-05-05 12:50:39.000000000 +0000 +@@ -4789,8 +4789,8 @@ + spin_unlock(&codec->power_lock); + + state = hda_call_codec_suspend(codec, true); +- codec->pm_down_notified = 0; +- if (!bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) { ++ if (!codec->pm_down_notified && ++ !bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) { + codec->pm_down_notified = 1; + hda_call_pm_notify(bus, false); + } +Index: linux-3.10-3.10.11/dummy/rpi_1533_c9e32ffdbe042276914daac9cdc737b8896eace6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1533_c9e32ffdbe042276914daac9cdc737b8896eace6.txt 2014-05-05 12:50:39.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1534_f08830dbf7af3b9c551d3112425a2d1b3c2757df.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1534_f08830dbf7af3b9c551d3112425a2d1b3c2757df.patch --- linux-3.10.11/debian/patches/rpi/rpi_1534_f08830dbf7af3b9c551d3112425a2d1b3c2757df.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1534_f08830dbf7af3b9c551d3112425a2d1b3c2757df.patch 2014-05-05 12:50:40.000000000 +0000 @@ -0,0 +1,33 @@ +commit f08830dbf7af3b9c551d3112425a2d1b3c2757df +Author: Takashi Iwai +Date: Wed Oct 30 12:29:40 2013 +0100 + + ALSA: hda - Add a fixup for ASUS N76VZ + + commit 6fc16e58adf50c0f1e4478538983fb5ff6f453d4 upstream. + + ASUS N76VZ needs the same fixup as N56VZ for supporting the boost + speaker. + + Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=846529 + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/pci/hda/patch_realtek.c 2014-05-05 12:48:41.000000000 +0000 ++++ linux-3.10-3.10.11/sound/pci/hda/patch_realtek.c 2014-05-05 12:50:40.000000000 +0000 +@@ -4253,6 +4253,7 @@ + SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), + SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4), ++ SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_ASUS_MODE4), + SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), +Index: linux-3.10-3.10.11/dummy/rpi_1534_f08830dbf7af3b9c551d3112425a2d1b3c2757df.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1534_f08830dbf7af3b9c551d3112425a2d1b3c2757df.txt 2014-05-05 12:50:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1535_58dc7706bb9becb535e8861c7b8f33d604381710.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1535_58dc7706bb9becb535e8861c7b8f33d604381710.patch --- linux-3.10.11/debian/patches/rpi/rpi_1535_58dc7706bb9becb535e8861c7b8f33d604381710.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1535_58dc7706bb9becb535e8861c7b8f33d604381710.patch 2014-05-05 12:50:41.000000000 +0000 @@ -0,0 +1,74 @@ +commit 58dc7706bb9becb535e8861c7b8f33d604381710 +Author: Russell King +Date: Thu Oct 31 15:01:37 2013 +0000 + + ALSA: fix oops in snd_pcm_info() caused by ASoC DPCM + + commit a4461f41b94cb52e0141af717dcf4ef6558c8e2e upstream. + + Unable to handle kernel NULL pointer dereference at virtual address 00000008 + pgd = d5300000 + [00000008] *pgd=0d265831, *pte=00000000, *ppte=00000000 + Internal error: Oops: 17 [#1] PREEMPT ARM + CPU: 0 PID: 2295 Comm: vlc Not tainted 3.11.0+ #755 + task: dee74800 ti: e213c000 task.ti: e213c000 + PC is at snd_pcm_info+0xc8/0xd8 + LR is at 0x30232065 + pc : [] lr : [<30232065>] psr: a0070013 + sp : e213dea8 ip : d81cb0d0 fp : c05f7678 + r10: c05f7770 r9 : fffffdfd r8 : 00000000 + r7 : d8a968a8 r6 : d8a96800 r5 : d8a96200 r4 : d81cb000 + r3 : 00000000 r2 : d81cb000 r1 : 00000001 r0 : d8a96200 + Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user + Control: 10c5387d Table: 15300019 DAC: 00000015 + Process vlc (pid: 2295, stack limit = 0xe213c248) + [] (snd_pcm_info) from [] (snd_pcm_info_user+0x34/0x9c) + [] (snd_pcm_info_user) from [] (snd_pcm_control_ioctl+0x274/0x280) + [] (snd_pcm_control_ioctl) from [] (snd_ctl_ioctl+0xc0/0x55c) + [] (snd_ctl_ioctl) from [] (do_vfs_ioctl+0x80/0x31c) + [] (do_vfs_ioctl) from [] (SyS_ioctl+0x3c/0x60) + [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x48) + Code: e1a00005 e59530dc e3a01001 e1a02004 (e5933008) + ---[ end trace cb3d9bdb8dfefb3c ]--- + + This is provoked when the ASoC front end is open along with its backend, + (which causes the backend to have a runtime assigned to it) and then the + SNDRV_CTL_IOCTL_PCM_INFO is requested for the (visible) backend device. + + Resolve this by ensuring that ASoC internal backend devices are not + visible to userspace, just as the commentry for snd_pcm_new_internal() + says it should be. + + Signed-off-by: Russell King + Acked-by: Mark Brown + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/core/pcm.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/core/pcm.c 2014-05-05 11:48:50.000000000 +0000 ++++ linux-3.10-3.10.11/sound/core/pcm.c 2014-05-05 12:50:40.000000000 +0000 +@@ -49,6 +49,8 @@ + struct snd_pcm *pcm; + + list_for_each_entry(pcm, &snd_pcm_devices, list) { ++ if (pcm->internal) ++ continue; + if (pcm->card == card && pcm->device == device) + return pcm; + } +@@ -60,6 +62,8 @@ + struct snd_pcm *pcm; + + list_for_each_entry(pcm, &snd_pcm_devices, list) { ++ if (pcm->internal) ++ continue; + if (pcm->card == card && pcm->device > device) + return pcm->device; + else if (pcm->card->number > card->number) +Index: linux-3.10-3.10.11/dummy/rpi_1535_58dc7706bb9becb535e8861c7b8f33d604381710.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1535_58dc7706bb9becb535e8861c7b8f33d604381710.txt 2014-05-05 12:50:40.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1536_0492665d67bb7bdff10f3027a26b9c145fe73ddb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1536_0492665d67bb7bdff10f3027a26b9c145fe73ddb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1536_0492665d67bb7bdff10f3027a26b9c145fe73ddb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1536_0492665d67bb7bdff10f3027a26b9c145fe73ddb.patch 2014-05-05 12:50:42.000000000 +0000 @@ -0,0 +1,32 @@ +commit 0492665d67bb7bdff10f3027a26b9c145fe73ddb +Author: Takashi Iwai +Date: Wed Oct 30 08:35:02 2013 +0100 + + ASoC: wm_hubs: Add missing break in hp_supply_event() + + commit 268ff14525edba31da29a12a9dd693cdd6a7872e upstream. + + Spotted by coverity CID 115170. + + Signed-off-by: Takashi Iwai + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/soc/codecs/wm_hubs.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/codecs/wm_hubs.c 2014-05-05 11:48:50.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/codecs/wm_hubs.c 2014-05-05 12:50:41.000000000 +0000 +@@ -530,6 +530,7 @@ + hubs->hp_startup_mode); + break; + } ++ break; + + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1, +Index: linux-3.10-3.10.11/dummy/rpi_1536_0492665d67bb7bdff10f3027a26b9c145fe73ddb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1536_0492665d67bb7bdff10f3027a26b9c145fe73ddb.txt 2014-05-05 12:50:41.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1537_2ca317899d45d60805b0b5dc9b6f879a8f93f7c6.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1537_2ca317899d45d60805b0b5dc9b6f879a8f93f7c6.patch --- linux-3.10.11/debian/patches/rpi/rpi_1537_2ca317899d45d60805b0b5dc9b6f879a8f93f7c6.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1537_2ca317899d45d60805b0b5dc9b6f879a8f93f7c6.patch 2014-05-05 12:50:43.000000000 +0000 @@ -0,0 +1,35 @@ +commit 2ca317899d45d60805b0b5dc9b6f879a8f93f7c6 +Author: Takashi Iwai +Date: Mon Oct 28 14:21:49 2013 +0100 + + ASoC: dapm: Fix source list debugfs outputs + + commit ff18620c2157671a8ee21ebb8e6a3520ea209b1f upstream. + + ... due to a copy & paste error. + + Spotted by coverity CID 710923. + + Signed-off-by: Takashi Iwai + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/sound/soc/soc-dapm.c +=================================================================== +--- linux-3.10-3.10.11.orig/sound/soc/soc-dapm.c 2014-05-05 11:48:49.000000000 +0000 ++++ linux-3.10-3.10.11/sound/soc/soc-dapm.c 2014-05-05 12:50:42.000000000 +0000 +@@ -1797,7 +1797,7 @@ + w->active ? "active" : "inactive"); + + list_for_each_entry(p, &w->sources, list_sink) { +- if (p->connected && !p->connected(w, p->sink)) ++ if (p->connected && !p->connected(w, p->source)) + continue; + + if (p->connect) +Index: linux-3.10-3.10.11/dummy/rpi_1537_2ca317899d45d60805b0b5dc9b6f879a8f93f7c6.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1537_2ca317899d45d60805b0b5dc9b6f879a8f93f7c6.txt 2014-05-05 12:50:42.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1538_a2f8eb6acf8b40793f3b798b0a63800f38707444.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1538_a2f8eb6acf8b40793f3b798b0a63800f38707444.patch --- linux-3.10.11/debian/patches/rpi/rpi_1538_a2f8eb6acf8b40793f3b798b0a63800f38707444.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1538_a2f8eb6acf8b40793f3b798b0a63800f38707444.patch 2014-05-05 12:50:43.000000000 +0000 @@ -0,0 +1,36 @@ +commit a2f8eb6acf8b40793f3b798b0a63800f38707444 +Author: Dan Carpenter +Date: Tue Oct 29 22:07:47 2013 +0300 + + staging: ozwpan: prevent overflow in oz_cdev_write() + + commit c2c65cd2e14ada6de44cb527e7f1990bede24e15 upstream. + + We need to check "count" so we don't overflow the ei->data buffer. + + Reported-by: Nico Golde + Reported-by: Fabian Yamaguchi + Signed-off-by: Dan Carpenter + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/ozwpan/ozcdev.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/ozwpan/ozcdev.c 2014-05-05 11:48:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/ozwpan/ozcdev.c 2014-05-05 12:50:43.000000000 +0000 +@@ -153,6 +153,9 @@ + struct oz_app_hdr *app_hdr; + struct oz_serial_ctx *ctx; + ++ if (count > sizeof(ei->data) - sizeof(*elt) - sizeof(*app_hdr)) ++ return -EINVAL; ++ + spin_lock_bh(&g_cdev.lock); + pd = g_cdev.active_pd; + if (pd) +Index: linux-3.10-3.10.11/dummy/rpi_1538_a2f8eb6acf8b40793f3b798b0a63800f38707444.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1538_a2f8eb6acf8b40793f3b798b0a63800f38707444.txt 2014-05-05 12:50:43.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1539_421a5dcd03c36833cfe3923b6943e999c3770973.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1539_421a5dcd03c36833cfe3923b6943e999c3770973.patch --- linux-3.10.11/debian/patches/rpi/rpi_1539_421a5dcd03c36833cfe3923b6943e999c3770973.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1539_421a5dcd03c36833cfe3923b6943e999c3770973.patch 2014-05-05 12:50:44.000000000 +0000 @@ -0,0 +1,35 @@ +commit 421a5dcd03c36833cfe3923b6943e999c3770973 +Author: Dan Carpenter +Date: Tue Oct 29 23:01:11 2013 +0300 + + Staging: bcm: info leak in ioctl + + commit 8d1e72250c847fa96498ec029891de4dc638a5ba upstream. + + The DevInfo.u32Reserved[] array isn't initialized so it leaks kernel + information to user space. + + Reported-by: Nico Golde + Reported-by: Fabian Yamaguchi + Signed-off-by: Dan Carpenter + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/bcm/Bcmchar.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/bcm/Bcmchar.c 2014-05-05 11:48:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/bcm/Bcmchar.c 2014-05-05 12:50:44.000000000 +0000 +@@ -1960,6 +1960,7 @@ + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); + ++ memset(&DevInfo, 0, sizeof(DevInfo)); + DevInfo.MaxRDMBufferSize = BUFFER_4K; + DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; + DevInfo.u32RxAlignmentCorrection = 0; +Index: linux-3.10-3.10.11/dummy/rpi_1539_421a5dcd03c36833cfe3923b6943e999c3770973.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1539_421a5dcd03c36833cfe3923b6943e999c3770973.txt 2014-05-05 12:50:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1540_2958a1199ee79b5ad4cb80a4bf8da95ac602d796.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1540_2958a1199ee79b5ad4cb80a4bf8da95ac602d796.patch --- linux-3.10.11/debian/patches/rpi/rpi_1540_2958a1199ee79b5ad4cb80a4bf8da95ac602d796.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1540_2958a1199ee79b5ad4cb80a4bf8da95ac602d796.patch 2014-05-05 12:50:45.000000000 +0000 @@ -0,0 +1,36 @@ +commit 2958a1199ee79b5ad4cb80a4bf8da95ac602d796 +Author: Dan Carpenter +Date: Tue Oct 29 23:01:43 2013 +0300 + + Staging: sb105x: info leak in mp_get_count() + + commit a8b33654b1e3b0c74d4a1fed041c9aae50b3c427 upstream. + + The icount.reserved[] array isn't initialized so it leaks stack + information to userspace. + + Reported-by: Nico Golde + Reported-by: Fabian Yamaguchi + Signed-off-by: Dan Carpenter + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/sb105x/sb_pci_mp.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/sb105x/sb_pci_mp.c 2014-05-05 11:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/sb105x/sb_pci_mp.c 2014-05-05 12:50:44.000000000 +0000 +@@ -1063,7 +1063,7 @@ + + static int mp_get_count(struct sb_uart_state *state, struct serial_icounter_struct *icnt) + { +- struct serial_icounter_struct icount; ++ struct serial_icounter_struct icount = {}; + struct sb_uart_icount cnow; + struct sb_uart_port *port = state->port; + +Index: linux-3.10-3.10.11/dummy/rpi_1540_2958a1199ee79b5ad4cb80a4bf8da95ac602d796.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1540_2958a1199ee79b5ad4cb80a4bf8da95ac602d796.txt 2014-05-05 12:50:44.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1541_e668dd8e47c2bc39c7bc31529dbe21c6169290bf.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1541_e668dd8e47c2bc39c7bc31529dbe21c6169290bf.patch --- linux-3.10.11/debian/patches/rpi/rpi_1541_e668dd8e47c2bc39c7bc31529dbe21c6169290bf.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1541_e668dd8e47c2bc39c7bc31529dbe21c6169290bf.patch 2014-05-05 12:50:46.000000000 +0000 @@ -0,0 +1,67 @@ +commit e668dd8e47c2bc39c7bc31529dbe21c6169290bf +Author: Dan Carpenter +Date: Tue Oct 29 23:00:15 2013 +0300 + + staging: wlags49_h2: buffer overflow setting station name + + commit b5e2f339865fb443107e5b10603e53bbc92dc054 upstream. + + We need to check the length parameter before doing the memcpy(). I've + actually changed it to strlcpy() as well so that it's NUL terminated. + + You need CAP_NET_ADMIN to trigger these so it's not the end of the + world. + + Reported-by: Nico Golde + Reported-by: Fabian Yamaguchi + Signed-off-by: Dan Carpenter + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/staging/wlags49_h2/wl_priv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/staging/wlags49_h2/wl_priv.c 2014-05-05 11:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/staging/wlags49_h2/wl_priv.c 2014-05-05 12:50:45.000000000 +0000 +@@ -570,6 +570,7 @@ + ltv_t *pLtv; + bool_t ltvAllocated = FALSE; + ENCSTRCT sEncryption; ++ size_t len; + + #ifdef USE_WDS + hcf_16 hcfPort = HCF_PORT_0; +@@ -686,7 +687,8 @@ + break; + case CFG_CNF_OWN_NAME: + memset(lp->StationName, 0, sizeof(lp->StationName)); +- memcpy((void *)lp->StationName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]); ++ len = min_t(size_t, pLtv->u.u16[0], sizeof(lp->StationName)); ++ strlcpy(lp->StationName, &pLtv->u.u8[2], len); + pLtv->u.u16[0] = CNV_INT_TO_LITTLE(pLtv->u.u16[0]); + break; + case CFG_CNF_LOAD_BALANCING: +@@ -1783,6 +1785,7 @@ + { + struct wl_private *lp = wl_priv(dev); + unsigned long flags; ++ size_t len; + int ret = 0; + /*------------------------------------------------------------------------*/ + +@@ -1793,8 +1796,8 @@ + wl_lock(lp, &flags); + + memset(lp->StationName, 0, sizeof(lp->StationName)); +- +- memcpy(lp->StationName, extra, wrqu->data.length); ++ len = min_t(size_t, wrqu->data.length, sizeof(lp->StationName)); ++ strlcpy(lp->StationName, extra, len); + + /* Commit the adapter parameters */ + wl_apply(lp); +Index: linux-3.10-3.10.11/dummy/rpi_1541_e668dd8e47c2bc39c7bc31529dbe21c6169290bf.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1541_e668dd8e47c2bc39c7bc31529dbe21c6169290bf.txt 2014-05-05 12:50:45.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1542_079584656265347f310c75fac6f863a6280a17e4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1542_079584656265347f310c75fac6f863a6280a17e4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1542_079584656265347f310c75fac6f863a6280a17e4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1542_079584656265347f310c75fac6f863a6280a17e4.patch 2014-05-05 12:50:46.000000000 +0000 @@ -0,0 +1,40 @@ +commit 079584656265347f310c75fac6f863a6280a17e4 +Author: Dan Carpenter +Date: Tue Oct 29 22:06:04 2013 +0300 + + uml: check length in exitcode_proc_write() + + commit 201f99f170df14ba52ea4c52847779042b7a623b upstream. + + We don't cap the size of buffer from the user so we could write past the + end of the array here. Only root can write to this file. + + Reported-by: Nico Golde + Reported-by: Fabian Yamaguchi + Signed-off-by: Dan Carpenter + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/um/kernel/exitcode.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/um/kernel/exitcode.c 2014-05-05 11:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/arch/um/kernel/exitcode.c 2014-05-05 12:50:46.000000000 +0000 +@@ -40,9 +40,11 @@ + const char __user *buffer, size_t count, loff_t *pos) + { + char *end, buf[sizeof("nnnnn\0")]; ++ size_t size; + int tmp; + +- if (copy_from_user(buf, buffer, count)) ++ size = min(count, sizeof(buf)); ++ if (copy_from_user(buf, buffer, size)) + return -EFAULT; + + tmp = simple_strtol(buf, &end, 0); +Index: linux-3.10-3.10.11/dummy/rpi_1542_079584656265347f310c75fac6f863a6280a17e4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1542_079584656265347f310c75fac6f863a6280a17e4.txt 2014-05-05 12:50:46.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1543_54a702cb065e49976f61d2130c16f585bfba6c44.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1543_54a702cb065e49976f61d2130c16f585bfba6c44.patch --- linux-3.10.11/debian/patches/rpi/rpi_1543_54a702cb065e49976f61d2130c16f585bfba6c44.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1543_54a702cb065e49976f61d2130c16f585bfba6c44.patch 2014-05-05 12:50:47.000000000 +0000 @@ -0,0 +1,41 @@ +commit 54a702cb065e49976f61d2130c16f585bfba6c44 +Author: Baruch Siach +Date: Tue Oct 15 02:22:43 2013 +0400 + + xtensa: don't use alternate signal stack on threads + + commit cba9a90053e3b7973eff4f1946f33032e98eeed5 upstream. + + According to create_thread(3): "The new thread does not inherit the creating + thread's alternate signal stack". Since commit f9a3879a (Fix sigaltstack + corruption among cloned threads), current->sas_ss_size is set to 0 for cloned + processes sharing VM with their parent. Don't use the (nonexistent) alternate + signal stack in this case. This has been broken since commit 29c4dfd9 ([XTENSA] + Remove non-rt signal handling). + + Fixes the SA_ONSTACK part of the nptl/tst-cancel20 test from uClibc. + + Signed-off-by: Baruch Siach + Signed-off-by: Max Filippov + Signed-off-by: Chris Zankel + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/arch/xtensa/kernel/signal.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/xtensa/kernel/signal.c 2014-05-05 11:48:48.000000000 +0000 ++++ linux-3.10-3.10.11/arch/xtensa/kernel/signal.c 2014-05-05 12:50:47.000000000 +0000 +@@ -341,7 +341,7 @@ + + sp = regs->areg[1]; + +- if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) { ++ if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) { + sp = current->sas_ss_sp + current->sas_ss_size; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1543_54a702cb065e49976f61d2130c16f585bfba6c44.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1543_54a702cb065e49976f61d2130c16f585bfba6c44.txt 2014-05-05 12:50:47.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1544_f80d1c35d87072b46bf47f323f8051c4a5073fb4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1544_f80d1c35d87072b46bf47f323f8051c4a5073fb4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1544_f80d1c35d87072b46bf47f323f8051c4a5073fb4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1544_f80d1c35d87072b46bf47f323f8051c4a5073fb4.patch 2014-05-05 12:50:48.000000000 +0000 @@ -0,0 +1,31 @@ +commit f80d1c35d87072b46bf47f323f8051c4a5073fb4 +Author: Uwe Kleine-König +Date: Wed Aug 7 13:02:52 2013 +0200 + + mm: make generic_access_phys available for modules + + commit 5a73633ef01cd8772defa6a3c34a588376a1df4c upstream. + + In the next commit this function will be used in the uio subsystem + + Signed-off-by: Uwe Kleine-König + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/memory.c 2014-05-05 11:48:47.000000000 +0000 ++++ linux-3.10-3.10.11/mm/memory.c 2014-05-05 12:50:48.000000000 +0000 +@@ -4074,6 +4074,7 @@ + + return len; + } ++EXPORT_SYMBOL_GPL(generic_access_phys); + #endif + + /* +Index: linux-3.10-3.10.11/dummy/rpi_1544_f80d1c35d87072b46bf47f323f8051c4a5073fb4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1544_f80d1c35d87072b46bf47f323f8051c4a5073fb4.txt 2014-05-05 12:50:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1545_5fa25ee0bde3ad47e99e9877313a36a9ace95b72.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1545_5fa25ee0bde3ad47e99e9877313a36a9ace95b72.patch --- linux-3.10.11/debian/patches/rpi/rpi_1545_5fa25ee0bde3ad47e99e9877313a36a9ace95b72.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1545_5fa25ee0bde3ad47e99e9877313a36a9ace95b72.patch 2014-05-05 12:50:49.000000000 +0000 @@ -0,0 +1,79 @@ +commit 5fa25ee0bde3ad47e99e9877313a36a9ace95b72 +Author: Uwe Kleine-König +Date: Wed Aug 7 13:02:53 2013 +0200 + + uio: provide vm access to UIO_MEM_PHYS maps + + commit 7294151d0592e0ff48c61fca9fd7c93d613134da upstream. + + This makes it possible to let gdb access mappings of the process that is + being debugged. + + uio_mmap_logical was moved and uio_vm_ops renamed to group related code + and differentiate to new stuff. + + Signed-off-by: Uwe Kleine-König + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/uio/uio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/uio/uio.c 2014-05-05 11:48:47.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/uio/uio.c 2014-05-05 12:50:48.000000000 +0000 +@@ -630,12 +630,26 @@ + return 0; + } + +-static const struct vm_operations_struct uio_vm_ops = { ++static const struct vm_operations_struct uio_logical_vm_ops = { + .open = uio_vma_open, + .close = uio_vma_close, + .fault = uio_vma_fault, + }; + ++static int uio_mmap_logical(struct vm_area_struct *vma) ++{ ++ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; ++ vma->vm_ops = &uio_logical_vm_ops; ++ uio_vma_open(vma); ++ return 0; ++} ++ ++static const struct vm_operations_struct uio_physical_vm_ops = { ++#ifdef CONFIG_HAVE_IOREMAP_PROT ++ .access = generic_access_phys, ++#endif ++}; ++ + static int uio_mmap_physical(struct vm_area_struct *vma) + { + struct uio_device *idev = vma->vm_private_data; +@@ -643,6 +657,8 @@ + if (mi < 0) + return -EINVAL; + ++ vma->vm_ops = &uio_physical_vm_ops; ++ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + return remap_pfn_range(vma, +@@ -652,14 +668,6 @@ + vma->vm_page_prot); + } + +-static int uio_mmap_logical(struct vm_area_struct *vma) +-{ +- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; +- vma->vm_ops = &uio_vm_ops; +- uio_vma_open(vma); +- return 0; +-} +- + static int uio_mmap(struct file *filep, struct vm_area_struct *vma) + { + struct uio_listener *listener = filep->private_data; +Index: linux-3.10-3.10.11/dummy/rpi_1545_5fa25ee0bde3ad47e99e9877313a36a9ace95b72.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1545_5fa25ee0bde3ad47e99e9877313a36a9ace95b72.txt 2014-05-05 12:50:48.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1546_a4c8ae2e72bdb85f6dfdfad82bec0df1e2749ac5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1546_a4c8ae2e72bdb85f6dfdfad82bec0df1e2749ac5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1546_a4c8ae2e72bdb85f6dfdfad82bec0df1e2749ac5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1546_a4c8ae2e72bdb85f6dfdfad82bec0df1e2749ac5.patch 2014-05-05 12:50:50.000000000 +0000 @@ -0,0 +1,30 @@ +commit a4c8ae2e72bdb85f6dfdfad82bec0df1e2749ac5 +Author: Al Viro +Date: Sat May 11 12:38:38 2013 -0400 + + au1100fb: VM_IO is set by io_remap_pfn_range() + + commit c607f450f6e49f5794f27617bedc638b51044d2e upstream. + + Signed-off-by: Al Viro + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/video/au1100fb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/au1100fb.c 2014-05-05 11:48:46.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/au1100fb.c 2014-05-05 12:50:49.000000000 +0000 +@@ -385,8 +385,6 @@ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 + +- vma->vm_flags |= VM_IO; +- + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { +Index: linux-3.10-3.10.11/dummy/rpi_1546_a4c8ae2e72bdb85f6dfdfad82bec0df1e2749ac5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1546_a4c8ae2e72bdb85f6dfdfad82bec0df1e2749ac5.txt 2014-05-05 12:50:49.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1547_f1e65e494c7914220ac6d87caa126114f46ac462.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1547_f1e65e494c7914220ac6d87caa126114f46ac462.patch --- linux-3.10.11/debian/patches/rpi/rpi_1547_f1e65e494c7914220ac6d87caa126114f46ac462.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1547_f1e65e494c7914220ac6d87caa126114f46ac462.patch 2014-05-05 12:50:51.000000000 +0000 @@ -0,0 +1,37 @@ +commit f1e65e494c7914220ac6d87caa126114f46ac462 +Author: Al Viro +Date: Sat May 11 12:37:38 2013 -0400 + + au1200fb: io_remap_pfn_range() sets VM_IO + + commit 1fca06fafb235a88c4fa91294aa1726c0e22855b upstream. + + ... and single return is quite sufficient to get out of function, TYVM + + Signed-off-by: Al Viro + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/video/au1200fb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/au1200fb.c 2014-05-05 11:48:46.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/au1200fb.c 2014-05-05 12:50:50.000000000 +0000 +@@ -1258,13 +1258,9 @@ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ + +- vma->vm_flags |= VM_IO; +- + return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); +- +- return 0; + } + + static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) +Index: linux-3.10-3.10.11/dummy/rpi_1547_f1e65e494c7914220ac6d87caa126114f46ac462.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1547_f1e65e494c7914220ac6d87caa126114f46ac462.txt 2014-05-05 12:50:50.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1548_c79c7ad9d1398787f907f85afc44cf7d6623027d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1548_c79c7ad9d1398787f907f85afc44cf7d6623027d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1548_c79c7ad9d1398787f907f85afc44cf7d6623027d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1548_c79c7ad9d1398787f907f85afc44cf7d6623027d.patch 2014-05-05 12:50:51.000000000 +0000 @@ -0,0 +1,143 @@ +commit c79c7ad9d1398787f907f85afc44cf7d6623027d +Author: Linus Torvalds +Date: Tue Oct 29 10:21:34 2013 -0700 + + Fix a few incorrectly checked [io_]remap_pfn_range() calls + + commit 7314e613d5ff9f0934f7a0f74ed7973b903315d1 upstream. + + Nico Golde reports a few straggling uses of [io_]remap_pfn_range() that + really should use the vm_iomap_memory() helper. This trivially converts + two of them to the helper, and comments about why the third one really + needs to continue to use remap_pfn_range(), and adds the missing size + check. + + Reported-by: Nico Golde + Signed-off-by: Linus Torvalds + +Index: linux-3.10-3.10.11/drivers/uio/uio.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/uio/uio.c 2014-05-05 12:50:48.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/uio/uio.c 2014-05-05 12:50:51.000000000 +0000 +@@ -654,16 +654,29 @@ + { + struct uio_device *idev = vma->vm_private_data; + int mi = uio_find_mem_index(vma); ++ struct uio_mem *mem; + if (mi < 0) + return -EINVAL; ++ mem = idev->info->mem + mi; + +- vma->vm_ops = &uio_physical_vm_ops; ++ if (vma->vm_end - vma->vm_start > mem->size) ++ return -EINVAL; + ++ vma->vm_ops = &uio_physical_vm_ops; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + ++ /* ++ * We cannot use the vm_iomap_memory() helper here, ++ * because vma->vm_pgoff is the map index we looked ++ * up above in uio_find_mem_index(), rather than an ++ * actual page offset into the mmap. ++ * ++ * So we just do the physical mmap without a page ++ * offset. ++ */ + return remap_pfn_range(vma, + vma->vm_start, +- idev->info->mem[mi].addr >> PAGE_SHIFT, ++ mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + } +Index: linux-3.10-3.10.11/drivers/video/au1100fb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/au1100fb.c 2014-05-05 12:50:49.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/au1100fb.c 2014-05-05 12:50:51.000000000 +0000 +@@ -361,37 +361,13 @@ + int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) + { + struct au1100fb_device *fbdev; +- unsigned int len; +- unsigned long start=0, off; + + fbdev = to_au1100fb_device(fbi); + +- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { +- return -EINVAL; +- } +- +- start = fbdev->fb_phys & PAGE_MASK; +- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); +- +- off = vma->vm_pgoff << PAGE_SHIFT; +- +- if ((vma->vm_end - vma->vm_start + off) > len) { +- return -EINVAL; +- } +- +- off += start; +- vma->vm_pgoff = off >> PAGE_SHIFT; +- + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 + +- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, +- vma->vm_page_prot)) { +- return -EAGAIN; +- } +- +- return 0; ++ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); + } + + static struct fb_ops au1100fb_ops = +Index: linux-3.10-3.10.11/drivers/video/au1200fb.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/au1200fb.c 2014-05-05 12:50:50.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/au1200fb.c 2014-05-05 12:50:51.000000000 +0000 +@@ -1233,34 +1233,13 @@ + * method mainly to allow the use of the TLB streaming flag (CCA=6) + */ + static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +- + { +- unsigned int len; +- unsigned long start=0, off; + struct au1200fb_device *fbdev = info->par; + +- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { +- return -EINVAL; +- } +- +- start = fbdev->fb_phys & PAGE_MASK; +- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); +- +- off = vma->vm_pgoff << PAGE_SHIFT; +- +- if ((vma->vm_end - vma->vm_start + off) > len) { +- return -EINVAL; +- } +- +- off += start; +- vma->vm_pgoff = off >> PAGE_SHIFT; +- + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ + +- return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, +- vma->vm_page_prot); ++ return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); + } + + static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) +Index: linux-3.10-3.10.11/dummy/rpi_1548_c79c7ad9d1398787f907f85afc44cf7d6623027d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1548_c79c7ad9d1398787f907f85afc44cf7d6623027d.txt 2014-05-05 12:50:51.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1549_e14594cd658f655ae3384fcc3ec8c345b36cd4d0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1549_e14594cd658f655ae3384fcc3ec8c345b36cd4d0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1549_e14594cd658f655ae3384fcc3ec8c345b36cd4d0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1549_e14594cd658f655ae3384fcc3ec8c345b36cd4d0.patch 2014-05-05 12:50:52.000000000 +0000 @@ -0,0 +1,65 @@ +commit e14594cd658f655ae3384fcc3ec8c345b36cd4d0 +Author: Ming Lei +Date: Thu Oct 31 16:34:17 2013 -0700 + + lib/scatterlist.c: don't flush_kernel_dcache_page on slab page + + commit 3d77b50c5874b7e923be946ba793644f82336b75 upstream. + + Commit b1adaf65ba03 ("[SCSI] block: add sg buffer copy helper + functions") introduces two sg buffer copy helpers, and calls + flush_kernel_dcache_page() on pages in SG list after these pages are + written to. + + Unfortunately, the commit may introduce a potential bug: + + - Before sending some SCSI commands, kmalloc() buffer may be passed to + block layper, so flush_kernel_dcache_page() can see a slab page + finally + + - According to cachetlb.txt, flush_kernel_dcache_page() is only called + on "a user page", which surely can't be a slab page. + + - ARCH's implementation of flush_kernel_dcache_page() may use page + mapping information to do optimization so page_mapping() will see the + slab page, then VM_BUG_ON() is triggered. + + Aaro Koskinen reported the bug on ARM/kirkwood when DEBUG_VM is enabled, + and this patch fixes the bug by adding test of '!PageSlab(miter->page)' + before calling flush_kernel_dcache_page(). + + Signed-off-by: Ming Lei + Reported-by: Aaro Koskinen + Tested-by: Simon Baatz + Cc: Russell King - ARM Linux + Cc: Will Deacon + Cc: Aaro Koskinen + Acked-by: Catalin Marinas + Cc: FUJITA Tomonori + Cc: Tejun Heo + Cc: "James E.J. Bottomley" + Cc: Jens Axboe + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/lib/scatterlist.c +=================================================================== +--- linux-3.10-3.10.11.orig/lib/scatterlist.c 2014-05-05 11:48:45.000000000 +0000 ++++ linux-3.10-3.10.11/lib/scatterlist.c 2014-05-05 12:50:52.000000000 +0000 +@@ -529,7 +529,8 @@ + miter->__offset += miter->consumed; + miter->__remaining -= miter->consumed; + +- if (miter->__flags & SG_MITER_TO_SG) ++ if ((miter->__flags & SG_MITER_TO_SG) && ++ !PageSlab(miter->page)) + flush_kernel_dcache_page(miter->page); + + if (miter->__flags & SG_MITER_ATOMIC) { +Index: linux-3.10-3.10.11/dummy/rpi_1549_e14594cd658f655ae3384fcc3ec8c345b36cd4d0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1549_e14594cd658f655ae3384fcc3ec8c345b36cd4d0.txt 2014-05-05 12:50:52.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1550_a33ed3974e7b75af36553589e7810da9d8b22382.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1550_a33ed3974e7b75af36553589e7810da9d8b22382.patch --- linux-3.10.11/debian/patches/rpi/rpi_1550_a33ed3974e7b75af36553589e7810da9d8b22382.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1550_a33ed3974e7b75af36553589e7810da9d8b22382.patch 2014-05-05 12:50:53.000000000 +0000 @@ -0,0 +1,35 @@ +commit a33ed3974e7b75af36553589e7810da9d8b22382 +Author: Dan Carpenter +Date: Tue Oct 29 22:11:06 2013 +0300 + + aacraid: missing capable() check in compat ioctl + + commit f856567b930dfcdbc3323261bf77240ccdde01f5 upstream. + + In commit d496f94d22d1 ('[SCSI] aacraid: fix security weakness') we + added a check on CAP_SYS_RAWIO to the ioctl. The compat ioctls need the + check as well. + + Signed-off-by: Dan Carpenter + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/scsi/aacraid/linit.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/scsi/aacraid/linit.c 2014-05-05 11:48:45.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/scsi/aacraid/linit.c 2014-05-05 12:50:53.000000000 +0000 +@@ -771,6 +771,8 @@ + static int aac_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) + { + struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; ++ if (!capable(CAP_SYS_RAWIO)) ++ return -EPERM; + return aac_compat_do_ioctl(dev, cmd, (unsigned long)arg); + } + +Index: linux-3.10-3.10.11/dummy/rpi_1550_a33ed3974e7b75af36553589e7810da9d8b22382.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1550_a33ed3974e7b75af36553589e7810da9d8b22382.txt 2014-05-05 12:50:53.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1551_165b4f8bf37ba929924e9099bd9a1ee5031cf4e7.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1551_165b4f8bf37ba929924e9099bd9a1ee5031cf4e7.patch --- linux-3.10.11/debian/patches/rpi/rpi_1551_165b4f8bf37ba929924e9099bd9a1ee5031cf4e7.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1551_165b4f8bf37ba929924e9099bd9a1ee5031cf4e7.patch 2014-05-05 12:50:54.000000000 +0000 @@ -0,0 +1,39 @@ +commit 165b4f8bf37ba929924e9099bd9a1ee5031cf4e7 +Author: Jonathan Austin +Date: Tue Jul 23 16:42:18 2013 +0100 + + clk: fixup argument order when setting VCO parameters + + commit 2f9f64bc5aa31836810cd25301aa4772ad73ebab upstream. + + The order of arguments in the call to vco_set() for the ICST clocks appears to + have been switched in error, which results in the VCO not being initialised + correctly. This in turn stops the integrated LCD on things like Integrator/CP + from working correctly. + + This patch fixes the order and restores the expected functionality. + + Reviewed-by: Linus Walleij + Signed-off-by: Jonathan Austin + Signed-off-by: Mike Turquette + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/clk/versatile/clk-icst.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/clk/versatile/clk-icst.c 2014-05-05 11:48:44.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/clk/versatile/clk-icst.c 2014-05-05 12:50:54.000000000 +0000 +@@ -107,7 +107,7 @@ + + vco = icst_hz_to_vco(icst->params, rate); + icst->rate = icst_hz(icst->params, vco); +- vco_set(icst->vcoreg, icst->lockreg, vco); ++ vco_set(icst->lockreg, icst->vcoreg, vco); + return 0; + } + +Index: linux-3.10-3.10.11/dummy/rpi_1551_165b4f8bf37ba929924e9099bd9a1ee5031cf4e7.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1551_165b4f8bf37ba929924e9099bd9a1ee5031cf4e7.txt 2014-05-05 12:50:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1552_699ba929e88a0c2b172e7beebf10fd37ef120142.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1552_699ba929e88a0c2b172e7beebf10fd37ef120142.patch --- linux-3.10.11/debian/patches/rpi/rpi_1552_699ba929e88a0c2b172e7beebf10fd37ef120142.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1552_699ba929e88a0c2b172e7beebf10fd37ef120142.patch 2014-05-05 12:50:55.000000000 +0000 @@ -0,0 +1,44 @@ +commit 699ba929e88a0c2b172e7beebf10fd37ef120142 +Author: Mel Gorman +Date: Mon Oct 7 11:28:42 2013 +0100 + + mm: numa: Do not account for a hinting fault if we raced + + commit 1dd49bfa3465756b3ce72214b58a33e4afb67aa3 upstream. + + If another task handled a hinting fault in parallel then do not double + account for it. + + Signed-off-by: Mel Gorman + Reviewed-by: Rik van Riel + Cc: Andrea Arcangeli + Cc: Johannes Weiner + Cc: Srikar Dronamraju + Signed-off-by: Peter Zijlstra + Link: http://lkml.kernel.org/r/1381141781-10992-5-git-send-email-mgorman@suse.de + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/huge_memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/huge_memory.c 2014-05-05 12:49:59.000000000 +0000 ++++ linux-3.10-3.10.11/mm/huge_memory.c 2014-05-05 12:50:54.000000000 +0000 +@@ -1335,8 +1335,11 @@ + + check_same: + spin_lock(&mm->page_table_lock); +- if (unlikely(!pmd_same(pmd, *pmdp))) ++ if (unlikely(!pmd_same(pmd, *pmdp))) { ++ /* Someone else took our fault */ ++ current_nid = -1; + goto out_unlock; ++ } + clear_pmdnuma: + pmd = pmd_mknonnuma(pmd); + set_pmd_at(mm, haddr, pmdp, pmd); +Index: linux-3.10-3.10.11/dummy/rpi_1552_699ba929e88a0c2b172e7beebf10fd37ef120142.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1552_699ba929e88a0c2b172e7beebf10fd37ef120142.txt 2014-05-05 12:50:54.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1553_2e39395e03fe936171a8b45894cbf75ccfae0375.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1553_2e39395e03fe936171a8b45894cbf75ccfae0375.patch --- linux-3.10.11/debian/patches/rpi/rpi_1553_2e39395e03fe936171a8b45894cbf75ccfae0375.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1553_2e39395e03fe936171a8b45894cbf75ccfae0375.patch 2014-05-05 12:50:55.000000000 +0000 @@ -0,0 +1,84 @@ +commit 2e39395e03fe936171a8b45894cbf75ccfae0375 +Author: Mel Gorman +Date: Mon Oct 7 11:28:43 2013 +0100 + + mm: Wait for THP migrations to complete during NUMA hinting faults + + commit 42836f5f8baa33085f547098b74aa98991ee9216 upstream. + + The locking for migrating THP is unusual. While normal page migration + prevents parallel accesses using a migration PTE, THP migration relies on + a combination of the page_table_lock, the page lock and the existance of + the NUMA hinting PTE to guarantee safety but there is a bug in the scheme. + + If a THP page is currently being migrated and another thread traps a + fault on the same page it checks if the page is misplaced. If it is not, + then pmd_numa is cleared. The problem is that it checks if the page is + misplaced without holding the page lock meaning that the racing thread + can be migrating the THP when the second thread clears the NUMA bit + and faults a stale page. + + This patch checks if the page is potentially being migrated and stalls + using the lock_page if it is potentially being migrated before checking + if the page is misplaced or not. + + Signed-off-by: Mel Gorman + Reviewed-by: Rik van Riel + Cc: Andrea Arcangeli + Cc: Johannes Weiner + Cc: Srikar Dronamraju + Signed-off-by: Peter Zijlstra + Link: http://lkml.kernel.org/r/1381141781-10992-6-git-send-email-mgorman@suse.de + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/huge_memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/huge_memory.c 2014-05-05 12:50:54.000000000 +0000 ++++ linux-3.10-3.10.11/mm/huge_memory.c 2014-05-05 12:50:55.000000000 +0000 +@@ -1305,13 +1305,14 @@ + if (current_nid == numa_node_id()) + count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL); + +- target_nid = mpol_misplaced(page, vma, haddr); +- if (target_nid == -1) { +- put_page(page); +- goto clear_pmdnuma; +- } ++ /* ++ * Acquire the page lock to serialise THP migrations but avoid dropping ++ * page_table_lock if at all possible ++ */ ++ if (trylock_page(page)) ++ goto got_lock; + +- /* Acquire the page lock to serialise THP migrations */ ++ /* Serialise against migrationa and check placement check placement */ + spin_unlock(&mm->page_table_lock); + lock_page(page); + +@@ -1322,9 +1323,17 @@ + put_page(page); + goto out_unlock; + } +- spin_unlock(&mm->page_table_lock); ++ ++got_lock: ++ target_nid = mpol_misplaced(page, vma, haddr); ++ if (target_nid == -1) { ++ unlock_page(page); ++ put_page(page); ++ goto clear_pmdnuma; ++ } + + /* Migrate the THP to the requested node */ ++ spin_unlock(&mm->page_table_lock); + migrated = migrate_misplaced_transhuge_page(mm, vma, + pmdp, pmd, addr, page, target_nid); + if (!migrated) +Index: linux-3.10-3.10.11/dummy/rpi_1553_2e39395e03fe936171a8b45894cbf75ccfae0375.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1553_2e39395e03fe936171a8b45894cbf75ccfae0375.txt 2014-05-05 12:50:55.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1554_299723f2297726ca4c0a9d8ef3548ece5466431d.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1554_299723f2297726ca4c0a9d8ef3548ece5466431d.patch --- linux-3.10.11/debian/patches/rpi/rpi_1554_299723f2297726ca4c0a9d8ef3548ece5466431d.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1554_299723f2297726ca4c0a9d8ef3548ece5466431d.patch 2014-05-05 12:50:56.000000000 +0000 @@ -0,0 +1,125 @@ +commit 299723f2297726ca4c0a9d8ef3548ece5466431d +Author: Mel Gorman +Date: Mon Oct 7 11:28:44 2013 +0100 + + mm: Prevent parallel splits during THP migration + + commit 587fe586f44a48f9691001ba6c45b86c8e4ba21f upstream. + + THP migrations are serialised by the page lock but on its own that does + not prevent THP splits. If the page is split during THP migration then + the pmd_same checks will prevent page table corruption but the unlock page + and other fix-ups potentially will cause corruption. This patch takes the + anon_vma lock to prevent parallel splits during migration. + + Signed-off-by: Mel Gorman + Reviewed-by: Rik van Riel + Cc: Andrea Arcangeli + Cc: Johannes Weiner + Cc: Srikar Dronamraju + Signed-off-by: Peter Zijlstra + Link: http://lkml.kernel.org/r/1381141781-10992-7-git-send-email-mgorman@suse.de + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/huge_memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/huge_memory.c 2014-05-05 12:50:55.000000000 +0000 ++++ linux-3.10-3.10.11/mm/huge_memory.c 2014-05-05 12:50:56.000000000 +0000 +@@ -1288,18 +1288,18 @@ + int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long addr, pmd_t pmd, pmd_t *pmdp) + { ++ struct anon_vma *anon_vma = NULL; + struct page *page; + unsigned long haddr = addr & HPAGE_PMD_MASK; + int target_nid; + int current_nid = -1; +- bool migrated; ++ bool migrated, page_locked; + + spin_lock(&mm->page_table_lock); + if (unlikely(!pmd_same(pmd, *pmdp))) + goto out_unlock; + + page = pmd_page(pmd); +- get_page(page); + current_nid = page_to_nid(page); + count_vm_numa_event(NUMA_HINT_FAULTS); + if (current_nid == numa_node_id()) +@@ -1309,12 +1309,29 @@ + * Acquire the page lock to serialise THP migrations but avoid dropping + * page_table_lock if at all possible + */ +- if (trylock_page(page)) +- goto got_lock; ++ page_locked = trylock_page(page); ++ target_nid = mpol_misplaced(page, vma, haddr); ++ if (target_nid == -1) { ++ /* If the page was locked, there are no parallel migrations */ ++ if (page_locked) { ++ unlock_page(page); ++ goto clear_pmdnuma; ++ } ++ ++ /* Otherwise wait for potential migrations and retry fault */ ++ spin_unlock(&mm->page_table_lock); ++ wait_on_page_locked(page); ++ goto out; ++ } + +- /* Serialise against migrationa and check placement check placement */ ++ /* Page is misplaced, serialise migrations and parallel THP splits */ ++ get_page(page); + spin_unlock(&mm->page_table_lock); +- lock_page(page); ++ if (!page_locked) { ++ lock_page(page); ++ page_locked = true; ++ } ++ anon_vma = page_lock_anon_vma_read(page); + + /* Confirm the PTE did not while locked */ + spin_lock(&mm->page_table_lock); +@@ -1324,14 +1341,6 @@ + goto out_unlock; + } + +-got_lock: +- target_nid = mpol_misplaced(page, vma, haddr); +- if (target_nid == -1) { +- unlock_page(page); +- put_page(page); +- goto clear_pmdnuma; +- } +- + /* Migrate the THP to the requested node */ + spin_unlock(&mm->page_table_lock); + migrated = migrate_misplaced_transhuge_page(mm, vma, +@@ -1340,6 +1349,8 @@ + goto check_same; + + task_numa_fault(target_nid, HPAGE_PMD_NR, true); ++ if (anon_vma) ++ page_unlock_anon_vma_read(anon_vma); + return 0; + + check_same: +@@ -1356,6 +1367,11 @@ + update_mmu_cache_pmd(vma, addr, pmdp); + out_unlock: + spin_unlock(&mm->page_table_lock); ++ ++out: ++ if (anon_vma) ++ page_unlock_anon_vma_read(anon_vma); ++ + if (current_nid != -1) + task_numa_fault(current_nid, HPAGE_PMD_NR, false); + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1554_299723f2297726ca4c0a9d8ef3548ece5466431d.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1554_299723f2297726ca4c0a9d8ef3548ece5466431d.txt 2014-05-05 12:50:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1555_174dfa40d63b2250e299d5376937d200e4662b7c.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1555_174dfa40d63b2250e299d5376937d200e4662b7c.patch --- linux-3.10.11/debian/patches/rpi/rpi_1555_174dfa40d63b2250e299d5376937d200e4662b7c.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1555_174dfa40d63b2250e299d5376937d200e4662b7c.patch 2014-05-05 12:50:57.000000000 +0000 @@ -0,0 +1,234 @@ +commit 174dfa40d63b2250e299d5376937d200e4662b7c +Author: Mel Gorman +Date: Mon Oct 7 11:28:45 2013 +0100 + + mm: numa: Sanitize task_numa_fault() callsites + + commit c61109e34f60f6e85bb43c5a1cd51c0e3db40847 upstream. + + There are three callers of task_numa_fault(): + + - do_huge_pmd_numa_page(): + Accounts against the current node, not the node where the + page resides, unless we migrated, in which case it accounts + against the node we migrated to. + + - do_numa_page(): + Accounts against the current node, not the node where the + page resides, unless we migrated, in which case it accounts + against the node we migrated to. + + - do_pmd_numa_page(): + Accounts not at all when the page isn't migrated, otherwise + accounts against the node we migrated towards. + + This seems wrong to me; all three sites should have the same + sementaics, furthermore we should accounts against where the page + really is, we already know where the task is. + + So modify all three sites to always account; we did after all receive + the fault; and always account to where the page is after migration, + regardless of success. + + They all still differ on when they clear the PTE/PMD; ideally that + would get sorted too. + + Signed-off-by: Mel Gorman + Reviewed-by: Rik van Riel + Cc: Andrea Arcangeli + Cc: Johannes Weiner + Cc: Srikar Dronamraju + Signed-off-by: Peter Zijlstra + Link: http://lkml.kernel.org/r/1381141781-10992-8-git-send-email-mgorman@suse.de + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/huge_memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/huge_memory.c 2014-05-05 12:50:56.000000000 +0000 ++++ linux-3.10-3.10.11/mm/huge_memory.c 2014-05-05 12:50:56.000000000 +0000 +@@ -1291,18 +1291,19 @@ + struct anon_vma *anon_vma = NULL; + struct page *page; + unsigned long haddr = addr & HPAGE_PMD_MASK; ++ int page_nid = -1, this_nid = numa_node_id(); + int target_nid; +- int current_nid = -1; +- bool migrated, page_locked; ++ bool page_locked; ++ bool migrated = false; + + spin_lock(&mm->page_table_lock); + if (unlikely(!pmd_same(pmd, *pmdp))) + goto out_unlock; + + page = pmd_page(pmd); +- current_nid = page_to_nid(page); ++ page_nid = page_to_nid(page); + count_vm_numa_event(NUMA_HINT_FAULTS); +- if (current_nid == numa_node_id()) ++ if (page_nid == this_nid) + count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL); + + /* +@@ -1345,19 +1346,18 @@ + spin_unlock(&mm->page_table_lock); + migrated = migrate_misplaced_transhuge_page(mm, vma, + pmdp, pmd, addr, page, target_nid); +- if (!migrated) ++ if (migrated) ++ page_nid = target_nid; ++ else + goto check_same; + +- task_numa_fault(target_nid, HPAGE_PMD_NR, true); +- if (anon_vma) +- page_unlock_anon_vma_read(anon_vma); +- return 0; ++ goto out; + + check_same: + spin_lock(&mm->page_table_lock); + if (unlikely(!pmd_same(pmd, *pmdp))) { + /* Someone else took our fault */ +- current_nid = -1; ++ page_nid = -1; + goto out_unlock; + } + clear_pmdnuma: +@@ -1372,8 +1372,9 @@ + if (anon_vma) + page_unlock_anon_vma_read(anon_vma); + +- if (current_nid != -1) +- task_numa_fault(current_nid, HPAGE_PMD_NR, false); ++ if (page_nid != -1) ++ task_numa_fault(page_nid, HPAGE_PMD_NR, migrated); ++ + return 0; + } + +Index: linux-3.10-3.10.11/mm/memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/memory.c 2014-05-05 12:50:48.000000000 +0000 ++++ linux-3.10-3.10.11/mm/memory.c 2014-05-05 12:50:56.000000000 +0000 +@@ -3525,12 +3525,12 @@ + } + + int numa_migrate_prep(struct page *page, struct vm_area_struct *vma, +- unsigned long addr, int current_nid) ++ unsigned long addr, int page_nid) + { + get_page(page); + + count_vm_numa_event(NUMA_HINT_FAULTS); +- if (current_nid == numa_node_id()) ++ if (page_nid == numa_node_id()) + count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL); + + return mpol_misplaced(page, vma, addr); +@@ -3541,7 +3541,7 @@ + { + struct page *page = NULL; + spinlock_t *ptl; +- int current_nid = -1; ++ int page_nid = -1; + int target_nid; + bool migrated = false; + +@@ -3571,15 +3571,10 @@ + return 0; + } + +- current_nid = page_to_nid(page); +- target_nid = numa_migrate_prep(page, vma, addr, current_nid); ++ page_nid = page_to_nid(page); ++ target_nid = numa_migrate_prep(page, vma, addr, page_nid); + pte_unmap_unlock(ptep, ptl); + if (target_nid == -1) { +- /* +- * Account for the fault against the current node if it not +- * being replaced regardless of where the page is located. +- */ +- current_nid = numa_node_id(); + put_page(page); + goto out; + } +@@ -3587,11 +3582,11 @@ + /* Migrate to the requested node */ + migrated = migrate_misplaced_page(page, target_nid); + if (migrated) +- current_nid = target_nid; ++ page_nid = target_nid; + + out: +- if (current_nid != -1) +- task_numa_fault(current_nid, 1, migrated); ++ if (page_nid != -1) ++ task_numa_fault(page_nid, 1, migrated); + return 0; + } + +@@ -3606,7 +3601,6 @@ + unsigned long offset; + spinlock_t *ptl; + bool numa = false; +- int local_nid = numa_node_id(); + + spin_lock(&mm->page_table_lock); + pmd = *pmdp; +@@ -3629,9 +3623,10 @@ + for (addr = _addr + offset; addr < _addr + PMD_SIZE; pte++, addr += PAGE_SIZE) { + pte_t pteval = *pte; + struct page *page; +- int curr_nid = local_nid; ++ int page_nid = -1; + int target_nid; +- bool migrated; ++ bool migrated = false; ++ + if (!pte_present(pteval)) + continue; + if (!pte_numa(pteval)) +@@ -3653,25 +3648,19 @@ + if (unlikely(page_mapcount(page) != 1)) + continue; + +- /* +- * Note that the NUMA fault is later accounted to either +- * the node that is currently running or where the page is +- * migrated to. +- */ +- curr_nid = local_nid; +- target_nid = numa_migrate_prep(page, vma, addr, +- page_to_nid(page)); +- if (target_nid == -1) { ++ page_nid = page_to_nid(page); ++ target_nid = numa_migrate_prep(page, vma, addr, page_nid); ++ pte_unmap_unlock(pte, ptl); ++ if (target_nid != -1) { ++ migrated = migrate_misplaced_page(page, target_nid); ++ if (migrated) ++ page_nid = target_nid; ++ } else { + put_page(page); +- continue; + } + +- /* Migrate to the requested node */ +- pte_unmap_unlock(pte, ptl); +- migrated = migrate_misplaced_page(page, target_nid); +- if (migrated) +- curr_nid = target_nid; +- task_numa_fault(curr_nid, 1, migrated); ++ if (page_nid != -1) ++ task_numa_fault(page_nid, 1, migrated); + + pte = pte_offset_map_lock(mm, pmdp, addr, &ptl); + } +Index: linux-3.10-3.10.11/dummy/rpi_1555_174dfa40d63b2250e299d5376937d200e4662b7c.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1555_174dfa40d63b2250e299d5376937d200e4662b7c.txt 2014-05-05 12:50:56.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1556_a490bb33b51d0fc625c87ed5fff1edfd3a2afeb0.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1556_a490bb33b51d0fc625c87ed5fff1edfd3a2afeb0.patch --- linux-3.10.11/debian/patches/rpi/rpi_1556_a490bb33b51d0fc625c87ed5fff1edfd3a2afeb0.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1556_a490bb33b51d0fc625c87ed5fff1edfd3a2afeb0.patch 2014-05-05 12:50:58.000000000 +0000 @@ -0,0 +1,177 @@ +commit a490bb33b51d0fc625c87ed5fff1edfd3a2afeb0 +Author: Mel Gorman +Date: Mon Oct 7 11:28:46 2013 +0100 + + mm: Close races between THP migration and PMD numa clearing + + commit 3f926ab945b60a5824369d21add7710622a2eac0 upstream. + + THP migration uses the page lock to guard against parallel allocations + but there are cases like this still open + + Task A Task B + --------------------- --------------------- + do_huge_pmd_numa_page do_huge_pmd_numa_page + lock_page + mpol_misplaced == -1 + unlock_page + goto clear_pmdnuma + lock_page + mpol_misplaced == 2 + migrate_misplaced_transhuge + pmd = pmd_mknonnuma + set_pmd_at + + During hours of testing, one crashed with weird errors and while I have + no direct evidence, I suspect something like the race above happened. + This patch extends the page lock to being held until the pmd_numa is + cleared to prevent migration starting in parallel while the pmd_numa is + being cleared. It also flushes the old pmd entry and orders pagetable + insertion before rmap insertion. + + Signed-off-by: Mel Gorman + Reviewed-by: Rik van Riel + Cc: Andrea Arcangeli + Cc: Johannes Weiner + Cc: Srikar Dronamraju + Signed-off-by: Peter Zijlstra + Link: http://lkml.kernel.org/r/1381141781-10992-9-git-send-email-mgorman@suse.de + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/huge_memory.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/huge_memory.c 2014-05-05 12:50:56.000000000 +0000 ++++ linux-3.10-3.10.11/mm/huge_memory.c 2014-05-05 12:50:57.000000000 +0000 +@@ -1314,24 +1314,25 @@ + target_nid = mpol_misplaced(page, vma, haddr); + if (target_nid == -1) { + /* If the page was locked, there are no parallel migrations */ +- if (page_locked) { +- unlock_page(page); ++ if (page_locked) + goto clear_pmdnuma; +- } + +- /* Otherwise wait for potential migrations and retry fault */ ++ /* ++ * Otherwise wait for potential migrations and retry. We do ++ * relock and check_same as the page may no longer be mapped. ++ * As the fault is being retried, do not account for it. ++ */ + spin_unlock(&mm->page_table_lock); + wait_on_page_locked(page); ++ page_nid = -1; + goto out; + } + + /* Page is misplaced, serialise migrations and parallel THP splits */ + get_page(page); + spin_unlock(&mm->page_table_lock); +- if (!page_locked) { ++ if (!page_locked) + lock_page(page); +- page_locked = true; +- } + anon_vma = page_lock_anon_vma_read(page); + + /* Confirm the PTE did not while locked */ +@@ -1339,32 +1340,28 @@ + if (unlikely(!pmd_same(pmd, *pmdp))) { + unlock_page(page); + put_page(page); ++ page_nid = -1; + goto out_unlock; + } + +- /* Migrate the THP to the requested node */ ++ /* ++ * Migrate the THP to the requested node, returns with page unlocked ++ * and pmd_numa cleared. ++ */ + spin_unlock(&mm->page_table_lock); + migrated = migrate_misplaced_transhuge_page(mm, vma, + pmdp, pmd, addr, page, target_nid); + if (migrated) + page_nid = target_nid; +- else +- goto check_same; + + goto out; +- +-check_same: +- spin_lock(&mm->page_table_lock); +- if (unlikely(!pmd_same(pmd, *pmdp))) { +- /* Someone else took our fault */ +- page_nid = -1; +- goto out_unlock; +- } + clear_pmdnuma: ++ BUG_ON(!PageLocked(page)); + pmd = pmd_mknonnuma(pmd); + set_pmd_at(mm, haddr, pmdp, pmd); + VM_BUG_ON(pmd_numa(*pmdp)); + update_mmu_cache_pmd(vma, addr, pmdp); ++ unlock_page(page); + out_unlock: + spin_unlock(&mm->page_table_lock); + +Index: linux-3.10-3.10.11/mm/migrate.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/migrate.c 2014-05-05 12:48:00.000000000 +0000 ++++ linux-3.10-3.10.11/mm/migrate.c 2014-05-05 12:50:57.000000000 +0000 +@@ -1710,12 +1710,12 @@ + unlock_page(new_page); + put_page(new_page); /* Free it */ + +- unlock_page(page); ++ /* Retake the callers reference and putback on LRU */ ++ get_page(page); + putback_lru_page(page); +- +- count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR); +- isolated = 0; +- goto out; ++ mod_zone_page_state(page_zone(page), ++ NR_ISOLATED_ANON + page_lru, -HPAGE_PMD_NR); ++ goto out_fail; + } + + /* +@@ -1732,9 +1732,9 @@ + entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); + entry = pmd_mkhuge(entry); + +- page_add_new_anon_rmap(new_page, vma, haddr); +- ++ pmdp_clear_flush(vma, haddr, pmd); + set_pmd_at(mm, haddr, pmd, entry); ++ page_add_new_anon_rmap(new_page, vma, haddr); + update_mmu_cache_pmd(vma, address, &entry); + page_remove_rmap(page); + /* +@@ -1753,7 +1753,6 @@ + count_vm_events(PGMIGRATE_SUCCESS, HPAGE_PMD_NR); + count_vm_numa_events(NUMA_PAGE_MIGRATE, HPAGE_PMD_NR); + +-out: + mod_zone_page_state(page_zone(page), + NR_ISOLATED_ANON + page_lru, + -HPAGE_PMD_NR); +@@ -1762,6 +1761,10 @@ + out_fail: + count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR); + out_dropref: ++ entry = pmd_mknonnuma(entry); ++ set_pmd_at(mm, haddr, pmd, entry); ++ update_mmu_cache_pmd(vma, address, &entry); ++ + unlock_page(page); + put_page(page); + return 0; +Index: linux-3.10-3.10.11/dummy/rpi_1556_a490bb33b51d0fc625c87ed5fff1edfd3a2afeb0.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1556_a490bb33b51d0fc625c87ed5fff1edfd3a2afeb0.txt 2014-05-05 12:50:57.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1557_e86100b54cd487c13956f09f2c38955f1a1a0909.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1557_e86100b54cd487c13956f09f2c38955f1a1a0909.patch --- linux-3.10.11/debian/patches/rpi/rpi_1557_e86100b54cd487c13956f09f2c38955f1a1a0909.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1557_e86100b54cd487c13956f09f2c38955f1a1a0909.patch 2014-05-05 12:50:59.000000000 +0000 @@ -0,0 +1,42 @@ +commit e86100b54cd487c13956f09f2c38955f1a1a0909 +Author: Mel Gorman +Date: Mon Oct 7 11:28:47 2013 +0100 + + mm: Account for a THP NUMA hinting update as one PTE update + + commit 0255d491848032f6c601b6410c3b8ebded3a37b1 upstream. + + A THP PMD update is accounted for as 512 pages updated in vmstat. This is + large difference when estimating the cost of automatic NUMA balancing and + can be misleading when comparing results that had collapsed versus split + THP. This patch addresses the accounting issue. + + Signed-off-by: Mel Gorman + Reviewed-by: Rik van Riel + Cc: Andrea Arcangeli + Cc: Johannes Weiner + Cc: Srikar Dronamraju + Signed-off-by: Peter Zijlstra + Link: http://lkml.kernel.org/r/1381141781-10992-10-git-send-email-mgorman@suse.de + Signed-off-by: Ingo Molnar + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/mprotect.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/mprotect.c 2014-05-05 11:48:42.000000000 +0000 ++++ linux-3.10-3.10.11/mm/mprotect.c 2014-05-05 12:50:58.000000000 +0000 +@@ -145,7 +145,7 @@ + split_huge_page_pmd(vma, addr, pmd); + else if (change_huge_pmd(vma, pmd, addr, newprot, + prot_numa)) { +- pages += HPAGE_PMD_NR; ++ pages++; + continue; + } + /* fall through */ +Index: linux-3.10-3.10.11/dummy/rpi_1557_e86100b54cd487c13956f09f2c38955f1a1a0909.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1557_e86100b54cd487c13956f09f2c38955f1a1a0909.txt 2014-05-05 12:50:58.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1558_18b683a2334848c003fe89e3002244ca298544f4.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1558_18b683a2334848c003fe89e3002244ca298544f4.patch --- linux-3.10.11/debian/patches/rpi/rpi_1558_18b683a2334848c003fe89e3002244ca298544f4.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1558_18b683a2334848c003fe89e3002244ca298544f4.patch 2014-05-05 12:50:59.000000000 +0000 @@ -0,0 +1,56 @@ +commit 18b683a2334848c003fe89e3002244ca298544f4 +Author: Chen LinX +Date: Wed Oct 30 13:56:18 2013 -0700 + + mm/pagewalk.c: fix walk_page_range() access of wrong PTEs + + commit 3017f079efd6af199b0852b5c425364513db460e upstream. + + When walk_page_range walk a memory map's page tables, it'll skip + VM_PFNMAP area, then variable 'next' will to assign to vma->vm_end, it + maybe larger than 'end'. In next loop, 'addr' will be larger than + 'next'. Then in /proc/XXXX/pagemap file reading procedure, the 'addr' + will growing forever in pagemap_pte_range, pte_to_pagemap_entry will + access the wrong pte. + + BUG: Bad page map in process procrank pte:8437526f pmd:785de067 + addr:9108d000 vm_flags:00200073 anon_vma:f0d99020 mapping: (null) index:9108d + CPU: 1 PID: 4974 Comm: procrank Tainted: G B W O 3.10.1+ #1 + Call Trace: + dump_stack+0x16/0x18 + print_bad_pte+0x114/0x1b0 + vm_normal_page+0x56/0x60 + pagemap_pte_range+0x17a/0x1d0 + walk_page_range+0x19e/0x2c0 + pagemap_read+0x16e/0x200 + vfs_read+0x84/0x150 + SyS_read+0x4a/0x80 + syscall_call+0x7/0xb + + Signed-off-by: Liu ShuoX + Signed-off-by: Chen LinX + Acked-by: Kirill A. Shutemov + Reviewed-by: Naoya Horiguchi + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/pagewalk.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/pagewalk.c 2014-05-05 11:48:41.000000000 +0000 ++++ linux-3.10-3.10.11/mm/pagewalk.c 2014-05-05 12:50:59.000000000 +0000 +@@ -242,7 +242,7 @@ + if (err) + break; + pgd++; +- } while (addr = next, addr != end); ++ } while (addr = next, addr < end); + + return err; + } +Index: linux-3.10-3.10.11/dummy/rpi_1558_18b683a2334848c003fe89e3002244ca298544f4.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1558_18b683a2334848c003fe89e3002244ca298544f4.txt 2014-05-05 12:50:59.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1559_7bff7accd427da171501b558457ef8fa81ee2767.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1559_7bff7accd427da171501b558457ef8fa81ee2767.patch --- linux-3.10.11/debian/patches/rpi/rpi_1559_7bff7accd427da171501b558457ef8fa81ee2767.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1559_7bff7accd427da171501b558457ef8fa81ee2767.patch 2014-05-05 12:51:00.000000000 +0000 @@ -0,0 +1,68 @@ +commit 7bff7accd427da171501b558457ef8fa81ee2767 +Author: Zhang Yanfei +Date: Mon Jul 8 16:00:19 2013 -0700 + + mm/vmalloc.c: fix an overflow bug in alloc_vmap_area() + + commit bcb615a81b1765864c71c50afb56631e7a1e5283 upstream. + + When searching a vmap area in the vmalloc space, we use (addr + size - + 1) to check if the value is less than addr, which is an overflow. But + we assign (addr + size) to vmap_area->va_end. + + So if we come across the below case: + + (addr + size - 1) : not overflow + (addr + size) : overflow + + we will assign an overflow value (e.g 0) to vmap_area->va_end, And this + will trigger BUG in __insert_vmap_area, causing system panic. + + So using (addr + size) to check the overflow should be the correct + behaviour, not (addr + size - 1). + + Signed-off-by: Zhang Yanfei + Reported-by: Ghennadi Procopciuc + Tested-by: Daniel Baluta + Cc: David Rientjes + Cc: Minchan Kim + Cc: KOSAKI Motohiro + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + Cc: Anatoly Muliarski + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/mm/vmalloc.c +=================================================================== +--- linux-3.10-3.10.11.orig/mm/vmalloc.c 2014-05-05 11:48:41.000000000 +0000 ++++ linux-3.10-3.10.11/mm/vmalloc.c 2014-05-05 12:51:00.000000000 +0000 +@@ -388,12 +388,12 @@ + addr = ALIGN(first->va_end, align); + if (addr < vstart) + goto nocache; +- if (addr + size - 1 < addr) ++ if (addr + size < addr) + goto overflow; + + } else { + addr = ALIGN(vstart, align); +- if (addr + size - 1 < addr) ++ if (addr + size < addr) + goto overflow; + + n = vmap_area_root.rb_node; +@@ -420,7 +420,7 @@ + if (addr + cached_hole_size < first->va_start) + cached_hole_size = first->va_start - addr; + addr = ALIGN(first->va_end, align); +- if (addr + size - 1 < addr) ++ if (addr + size < addr) + goto overflow; + + if (list_is_last(&first->list, &vmap_area_list)) +Index: linux-3.10-3.10.11/dummy/rpi_1559_7bff7accd427da171501b558457ef8fa81ee2767.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1559_7bff7accd427da171501b558457ef8fa81ee2767.txt 2014-05-05 12:51:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1560_0d6d09974ba93877afa53f5ce5ce89f20b3dfe20.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1560_0d6d09974ba93877afa53f5ce5ce89f20b3dfe20.patch --- linux-3.10.11/debian/patches/rpi/rpi_1560_0d6d09974ba93877afa53f5ce5ce89f20b3dfe20.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1560_0d6d09974ba93877afa53f5ce5ce89f20b3dfe20.patch 2014-05-05 12:51:01.000000000 +0000 @@ -0,0 +1,35 @@ +commit 0d6d09974ba93877afa53f5ce5ce89f20b3dfe20 +Author: Thomas Hellstrom +Date: Wed Oct 9 01:42:50 2013 -0700 + + drm/vmwgfx: Don't put resources with invalid id's on lru list + + commit 26682480c202e7360cbcdc3bc9e962bf749c6b8d upstream. + + The evict code may try to swap them out causing a BUG in the destroy + function. + + Signed-off-by: Thomas Hellstrom + Reviewed-by: Jakob Bornecrantz + Signed-off-by: Dave Airlie + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c 2014-05-05 11:48:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c 2014-05-05 12:51:00.000000000 +0000 +@@ -970,7 +970,7 @@ + if (new_backup) + res->backup_offset = new_backup_offset; + +- if (!res->func->may_evict) ++ if (!res->func->may_evict || res->id == -1) + return; + + write_lock(&dev_priv->resource_lock); +Index: linux-3.10-3.10.11/dummy/rpi_1560_0d6d09974ba93877afa53f5ce5ce89f20b3dfe20.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1560_0d6d09974ba93877afa53f5ce5ce89f20b3dfe20.txt 2014-05-05 12:51:00.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1561_09c2c79ce6e82b226262e667971db7f4a666e430.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1561_09c2c79ce6e82b226262e667971db7f4a666e430.patch --- linux-3.10.11/debian/patches/rpi/rpi_1561_09c2c79ce6e82b226262e667971db7f4a666e430.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1561_09c2c79ce6e82b226262e667971db7f4a666e430.patch 2014-05-05 12:51:02.000000000 +0000 @@ -0,0 +1,65 @@ +commit 09c2c79ce6e82b226262e667971db7f4a666e430 +Author: Thomas Hellstrom +Date: Wed Oct 9 01:42:51 2013 -0700 + + drm/vmwgfx: Don't kill clients on VT switch + + commit c4249855ac5b2a383704d31e040d3831d6a25c6f upstream. + + DRI clients that tried to grab the TTM lock when the master (X server) was + switched away during a VT switch were sent the SIGTERM signal by the + kernel. Fix this so that they are only sent that signal when the master has + exited. + + Signed-off-by: Thomas Hellstrom + Reviewed-by: Jakob Bornecrantz + Signed-off-by: Dave Airlie + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 2014-05-05 11:48:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 2014-05-05 12:51:01.000000000 +0000 +@@ -740,9 +740,17 @@ + struct vmw_fpriv *vmw_fp; + + vmw_fp = vmw_fpriv(file_priv); +- ttm_object_file_release(&vmw_fp->tfile); +- if (vmw_fp->locked_master) ++ ++ if (vmw_fp->locked_master) { ++ struct vmw_master *vmaster = ++ vmw_master(vmw_fp->locked_master); ++ ++ ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); ++ ttm_vt_unlock(&vmaster->lock); + drm_master_put(&vmw_fp->locked_master); ++ } ++ ++ ttm_object_file_release(&vmw_fp->tfile); + kfree(vmw_fp); + } + +@@ -942,14 +950,13 @@ + + vmw_fp->locked_master = drm_master_get(file_priv->master); + ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); +- vmw_execbuf_release_pinned_bo(dev_priv); +- + if (unlikely((ret != 0))) { + DRM_ERROR("Unable to lock TTM at VT switch.\n"); + drm_master_put(&vmw_fp->locked_master); + } + +- ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); ++ ttm_lock_set_kill(&vmaster->lock, false, SIGTERM); ++ vmw_execbuf_release_pinned_bo(dev_priv); + + if (!dev_priv->enable_fb) { + ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); +Index: linux-3.10-3.10.11/dummy/rpi_1561_09c2c79ce6e82b226262e667971db7f4a666e430.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1561_09c2c79ce6e82b226262e667971db7f4a666e430.txt 2014-05-05 12:51:01.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1562_45da934f7431181cd1ccc33b4d138dc41c2cd1ba.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1562_45da934f7431181cd1ccc33b4d138dc41c2cd1ba.patch --- linux-3.10.11/debian/patches/rpi/rpi_1562_45da934f7431181cd1ccc33b4d138dc41c2cd1ba.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1562_45da934f7431181cd1ccc33b4d138dc41c2cd1ba.patch 2014-05-05 12:51:02.000000000 +0000 @@ -0,0 +1,55 @@ +commit 45da934f7431181cd1ccc33b4d138dc41c2cd1ba +Author: Chris Wilson +Date: Wed Oct 16 11:22:44 2013 +0100 + + drm: Prevent overwriting from userspace underallocating core ioctl structs + + commit b062672e305ce071f21eb9e18b102c2a430e0999 upstream. + + Apply the protections from + + commit 1b2f1489633888d4a06028315dc19d65768a1c05 + Author: Dave Airlie + Date: Sat Aug 14 20:20:34 2010 +1000 + + drm: block userspace under allocating buffer and having drivers overwrite it (v2) + + to the core ioctl structs as well, for we found one instance where there + is a 32-/64-bit size mismatch and were guilty of writing beyond the end + of the user's buffer. + + Signed-off-by: Chris Wilson + Cc: Dave Airlie + Reviewed-by: Ville Syrjälä + Cc: dri-devel@lists.freedesktop.org + Signed-off-by: Dave Airlie + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/drm_drv.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/drm_drv.c 2014-05-05 11:48:41.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/drm_drv.c 2014-05-05 12:51:02.000000000 +0000 +@@ -406,9 +406,16 @@ + cmd = ioctl->cmd_drv; + } + else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { ++ u32 drv_size; ++ + ioctl = &drm_ioctls[nr]; +- cmd = ioctl->cmd; ++ ++ drv_size = _IOC_SIZE(ioctl->cmd); + usize = asize = _IOC_SIZE(cmd); ++ if (drv_size > asize) ++ asize = drv_size; ++ ++ cmd = ioctl->cmd; + } else + goto err_i1; + +Index: linux-3.10-3.10.11/dummy/rpi_1562_45da934f7431181cd1ccc33b4d138dc41c2cd1ba.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1562_45da934f7431181cd1ccc33b4d138dc41c2cd1ba.txt 2014-05-05 12:51:02.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1563_9c1aab0da00ed04f096fabc4136241cb45f92cc1.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1563_9c1aab0da00ed04f096fabc4136241cb45f92cc1.patch --- linux-3.10.11/debian/patches/rpi/rpi_1563_9c1aab0da00ed04f096fabc4136241cb45f92cc1.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1563_9c1aab0da00ed04f096fabc4136241cb45f92cc1.patch 2014-05-05 12:51:03.000000000 +0000 @@ -0,0 +1,55 @@ +commit 9c1aab0da00ed04f096fabc4136241cb45f92cc1 +Author: Chris Wilson +Date: Wed Oct 16 09:49:02 2013 +0100 + + drm: Pad drm_mode_get_connector to 64-bit boundary + + commit bc5bd37ce48c66e9192ad2e7231e9678880f6f8e upstream. + + Pavel Roskin reported that DRM_IOCTL_MODE_GETCONNECTOR was overwritting + the 4 bytes beyond the end of its structure with a 32-bit userspace + running on a 64-bit kernel. This is due to the padding gcc inserts as + the drm_mode_get_connector struct includes a u64 and its size is not a + natural multiple of u64s. + + 64-bit kernel: + + sizeof(drm_mode_get_connector)=80, alignof=8 + sizeof(drm_mode_get_encoder)=20, alignof=4 + sizeof(drm_mode_modeinfo)=68, alignof=4 + + 32-bit userspace: + + sizeof(drm_mode_get_connector)=76, alignof=4 + sizeof(drm_mode_get_encoder)=20, alignof=4 + sizeof(drm_mode_modeinfo)=68, alignof=4 + + Fortuituously we can insert explicit padding to the tail of our + structures without breaking ABI. + + Reported-by: Pavel Roskin + Signed-off-by: Chris Wilson + Cc: Dave Airlie + Cc: dri-devel@lists.freedesktop.org + Signed-off-by: Dave Airlie + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/include/uapi/drm/drm_mode.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/uapi/drm/drm_mode.h 2014-05-05 11:48:40.000000000 +0000 ++++ linux-3.10-3.10.11/include/uapi/drm/drm_mode.h 2014-05-05 12:51:03.000000000 +0000 +@@ -223,6 +223,8 @@ + __u32 connection; + __u32 mm_width, mm_height; /**< HxW in millimeters */ + __u32 subpixel; ++ ++ __u32 pad; + }; + + #define DRM_MODE_PROP_PENDING (1<<0) +Index: linux-3.10-3.10.11/dummy/rpi_1563_9c1aab0da00ed04f096fabc4136241cb45f92cc1.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1563_9c1aab0da00ed04f096fabc4136241cb45f92cc1.txt 2014-05-05 12:51:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1564_2233b4db914786e69960d717a3019c87ba3bb5a5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1564_2233b4db914786e69960d717a3019c87ba3bb5a5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1564_2233b4db914786e69960d717a3019c87ba3bb5a5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1564_2233b4db914786e69960d717a3019c87ba3bb5a5.patch 2014-05-05 12:51:04.000000000 +0000 @@ -0,0 +1,38 @@ +commit 2233b4db914786e69960d717a3019c87ba3bb5a5 +Author: Alex Deucher +Date: Thu Oct 10 16:45:27 2013 -0400 + + drm/radeon/atom: workaround vbios bug in transmitter table on rs780 + + commit c23632d4e57c0dd20bf50eca08fa0eb8ad3ff680 upstream. + + Some rs780 asics seem to be affected as well. + + See: + http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=91f3a6aaf280294b07c05dfe606e6c27b7ba3c72 + + Fixes: + https://bugzilla.kernel.org/show_bug.cgi?id=60791 + + Signed-off-by: Alex Deucher + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_encoders.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/gpu/drm/radeon/atombios_encoders.c 2014-05-05 12:45:46.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/gpu/drm/radeon/atombios_encoders.c 2014-05-05 12:51:03.000000000 +0000 +@@ -1641,7 +1641,7 @@ + * does the same thing and more. + */ + if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) && +- (rdev->family != CHIP_RS880)) ++ (rdev->family != CHIP_RS780) && (rdev->family != CHIP_RS880)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + } + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { +Index: linux-3.10-3.10.11/dummy/rpi_1564_2233b4db914786e69960d717a3019c87ba3bb5a5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1564_2233b4db914786e69960d717a3019c87ba3bb5a5.txt 2014-05-05 12:51:03.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1565_dad483b78d280665a110591fd418535e0f9791dc.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1565_dad483b78d280665a110591fd418535e0f9791dc.patch --- linux-3.10.11/debian/patches/rpi/rpi_1565_dad483b78d280665a110591fd418535e0f9791dc.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1565_dad483b78d280665a110591fd418535e0f9791dc.patch 2014-05-05 12:51:05.000000000 +0000 @@ -0,0 +1,73 @@ +commit dad483b78d280665a110591fd418535e0f9791dc +Author: Gu Zheng +Date: Fri Oct 25 18:15:06 2013 +0800 + + seq_file: always update file->f_pos in seq_lseek() + + commit 05e16745c0c471bba313961b605b6da3b21a853d upstream. + + This issue was first pointed out by Jiaxing Wang several months ago, but no + further comments: + https://lkml.org/lkml/2013/6/29/41 + + As we know pread() does not change f_pos, so after pread(), file->f_pos + and m->read_pos become different. And seq_lseek() does not update file->f_pos + if offset equals to m->read_pos, so after pread() and seq_lseek()(lseek to + m->read_pos), then a subsequent read may read from a wrong position, the + following program produces the problem: + + char str1[32] = { 0 }; + char str2[32] = { 0 }; + int poffset = 10; + int count = 20; + + /*open any seq file*/ + int fd = open("/proc/modules", O_RDONLY); + + pread(fd, str1, count, poffset); + printf("pread:%s\n", str1); + + /*seek to where m->read_pos is*/ + lseek(fd, poffset+count, SEEK_SET); + + /*supposed to read from poffset+count, but this read from position 0*/ + read(fd, str2, count); + printf("read:%s\n", str2); + + out put: + pread: + ck_netbios_ns 12665 + read: + nf_conntrack_netbios + + /proc/modules: + nf_conntrack_netbios_ns 12665 0 - Live 0xffffffffa038b000 + nf_conntrack_broadcast 12589 1 nf_conntrack_netbios_ns, Live 0xffffffffa0386000 + + So we always update file->f_pos to offset in seq_lseek() to fix this issue. + + Signed-off-by: Jiaxing Wang + Signed-off-by: Gu Zheng + Signed-off-by: Al Viro + Cc: Jonghwan Choi + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/fs/seq_file.c +=================================================================== +--- linux-3.10-3.10.11.orig/fs/seq_file.c 2014-05-05 11:48:40.000000000 +0000 ++++ linux-3.10-3.10.11/fs/seq_file.c 2014-05-05 12:51:04.000000000 +0000 +@@ -328,6 +328,8 @@ + m->read_pos = offset; + retval = file->f_pos = offset; + } ++ } else { ++ file->f_pos = offset; + } + } + file->f_version = m->version; +Index: linux-3.10-3.10.11/dummy/rpi_1565_dad483b78d280665a110591fd418535e0f9791dc.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1565_dad483b78d280665a110591fd418535e0f9791dc.txt 2014-05-05 12:51:04.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1566_21720562911f038d7406654e7ea0c171cfac47b8.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1566_21720562911f038d7406654e7ea0c171cfac47b8.patch --- linux-3.10.11/debian/patches/rpi/rpi_1566_21720562911f038d7406654e7ea0c171cfac47b8.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1566_21720562911f038d7406654e7ea0c171cfac47b8.patch 2014-05-05 12:51:06.000000000 +0000 @@ -0,0 +1,43 @@ +commit 21720562911f038d7406654e7ea0c171cfac47b8 +Author: Jon Mason +Date: Mon Jul 15 13:23:47 2013 -0700 + + NTB: Add Error Handling in ntb_device_setup + + commit 3b12a0d15bd1559e72ad21d9d807fd2a6706f0ab upstream. + + If an error is encountered in ntb_device_setup, it is possible that the + spci_cmd isn't populated. Writes to the offset can result in a NULL + pointer dereference. This issue is easily encountered by running in + NTB-RP mode, as it currently is not supported and will generate an + error. To get around this issue, return if an error is encountered + prior to attempting to write to the spci_cmd offset. + + Signed-off-by: Jon Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/ntb/ntb_hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ntb/ntb_hw.c 2014-05-05 11:48:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ntb/ntb_hw.c 2014-05-05 12:51:05.000000000 +0000 +@@ -644,10 +644,13 @@ + rc = -ENODEV; + } + ++ if (rc) ++ return rc; ++ + /* Enable Bus Master and Memory Space on the secondary side */ + writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, ndev->reg_ofs.spci_cmd); + +- return rc; ++ return 0; + } + + static void ntb_device_free(struct ntb_device *ndev) +Index: linux-3.10-3.10.11/dummy/rpi_1566_21720562911f038d7406654e7ea0c171cfac47b8.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1566_21720562911f038d7406654e7ea0c171cfac47b8.txt 2014-05-05 12:51:05.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1567_576db18cb68483e6e54f18dfda4b9c24f7e07dfe.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1567_576db18cb68483e6e54f18dfda4b9c24f7e07dfe.patch --- linux-3.10.11/debian/patches/rpi/rpi_1567_576db18cb68483e6e54f18dfda4b9c24f7e07dfe.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1567_576db18cb68483e6e54f18dfda4b9c24f7e07dfe.patch 2014-05-05 12:51:06.000000000 +0000 @@ -0,0 +1,49 @@ +commit 576db18cb68483e6e54f18dfda4b9c24f7e07dfe +Author: Jon Mason +Date: Mon Jul 15 15:26:14 2013 -0700 + + NTB: Correct Number of Scratch Pad Registers + + commit 87034511519815259e37336f52edf06d114d43b6 upstream. + + The NTB Xeon hardware has 16 scratch pad registers and 16 back-to-back + scratch pad registers. Correct the #define to represent this and update + the variable names to reflect their usage. + + Signed-off-by: Jon Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/ntb/ntb_hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ntb/ntb_hw.c 2014-05-05 12:51:05.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ntb/ntb_hw.c 2014-05-05 12:51:06.000000000 +0000 +@@ -547,7 +547,7 @@ + if (ndev->conn_type == NTB_CONN_B2B) { + ndev->reg_ofs.sdb = ndev->reg_base + SNB_B2B_DOORBELL_OFFSET; + ndev->reg_ofs.spad_write = ndev->reg_base + SNB_B2B_SPAD_OFFSET; +- ndev->limits.max_spads = SNB_MAX_SPADS; ++ ndev->limits.max_spads = SNB_MAX_B2B_SPADS; + } else { + ndev->reg_ofs.sdb = ndev->reg_base + SNB_SDOORBELL_OFFSET; + ndev->reg_ofs.spad_write = ndev->reg_base + SNB_SPAD_OFFSET; +Index: linux-3.10-3.10.11/drivers/ntb/ntb_regs.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ntb/ntb_regs.h 2014-05-05 11:48:39.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ntb/ntb_regs.h 2014-05-05 12:51:06.000000000 +0000 +@@ -53,8 +53,8 @@ + #define NTB_LINK_WIDTH_MASK 0x03f0 + + #define SNB_MSIX_CNT 4 +-#define SNB_MAX_SPADS 16 +-#define SNB_MAX_COMPAT_SPADS 8 ++#define SNB_MAX_B2B_SPADS 16 ++#define SNB_MAX_COMPAT_SPADS 16 + /* Reserve the uppermost bit for link interrupt */ + #define SNB_MAX_DB_BITS 15 + #define SNB_DB_BITS_PER_VEC 5 +Index: linux-3.10-3.10.11/dummy/rpi_1567_576db18cb68483e6e54f18dfda4b9c24f7e07dfe.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1567_576db18cb68483e6e54f18dfda4b9c24f7e07dfe.txt 2014-05-05 12:51:06.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1568_8293fc2416f0eb13ff81501b31f0206c5331b9cb.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1568_8293fc2416f0eb13ff81501b31f0206c5331b9cb.patch --- linux-3.10.11/debian/patches/rpi/rpi_1568_8293fc2416f0eb13ff81501b31f0206c5331b9cb.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1568_8293fc2416f0eb13ff81501b31f0206c5331b9cb.patch 2014-05-05 12:51:07.000000000 +0000 @@ -0,0 +1,47 @@ +commit 8293fc2416f0eb13ff81501b31f0206c5331b9cb +Author: Jon Mason +Date: Fri May 31 14:05:53 2013 -0700 + + NTB: Correct USD/DSD Identification + + commit b6750cfe0710a14fd147ba27fddbecae8ba88c77 upstream. + + Due to ambiguous documentation, the USD/DSD identification is backward + when compared to the setting in BIOS. Correct the bits to match the + BIOS setting. + + Signed-off-by: Jon Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/ntb/ntb_hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ntb/ntb_hw.c 2014-05-05 12:51:06.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ntb/ntb_hw.c 2014-05-05 12:51:07.000000000 +0000 +@@ -531,9 +531,9 @@ + } + + if (val & SNB_PPD_DEV_TYPE) +- ndev->dev_type = NTB_DEV_DSD; +- else + ndev->dev_type = NTB_DEV_USD; ++ else ++ ndev->dev_type = NTB_DEV_DSD; + + ndev->reg_ofs.pdb = ndev->reg_base + SNB_PDOORBELL_OFFSET; + ndev->reg_ofs.pdb_mask = ndev->reg_base + SNB_PDBMSK_OFFSET; +@@ -647,6 +647,9 @@ + if (rc) + return rc; + ++ dev_info(&ndev->pdev->dev, "Device Type = %s\n", ++ ndev->dev_type == NTB_DEV_USD ? "USD/DSP" : "DSD/USP"); ++ + /* Enable Bus Master and Memory Space on the secondary side */ + writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, ndev->reg_ofs.spci_cmd); + +Index: linux-3.10-3.10.11/dummy/rpi_1568_8293fc2416f0eb13ff81501b31f0206c5331b9cb.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1568_8293fc2416f0eb13ff81501b31f0206c5331b9cb.txt 2014-05-05 12:51:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1569_cfa234b144de51eb96e877ee0bee47a3420e8bed.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1569_cfa234b144de51eb96e877ee0bee47a3420e8bed.patch --- linux-3.10.11/debian/patches/rpi/rpi_1569_cfa234b144de51eb96e877ee0bee47a3420e8bed.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1569_cfa234b144de51eb96e877ee0bee47a3420e8bed.patch 2014-05-05 12:51:08.000000000 +0000 @@ -0,0 +1,192 @@ +commit cfa234b144de51eb96e877ee0bee47a3420e8bed +Author: Jon Mason +Date: Tue Jul 30 15:58:49 2013 -0700 + + NTB: Correct debugfs to work with more than 1 NTB Device + + commit 1517a3f21a1dd321f16bcf44204bddff9d21abd0 upstream. + + Debugfs was setup in NTB to only have a single debugfs directory. This + resulted in the leaking of debugfs directories and files when multiple + NTB devices were present, due to each device stomping on the variables + containing the previous device's values (thus preventing them from being + freed on cleanup). Correct this by creating a secondary directory of + the PCI BDF for each device present, and nesting the previously existing + information in those directories. + + Signed-off-by: Jon Mason + Signed-off-by: Greg Kroah-Hartman + +Index: linux-3.10-3.10.11/drivers/ntb/ntb_hw.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ntb/ntb_hw.c 2014-05-05 12:51:07.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ntb/ntb_hw.c 2014-05-05 12:51:07.000000000 +0000 +@@ -78,6 +78,8 @@ + BWD_HW, + }; + ++static struct dentry *debugfs_dir; ++ + /* Translate memory window 0,1 to BAR 2,4 */ + #define MW_TO_BAR(mw) (mw * 2 + 2) + +@@ -998,6 +1000,28 @@ + kfree(ndev->db_cb); + } + ++static void ntb_setup_debugfs(struct ntb_device *ndev) ++{ ++ if (!debugfs_initialized()) ++ return; ++ ++ if (!debugfs_dir) ++ debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); ++ ++ ndev->debugfs_dir = debugfs_create_dir(pci_name(ndev->pdev), ++ debugfs_dir); ++} ++ ++static void ntb_free_debugfs(struct ntb_device *ndev) ++{ ++ debugfs_remove_recursive(ndev->debugfs_dir); ++ ++ if (debugfs_dir && simple_empty(debugfs_dir)) { ++ debugfs_remove_recursive(debugfs_dir); ++ debugfs_dir = NULL; ++ } ++} ++ + static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { + struct ntb_device *ndev; +@@ -1010,6 +1034,7 @@ + ndev->pdev = pdev; + ndev->link_status = NTB_LINK_DOWN; + pci_set_drvdata(pdev, ndev); ++ ntb_setup_debugfs(ndev); + + rc = pci_enable_device(pdev); + if (rc) +@@ -1106,6 +1131,7 @@ + err1: + pci_disable_device(pdev); + err: ++ ntb_free_debugfs(ndev); + kfree(ndev); + + dev_err(&pdev->dev, "Error loading %s module\n", KBUILD_MODNAME); +@@ -1135,6 +1161,7 @@ + iounmap(ndev->reg_base); + pci_release_selected_regions(pdev, NTB_BAR_MASK); + pci_disable_device(pdev); ++ ntb_free_debugfs(ndev); + kfree(ndev); + } + +Index: linux-3.10-3.10.11/drivers/ntb/ntb_hw.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ntb/ntb_hw.h 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ntb/ntb_hw.h 2014-05-05 12:51:07.000000000 +0000 +@@ -127,6 +127,8 @@ + unsigned char link_status; + struct delayed_work hb_timer; + unsigned long last_ts; ++ ++ struct dentry *debugfs_dir; + }; + + /** +@@ -155,6 +157,20 @@ + return ndev->pdev; + } + ++/** ++ * ntb_query_debugfs() - return the debugfs pointer ++ * @ndev: pointer to ntb_device instance ++ * ++ * Given the ntb pointer, return the debugfs directory pointer for the NTB ++ * hardware device ++ * ++ * RETURNS: a pointer to the debugfs directory ++ */ ++static inline struct dentry *ntb_query_debugfs(struct ntb_device *ndev) ++{ ++ return ndev->debugfs_dir; ++} ++ + struct ntb_device *ntb_register_transport(struct pci_dev *pdev, + void *transport); + void ntb_unregister_transport(struct ntb_device *ndev); +Index: linux-3.10-3.10.11/drivers/ntb/ntb_transport.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/ntb/ntb_transport.c 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/ntb/ntb_transport.c 2014-05-05 12:51:07.000000000 +0000 +@@ -157,7 +157,6 @@ + bool transport_link; + struct delayed_work link_work; + struct work_struct link_cleanup; +- struct dentry *debugfs_dir; + }; + + enum { +@@ -824,12 +823,12 @@ + qp->tx_max_frame = min(transport_mtu, tx_size / 2); + qp->tx_max_entry = tx_size / qp->tx_max_frame; + +- if (nt->debugfs_dir) { ++ if (ntb_query_debugfs(nt->ndev)) { + char debugfs_name[4]; + + snprintf(debugfs_name, 4, "qp%d", qp_num); + qp->debugfs_dir = debugfs_create_dir(debugfs_name, +- nt->debugfs_dir); ++ ntb_query_debugfs(nt->ndev)); + + qp->debugfs_stats = debugfs_create_file("stats", S_IRUSR, + qp->debugfs_dir, qp, +@@ -857,11 +856,6 @@ + if (!nt) + return -ENOMEM; + +- if (debugfs_initialized()) +- nt->debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); +- else +- nt->debugfs_dir = NULL; +- + nt->ndev = ntb_register_transport(pdev, nt); + if (!nt->ndev) { + rc = -EIO; +@@ -907,7 +901,6 @@ + err1: + ntb_unregister_transport(nt->ndev); + err: +- debugfs_remove_recursive(nt->debugfs_dir); + kfree(nt); + return rc; + } +@@ -921,16 +914,16 @@ + nt->transport_link = NTB_LINK_DOWN; + + /* verify that all the qp's are freed */ +- for (i = 0; i < nt->max_qps; i++) ++ for (i = 0; i < nt->max_qps; i++) { + if (!test_bit(i, &nt->qp_bitmap)) + ntb_transport_free_queue(&nt->qps[i]); ++ debugfs_remove_recursive(nt->qps[i].debugfs_dir); ++ } + + ntb_bus_remove(nt); + + cancel_delayed_work_sync(&nt->link_work); + +- debugfs_remove_recursive(nt->debugfs_dir); +- + ntb_unregister_event_callback(nt->ndev); + + pdev = ntb_query_pdev(nt->ndev); +Index: linux-3.10-3.10.11/dummy/rpi_1569_cfa234b144de51eb96e877ee0bee47a3420e8bed.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1569_cfa234b144de51eb96e877ee0bee47a3420e8bed.txt 2014-05-05 12:51:07.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1570_3729ed7c6aa8c5b9eee8f832e4a246b8fa1d56b5.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1570_3729ed7c6aa8c5b9eee8f832e4a246b8fa1d56b5.patch --- linux-3.10.11/debian/patches/rpi/rpi_1570_3729ed7c6aa8c5b9eee8f832e4a246b8fa1d56b5.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1570_3729ed7c6aa8c5b9eee8f832e4a246b8fa1d56b5.patch 2014-05-05 12:51:09.000000000 +0000 @@ -0,0 +1,24 @@ +commit 3729ed7c6aa8c5b9eee8f832e4a246b8fa1d56b5 +Author: Greg Kroah-Hartman +Date: Wed Nov 13 12:05:59 2013 +0900 + + Linux 3.10.19 + +Index: linux-3.10-3.10.11/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/Makefile 2014-05-05 12:50:06.000000000 +0000 ++++ linux-3.10-3.10.11/Makefile 2014-05-05 12:51:08.000000000 +0000 +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 18 ++SUBLEVEL = 19 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +Index: linux-3.10-3.10.11/dummy/rpi_1570_3729ed7c6aa8c5b9eee8f832e4a246b8fa1d56b5.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1570_3729ed7c6aa8c5b9eee8f832e4a246b8fa1d56b5.txt 2014-05-05 12:51:08.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1571_464ff6a40a8e684ebc730b5ede44c646b1d4e6c9.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1571_464ff6a40a8e684ebc730b5ede44c646b1d4e6c9.patch --- linux-3.10.11/debian/patches/rpi/rpi_1571_464ff6a40a8e684ebc730b5ede44c646b1d4e6c9.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1571_464ff6a40a8e684ebc730b5ede44c646b1d4e6c9.patch 2014-05-05 12:51:13.000000000 +0000 @@ -0,0 +1,8450 @@ +commit 464ff6a40a8e684ebc730b5ede44c646b1d4e6c9 +Author: popcornmix +Date: Sun May 12 12:24:19 2013 +0100 + + Main bcm2708 linux port + + Signed-off-by: popcornmix + +Index: linux-3.10-3.10.11/arch/arm/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/Kconfig 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/Kconfig 2014-05-05 12:51:09.000000000 +0000 +@@ -361,6 +361,21 @@ + This enables support for systems based on Atmel + AT91RM9200 and AT91SAM9* processors. + ++config ARCH_BCM2708 ++ bool "Broadcom BCM2708 family" ++ select CPU_V6 ++ select ARM_AMBA ++ select HAVE_CLK ++ select HAVE_SCHED_CLOCK ++ select NEED_MACH_MEMORY_H ++ select CLKDEV_LOOKUP ++ select GENERIC_CLOCKEVENTS ++ select ARM_ERRATA_411920 ++ select MACH_BCM2708 ++ select VC4 ++ help ++ This enables support for Broadcom BCM2708 boards. ++ + config ARCH_CLPS711X + bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" + select ARCH_REQUIRE_GPIOLIB +@@ -1025,6 +1040,7 @@ + source "arch/arm/mach-vt8500/Kconfig" + + source "arch/arm/mach-w90x900/Kconfig" ++source "arch/arm/mach-bcm2708/Kconfig" + + source "arch/arm/mach-zynq/Kconfig" + +Index: linux-3.10-3.10.11/arch/arm/Kconfig.debug +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/Kconfig.debug 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/Kconfig.debug 2014-05-05 12:51:09.000000000 +0000 +@@ -519,6 +519,14 @@ + For more details about semihosting, please see + chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. + ++ config DEBUG_BCM2708_UART0 ++ bool "Broadcom BCM2708 UART0 (PL011)" ++ depends on MACH_BCM2708 ++ help ++ Say Y here if you want the debug print routines to direct ++ their output to UART 0. The port must have been initialised ++ by the boot-loader before use. ++ + endchoice + + config DEBUG_EXYNOS_UART +Index: linux-3.10-3.10.11/arch/arm/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/Makefile 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/Makefile 2014-05-05 12:51:09.000000000 +0000 +@@ -139,6 +139,7 @@ + # by CONFIG_* macro name. + machine-$(CONFIG_ARCH_AT91) += at91 + machine-$(CONFIG_ARCH_BCM) += bcm ++machine-$(CONFIG_ARCH_BCM2708) += bcm2708 + machine-$(CONFIG_ARCH_BCM2835) += bcm2835 + machine-$(CONFIG_ARCH_CLPS711X) += clps711x + machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx +Index: linux-3.10-3.10.11/arch/arm/configs/bcmrpi_cutdown_defconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/configs/bcmrpi_cutdown_defconfig 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,474 @@ ++CONFIG_EXPERIMENTAL=y ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++# CONFIG_UID16 is not set ++# CONFIG_KALLSYMS is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_ARCH_BCM2708=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_AEABI=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" ++CONFIG_CPU_IDLE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_NET_PKTGEN=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_L2CAP=y ++CONFIG_BT_SCO=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_RC_PID=y ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_DEVTMPFS=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_MISC_DEVICES=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_SCSI_MULTI_LUN=y ++# CONFIG_SCSI_LOWLEVEL is not set ++CONFIG_NETDEVICES=y ++CONFIG_TUN=m ++CONFIG_PHYLIB=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_NET_ETHERNET=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_AT76C50X_USB=m ++CONFIG_USB_ZD1201=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_RTL8187=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_ATH_COMMON=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_B43=m ++CONFIG_B43LEGACY=m ++CONFIG_HOSTAP=m ++CONFIG_IWM=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RTL8192CU=m ++CONFIG_WL1251=m ++CONFIG_WL12XX_MENU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_KC2190=y ++# CONFIG_USB_NET_ZAURUS is not set ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_PPP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_NETCONSOLE=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_VT_HW_CONSOLE_BINDING=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_HW_RANDOM is not set ++CONFIG_RAW_DRIVER=y ++CONFIG_GPIO_SYSFS=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_BCM2708_WDT=m ++# CONFIG_MFD_SUPPORT is not set ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_QUANTA=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=m ++CONFIG_USB_LIBUSUAL=y ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_FUNSOFT=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_MOTOROLA=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_HP4X=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIEMENS_MPI=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m ++CONFIG_USB_SERIAL_ZIO=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_BCM2708=y ++CONFIG_MMC_SDHCI_BCM2708_DMA=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=m ++CONFIG_LEDS_TRIGGER_HEARTBEAT=m ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=m ++CONFIG_UIO=m ++CONFIG_UIO_PDRV=m ++CONFIG_UIO_PDRV_GENIRQ=m ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_FSCACHE=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_EFI_PARTITION=y ++CONFIG_NLS_DEFAULT="utf8" ++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=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_NLS_UTF8=m ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_DEBUG_BUGVERBOSE is not set ++# CONFIG_FTRACE is not set ++# CONFIG_ARM_UNWIND is not set ++CONFIG_CRYPTO_AUTHENC=m ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_DEFLATE=m ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +Index: linux-3.10-3.10.11/arch/arm/configs/bcmrpi_defconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/configs/bcmrpi_defconfig 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,510 @@ ++CONFIG_EXPERIMENTAL=y ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_FHANDLE=y ++CONFIG_AUDIT=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_RESOURCE_COUNTERS=y ++CONFIG_BLK_CGROUP=y ++CONFIG_NAMESPACES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_ARCH_BCM2708=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_AEABI=y ++CONFIG_SECCOMP=y ++CONFIG_CC_STACKPROTECTOR=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" ++CONFIG_KEXEC=y ++CONFIG_CPU_IDLE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_NET_PKTGEN=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_L2CAP=y ++CONFIG_BT_SCO=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_RC_PID=y ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_MISC_DEVICES=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_SCSI_MULTI_LUN=y ++# CONFIG_SCSI_LOWLEVEL is not set ++CONFIG_MD=y ++CONFIG_NETDEVICES=y ++CONFIG_TUN=m ++CONFIG_PHYLIB=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_NET_ETHERNET=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_AT76C50X_USB=m ++CONFIG_USB_ZD1201=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_RTL8187=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_ATH_COMMON=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_B43=m ++CONFIG_B43LEGACY=m ++CONFIG_HOSTAP=m ++CONFIG_IWM=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RTL8192CU=m ++CONFIG_WL1251=m ++CONFIG_WL12XX_MENU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_KC2190=y ++# CONFIG_USB_NET_ZAURUS is not set ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_PPP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_NETCONSOLE=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_VT_HW_CONSOLE_BINDING=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_HW_RANDOM is not set ++CONFIG_RAW_DRIVER=y ++CONFIG_GPIO_SYSFS=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_BCM2708_WDT=m ++# CONFIG_MFD_SUPPORT is not set ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_QUANTA=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=m ++CONFIG_USB_LIBUSUAL=y ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_FUNSOFT=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_MOTOROLA=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_HP4X=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIEMENS_MPI=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m ++CONFIG_USB_SERIAL_ZIO=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_BCM2708=y ++CONFIG_MMC_SDHCI_BCM2708_DMA=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=m ++CONFIG_LEDS_TRIGGER_HEARTBEAT=m ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=m ++CONFIG_UIO=m ++CONFIG_UIO_PDRV=m ++CONFIG_UIO_PDRV_GENIRQ=m ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_FANOTIFY=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_EFI_PARTITION=y ++CONFIG_NLS_DEFAULT="utf8" ++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=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_NLS_UTF8=m ++CONFIG_PRINTK_TIME=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_TIMER_STATS=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_LATENCYTOP=y ++CONFIG_SYSCTL_SYSCALL_CHECK=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y ++CONFIG_STRICT_DEVMEM=y ++CONFIG_CRYPTO_AUTHENC=m ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_DEFLATE=m ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +Index: linux-3.10-3.10.11/arch/arm/configs/bcmrpi_emergency_defconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/configs/bcmrpi_emergency_defconfig 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,532 @@ ++CONFIG_EXPERIMENTAL=y ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_FHANDLE=y ++CONFIG_AUDIT=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="../target_fs" ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_RESOURCE_COUNTERS=y ++CONFIG_BLK_CGROUP=y ++CONFIG_NAMESPACES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_ARCH_BCM2708=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_AEABI=y ++CONFIG_SECCOMP=y ++CONFIG_CC_STACKPROTECTOR=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" ++CONFIG_KEXEC=y ++CONFIG_CPU_IDLE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_NET_PKTGEN=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_L2CAP=y ++CONFIG_BT_SCO=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_RC_PID=y ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_MISC_DEVICES=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_DEV_SR=m ++CONFIG_SCSI_MULTI_LUN=y ++# CONFIG_SCSI_LOWLEVEL is not set ++CONFIG_MD=y ++CONFIG_NETDEVICES=y ++CONFIG_TUN=m ++CONFIG_PHYLIB=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_NET_ETHERNET=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_AT76C50X_USB=m ++CONFIG_USB_ZD1201=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_RTL8187=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_ATH_COMMON=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_B43=m ++CONFIG_B43LEGACY=m ++CONFIG_HOSTAP=m ++CONFIG_IWM=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RTL8192CU=m ++CONFIG_WL1251=m ++CONFIG_WL12XX_MENU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_KC2190=y ++# CONFIG_USB_NET_ZAURUS is not set ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_PPP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_NETCONSOLE=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_VT_HW_CONSOLE_BINDING=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_HW_RANDOM is not set ++CONFIG_RAW_DRIVER=y ++CONFIG_GPIO_SYSFS=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_BCM2708_WDT=m ++# CONFIG_MFD_SUPPORT is not set ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_MIXER_OSS=m ++CONFIG_SND_PCM_OSS=m ++CONFIG_SND_SEQUENCER_OSS=y ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_BCM2835=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SOUND_PRIME=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_QUANTA=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=y ++CONFIG_USB_LIBUSUAL=y ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_FUNSOFT=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_MOTOROLA=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_HP4X=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIEMENS_MPI=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m ++CONFIG_USB_SERIAL_ZIO=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_BCM2708=y ++CONFIG_MMC_SDHCI_BCM2708_DMA=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=m ++CONFIG_LEDS_TRIGGER_HEARTBEAT=m ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=m ++CONFIG_UIO=m ++CONFIG_UIO_PDRV=m ++CONFIG_UIO_PDRV_GENIRQ=m ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_FANOTIFY=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_EFI_PARTITION=y ++CONFIG_NLS_DEFAULT="utf8" ++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=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_NLS_UTF8=m ++CONFIG_PRINTK_TIME=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_TIMER_STATS=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_LATENCYTOP=y ++CONFIG_SYSCTL_SYSCALL_CHECK=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y ++CONFIG_STRICT_DEVMEM=y ++CONFIG_CRYPTO_AUTHENC=m ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_DEFLATE=m ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +Index: linux-3.10-3.10.11/arch/arm/kernel/process.c +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/kernel/process.c 2014-05-05 12:48:29.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/kernel/process.c 2014-05-05 12:51:09.000000000 +0000 +@@ -174,7 +174,7 @@ + default_idle(); + } + +-static char reboot_mode = 'h'; ++char reboot_mode = 'h'; + + int __init reboot_setup(char *str) + { +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/Kconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/Kconfig 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,34 @@ ++menu "Broadcom BCM2708 Implementations" ++ depends on ARCH_BCM2708 ++ ++config MACH_BCM2708 ++ bool "Broadcom BCM2708 Development Platform" ++ select NEED_MACH_MEMORY_H ++ select NEED_MACH_IO_H ++ select CPU_V6 ++ help ++ Include support for the Broadcom(R) BCM2708 platform. ++ ++config BCM2708_GPIO ++ bool "BCM2708 gpio support" ++ depends on MACH_BCM2708 ++ select ARCH_REQUIRE_GPIOLIB ++ default y ++ help ++ Include support for the Broadcom(R) BCM2708 gpio. ++ ++config BCM2708_VCMEM ++ bool "Videocore Memory" ++ depends on MACH_BCM2708 ++ default y ++ help ++ Helper for videocore memory access and total size allocation. ++ ++config BCM2708_NOL2CACHE ++ bool "Videocore L2 cache disable" ++ depends on MACH_BCM2708 ++ default n ++ help ++ Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt. ++ ++endmenu +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/Makefile 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,8 @@ ++# ++# Makefile for the linux kernel. ++# ++ ++obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o ++obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o ++obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o ++ +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/Makefile.boot +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/Makefile.boot 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,3 @@ ++ zreladdr-y := 0x00008000 ++params_phys-y := 0x00000100 ++initrd_phys-y := 0x00800000 +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/armctrl.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/armctrl.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,208 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/armctrl.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include "armctrl.h" ++ ++/* For support of kernels >= 3.0 assume only one VIC for now*/ ++static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { ++ INTERRUPT_VC_JPEG, ++ INTERRUPT_VC_USB, ++ INTERRUPT_VC_3D, ++ INTERRUPT_VC_DMA2, ++ INTERRUPT_VC_DMA3, ++ INTERRUPT_VC_I2C, ++ INTERRUPT_VC_SPI, ++ INTERRUPT_VC_I2SPCM, ++ INTERRUPT_VC_SDIO, ++ INTERRUPT_VC_UART, ++ INTERRUPT_VC_ARASANSDIO ++}; ++ ++static void armctrl_mask_irq(struct irq_data *d) ++{ ++ static const unsigned int disables[4] = { ++ ARM_IRQ_DIBL1, ++ ARM_IRQ_DIBL2, ++ ARM_IRQ_DIBL3, ++ 0 ++ }; ++ ++ unsigned int data = (unsigned int)irq_get_chip_data(d->irq); ++ writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3])); ++} ++ ++static void armctrl_unmask_irq(struct irq_data *d) ++{ ++ static const unsigned int enables[4] = { ++ ARM_IRQ_ENBL1, ++ ARM_IRQ_ENBL2, ++ ARM_IRQ_ENBL3, ++ 0 ++ }; ++ ++ unsigned int data = (unsigned int)irq_get_chip_data(d->irq); ++ writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); ++} ++ ++#if defined(CONFIG_PM) ++ ++/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ ++ ++/* Static defines ++ * struct armctrl_device - VIC PM device (< 3.xx) ++ * @sysdev: The system device which is registered. (< 3.xx) ++ * @irq: The IRQ number for the base of the VIC. ++ * @base: The register base for the VIC. ++ * @resume_sources: A bitmask of interrupts for resume. ++ * @resume_irqs: The IRQs enabled for resume. ++ * @int_select: Save for VIC_INT_SELECT. ++ * @int_enable: Save for VIC_INT_ENABLE. ++ * @soft_int: Save for VIC_INT_SOFT. ++ * @protect: Save for VIC_PROTECT. ++ */ ++struct armctrl_info { ++ void __iomem *base; ++ int irq; ++ u32 resume_sources; ++ u32 resume_irqs; ++ u32 int_select; ++ u32 int_enable; ++ u32 soft_int; ++ u32 protect; ++} armctrl; ++ ++static int armctrl_suspend(void) ++{ ++ return 0; ++} ++ ++static void armctrl_resume(void) ++{ ++ return; ++} ++ ++/** ++ * armctrl_pm_register - Register a VIC for later power management control ++ * @base: The base address of the VIC. ++ * @irq: The base IRQ for the VIC. ++ * @resume_sources: bitmask of interrupts allowed for resume sources. ++ * ++ * For older kernels (< 3.xx) do - ++ * Register the VIC with the system device tree so that it can be notified ++ * of suspend and resume requests and ensure that the correct actions are ++ * taken to re-instate the settings on resume. ++ */ ++static void __init armctrl_pm_register(void __iomem * base, unsigned int irq, ++ u32 resume_sources) ++{ ++ armctrl.base = base; ++ armctrl.resume_sources = resume_sources; ++ armctrl.irq = irq; ++} ++ ++static int armctrl_set_wake(struct irq_data *d, unsigned int on) ++{ ++ unsigned int off = d->irq & 31; ++ u32 bit = 1 << off; ++ ++ if (!(bit & armctrl.resume_sources)) ++ return -EINVAL; ++ ++ if (on) ++ armctrl.resume_irqs |= bit; ++ else ++ armctrl.resume_irqs &= ~bit; ++ ++ return 0; ++} ++ ++#else ++static inline void armctrl_pm_register(void __iomem * base, unsigned int irq, ++ u32 arg1) ++{ ++} ++ ++#define armctrl_suspend NULL ++#define armctrl_resume NULL ++#define armctrl_set_wake NULL ++#endif /* CONFIG_PM */ ++ ++static struct syscore_ops armctrl_syscore_ops = { ++ .suspend = armctrl_suspend, ++ .resume = armctrl_resume, ++}; ++ ++/** ++ * armctrl_syscore_init - initicall to register VIC pm functions ++ * ++ * This is called via late_initcall() to register ++ * the resources for the VICs due to the early ++ * nature of the VIC's registration. ++*/ ++static int __init armctrl_syscore_init(void) ++{ ++ register_syscore_ops(&armctrl_syscore_ops); ++ return 0; ++} ++ ++late_initcall(armctrl_syscore_init); ++ ++static struct irq_chip armctrl_chip = { ++ .name = "ARMCTRL", ++ .irq_ack = armctrl_mask_irq, ++ .irq_mask = armctrl_mask_irq, ++ .irq_unmask = armctrl_unmask_irq, ++ .irq_set_wake = armctrl_set_wake, ++}; ++ ++/** ++ * armctrl_init - initialise a vectored interrupt controller ++ * @base: iomem base address ++ * @irq_start: starting interrupt number, must be muliple of 32 ++ * @armctrl_sources: bitmask of interrupt sources to allow ++ * @resume_sources: bitmask of interrupt sources to allow for resume ++ */ ++int __init armctrl_init(void __iomem * base, unsigned int irq_start, ++ u32 armctrl_sources, u32 resume_sources) ++{ ++ unsigned int irq; ++ ++ for (irq = 0; irq < NR_IRQS; irq++) { ++ unsigned int data = irq; ++ if (irq >= INTERRUPT_JPEG && irq <= INTERRUPT_ARASANSDIO) ++ data = remap_irqs[irq - INTERRUPT_JPEG]; ++ ++ irq_set_chip(irq, &armctrl_chip); ++ irq_set_chip_data(irq, (void *)data); ++ irq_set_handler(irq, handle_level_irq); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED); ++ } ++ ++ armctrl_pm_register(base, irq_start, resume_sources); ++ return 0; ++} +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/armctrl.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/armctrl.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,27 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/armctrl.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 __BCM2708_ARMCTRL_H ++#define __BCM2708_ARMCTRL_H ++ ++extern int __init armctrl_init(void __iomem * base, unsigned int irq_start, ++ u32 armctrl_sources, u32 resume_sources); ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/bcm2708.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/bcm2708.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,695 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/bcm2708.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "bcm2708.h" ++#include "armctrl.h" ++#include "clock.h" ++ ++/* Effectively we have an IOMMU (ARM<->VideoCore map) that is set up to ++ * give us IO access only to 64Mbytes of physical memory (26 bits). We could ++ * represent this window by setting our dmamasks to 26 bits but, in fact ++ * we're not going to use addresses outside this range (they're not in real ++ * memory) so we don't bother. ++ * ++ * In the future we might include code to use this IOMMU to remap other ++ * physical addresses onto VideoCore memory then the use of 32-bits would be ++ * more legitimate. ++ */ ++#define DMA_MASK_BITS_COMMON 32 ++ ++/* command line parameters */ ++static unsigned boardrev, serial; ++static unsigned uart_clock; ++static unsigned reboot_part = 0; ++ ++static void __init bcm2708_init_led(void); ++ ++void __init bcm2708_init_irq(void) ++{ ++ armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0); ++} ++ ++static struct map_desc bcm2708_io_desc[] __initdata = { ++ { ++ .virtual = IO_ADDRESS(ARMCTRL_BASE), ++ .pfn = __phys_to_pfn(ARMCTRL_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(UART0_BASE), ++ .pfn = __phys_to_pfn(UART0_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(UART1_BASE), ++ .pfn = __phys_to_pfn(UART1_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(DMA_BASE), ++ .pfn = __phys_to_pfn(DMA_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(MCORE_BASE), ++ .pfn = __phys_to_pfn(MCORE_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(ST_BASE), ++ .pfn = __phys_to_pfn(ST_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(USB_BASE), ++ .pfn = __phys_to_pfn(USB_BASE), ++ .length = SZ_128K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(PM_BASE), ++ .pfn = __phys_to_pfn(PM_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(GPIO_BASE), ++ .pfn = __phys_to_pfn(GPIO_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE} ++}; ++ ++void __init bcm2708_map_io(void) ++{ ++ iotable_init(bcm2708_io_desc, ARRAY_SIZE(bcm2708_io_desc)); ++} ++ ++/* The STC is a free running counter that increments at the rate of 1MHz */ ++#define STC_FREQ_HZ 1000000 ++ ++static inline uint32_t timer_read(void) ++{ ++ /* STC: a free running counter that increments at the rate of 1MHz */ ++ return readl(__io_address(ST_BASE + 0x04)); ++} ++ ++static unsigned long bcm2708_read_current_timer(void) ++{ ++ return timer_read(); ++} ++ ++static u32 notrace bcm2708_read_sched_clock(void) ++{ ++ return timer_read(); ++} ++ ++static cycle_t clksrc_read(struct clocksource *cs) ++{ ++ return timer_read(); ++} ++ ++static struct clocksource clocksource_stc = { ++ .name = "stc", ++ .rating = 300, ++ .read = clksrc_read, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++unsigned long frc_clock_ticks32(void) ++{ ++ return timer_read(); ++} ++ ++static void __init bcm2708_clocksource_init(void) ++{ ++ if (clocksource_register_hz(&clocksource_stc, STC_FREQ_HZ)) { ++ printk(KERN_ERR "timer: failed to initialize clock " ++ "source %s\n", clocksource_stc.name); ++ } ++} ++ ++ ++/* ++ * These are fixed clocks. ++ */ ++static struct clk ref24_clk = { ++ .rate = UART0_CLOCK, /* The UART is clocked at 3MHz via APB_CLK */ ++}; ++ ++static struct clk osc_clk = { ++#ifdef CONFIG_ARCH_BCM2708_CHIPIT ++ .rate = 27000000, ++#else ++ .rate = 500000000, /* ARM clock is set from the VideoCore booter */ ++#endif ++}; ++ ++/* warning - the USB needs a clock > 34MHz */ ++ ++#ifdef CONFIG_MMC_BCM2708 ++static struct clk sdhost_clk = { ++#ifdef CONFIG_ARCH_BCM2708_CHIPIT ++ .rate = 4000000, /* 4MHz */ ++#else ++ .rate = 250000000, /* 250MHz */ ++#endif ++}; ++#endif ++ ++static struct clk_lookup lookups[] = { ++ { /* UART0 */ ++ .dev_id = "dev:f1", ++ .clk = &ref24_clk, ++ }, ++ { /* USB */ ++ .dev_id = "bcm2708_usb", ++ .clk = &osc_clk, ++ } ++}; ++ ++#define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ } ++#define UART0_DMA { 15, 14 } ++ ++AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); ++ ++static struct amba_device *amba_devs[] __initdata = { ++ &uart0_device, ++}; ++ ++static struct resource bcm2708_dmaman_resources[] = { ++ { ++ .start = DMA_BASE, ++ .end = DMA_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device bcm2708_dmaman_device = { ++ .name = BCM_DMAMAN_DRIVER_NAME, ++ .id = 0, /* first bcm2708_dma */ ++ .resource = bcm2708_dmaman_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), ++}; ++ ++static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_fb_device = { ++ .name = "bcm2708_fb", ++ .id = -1, /* only one bcm2708_fb */ ++ .resource = NULL, ++ .num_resources = 0, ++ .dev = { ++ .dma_mask = &fb_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++static struct plat_serial8250_port bcm2708_uart1_platform_data[] = { ++ { ++ .mapbase = UART1_BASE + 0x40, ++ .irq = IRQ_AUX, ++ .uartclk = 125000000, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_FIXED_TYPE | UPF_IOREMAP | UPF_SKIP_TEST, ++ .type = PORT_8250, ++ }, ++ {}, ++}; ++ ++static struct platform_device bcm2708_uart1_device = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev = { ++ .platform_data = bcm2708_uart1_platform_data, ++ }, ++}; ++ ++static struct resource bcm2708_usb_resources[] = { ++ [0] = { ++ .start = USB_BASE, ++ .end = USB_BASE + SZ_128K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_USB, ++ .end = IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_usb_device = { ++ .name = "bcm2708_usb", ++ .id = -1, /* only one bcm2708_usb */ ++ .resource = bcm2708_usb_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_usb_resources), ++ .dev = { ++ .dma_mask = &usb_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++static struct resource bcm2708_vcio_resources[] = { ++ [0] = { /* mailbox/semaphore/doorbell access */ ++ .start = MCORE_BASE, ++ .end = MCORE_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_vcio_device = { ++ .name = BCM_VCIO_DRIVER_NAME, ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_vcio_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), ++ .dev = { ++ .dma_mask = &vcio_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++#ifdef CONFIG_BCM2708_GPIO ++#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" ++ ++static struct resource bcm2708_gpio_resources[] = { ++ [0] = { /* general purpose I/O */ ++ .start = GPIO_BASE, ++ .end = GPIO_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static u64 gpio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_gpio_device = { ++ .name = BCM_GPIO_DRIVER_NAME, ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_gpio_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_gpio_resources), ++ .dev = { ++ .dma_mask = &gpio_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++#endif ++ ++static struct resource bcm2708_systemtimer_resources[] = { ++ [0] = { /* system timer access */ ++ .start = ST_BASE, ++ .end = ST_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_TIMER3, ++ .end = IRQ_TIMER3, ++ .flags = IORESOURCE_IRQ, ++ } ++ ++}; ++ ++static u64 systemtimer_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_systemtimer_device = { ++ .name = "bcm2708_systemtimer", ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_systemtimer_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_systemtimer_resources), ++ .dev = { ++ .dma_mask = &systemtimer_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++#ifdef CONFIG_MMC_SDHCI_BCM2708 /* Arasan emmc SD */ ++static struct resource bcm2708_emmc_resources[] = { ++ [0] = { ++ .start = EMMC_BASE, ++ .end = EMMC_BASE + SZ_256 - 1, /* we only need this area */ ++ /* the memory map actually makes SZ_4K available */ ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_ARASANSDIO, ++ .end = IRQ_ARASANSDIO, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 bcm2708_emmc_dmamask = 0xffffffffUL; ++ ++struct platform_device bcm2708_emmc_device = { ++ .name = "bcm2708_sdhci", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_emmc_resources), ++ .resource = bcm2708_emmc_resources, ++ .dev = { ++ .dma_mask = &bcm2708_emmc_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, ++}; ++#endif /* CONFIG_MMC_SDHCI_BCM2708 */ ++ ++static struct resource bcm2708_powerman_resources[] = { ++ [0] = { ++ .start = PM_BASE, ++ .end = PM_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static u64 powerman_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++struct platform_device bcm2708_powerman_device = { ++ .name = "bcm2708_powerman", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_powerman_resources), ++ .resource = bcm2708_powerman_resources, ++ .dev = { ++ .dma_mask = &powerman_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, ++}; ++ ++int __init bcm_register_device(struct platform_device *pdev) ++{ ++ int ret; ++ ++ ret = platform_device_register(pdev); ++ if (ret) ++ pr_debug("Unable to register platform device '%s': %d\n", ++ pdev->name, ret); ++ ++ return ret; ++} ++ ++int calc_rsts(int partition) ++{ ++ return PM_PASSWORD | ++ ((partition & (1 << 0)) << 0) | ++ ((partition & (1 << 1)) << 1) | ++ ((partition & (1 << 2)) << 2) | ++ ((partition & (1 << 3)) << 3) | ++ ((partition & (1 << 4)) << 4) | ++ ((partition & (1 << 5)) << 5); ++} ++ ++static void bcm2708_restart(char mode, const char *cmd) ++{ ++ uint32_t pm_rstc, pm_wdog; ++ uint32_t timeout = 10; ++ uint32_t pm_rsts = 0; ++ ++ if(mode == 'q') ++ { ++ // NOOBS < 1.3 booting with reboot=q ++ pm_rsts = readl(__io_address(PM_RSTS)); ++ pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRQ_SET; ++ } ++ else if(mode == 'p') ++ { ++ // NOOBS < 1.3 halting ++ pm_rsts = readl(__io_address(PM_RSTS)); ++ pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRH_SET; ++ } ++ else ++ { ++ pm_rsts = calc_rsts(reboot_part); ++ } ++ ++ writel(pm_rsts, __io_address(PM_RSTS)); ++ ++ /* Setup watchdog for reset */ ++ pm_rstc = readl(__io_address(PM_RSTC)); ++ ++ pm_wdog = PM_PASSWORD | (timeout & PM_WDOG_TIME_SET); // watchdog timer = timer clock / 16; need password (31:16) + value (11:0) ++ pm_rstc = PM_PASSWORD | (pm_rstc & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET; ++ ++ writel(pm_wdog, __io_address(PM_WDOG)); ++ writel(pm_rstc, __io_address(PM_RSTC)); ++} ++ ++/* We can't really power off, but if we do the normal reset scheme, and indicate to bootcode.bin not to reboot, then most of the chip will be powered off */ ++static void bcm2708_power_off(void) ++{ ++ extern char reboot_mode; ++ ++ if(reboot_mode == 'q') ++ { ++ // NOOBS < v1.3 ++ bcm2708_restart('p', ""); ++ } ++ else ++ { ++ /* partition 63 is special code for HALT the bootloader knows not to boot*/ ++ reboot_part = 63; ++ /* continue with normal reset mechanism */ ++ bcm2708_restart(0, ""); ++ } ++} ++ ++void __init bcm2708_init(void) ++{ ++ int i; ++ ++ printk("bcm2708.uart_clock = %d\n", uart_clock); ++ pm_power_off = bcm2708_power_off; ++ ++ if (uart_clock) ++ lookups[0].clk->rate = uart_clock; ++ ++ for (i = 0; i < ARRAY_SIZE(lookups); i++) ++ clkdev_add(&lookups[i]); ++ ++ bcm_register_device(&bcm2708_dmaman_device); ++ bcm_register_device(&bcm2708_vcio_device); ++#ifdef CONFIG_BCM2708_GPIO ++ bcm_register_device(&bcm2708_gpio_device); ++#endif ++ bcm_register_device(&bcm2708_systemtimer_device); ++ bcm_register_device(&bcm2708_fb_device); ++ bcm_register_device(&bcm2708_usb_device); ++ bcm_register_device(&bcm2708_uart1_device); ++ bcm_register_device(&bcm2708_powerman_device); ++ ++#ifdef CONFIG_MMC_SDHCI_BCM2708 ++ bcm_register_device(&bcm2708_emmc_device); ++#endif ++ bcm2708_init_led(); ++ ++ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { ++ struct amba_device *d = amba_devs[i]; ++ amba_device_register(d, &iomem_resource); ++ } ++ system_rev = boardrev; ++ system_serial_low = serial; ++} ++ ++static void timer_set_mode(enum clock_event_mode mode, ++ struct clock_event_device *clk) ++{ ++ switch (mode) { ++ case CLOCK_EVT_MODE_ONESHOT: /* Leave the timer disabled, .set_next_event will enable it */ ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ break; ++ case CLOCK_EVT_MODE_PERIODIC: ++ ++ case CLOCK_EVT_MODE_UNUSED: ++ case CLOCK_EVT_MODE_RESUME: ++ ++ default: ++ printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n", ++ (int)mode); ++ break; ++ } ++ ++} ++ ++static int timer_set_next_event(unsigned long cycles, ++ struct clock_event_device *unused) ++{ ++ unsigned long stc; ++ ++ stc = readl(__io_address(ST_BASE + 0x04)); ++ writel(stc + cycles, __io_address(ST_BASE + 0x18)); /* stc3 */ ++ return 0; ++} ++ ++static struct clock_event_device timer0_clockevent = { ++ .name = "timer0", ++ .shift = 32, ++ .features = CLOCK_EVT_FEAT_ONESHOT, ++ .set_mode = timer_set_mode, ++ .set_next_event = timer_set_next_event, ++}; ++ ++/* ++ * IRQ handler for the timer ++ */ ++static irqreturn_t bcm2708_timer_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = &timer0_clockevent; ++ ++ writel(1 << 3, __io_address(ST_BASE + 0x00)); /* stcs clear timer int */ ++ ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction bcm2708_timer_irq = { ++ .name = "BCM2708 Timer Tick", ++ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = bcm2708_timer_interrupt, ++}; ++ ++/* ++ * Set up timer interrupt, and return the current time in seconds. ++ */ ++ ++static struct delay_timer bcm2708_delay_timer = { ++ .read_current_timer = bcm2708_read_current_timer, ++ .freq = STC_FREQ_HZ, ++}; ++ ++static void __init bcm2708_timer_init(void) ++{ ++ /* init high res timer */ ++ bcm2708_clocksource_init(); ++ ++ /* ++ * Initialise to a known state (all timers off) ++ */ ++ writel(0, __io_address(ARM_T_CONTROL)); ++ /* ++ * Make irqs happen for the system timer ++ */ ++ setup_irq(IRQ_TIMER3, &bcm2708_timer_irq); ++ ++ setup_sched_clock(bcm2708_read_sched_clock, 32, STC_FREQ_HZ); ++ ++ timer0_clockevent.mult = ++ div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift); ++ timer0_clockevent.max_delta_ns = ++ clockevent_delta2ns(0xffffffff, &timer0_clockevent); ++ timer0_clockevent.min_delta_ns = ++ clockevent_delta2ns(0xf, &timer0_clockevent); ++ ++ timer0_clockevent.cpumask = cpumask_of(0); ++ clockevents_register_device(&timer0_clockevent); ++ ++ register_current_timer_delay(&bcm2708_delay_timer); ++} ++ ++#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) ++#include ++ ++static struct gpio_led bcm2708_leds[] = { ++ [0] = { ++ .gpio = 16, ++ .name = "led0", ++ .default_trigger = "mmc0", ++ .active_low = 1, ++ }, ++}; ++ ++static struct gpio_led_platform_data bcm2708_led_pdata = { ++ .num_leds = ARRAY_SIZE(bcm2708_leds), ++ .leds = bcm2708_leds, ++}; ++ ++static struct platform_device bcm2708_led_device = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev = { ++ .platform_data = &bcm2708_led_pdata, ++ }, ++}; ++ ++static void __init bcm2708_init_led(void) ++{ ++ platform_device_register(&bcm2708_led_device); ++} ++#else ++static inline void bcm2708_init_led(void) ++{ ++} ++#endif ++ ++void __init bcm2708_init_early(void) ++{ ++ /* ++ * Some devices allocate their coherent buffers from atomic ++ * context. Increase size of atomic coherent pool to make sure such ++ * the allocations won't fail. ++ */ ++ init_dma_coherent_pool_size(SZ_4M); ++} ++ ++MACHINE_START(BCM2708, "BCM2708") ++ /* Maintainer: Broadcom Europe Ltd. */ ++ .map_io = bcm2708_map_io, ++ .init_irq = bcm2708_init_irq, ++ .init_time = bcm2708_timer_init, ++ .init_machine = bcm2708_init, ++ .init_early = bcm2708_init_early, ++ .restart = bcm2708_restart, ++MACHINE_END ++ ++module_param(boardrev, uint, 0644); ++module_param(serial, uint, 0644); ++module_param(uart_clock, uint, 0644); ++module_param(reboot_part, uint, 0644); +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/bcm2708.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/bcm2708.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,51 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/bcm2708.h ++ * ++ * BCM2708 machine support header ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 __BCM2708_BCM2708_H ++#define __BCM2708_BCM2708_H ++ ++#include ++ ++extern void __init bcm2708_init(void); ++extern void __init bcm2708_init_irq(void); ++extern void __init bcm2708_map_io(void); ++extern struct sys_timer bcm2708_timer; ++extern unsigned int mmc_status(struct device *dev); ++ ++#define AMBA_DEVICE(name, busid, base, plat) \ ++static struct amba_device name##_device = { \ ++ .dev = { \ ++ .coherent_dma_mask = ~0, \ ++ .init_name = busid, \ ++ .platform_data = plat, \ ++ }, \ ++ .res = { \ ++ .start = base##_BASE, \ ++ .end = (base##_BASE) + SZ_4K - 1,\ ++ .flags = IORESOURCE_MEM, \ ++ }, \ ++ .dma_mask = ~0, \ ++ .irq = base##_IRQ, \ ++ /* .dma = base##_DMA,*/ \ ++} ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/bcm2708_gpio.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/bcm2708_gpio.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,339 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/bcm2708_gpio.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" ++#define DRIVER_NAME BCM_GPIO_DRIVER_NAME ++#define BCM_GPIO_USE_IRQ 1 ++ ++#define GPIOFSEL(x) (0x00+(x)*4) ++#define GPIOSET(x) (0x1c+(x)*4) ++#define GPIOCLR(x) (0x28+(x)*4) ++#define GPIOLEV(x) (0x34+(x)*4) ++#define GPIOEDS(x) (0x40+(x)*4) ++#define GPIOREN(x) (0x4c+(x)*4) ++#define GPIOFEN(x) (0x58+(x)*4) ++#define GPIOHEN(x) (0x64+(x)*4) ++#define GPIOLEN(x) (0x70+(x)*4) ++#define GPIOAREN(x) (0x7c+(x)*4) ++#define GPIOAFEN(x) (0x88+(x)*4) ++#define GPIOUD(x) (0x94+(x)*4) ++#define GPIOUDCLK(x) (0x98+(x)*4) ++ ++enum { GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT, ++ GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4, ++ GPIO_FSEL_ALT0, GPIO_FSEL_ALT1, ++ GPIO_FSEL_ALT2, GPIO_FSEL_ALT3, ++}; ++ ++ /* Each of the two spinlocks protects a different set of hardware ++ * regiters and data structurs. This decouples the code of the IRQ from ++ * the GPIO code. This also makes the case of a GPIO routine call from ++ * the IRQ code simpler. ++ */ ++static DEFINE_SPINLOCK(lock); /* GPIO registers */ ++ ++struct bcm2708_gpio { ++ struct list_head list; ++ void __iomem *base; ++ struct gpio_chip gc; ++ unsigned long rising; ++ unsigned long falling; ++}; ++ ++static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, ++ int function) ++{ ++ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc); ++ unsigned long flags; ++ unsigned gpiodir; ++ unsigned gpio_bank = offset / 10; ++ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3; ++ ++//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set_function %p (%d,%d)\n", gc, offset, function); ++ if (offset >= ARCH_NR_GPIOS) ++ return -EINVAL; ++ ++ spin_lock_irqsave(&lock, flags); ++ ++ gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank)); ++ gpiodir &= ~(7 << gpio_field_offset); ++ gpiodir |= function << gpio_field_offset; ++ writel(gpiodir, gpio->base + GPIOFSEL(gpio_bank)); ++ spin_unlock_irqrestore(&lock, flags); ++ gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank)); ++ ++ return 0; ++} ++ ++static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset) ++{ ++ return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT); ++} ++ ++static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value); ++static int bcm2708_gpio_dir_out(struct gpio_chip *gc, unsigned offset, ++ int value) ++{ ++ int ret; ++ ret = bcm2708_set_function(gc, offset, GPIO_FSEL_OUTPUT); ++ if (ret >= 0) ++ bcm2708_gpio_set(gc, offset, value); ++ return ret; ++} ++ ++static int bcm2708_gpio_get(struct gpio_chip *gc, unsigned offset) ++{ ++ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc); ++ unsigned gpio_bank = offset / 32; ++ unsigned gpio_field_offset = (offset - 32 * gpio_bank); ++ unsigned lev; ++ ++ if (offset >= ARCH_NR_GPIOS) ++ return 0; ++ lev = readl(gpio->base + GPIOLEV(gpio_bank)); ++//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_get %p (%d)=%d\n", gc, offset, 0x1 & (lev>>gpio_field_offset)); ++ return 0x1 & (lev >> gpio_field_offset); ++} ++ ++static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value) ++{ ++ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc); ++ unsigned gpio_bank = offset / 32; ++ unsigned gpio_field_offset = (offset - 32 * gpio_bank); ++//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set %p (%d=%d)\n", gc, offset, value); ++ if (offset >= ARCH_NR_GPIOS) ++ return; ++ if (value) ++ writel(1 << gpio_field_offset, gpio->base + GPIOSET(gpio_bank)); ++ else ++ writel(1 << gpio_field_offset, gpio->base + GPIOCLR(gpio_bank)); ++} ++ ++/************************************************************************************************************************* ++ * bcm2708 GPIO IRQ ++ */ ++ ++#if BCM_GPIO_USE_IRQ ++ ++static int bcm2708_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) ++{ ++ return gpio_to_irq(gpio); ++} ++ ++static int bcm2708_gpio_irq_set_type(struct irq_data *d, unsigned type) ++{ ++ unsigned irq = d->irq; ++ struct bcm2708_gpio *gpio = irq_get_chip_data(irq); ++ ++ if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) ++ return -EINVAL; ++ ++ if (type & IRQ_TYPE_EDGE_RISING) { ++ gpio->rising |= (1 << irq_to_gpio(irq)); ++ } else { ++ gpio->rising &= ~(1 << irq_to_gpio(irq)); ++ } ++ ++ if (type & IRQ_TYPE_EDGE_FALLING) { ++ gpio->falling |= (1 << irq_to_gpio(irq)); ++ } else { ++ gpio->falling &= ~(1 << irq_to_gpio(irq)); ++ } ++ return 0; ++} ++ ++static void bcm2708_gpio_irq_mask(struct irq_data *d) ++{ ++ unsigned irq = d->irq; ++ struct bcm2708_gpio *gpio = irq_get_chip_data(irq); ++ unsigned gn = irq_to_gpio(irq); ++ unsigned gb = gn / 32; ++ unsigned long rising = readl(gpio->base + GPIOREN(gb)); ++ unsigned long falling = readl(gpio->base + GPIOFEN(gb)); ++ ++ gn = gn % 32; ++ ++ writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb)); ++ writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb)); ++} ++ ++static void bcm2708_gpio_irq_unmask(struct irq_data *d) ++{ ++ unsigned irq = d->irq; ++ struct bcm2708_gpio *gpio = irq_get_chip_data(irq); ++ unsigned gn = irq_to_gpio(irq); ++ unsigned gb = gn / 32; ++ unsigned long rising = readl(gpio->base + GPIOREN(gb)); ++ unsigned long falling = readl(gpio->base + GPIOFEN(gb)); ++ ++ gn = gn % 32; ++ ++ writel(1 << gn, gpio->base + GPIOEDS(gb)); ++ ++ if (gpio->rising & (1 << gn)) { ++ writel(rising | (1 << gn), gpio->base + GPIOREN(gb)); ++ } else { ++ writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb)); ++ } ++ ++ if (gpio->falling & (1 << gn)) { ++ writel(falling | (1 << gn), gpio->base + GPIOFEN(gb)); ++ } else { ++ writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb)); ++ } ++} ++ ++static struct irq_chip bcm2708_irqchip = { ++ .name = "GPIO", ++ .irq_enable = bcm2708_gpio_irq_unmask, ++ .irq_disable = bcm2708_gpio_irq_mask, ++ .irq_unmask = bcm2708_gpio_irq_unmask, ++ .irq_mask = bcm2708_gpio_irq_mask, ++ .irq_set_type = bcm2708_gpio_irq_set_type, ++}; ++ ++static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id) ++{ ++ unsigned long edsr; ++ unsigned bank; ++ int i; ++ unsigned gpio; ++ for (bank = 0; bank <= 1; bank++) { ++ edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank)); ++ for_each_set_bit(i, &edsr, 32) { ++ gpio = i + bank * 32; ++ generic_handle_irq(gpio_to_irq(gpio)); ++ } ++ writel(0xffffffff, __io_address(GPIO_BASE) + GPIOEDS(bank)); ++ } ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction bcm2708_gpio_irq = { ++ .name = "BCM2708 GPIO catchall handler", ++ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = bcm2708_gpio_interrupt, ++}; ++ ++static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb) ++{ ++ unsigned irq; ++ ++ ucb->gc.to_irq = bcm2708_gpio_to_irq; ++ ++ for (irq = GPIO_IRQ_START; irq < (GPIO_IRQ_START + GPIO_IRQS); irq++) { ++ irq_set_chip_data(irq, ucb); ++ irq_set_chip(irq, &bcm2708_irqchip); ++ set_irq_flags(irq, IRQF_VALID); ++ } ++ setup_irq(IRQ_GPIO3, &bcm2708_gpio_irq); ++} ++ ++#else ++ ++static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb) ++{ ++} ++ ++#endif /* #if BCM_GPIO_USE_IRQ ***************************************************************************************************************** */ ++ ++static int bcm2708_gpio_probe(struct platform_device *dev) ++{ ++ struct bcm2708_gpio *ucb; ++ struct resource *res; ++ int err = 0; ++ ++ printk(KERN_INFO DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev); ++ ++ ucb = kzalloc(sizeof(*ucb), GFP_KERNEL); ++ if (NULL == ucb) { ++ printk(KERN_ERR DRIVER_NAME ": failed to allocate " ++ "mailbox memory\n"); ++ err = -ENOMEM; ++ goto err; ++ } ++ ++ res = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ ++ platform_set_drvdata(dev, ucb); ++ ucb->base = __io_address(GPIO_BASE); ++ ++ ucb->gc.label = "bcm2708_gpio"; ++ ucb->gc.base = 0; ++ ucb->gc.ngpio = ARCH_NR_GPIOS; ++ ucb->gc.owner = THIS_MODULE; ++ ++ ucb->gc.direction_input = bcm2708_gpio_dir_in; ++ ucb->gc.direction_output = bcm2708_gpio_dir_out; ++ ucb->gc.get = bcm2708_gpio_get; ++ ucb->gc.set = bcm2708_gpio_set; ++ ucb->gc.can_sleep = 0; ++ ++ bcm2708_gpio_irq_init(ucb); ++ ++ err = gpiochip_add(&ucb->gc); ++ if (err) ++ goto err; ++ ++err: ++ return err; ++ ++} ++ ++static int bcm2708_gpio_remove(struct platform_device *dev) ++{ ++ int err = 0; ++ struct bcm2708_gpio *ucb = platform_get_drvdata(dev); ++ ++ printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_remove %p\n", dev); ++ ++ err = gpiochip_remove(&ucb->gc); ++ ++ platform_set_drvdata(dev, NULL); ++ kfree(ucb); ++ ++ return err; ++} ++ ++static struct platform_driver bcm2708_gpio_driver = { ++ .probe = bcm2708_gpio_probe, ++ .remove = bcm2708_gpio_remove, ++ .driver = { ++ .name = "bcm2708_gpio"}, ++}; ++ ++static int __init bcm2708_gpio_init(void) ++{ ++ return platform_driver_register(&bcm2708_gpio_driver); ++} ++ ++static void __exit bcm2708_gpio_exit(void) ++{ ++ platform_driver_unregister(&bcm2708_gpio_driver); ++} ++ ++module_init(bcm2708_gpio_init); ++module_exit(bcm2708_gpio_exit); ++ ++MODULE_DESCRIPTION("Broadcom BCM2708 GPIO driver"); ++MODULE_LICENSE("GPL"); +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/clock.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/clock.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,61 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/clock.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "clock.h" ++ ++int clk_enable(struct clk *clk) ++{ ++ return 0; ++} ++EXPORT_SYMBOL(clk_enable); ++ ++void clk_disable(struct clk *clk) ++{ ++} ++EXPORT_SYMBOL(clk_disable); ++ ++unsigned long clk_get_rate(struct clk *clk) ++{ ++ return clk->rate; ++} ++EXPORT_SYMBOL(clk_get_rate); ++ ++long clk_round_rate(struct clk *clk, unsigned long rate) ++{ ++ return clk->rate; ++} ++EXPORT_SYMBOL(clk_round_rate); ++ ++int clk_set_rate(struct clk *clk, unsigned long rate) ++{ ++ return -EIO; ++} ++EXPORT_SYMBOL(clk_set_rate); +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/clock.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/clock.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,24 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/clock.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 ++ */ ++struct module; ++ ++struct clk { ++ unsigned long rate; ++}; +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/dma.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/dma.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,399 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/dma.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/*****************************************************************************\ ++ * * ++ * Configuration * ++ * * ++\*****************************************************************************/ ++ ++#define CACHE_LINE_MASK 31 ++#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME ++#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ ++ ++/* valid only for channels 0 - 14, 15 has its own base address */ ++#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ ++#define BCM2708_DMA_CHANIO(dma_base, n) \ ++ ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) ++ ++ ++/*****************************************************************************\ ++ * * ++ * DMA Auxilliary Functions * ++ * * ++\*****************************************************************************/ ++ ++/* A DMA buffer on an arbitrary boundary may separate a cache line into a ++ section inside the DMA buffer and another section outside it. ++ Even if we flush DMA buffers from the cache there is always the chance that ++ during a DMA someone will access the part of a cache line that is outside ++ the DMA buffer - which will then bring in unwelcome data. ++ Without being able to dictate our own buffer pools we must insist that ++ DMA buffers consist of a whole number of cache lines. ++*/ ++ ++extern int ++bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) ++{ ++ int i; ++ ++ for (i = 0; i < sg_len; i++) { ++ if (sg_ptr[i].offset & CACHE_LINE_MASK || ++ sg_ptr[i].length & CACHE_LINE_MASK) ++ return 0; ++ } ++ ++ return 1; ++} ++EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); ++ ++extern void ++bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) ++{ ++ dsb(); /* ARM data synchronization (push) operation */ ++ ++ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); ++ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); ++} ++ ++extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) ++{ ++ dsb(); ++ ++ /* ugly busy wait only option for now */ ++ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) ++ cpu_relax(); ++} ++ ++EXPORT_SYMBOL_GPL(bcm_dma_start); ++ ++/* Complete an ongoing DMA (assuming its results are to be ignored) ++ Does nothing if there is no DMA in progress. ++ This routine waits for the current AXI transfer to complete before ++ terminating the current DMA. If the current transfer is hung on a DREQ used ++ by an uncooperative peripheral the AXI transfer may never complete. In this ++ case the routine times out and return a non-zero error code. ++ Use of this routine doesn't guarantee that the ongoing or aborted DMA ++ does not produce an interrupt. ++*/ ++extern int ++bcm_dma_abort(void __iomem *dma_chan_base) ++{ ++ unsigned long int cs; ++ int rc = 0; ++ ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (BCM2708_DMA_ACTIVE & cs) { ++ long int timeout = 10000; ++ ++ /* write 0 to the active bit - pause the DMA */ ++ writel(0, dma_chan_base + BCM2708_DMA_CS); ++ ++ /* wait for any current AXI transfer to complete */ ++ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { ++ /* we'll un-pause when we set of our next DMA */ ++ rc = -ETIMEDOUT; ++ ++ } else if (BCM2708_DMA_ACTIVE & cs) { ++ /* terminate the control block chain */ ++ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); ++ ++ /* abort the whole DMA */ ++ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, ++ dma_chan_base + BCM2708_DMA_CS); ++ } ++ } ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_abort); ++ ++ ++/***************************************************************************** \ ++ * * ++ * DMA Manager Device Methods * ++ * * ++\*****************************************************************************/ ++ ++struct vc_dmaman { ++ void __iomem *dma_base; ++ u32 chan_available; /* bitmap of available channels */ ++ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ ++}; ++ ++static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, ++ u32 chans_available) ++{ ++ dmaman->dma_base = dma_base; ++ dmaman->chan_available = chans_available; ++ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ ++} ++ ++static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, ++ unsigned preferred_feature_set) ++{ ++ u32 chans; ++ int feature; ++ ++ chans = dmaman->chan_available; ++ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) ++ /* select the subset of available channels with the desired ++ feature so long as some of the candidate channels have that ++ feature */ ++ if ((preferred_feature_set & (1 << feature)) && ++ (chans & dmaman->has_feature[feature])) ++ chans &= dmaman->has_feature[feature]; ++ ++ if (chans) { ++ int chan = 0; ++ /* return the ordinal of the first channel in the bitmap */ ++ while (chans != 0 && (chans & 1) == 0) { ++ chans >>= 1; ++ chan++; ++ } ++ /* claim the channel */ ++ dmaman->chan_available &= ~(1 << chan); ++ return chan; ++ } else ++ return -ENOMEM; ++} ++ ++static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) ++{ ++ if (chan < 0) ++ return -EINVAL; ++ else if ((1 << chan) & dmaman->chan_available) ++ return -EIDRM; ++ else { ++ dmaman->chan_available |= (1 << chan); ++ return 0; ++ } ++} ++ ++/*****************************************************************************\ ++ * * ++ * DMA IRQs * ++ * * ++\*****************************************************************************/ ++ ++static unsigned char bcm_dma_irqs[] = { ++ IRQ_DMA0, ++ IRQ_DMA1, ++ IRQ_DMA2, ++ IRQ_DMA3, ++ IRQ_DMA4, ++ IRQ_DMA5, ++ IRQ_DMA6, ++ IRQ_DMA7, ++ IRQ_DMA8, ++ IRQ_DMA9, ++ IRQ_DMA10, ++ IRQ_DMA11, ++ IRQ_DMA12 ++}; ++ ++ ++/***************************************************************************** \ ++ * * ++ * DMA Manager Monitor * ++ * * ++\*****************************************************************************/ ++ ++static struct device *dmaman_dev; /* we assume there's only one! */ ++ ++extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, int *out_dma_irq) ++{ ++ if (!dmaman_dev) ++ return -ENODEV; ++ else { ++ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); ++ int rc; ++ ++ device_lock(dmaman_dev); ++ rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); ++ if (rc >= 0) { ++ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, ++ rc); ++ *out_dma_irq = bcm_dma_irqs[rc]; ++ } ++ device_unlock(dmaman_dev); ++ ++ return rc; ++ } ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); ++ ++extern int bcm_dma_chan_free(int channel) ++{ ++ if (dmaman_dev) { ++ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); ++ int rc; ++ ++ device_lock(dmaman_dev); ++ rc = vc_dmaman_chan_free(dmaman, channel); ++ device_unlock(dmaman_dev); ++ ++ return rc; ++ } else ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_free); ++ ++static int dev_dmaman_register(const char *dev_name, struct device *dev) ++{ ++ int rc = dmaman_dev ? -EINVAL : 0; ++ dmaman_dev = dev; ++ return rc; ++} ++ ++static void dev_dmaman_deregister(const char *dev_name, struct device *dev) ++{ ++ dmaman_dev = NULL; ++} ++ ++/*****************************************************************************\ ++ * * ++ * DMA Device * ++ * * ++\*****************************************************************************/ ++ ++static int dmachans = -1; /* module parameter */ ++ ++static int bcm_dmaman_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct vc_dmaman *dmaman; ++ struct resource *dma_res = NULL; ++ void __iomem *dma_base = NULL; ++ int have_dma_region = 0; ++ ++ dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); ++ if (NULL == dmaman) { ++ printk(KERN_ERR DRIVER_NAME ": failed to allocate " ++ "DMA management memory\n"); ++ ret = -ENOMEM; ++ } else { ++ ++ dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (dma_res == NULL) { ++ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " ++ "resource\n"); ++ ret = -ENODEV; ++ } else if (!request_mem_region(dma_res->start, ++ resource_size(dma_res), ++ DRIVER_NAME)) { ++ dev_err(&pdev->dev, "cannot obtain DMA region\n"); ++ ret = -EBUSY; ++ } else { ++ have_dma_region = 1; ++ dma_base = ioremap(dma_res->start, ++ resource_size(dma_res)); ++ if (!dma_base) { ++ dev_err(&pdev->dev, "cannot map DMA region\n"); ++ ret = -ENOMEM; ++ } else { ++ /* use module parameter if one was provided */ ++ if (dmachans > 0) ++ vc_dmaman_init(dmaman, dma_base, ++ dmachans); ++ else ++ vc_dmaman_init(dmaman, dma_base, ++ DEFAULT_DMACHAN_BITMAP); ++ ++ platform_set_drvdata(pdev, dmaman); ++ dev_dmaman_register(DRIVER_NAME, &pdev->dev); ++ ++ printk(KERN_INFO DRIVER_NAME ": DMA manager " ++ "at %p\n", dma_base); ++ } ++ } ++ } ++ if (ret != 0) { ++ if (dma_base) ++ iounmap(dma_base); ++ if (dma_res && have_dma_region) ++ release_mem_region(dma_res->start, ++ resource_size(dma_res)); ++ if (dmaman) ++ kfree(dmaman); ++ } ++ return ret; ++} ++ ++static int bcm_dmaman_remove(struct platform_device *pdev) ++{ ++ struct vc_dmaman *dmaman = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); ++ kfree(dmaman); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm_dmaman_driver = { ++ .probe = bcm_dmaman_probe, ++ .remove = bcm_dmaman_remove, ++ ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++/*****************************************************************************\ ++ * * ++ * Driver init/exit * ++ * * ++\*****************************************************************************/ ++ ++static int __init bcm_dmaman_drv_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&bcm_dmaman_driver); ++ if (ret != 0) { ++ printk(KERN_ERR DRIVER_NAME ": failed to register " ++ "on platform\n"); ++ } ++ ++ return ret; ++} ++ ++static void __exit bcm_dmaman_drv_exit(void) ++{ ++ platform_driver_unregister(&bcm_dmaman_driver); ++} ++ ++module_init(bcm_dmaman_drv_init); ++module_exit(bcm_dmaman_drv_exit); ++ ++module_param(dmachans, int, 0644); ++ ++MODULE_AUTHOR("Gray Girling "); ++MODULE_DESCRIPTION("DMA channel manager driver"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/arm_control.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/arm_control.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,419 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/arm_control.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 __BCM2708_ARM_CONTROL_H ++#define __BCM2708_ARM_CONTROL_H ++ ++/* ++ * Definitions and addresses for the ARM CONTROL logic ++ * This file is manually generated. ++ */ ++ ++#define ARM_BASE 0x7E00B000 ++ ++/* Basic configuration */ ++#define ARM_CONTROL0 HW_REGISTER_RW(ARM_BASE+0x000) ++#define ARM_C0_SIZ128M 0x00000000 ++#define ARM_C0_SIZ256M 0x00000001 ++#define ARM_C0_SIZ512M 0x00000002 ++#define ARM_C0_SIZ1G 0x00000003 ++#define ARM_C0_BRESP0 0x00000000 ++#define ARM_C0_BRESP1 0x00000004 ++#define ARM_C0_BRESP2 0x00000008 ++#define ARM_C0_BOOTHI 0x00000010 ++#define ARM_C0_UNUSED05 0x00000020 /* free */ ++#define ARM_C0_FULLPERI 0x00000040 ++#define ARM_C0_UNUSED78 0x00000180 /* free */ ++#define ARM_C0_JTAGMASK 0x00000E00 ++#define ARM_C0_JTAGOFF 0x00000000 ++#define ARM_C0_JTAGBASH 0x00000800 /* Debug on GPIO off */ ++#define ARM_C0_JTAGGPIO 0x00000C00 /* Debug on GPIO on */ ++#define ARM_C0_APROTMSK 0x0000F000 ++#define ARM_C0_DBG0SYNC 0x00010000 /* VPU0 halt sync */ ++#define ARM_C0_DBG1SYNC 0x00020000 /* VPU1 halt sync */ ++#define ARM_C0_SWDBGREQ 0x00040000 /* HW debug request */ ++#define ARM_C0_PASSHALT 0x00080000 /* ARM halt passed to debugger */ ++#define ARM_C0_PRIO_PER 0x00F00000 /* per priority mask */ ++#define ARM_C0_PRIO_L2 0x0F000000 ++#define ARM_C0_PRIO_UC 0xF0000000 ++ ++#define ARM_C0_APROTPASS 0x0000A000 /* Translate 1:1 */ ++#define ARM_C0_APROTUSER 0x00000000 /* Only user mode */ ++#define ARM_C0_APROTSYST 0x0000F000 /* Only system mode */ ++ ++ ++#define ARM_CONTROL1 HW_REGISTER_RW(ARM_BASE+0x440) ++#define ARM_C1_TIMER 0x00000001 /* re-route timer IRQ to VC */ ++#define ARM_C1_MAIL 0x00000002 /* re-route Mail IRQ to VC */ ++#define ARM_C1_BELL0 0x00000004 /* re-route Doorbell 0 to VC */ ++#define ARM_C1_BELL1 0x00000008 /* re-route Doorbell 1 to VC */ ++#define ARM_C1_PERSON 0x00000100 /* peripherals on */ ++#define ARM_C1_REQSTOP 0x00000200 /* ASYNC bridge request stop */ ++ ++#define ARM_STATUS HW_REGISTER_RW(ARM_BASE+0x444) ++#define ARM_S_ACKSTOP 0x80000000 /* Bridge stopped */ ++#define ARM_S_READPEND 0x000003FF /* pending reads counter */ ++#define ARM_S_WRITPEND 0x000FFC00 /* pending writes counter */ ++ ++#define ARM_ERRHALT HW_REGISTER_RW(ARM_BASE+0x448) ++#define ARM_EH_PERIBURST 0x00000001 /* Burst write seen on peri bus */ ++#define ARM_EH_ILLADDRS1 0x00000002 /* Address bits 25-27 error */ ++#define ARM_EH_ILLADDRS2 0x00000004 /* Address bits 31-28 error */ ++#define ARM_EH_VPU0HALT 0x00000008 /* VPU0 halted & in debug mode */ ++#define ARM_EH_VPU1HALT 0x00000010 /* VPU1 halted & in debug mode */ ++#define ARM_EH_ARMHALT 0x00000020 /* ARM in halted debug mode */ ++ ++#define ARM_ID_SECURE HW_REGISTER_RW(ARM_BASE+0x00C) ++#define ARM_ID HW_REGISTER_RW(ARM_BASE+0x44C) ++#define ARM_IDVAL 0x364D5241 ++ ++/* Translation memory */ ++#define ARM_TRANSLATE HW_REGISTER_RW(ARM_BASE+0x100) ++/* 32 locations: 0x100.. 0x17F */ ++/* 32 spare means we CAN go to 64 pages.... */ ++ ++ ++/* Interrupts */ ++#define ARM_IRQ_PEND0 HW_REGISTER_RW(ARM_BASE+0x200) /* Top IRQ bits */ ++#define ARM_I0_TIMER 0x00000001 /* timer IRQ */ ++#define ARM_I0_MAIL 0x00000002 /* Mail IRQ */ ++#define ARM_I0_BELL0 0x00000004 /* Doorbell 0 */ ++#define ARM_I0_BELL1 0x00000008 /* Doorbell 1 */ ++#define ARM_I0_BANK1 0x00000100 /* Bank1 IRQ */ ++#define ARM_I0_BANK2 0x00000200 /* Bank2 IRQ */ ++ ++#define ARM_IRQ_PEND1 HW_REGISTER_RW(ARM_BASE+0x204) /* All bank1 IRQ bits */ ++/* todo: all I1_interrupt sources */ ++#define ARM_IRQ_PEND2 HW_REGISTER_RW(ARM_BASE+0x208) /* All bank2 IRQ bits */ ++/* todo: all I2_interrupt sources */ ++ ++#define ARM_IRQ_FAST HW_REGISTER_RW(ARM_BASE+0x20C) /* FIQ control */ ++#define ARM_IF_INDEX 0x0000007F /* FIQ select */ ++#define ARM_IF_ENABLE 0x00000080 /* FIQ enable */ ++#define ARM_IF_VCMASK 0x0000003F /* FIQ = (index from VC source) */ ++#define ARM_IF_TIMER 0x00000040 /* FIQ = ARM timer */ ++#define ARM_IF_MAIL 0x00000041 /* FIQ = ARM Mail */ ++#define ARM_IF_BELL0 0x00000042 /* FIQ = ARM Doorbell 0 */ ++#define ARM_IF_BELL1 0x00000043 /* FIQ = ARM Doorbell 1 */ ++#define ARM_IF_VP0HALT 0x00000044 /* FIQ = VPU0 Halt seen */ ++#define ARM_IF_VP1HALT 0x00000045 /* FIQ = VPU1 Halt seen */ ++#define ARM_IF_ILLEGAL 0x00000046 /* FIQ = Illegal access seen */ ++ ++#define ARM_IRQ_ENBL1 HW_REGISTER_RW(ARM_BASE+0x210) /* Bank1 enable bits */ ++#define ARM_IRQ_ENBL2 HW_REGISTER_RW(ARM_BASE+0x214) /* Bank2 enable bits */ ++#define ARM_IRQ_ENBL3 HW_REGISTER_RW(ARM_BASE+0x218) /* ARM irqs enable bits */ ++#define ARM_IRQ_DIBL1 HW_REGISTER_RW(ARM_BASE+0x21C) /* Bank1 disable bits */ ++#define ARM_IRQ_DIBL2 HW_REGISTER_RW(ARM_BASE+0x220) /* Bank2 disable bits */ ++#define ARM_IRQ_DIBL3 HW_REGISTER_RW(ARM_BASE+0x224) /* ARM irqs disable bits */ ++#define ARM_IE_TIMER 0x00000001 /* Timer IRQ */ ++#define ARM_IE_MAIL 0x00000002 /* Mail IRQ */ ++#define ARM_IE_BELL0 0x00000004 /* Doorbell 0 */ ++#define ARM_IE_BELL1 0x00000008 /* Doorbell 1 */ ++#define ARM_IE_VP0HALT 0x00000010 /* VPU0 Halt */ ++#define ARM_IE_VP1HALT 0x00000020 /* VPU1 Halt */ ++#define ARM_IE_ILLEGAL 0x00000040 /* Illegal access seen */ ++ ++/* Timer */ ++/* For reg. fields see sp804 spec. */ ++#define ARM_T_LOAD HW_REGISTER_RW(ARM_BASE+0x400) ++#define ARM_T_VALUE HW_REGISTER_RW(ARM_BASE+0x404) ++#define ARM_T_CONTROL HW_REGISTER_RW(ARM_BASE+0x408) ++#define ARM_T_IRQCNTL HW_REGISTER_RW(ARM_BASE+0x40C) ++#define ARM_T_RAWIRQ HW_REGISTER_RW(ARM_BASE+0x410) ++#define ARM_T_MSKIRQ HW_REGISTER_RW(ARM_BASE+0x414) ++#define ARM_T_RELOAD HW_REGISTER_RW(ARM_BASE+0x418) ++#define ARM_T_PREDIV HW_REGISTER_RW(ARM_BASE+0x41c) ++#define ARM_T_FREECNT HW_REGISTER_RW(ARM_BASE+0x420) ++ ++#define TIMER_CTRL_ONESHOT (1 << 0) ++#define TIMER_CTRL_32BIT (1 << 1) ++#define TIMER_CTRL_DIV1 (0 << 2) ++#define TIMER_CTRL_DIV16 (1 << 2) ++#define TIMER_CTRL_DIV256 (2 << 2) ++#define TIMER_CTRL_IE (1 << 5) ++#define TIMER_CTRL_PERIODIC (1 << 6) ++#define TIMER_CTRL_ENABLE (1 << 7) ++#define TIMER_CTRL_DBGHALT (1 << 8) ++#define TIMER_CTRL_ENAFREE (1 << 9) ++#define TIMER_CTRL_FREEDIV_SHIFT 16) ++#define TIMER_CTRL_FREEDIV_MASK 0xff ++ ++/* Semaphores, Doorbells, Mailboxes */ ++#define ARM_SBM_OWN0 (ARM_BASE+0x800) ++#define ARM_SBM_OWN1 (ARM_BASE+0x900) ++#define ARM_SBM_OWN2 (ARM_BASE+0xA00) ++#define ARM_SBM_OWN3 (ARM_BASE+0xB00) ++ ++/* MAILBOXES ++ * Register flags are common across all ++ * owner registers. See end of this section ++ * ++ * Semaphores, Doorbells, Mailboxes Owner 0 ++ * ++ */ ++ ++#define ARM_0_SEMS HW_REGISTER_RW(ARM_SBM_OWN0+0x00) ++#define ARM_0_SEM0 HW_REGISTER_RW(ARM_SBM_OWN0+0x00) ++#define ARM_0_SEM1 HW_REGISTER_RW(ARM_SBM_OWN0+0x04) ++#define ARM_0_SEM2 HW_REGISTER_RW(ARM_SBM_OWN0+0x08) ++#define ARM_0_SEM3 HW_REGISTER_RW(ARM_SBM_OWN0+0x0C) ++#define ARM_0_SEM4 HW_REGISTER_RW(ARM_SBM_OWN0+0x10) ++#define ARM_0_SEM5 HW_REGISTER_RW(ARM_SBM_OWN0+0x14) ++#define ARM_0_SEM6 HW_REGISTER_RW(ARM_SBM_OWN0+0x18) ++#define ARM_0_SEM7 HW_REGISTER_RW(ARM_SBM_OWN0+0x1C) ++#define ARM_0_BELL0 HW_REGISTER_RW(ARM_SBM_OWN0+0x40) ++#define ARM_0_BELL1 HW_REGISTER_RW(ARM_SBM_OWN0+0x44) ++#define ARM_0_BELL2 HW_REGISTER_RW(ARM_SBM_OWN0+0x48) ++#define ARM_0_BELL3 HW_REGISTER_RW(ARM_SBM_OWN0+0x4C) ++/* MAILBOX 0 access in Owner 0 area */ ++/* Some addresses should ONLY be used by owner 0 */ ++#define ARM_0_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN0+0x80) /* .. 0x8C (4 locations) */ ++#define ARM_0_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN0+0x80) /* .. 0x8C (4 locations) Normal read */ ++#define ARM_0_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN0+0x90) /* none-pop read */ ++#define ARM_0_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN0+0x94) /* Sender read (only LS 2 bits) */ ++#define ARM_0_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN0+0x98) /* Status read */ ++#define ARM_0_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN0+0x9C) /* Config read/write */ ++/* MAILBOX 1 access in Owner 0 area */ ++/* Owner 0 should only WRITE to this mailbox */ ++#define ARM_0_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) /* .. 0xAC (4 locations) */ ++/*#define ARM_0_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_0_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN0+0xB0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_0_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN0+0xB4) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_0_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN0+0xB8) /* Status read */ ++/*#define ARM_0_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN0+0xBC) */ /* DO NOT USE THIS !!!!! */ ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_0_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN0+0xE0) /* semaphore clear/debug register */ ++#define ARM_0_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN0+0xE4) /* Doorbells clear/debug register */ ++#define ARM_0_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN0+0xF8) /* ALL interrupts */ ++#define ARM_0_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN0+0xFC) /* IRQS pending for owner 0 */ ++ ++/* Semaphores, Doorbells, Mailboxes Owner 1 */ ++#define ARM_1_SEMS HW_REGISTER_RW(ARM_SBM_OWN1+0x00) ++#define ARM_1_SEM0 HW_REGISTER_RW(ARM_SBM_OWN1+0x00) ++#define ARM_1_SEM1 HW_REGISTER_RW(ARM_SBM_OWN1+0x04) ++#define ARM_1_SEM2 HW_REGISTER_RW(ARM_SBM_OWN1+0x08) ++#define ARM_1_SEM3 HW_REGISTER_RW(ARM_SBM_OWN1+0x0C) ++#define ARM_1_SEM4 HW_REGISTER_RW(ARM_SBM_OWN1+0x10) ++#define ARM_1_SEM5 HW_REGISTER_RW(ARM_SBM_OWN1+0x14) ++#define ARM_1_SEM6 HW_REGISTER_RW(ARM_SBM_OWN1+0x18) ++#define ARM_1_SEM7 HW_REGISTER_RW(ARM_SBM_OWN1+0x1C) ++#define ARM_1_BELL0 HW_REGISTER_RW(ARM_SBM_OWN1+0x40) ++#define ARM_1_BELL1 HW_REGISTER_RW(ARM_SBM_OWN1+0x44) ++#define ARM_1_BELL2 HW_REGISTER_RW(ARM_SBM_OWN1+0x48) ++#define ARM_1_BELL3 HW_REGISTER_RW(ARM_SBM_OWN1+0x4C) ++/* MAILBOX 0 access in Owner 0 area */ ++/* Owner 1 should only WRITE to this mailbox */ ++#define ARM_1_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN1+0x80) /* .. 0x8C (4 locations) */ ++/*#define ARM_1_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN1+0x80) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_1_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN1+0x90) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_1_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN1+0x94) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_1_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN1+0x98) /* Status read */ ++/*#define ARM_1_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN1+0x9C) */ /* DO NOT USE THIS !!!!! */ ++/* MAILBOX 1 access in Owner 0 area */ ++#define ARM_1_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN1+0xA0) /* .. 0xAC (4 locations) */ ++#define ARM_1_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN1+0xA0) /* .. 0xAC (4 locations) Normal read */ ++#define ARM_1_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN1+0xB0) /* none-pop read */ ++#define ARM_1_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN1+0xB4) /* Sender read (only LS 2 bits) */ ++#define ARM_1_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN1+0xB8) /* Status read */ ++#define ARM_1_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN1+0xBC) ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_1_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN1+0xE0) /* semaphore clear/debug register */ ++#define ARM_1_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN1+0xE4) /* Doorbells clear/debug register */ ++#define ARM_1_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN1+0xFC) /* IRQS pending for owner 1 */ ++#define ARM_1_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN1+0xF8) /* ALL interrupts */ ++ ++/* Semaphores, Doorbells, Mailboxes Owner 2 */ ++#define ARM_2_SEMS HW_REGISTER_RW(ARM_SBM_OWN2+0x00) ++#define ARM_2_SEM0 HW_REGISTER_RW(ARM_SBM_OWN2+0x00) ++#define ARM_2_SEM1 HW_REGISTER_RW(ARM_SBM_OWN2+0x04) ++#define ARM_2_SEM2 HW_REGISTER_RW(ARM_SBM_OWN2+0x08) ++#define ARM_2_SEM3 HW_REGISTER_RW(ARM_SBM_OWN2+0x0C) ++#define ARM_2_SEM4 HW_REGISTER_RW(ARM_SBM_OWN2+0x10) ++#define ARM_2_SEM5 HW_REGISTER_RW(ARM_SBM_OWN2+0x14) ++#define ARM_2_SEM6 HW_REGISTER_RW(ARM_SBM_OWN2+0x18) ++#define ARM_2_SEM7 HW_REGISTER_RW(ARM_SBM_OWN2+0x1C) ++#define ARM_2_BELL0 HW_REGISTER_RW(ARM_SBM_OWN2+0x40) ++#define ARM_2_BELL1 HW_REGISTER_RW(ARM_SBM_OWN2+0x44) ++#define ARM_2_BELL2 HW_REGISTER_RW(ARM_SBM_OWN2+0x48) ++#define ARM_2_BELL3 HW_REGISTER_RW(ARM_SBM_OWN2+0x4C) ++/* MAILBOX 0 access in Owner 2 area */ ++/* Owner 2 should only WRITE to this mailbox */ ++#define ARM_2_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN2+0x80) /* .. 0x8C (4 locations) */ ++/*#define ARM_2_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN2+0x80) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN2+0x90) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN2+0x94) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_2_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN2+0x98) /* Status read */ ++/*#define ARM_2_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN2+0x9C) */ /* DO NOT USE THIS !!!!! */ ++/* MAILBOX 1 access in Owner 2 area */ ++/* Owner 2 should only WRITE to this mailbox */ ++#define ARM_2_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) /* .. 0xAC (4 locations) */ ++/*#define ARM_2_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN2+0xB0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN2+0xB4) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_2_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN2+0xB8) /* Status read */ ++/*#define ARM_2_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN2+0xBC) */ /* DO NOT USE THIS !!!!! */ ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_2_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN2+0xE0) /* semaphore clear/debug register */ ++#define ARM_2_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN2+0xE4) /* Doorbells clear/debug register */ ++#define ARM_2_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN2+0xFC) /* IRQS pending for owner 2 */ ++#define ARM_2_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN2+0xF8) /* ALL interrupts */ ++ ++/* Semaphores, Doorbells, Mailboxes Owner 3 */ ++#define ARM_3_SEMS HW_REGISTER_RW(ARM_SBM_OWN3+0x00) ++#define ARM_3_SEM0 HW_REGISTER_RW(ARM_SBM_OWN3+0x00) ++#define ARM_3_SEM1 HW_REGISTER_RW(ARM_SBM_OWN3+0x04) ++#define ARM_3_SEM2 HW_REGISTER_RW(ARM_SBM_OWN3+0x08) ++#define ARM_3_SEM3 HW_REGISTER_RW(ARM_SBM_OWN3+0x0C) ++#define ARM_3_SEM4 HW_REGISTER_RW(ARM_SBM_OWN3+0x10) ++#define ARM_3_SEM5 HW_REGISTER_RW(ARM_SBM_OWN3+0x14) ++#define ARM_3_SEM6 HW_REGISTER_RW(ARM_SBM_OWN3+0x18) ++#define ARM_3_SEM7 HW_REGISTER_RW(ARM_SBM_OWN3+0x1C) ++#define ARM_3_BELL0 HW_REGISTER_RW(ARM_SBM_OWN3+0x40) ++#define ARM_3_BELL1 HW_REGISTER_RW(ARM_SBM_OWN3+0x44) ++#define ARM_3_BELL2 HW_REGISTER_RW(ARM_SBM_OWN3+0x48) ++#define ARM_3_BELL3 HW_REGISTER_RW(ARM_SBM_OWN3+0x4C) ++/* MAILBOX 0 access in Owner 3 area */ ++/* Owner 3 should only WRITE to this mailbox */ ++#define ARM_3_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN3+0x80) /* .. 0x8C (4 locations) */ ++/*#define ARM_3_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN3+0x80) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN3+0x90) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN3+0x94) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_3_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN3+0x98) /* Status read */ ++/*#define ARM_3_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN3+0x9C) */ /* DO NOT USE THIS !!!!! */ ++/* MAILBOX 1 access in Owner 3 area */ ++/* Owner 3 should only WRITE to this mailbox */ ++#define ARM_3_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) /* .. 0xAC (4 locations) */ ++/*#define ARM_3_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN3+0xB0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN3+0xB4) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_3_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN3+0xB8) /* Status read */ ++/*#define ARM_3_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN3+0xBC) */ /* DO NOT USE THIS !!!!! */ ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_3_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN3+0xE0) /* semaphore clear/debug register */ ++#define ARM_3_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN3+0xE4) /* Doorbells clear/debug register */ ++#define ARM_3_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN3+0xFC) /* IRQS pending for owner 3 */ ++#define ARM_3_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN3+0xF8) /* ALL interrupts */ ++ ++ ++ ++/* Mailbox flags. Valid for all owners */ ++ ++/* Mailbox status register (...0x98) */ ++#define ARM_MS_FULL 0x80000000 ++#define ARM_MS_EMPTY 0x40000000 ++#define ARM_MS_LEVEL 0x400000FF /* Max. value depdnds on mailbox depth parameter */ ++ ++/* MAILBOX config/status register (...0x9C) */ ++/* ANY write to this register clears the error bits! */ ++#define ARM_MC_IHAVEDATAIRQEN 0x00000001 /* mailbox irq enable: has data */ ++#define ARM_MC_IHAVESPACEIRQEN 0x00000002 /* mailbox irq enable: has space */ ++#define ARM_MC_OPPISEMPTYIRQEN 0x00000004 /* mailbox irq enable: Opp. is empty */ ++#define ARM_MC_MAIL_CLEAR 0x00000008 /* mailbox clear write 1, then 0 */ ++#define ARM_MC_IHAVEDATAIRQPEND 0x00000010 /* mailbox irq pending: has space */ ++#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mailbox irq pending: Opp. is empty */ ++#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mailbox irq pending */ ++/* Bit 7 is unused */ ++#define ARM_MC_ERRNOOWN 0x00000100 /* error : none owner read from mailbox */ ++#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */ ++#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */ ++ ++/* Semaphore clear/debug register (...0xE0) */ ++#define ARM_SD_OWN0 0x00000003 /* Owner of sem 0 */ ++#define ARM_SD_OWN1 0x0000000C /* Owner of sem 1 */ ++#define ARM_SD_OWN2 0x00000030 /* Owner of sem 2 */ ++#define ARM_SD_OWN3 0x000000C0 /* Owner of sem 3 */ ++#define ARM_SD_OWN4 0x00000300 /* Owner of sem 4 */ ++#define ARM_SD_OWN5 0x00000C00 /* Owner of sem 5 */ ++#define ARM_SD_OWN6 0x00003000 /* Owner of sem 6 */ ++#define ARM_SD_OWN7 0x0000C000 /* Owner of sem 7 */ ++#define ARM_SD_SEM0 0x00010000 /* Status of sem 0 */ ++#define ARM_SD_SEM1 0x00020000 /* Status of sem 1 */ ++#define ARM_SD_SEM2 0x00040000 /* Status of sem 2 */ ++#define ARM_SD_SEM3 0x00080000 /* Status of sem 3 */ ++#define ARM_SD_SEM4 0x00100000 /* Status of sem 4 */ ++#define ARM_SD_SEM5 0x00200000 /* Status of sem 5 */ ++#define ARM_SD_SEM6 0x00400000 /* Status of sem 6 */ ++#define ARM_SD_SEM7 0x00800000 /* Status of sem 7 */ ++ ++/* Doorbells clear/debug register (...0xE4) */ ++#define ARM_BD_OWN0 0x00000003 /* Owner of doorbell 0 */ ++#define ARM_BD_OWN1 0x0000000C /* Owner of doorbell 1 */ ++#define ARM_BD_OWN2 0x00000030 /* Owner of doorbell 2 */ ++#define ARM_BD_OWN3 0x000000C0 /* Owner of doorbell 3 */ ++#define ARM_BD_BELL0 0x00000100 /* Status of doorbell 0 */ ++#define ARM_BD_BELL1 0x00000200 /* Status of doorbell 1 */ ++#define ARM_BD_BELL2 0x00000400 /* Status of doorbell 2 */ ++#define ARM_BD_BELL3 0x00000800 /* Status of doorbell 3 */ ++ ++/* MY IRQS register (...0xF8) */ ++#define ARM_MYIRQ_BELL 0x00000001 /* This owner has a doorbell IRQ */ ++#define ARM_MYIRQ_MAIL 0x00000002 /* This owner has a mailbox IRQ */ ++ ++/* ALL IRQS register (...0xF8) */ ++#define ARM_AIS_BELL0 0x00000001 /* Doorbell 0 IRQ pending */ ++#define ARM_AIS_BELL1 0x00000002 /* Doorbell 1 IRQ pending */ ++#define ARM_AIS_BELL2 0x00000004 /* Doorbell 2 IRQ pending */ ++#define ARM_AIS_BELL3 0x00000008 /* Doorbell 3 IRQ pending */ ++#define ARM_AIS0_HAVEDATA 0x00000010 /* MAIL 0 has data IRQ pending */ ++#define ARM_AIS0_HAVESPAC 0x00000020 /* MAIL 0 has space IRQ pending */ ++#define ARM_AIS0_OPPEMPTY 0x00000040 /* MAIL 0 opposite is empty IRQ */ ++#define ARM_AIS1_HAVEDATA 0x00000080 /* MAIL 1 has data IRQ pending */ ++#define ARM_AIS1_HAVESPAC 0x00000100 /* MAIL 1 has space IRQ pending */ ++#define ARM_AIS1_OPPEMPTY 0x00000200 /* MAIL 1 opposite is empty IRQ */ ++/* Note that bell-0, bell-1 and MAIL0 IRQ go only to the ARM */ ++/* Whilst that bell-2, bell-3 and MAIL1 IRQ go only to the VC */ ++/* */ ++/* ARM JTAG BASH */ ++/* */ ++#define AJB_BASE 0x7e2000c0 ++ ++#define AJBCONF HW_REGISTER_RW(AJB_BASE+0x00) ++#define AJB_BITS0 0x000000 ++#define AJB_BITS4 0x000004 ++#define AJB_BITS8 0x000008 ++#define AJB_BITS12 0x00000C ++#define AJB_BITS16 0x000010 ++#define AJB_BITS20 0x000014 ++#define AJB_BITS24 0x000018 ++#define AJB_BITS28 0x00001C ++#define AJB_BITS32 0x000020 ++#define AJB_BITS34 0x000022 ++#define AJB_OUT_MS 0x000040 ++#define AJB_OUT_LS 0x000000 ++#define AJB_INV_CLK 0x000080 ++#define AJB_D0_RISE 0x000100 ++#define AJB_D0_FALL 0x000000 ++#define AJB_D1_RISE 0x000200 ++#define AJB_D1_FALL 0x000000 ++#define AJB_IN_RISE 0x000400 ++#define AJB_IN_FALL 0x000000 ++#define AJB_ENABLE 0x000800 ++#define AJB_HOLD0 0x000000 ++#define AJB_HOLD1 0x001000 ++#define AJB_HOLD2 0x002000 ++#define AJB_HOLD3 0x003000 ++#define AJB_RESETN 0x004000 ++#define AJB_CLKSHFT 16 ++#define AJB_BUSY 0x80000000 ++#define AJBTMS HW_REGISTER_RW(AJB_BASE+0x04) ++#define AJBTDI HW_REGISTER_RW(AJB_BASE+0x08) ++#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c) ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/arm_power.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/arm_power.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,60 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 _ARM_POWER_H ++#define _ARM_POWER_H ++ ++/* Use meaningful names on each side */ ++#ifdef __VIDEOCORE__ ++#define PREFIX(x) ARM_##x ++#else ++#define PREFIX(x) BCM_##x ++#endif ++ ++enum { ++ PREFIX(POWER_SDCARD_BIT), ++ PREFIX(POWER_UART_BIT), ++ PREFIX(POWER_MINIUART_BIT), ++ PREFIX(POWER_USB_BIT), ++ PREFIX(POWER_I2C0_BIT), ++ PREFIX(POWER_I2C1_BIT), ++ PREFIX(POWER_I2C2_BIT), ++ PREFIX(POWER_SPI_BIT), ++ PREFIX(POWER_CCP2TX_BIT), ++ ++ PREFIX(POWER_MAX) ++}; ++ ++enum { ++ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), ++ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), ++ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), ++ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), ++ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), ++ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), ++ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), ++ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), ++ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), ++ ++ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, ++ PREFIX(POWER_NONE) = 0 ++}; ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/clkdev.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/clkdev.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,7 @@ ++#ifndef __ASM_MACH_CLKDEV_H ++#define __ASM_MACH_CLKDEV_H ++ ++#define __clk_get(clk) ({ 1; }) ++#define __clk_put(clk) do { } while (0) ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/debug-macro.S +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/debug-macro.S 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,22 @@ ++/* arch/arm/mach-bcm2708/include/mach/debug-macro.S ++ * ++ * Debugging macro include header ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 1994-1999 Russell King ++ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++*/ ++ ++#include ++ ++ .macro addruart, rp, rv, tmp ++ ldr \rp, =UART0_BASE ++ ldr \rv, =IO_ADDRESS(UART0_BASE) ++ .endm ++ ++#include +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/dma.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/dma.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,86 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/include/mach/dma.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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. ++ */ ++ ++ ++#ifndef _MACH_BCM2708_DMA_H ++#define _MACH_BCM2708_DMA_H ++ ++#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" ++ ++/* DMA CS Control and Status bits */ ++#define BCM2708_DMA_ACTIVE (1 << 0) ++#define BCM2708_DMA_INT (1 << 2) ++#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ ++#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ ++#define BCM2708_DMA_ERR (1 << 8) ++#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ ++#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ ++ ++/* DMA control block "info" field bits */ ++#define BCM2708_DMA_INT_EN (1 << 0) ++#define BCM2708_DMA_TDMODE (1 << 1) ++#define BCM2708_DMA_WAIT_RESP (1 << 3) ++#define BCM2708_DMA_D_INC (1 << 4) ++#define BCM2708_DMA_D_WIDTH (1 << 5) ++#define BCM2708_DMA_D_DREQ (1 << 6) ++#define BCM2708_DMA_S_INC (1 << 8) ++#define BCM2708_DMA_S_WIDTH (1 << 9) ++#define BCM2708_DMA_S_DREQ (1 << 10) ++ ++#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) ++#define BCM2708_DMA_PER_MAP(x) ((x) << 16) ++#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) ++ ++#define BCM2708_DMA_DREQ_EMMC 11 ++#define BCM2708_DMA_DREQ_SDHOST 13 ++ ++#define BCM2708_DMA_CS 0x00 /* Control and Status */ ++#define BCM2708_DMA_ADDR 0x04 ++/* the current control block appears in the following registers - read only */ ++#define BCM2708_DMA_INFO 0x08 ++#define BCM2708_DMA_NEXTCB 0x1C ++#define BCM2708_DMA_DEBUG 0x20 ++ ++#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) ++#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) ++ ++#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) ++ ++struct bcm2708_dma_cb { ++ unsigned long info; ++ unsigned long src; ++ unsigned long dst; ++ unsigned long length; ++ unsigned long stride; ++ unsigned long next; ++ unsigned long pad[2]; ++}; ++ ++extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); ++extern void bcm_dma_start(void __iomem *dma_chan_base, ++ dma_addr_t control_block); ++extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); ++extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); ++ ++/* When listing features we can ask for when allocating DMA channels give ++ those with higher priority smaller ordinal numbers */ ++#define BCM_DMA_FEATURE_FAST_ORD 0 ++#define BCM_DMA_FEATURE_BULK_ORD 1 ++#define BCM_DMA_FEATURE_FAST (1< ++ ++ .macro disable_fiq ++ .endm ++ ++ .macro get_irqnr_preamble, base, tmp ++ ldr \base, =IO_ADDRESS(ARMCTRL_IC_BASE) ++ .endm ++ ++ .macro arch_ret_to_user, tmp1, tmp2 ++ .endm ++ ++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ++ /* get masked status */ ++ ldr \irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)] ++ mov \irqnr, #(ARM_IRQ0_BASE + 31) ++ and \tmp, \irqstat, #0x300 @ save bits 8 and 9 ++ /* clear bits 8 and 9, and test */ ++ bics \irqstat, \irqstat, #0x300 ++ bne 1010f ++ ++ tst \tmp, #0x100 ++ ldrne \irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)] ++ movne \irqnr, #(ARM_IRQ1_BASE + 31) ++ @ Mask out the interrupts also present in PEND0 - see SW-5809 ++ bicne \irqstat, #((1<<7) | (1<<9) | (1<<10)) ++ bicne \irqstat, #((1<<18) | (1<<19)) ++ bne 1010f ++ ++ tst \tmp, #0x200 ++ ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)] ++ movne \irqnr, #(ARM_IRQ2_BASE + 31) ++ @ Mask out the interrupts also present in PEND0 - see SW-5809 ++ bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25)) ++ bicne \irqstat, #((1<<30)) ++ beq 1020f ++ ++1010: ++ @ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1)) ++ @ N.B. CLZ is an ARM5 instruction. ++ sub \tmp, \irqstat, #1 ++ eor \irqstat, \irqstat, \tmp ++ clz \tmp, \irqstat ++ sub \irqnr, \tmp ++ ++1020: @ EQ will be set if no irqs pending ++ ++ .endm +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/frc.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/frc.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,38 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/timex.h ++ * ++ * BCM2708 free running counter (timer) ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 _MACH_FRC_H ++#define _MACH_FRC_H ++ ++#define FRC_TICK_RATE (1000000) ++ ++/*! Free running counter incrementing at the CLOCK_TICK_RATE ++ (slightly faster than frc_clock_ticks63() ++ */ ++extern unsigned long frc_clock_ticks32(void); ++ ++/*! Free running counter incrementing at the CLOCK_TICK_RATE ++ * Note - top bit should be ignored (see cnt32_to_63) ++ */ ++extern unsigned long long frc_clock_ticks63(void); ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/gpio.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/gpio.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,18 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/gpio.h ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#ifndef __ASM_ARCH_GPIO_H ++#define __ASM_ARCH_GPIO_H ++ ++#define ARCH_NR_GPIOS 54 // number of gpio lines ++ ++#define gpio_to_irq(x) ((x) + GPIO_IRQ_START) ++#define irq_to_gpio(x) ((x) - GPIO_IRQ_START) ++ ++#endif ++ +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/hardware.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/hardware.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,28 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/hardware.h ++ * ++ * This file contains the hardware definitions of the BCM2708 devices. ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 __ASM_ARCH_HARDWARE_H ++#define __ASM_ARCH_HARDWARE_H ++ ++#include ++#include ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/io.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/io.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,27 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/io.h ++ * ++ * Copyright (C) 2003 ARM Limited ++ * ++ * 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 __ASM_ARM_ARCH_IO_H ++#define __ASM_ARM_ARCH_IO_H ++ ++#define IO_SPACE_LIMIT 0xffffffff ++ ++#define __io(a) __typesafe_io(a) ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/irqs.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/irqs.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,196 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/irqs.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2003 ARM Limited ++ * Copyright (C) 2000 Deep Blue Solutions Ltd. ++ * ++ * 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 _BCM2708_IRQS_H_ ++#define _BCM2708_IRQS_H_ ++ ++#include ++ ++/* ++ * IRQ interrupts definitions are the same as the INT definitions ++ * held within platform.h ++ */ ++#define IRQ_ARMCTRL_START 0 ++#define IRQ_TIMER0 (IRQ_ARMCTRL_START + INTERRUPT_TIMER0) ++#define IRQ_TIMER1 (IRQ_ARMCTRL_START + INTERRUPT_TIMER1) ++#define IRQ_TIMER2 (IRQ_ARMCTRL_START + INTERRUPT_TIMER2) ++#define IRQ_TIMER3 (IRQ_ARMCTRL_START + INTERRUPT_TIMER3) ++#define IRQ_CODEC0 (IRQ_ARMCTRL_START + INTERRUPT_CODEC0) ++#define IRQ_CODEC1 (IRQ_ARMCTRL_START + INTERRUPT_CODEC1) ++#define IRQ_CODEC2 (IRQ_ARMCTRL_START + INTERRUPT_CODEC2) ++#define IRQ_JPEG (IRQ_ARMCTRL_START + INTERRUPT_JPEG) ++#define IRQ_ISP (IRQ_ARMCTRL_START + INTERRUPT_ISP) ++#define IRQ_USB (IRQ_ARMCTRL_START + INTERRUPT_USB) ++#define IRQ_3D (IRQ_ARMCTRL_START + INTERRUPT_3D) ++#define IRQ_TRANSPOSER (IRQ_ARMCTRL_START + INTERRUPT_TRANSPOSER) ++#define IRQ_MULTICORESYNC0 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC0) ++#define IRQ_MULTICORESYNC1 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC1) ++#define IRQ_MULTICORESYNC2 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC2) ++#define IRQ_MULTICORESYNC3 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC3) ++#define IRQ_DMA0 (IRQ_ARMCTRL_START + INTERRUPT_DMA0) ++#define IRQ_DMA1 (IRQ_ARMCTRL_START + INTERRUPT_DMA1) ++#define IRQ_DMA2 (IRQ_ARMCTRL_START + INTERRUPT_DMA2) ++#define IRQ_DMA3 (IRQ_ARMCTRL_START + INTERRUPT_DMA3) ++#define IRQ_DMA4 (IRQ_ARMCTRL_START + INTERRUPT_DMA4) ++#define IRQ_DMA5 (IRQ_ARMCTRL_START + INTERRUPT_DMA5) ++#define IRQ_DMA6 (IRQ_ARMCTRL_START + INTERRUPT_DMA6) ++#define IRQ_DMA7 (IRQ_ARMCTRL_START + INTERRUPT_DMA7) ++#define IRQ_DMA8 (IRQ_ARMCTRL_START + INTERRUPT_DMA8) ++#define IRQ_DMA9 (IRQ_ARMCTRL_START + INTERRUPT_DMA9) ++#define IRQ_DMA10 (IRQ_ARMCTRL_START + INTERRUPT_DMA10) ++#define IRQ_DMA11 (IRQ_ARMCTRL_START + INTERRUPT_DMA11) ++#define IRQ_DMA12 (IRQ_ARMCTRL_START + INTERRUPT_DMA12) ++#define IRQ_AUX (IRQ_ARMCTRL_START + INTERRUPT_AUX) ++#define IRQ_ARM (IRQ_ARMCTRL_START + INTERRUPT_ARM) ++#define IRQ_VPUDMA (IRQ_ARMCTRL_START + INTERRUPT_VPUDMA) ++#define IRQ_HOSTPORT (IRQ_ARMCTRL_START + INTERRUPT_HOSTPORT) ++#define IRQ_VIDEOSCALER (IRQ_ARMCTRL_START + INTERRUPT_VIDEOSCALER) ++#define IRQ_CCP2TX (IRQ_ARMCTRL_START + INTERRUPT_CCP2TX) ++#define IRQ_SDC (IRQ_ARMCTRL_START + INTERRUPT_SDC) ++#define IRQ_DSI0 (IRQ_ARMCTRL_START + INTERRUPT_DSI0) ++#define IRQ_AVE (IRQ_ARMCTRL_START + INTERRUPT_AVE) ++#define IRQ_CAM0 (IRQ_ARMCTRL_START + INTERRUPT_CAM0) ++#define IRQ_CAM1 (IRQ_ARMCTRL_START + INTERRUPT_CAM1) ++#define IRQ_HDMI0 (IRQ_ARMCTRL_START + INTERRUPT_HDMI0) ++#define IRQ_HDMI1 (IRQ_ARMCTRL_START + INTERRUPT_HDMI1) ++#define IRQ_PIXELVALVE1 (IRQ_ARMCTRL_START + INTERRUPT_PIXELVALVE1) ++#define IRQ_I2CSPISLV (IRQ_ARMCTRL_START + INTERRUPT_I2CSPISLV) ++#define IRQ_DSI1 (IRQ_ARMCTRL_START + INTERRUPT_DSI1) ++#define IRQ_PWA0 (IRQ_ARMCTRL_START + INTERRUPT_PWA0) ++#define IRQ_PWA1 (IRQ_ARMCTRL_START + INTERRUPT_PWA1) ++#define IRQ_CPR (IRQ_ARMCTRL_START + INTERRUPT_CPR) ++#define IRQ_SMI (IRQ_ARMCTRL_START + INTERRUPT_SMI) ++#define IRQ_GPIO0 (IRQ_ARMCTRL_START + INTERRUPT_GPIO0) ++#define IRQ_GPIO1 (IRQ_ARMCTRL_START + INTERRUPT_GPIO1) ++#define IRQ_GPIO2 (IRQ_ARMCTRL_START + INTERRUPT_GPIO2) ++#define IRQ_GPIO3 (IRQ_ARMCTRL_START + INTERRUPT_GPIO3) ++#define IRQ_I2C (IRQ_ARMCTRL_START + INTERRUPT_I2C) ++#define IRQ_SPI (IRQ_ARMCTRL_START + INTERRUPT_SPI) ++#define IRQ_I2SPCM (IRQ_ARMCTRL_START + INTERRUPT_I2SPCM) ++#define IRQ_SDIO (IRQ_ARMCTRL_START + INTERRUPT_SDIO) ++#define IRQ_UART (IRQ_ARMCTRL_START + INTERRUPT_UART) ++#define IRQ_SLIMBUS (IRQ_ARMCTRL_START + INTERRUPT_SLIMBUS) ++#define IRQ_VEC (IRQ_ARMCTRL_START + INTERRUPT_VEC) ++#define IRQ_CPG (IRQ_ARMCTRL_START + INTERRUPT_CPG) ++#define IRQ_RNG (IRQ_ARMCTRL_START + INTERRUPT_RNG) ++#define IRQ_ARASANSDIO (IRQ_ARMCTRL_START + INTERRUPT_ARASANSDIO) ++#define IRQ_AVSPMON (IRQ_ARMCTRL_START + INTERRUPT_AVSPMON) ++ ++#define IRQ_ARM_TIMER (IRQ_ARMCTRL_START + INTERRUPT_ARM_TIMER) ++#define IRQ_ARM_MAILBOX (IRQ_ARMCTRL_START + INTERRUPT_ARM_MAILBOX) ++#define IRQ_ARM_DOORBELL_0 (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_0) ++#define IRQ_ARM_DOORBELL_1 (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_1) ++#define IRQ_VPU0_HALTED (IRQ_ARMCTRL_START + INTERRUPT_VPU0_HALTED) ++#define IRQ_VPU1_HALTED (IRQ_ARMCTRL_START + INTERRUPT_VPU1_HALTED) ++#define IRQ_ILLEGAL_TYPE0 (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE0) ++#define IRQ_ILLEGAL_TYPE1 (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE1) ++#define IRQ_PENDING1 (IRQ_ARMCTRL_START + INTERRUPT_PENDING1) ++#define IRQ_PENDING2 (IRQ_ARMCTRL_START + INTERRUPT_PENDING2) ++ ++/* ++ * FIQ interrupts definitions are the same as the INT definitions. ++ */ ++#define FIQ_TIMER0 INT_TIMER0 ++#define FIQ_TIMER1 INT_TIMER1 ++#define FIQ_TIMER2 INT_TIMER2 ++#define FIQ_TIMER3 INT_TIMER3 ++#define FIQ_CODEC0 INT_CODEC0 ++#define FIQ_CODEC1 INT_CODEC1 ++#define FIQ_CODEC2 INT_CODEC2 ++#define FIQ_JPEG INT_JPEG ++#define FIQ_ISP INT_ISP ++#define FIQ_USB INT_USB ++#define FIQ_3D INT_3D ++#define FIQ_TRANSPOSER INT_TRANSPOSER ++#define FIQ_MULTICORESYNC0 INT_MULTICORESYNC0 ++#define FIQ_MULTICORESYNC1 INT_MULTICORESYNC1 ++#define FIQ_MULTICORESYNC2 INT_MULTICORESYNC2 ++#define FIQ_MULTICORESYNC3 INT_MULTICORESYNC3 ++#define FIQ_DMA0 INT_DMA0 ++#define FIQ_DMA1 INT_DMA1 ++#define FIQ_DMA2 INT_DMA2 ++#define FIQ_DMA3 INT_DMA3 ++#define FIQ_DMA4 INT_DMA4 ++#define FIQ_DMA5 INT_DMA5 ++#define FIQ_DMA6 INT_DMA6 ++#define FIQ_DMA7 INT_DMA7 ++#define FIQ_DMA8 INT_DMA8 ++#define FIQ_DMA9 INT_DMA9 ++#define FIQ_DMA10 INT_DMA10 ++#define FIQ_DMA11 INT_DMA11 ++#define FIQ_DMA12 INT_DMA12 ++#define FIQ_AUX INT_AUX ++#define FIQ_ARM INT_ARM ++#define FIQ_VPUDMA INT_VPUDMA ++#define FIQ_HOSTPORT INT_HOSTPORT ++#define FIQ_VIDEOSCALER INT_VIDEOSCALER ++#define FIQ_CCP2TX INT_CCP2TX ++#define FIQ_SDC INT_SDC ++#define FIQ_DSI0 INT_DSI0 ++#define FIQ_AVE INT_AVE ++#define FIQ_CAM0 INT_CAM0 ++#define FIQ_CAM1 INT_CAM1 ++#define FIQ_HDMI0 INT_HDMI0 ++#define FIQ_HDMI1 INT_HDMI1 ++#define FIQ_PIXELVALVE1 INT_PIXELVALVE1 ++#define FIQ_I2CSPISLV INT_I2CSPISLV ++#define FIQ_DSI1 INT_DSI1 ++#define FIQ_PWA0 INT_PWA0 ++#define FIQ_PWA1 INT_PWA1 ++#define FIQ_CPR INT_CPR ++#define FIQ_SMI INT_SMI ++#define FIQ_GPIO0 INT_GPIO0 ++#define FIQ_GPIO1 INT_GPIO1 ++#define FIQ_GPIO2 INT_GPIO2 ++#define FIQ_GPIO3 INT_GPIO3 ++#define FIQ_I2C INT_I2C ++#define FIQ_SPI INT_SPI ++#define FIQ_I2SPCM INT_I2SPCM ++#define FIQ_SDIO INT_SDIO ++#define FIQ_UART INT_UART ++#define FIQ_SLIMBUS INT_SLIMBUS ++#define FIQ_VEC INT_VEC ++#define FIQ_CPG INT_CPG ++#define FIQ_RNG INT_RNG ++#define FIQ_ARASANSDIO INT_ARASANSDIO ++#define FIQ_AVSPMON INT_AVSPMON ++ ++#define FIQ_ARM_TIMER INT_ARM_TIMER ++#define FIQ_ARM_MAILBOX INT_ARM_MAILBOX ++#define FIQ_ARM_DOORBELL_0 INT_ARM_DOORBELL_0 ++#define FIQ_ARM_DOORBELL_1 INT_ARM_DOORBELL_1 ++#define FIQ_VPU0_HALTED INT_VPU0_HALTED ++#define FIQ_VPU1_HALTED INT_VPU1_HALTED ++#define FIQ_ILLEGAL_TYPE0 INT_ILLEGAL_TYPE0 ++#define FIQ_ILLEGAL_TYPE1 INT_ILLEGAL_TYPE1 ++#define FIQ_PENDING1 INT_PENDING1 ++#define FIQ_PENDING2 INT_PENDING2 ++ ++#define HARD_IRQS (64 + 21) ++#define GPIO_IRQ_START HARD_IRQS ++ ++#define GPIO_IRQS 32*5 ++ ++#define NR_IRQS HARD_IRQS+GPIO_IRQS ++ ++ ++#endif /* _BCM2708_IRQS_H_ */ +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/memory.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/memory.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,57 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/memory.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 __ASM_ARCH_MEMORY_H ++#define __ASM_ARCH_MEMORY_H ++ ++/* Memory overview: ++ ++ [ARMcore] <--virtual addr--> ++ [ARMmmu] <--physical addr--> ++ [GERTmap] <--bus add--> ++ [VCperiph] ++ ++*/ ++ ++/* ++ * Physical DRAM offset. ++ */ ++#define PLAT_PHYS_OFFSET UL(0x00000000) ++#define VC_ARMMEM_OFFSET UL(0x00000000) /* offset in VC of ARM memory */ ++ ++#ifdef CONFIG_BCM2708_NOL2CACHE ++ #define _REAL_BUS_OFFSET UL(0xC0000000) /* don't use L1 or L2 caches */ ++#else ++ #define _REAL_BUS_OFFSET UL(0x40000000) /* use L2 cache */ ++#endif ++ ++/* We're using the memory at 64M in the VideoCore for Linux - this adjustment ++ * will provide the offset into this area as well as setting the bits that ++ * stop the L1 and L2 cache from being used ++ * ++ * WARNING: this only works because the ARM is given memory at a fixed location ++ * (ARMMEM_OFFSET) ++ */ ++#define BUS_OFFSET (VC_ARMMEM_OFFSET + _REAL_BUS_OFFSET) ++#define __virt_to_bus(x) ((x) + (BUS_OFFSET - PAGE_OFFSET)) ++#define __bus_to_virt(x) ((x) - (BUS_OFFSET - PAGE_OFFSET)) ++#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PLAT_PHYS_OFFSET)) ++#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PLAT_PHYS_OFFSET)) ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/platform.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/platform.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,220 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/platform.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 _BCM2708_PLATFORM_H ++#define _BCM2708_PLATFORM_H ++ ++ ++/* macros to get at IO space when running virtually */ ++#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) ++ ++#define __io_address(n) IOMEM(IO_ADDRESS(n)) ++ ++ ++/* ++ * SDRAM ++ */ ++#define BCM2708_SDRAM_BASE 0x00000000 ++ ++/* ++ * Logic expansion modules ++ * ++ */ ++ ++ ++/* ------------------------------------------------------------------------ ++ * BCM2708 ARMCTRL Registers ++ * ------------------------------------------------------------------------ ++ */ ++ ++#define HW_REGISTER_RW(addr) (addr) ++#define HW_REGISTER_RO(addr) (addr) ++ ++#include "arm_control.h" ++#undef ARM_BASE ++ ++/* ++ * Definitions and addresses for the ARM CONTROL logic ++ * This file is manually generated. ++ */ ++ ++#define BCM2708_PERI_BASE 0x20000000 ++#define ST_BASE (BCM2708_PERI_BASE + 0x3000) /* System Timer */ ++#define DMA_BASE (BCM2708_PERI_BASE + 0x7000) /* DMA controller */ ++#define ARM_BASE (BCM2708_PERI_BASE + 0xB000) /* BCM2708 ARM control block */ ++#define PM_BASE (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */ ++#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO */ ++#define UART0_BASE (BCM2708_PERI_BASE + 0x201000) /* Uart 0 */ ++#define MMCI0_BASE (BCM2708_PERI_BASE + 0x202000) /* MMC interface */ ++#define UART1_BASE (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */ ++#define EMMC_BASE (BCM2708_PERI_BASE + 0x300000) /* eMMC interface */ ++#define SMI_BASE (BCM2708_PERI_BASE + 0x600000) /* SMI */ ++#define USB_BASE (BCM2708_PERI_BASE + 0x980000) /* DTC_OTG USB controller */ ++#define MCORE_BASE (BCM2708_PERI_BASE + 0x0000) /* Fake frame buffer device (actually the multicore sync block*/ ++ ++#define ARMCTRL_BASE (ARM_BASE + 0x000) ++#define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ ++#define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ ++#define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ ++ ++ ++/* ++ * Interrupt assignments ++ */ ++ ++#define ARM_IRQ1_BASE 0 ++#define INTERRUPT_TIMER0 (ARM_IRQ1_BASE + 0) ++#define INTERRUPT_TIMER1 (ARM_IRQ1_BASE + 1) ++#define INTERRUPT_TIMER2 (ARM_IRQ1_BASE + 2) ++#define INTERRUPT_TIMER3 (ARM_IRQ1_BASE + 3) ++#define INTERRUPT_CODEC0 (ARM_IRQ1_BASE + 4) ++#define INTERRUPT_CODEC1 (ARM_IRQ1_BASE + 5) ++#define INTERRUPT_CODEC2 (ARM_IRQ1_BASE + 6) ++#define INTERRUPT_VC_JPEG (ARM_IRQ1_BASE + 7) ++#define INTERRUPT_ISP (ARM_IRQ1_BASE + 8) ++#define INTERRUPT_VC_USB (ARM_IRQ1_BASE + 9) ++#define INTERRUPT_VC_3D (ARM_IRQ1_BASE + 10) ++#define INTERRUPT_TRANSPOSER (ARM_IRQ1_BASE + 11) ++#define INTERRUPT_MULTICORESYNC0 (ARM_IRQ1_BASE + 12) ++#define INTERRUPT_MULTICORESYNC1 (ARM_IRQ1_BASE + 13) ++#define INTERRUPT_MULTICORESYNC2 (ARM_IRQ1_BASE + 14) ++#define INTERRUPT_MULTICORESYNC3 (ARM_IRQ1_BASE + 15) ++#define INTERRUPT_DMA0 (ARM_IRQ1_BASE + 16) ++#define INTERRUPT_DMA1 (ARM_IRQ1_BASE + 17) ++#define INTERRUPT_VC_DMA2 (ARM_IRQ1_BASE + 18) ++#define INTERRUPT_VC_DMA3 (ARM_IRQ1_BASE + 19) ++#define INTERRUPT_DMA4 (ARM_IRQ1_BASE + 20) ++#define INTERRUPT_DMA5 (ARM_IRQ1_BASE + 21) ++#define INTERRUPT_DMA6 (ARM_IRQ1_BASE + 22) ++#define INTERRUPT_DMA7 (ARM_IRQ1_BASE + 23) ++#define INTERRUPT_DMA8 (ARM_IRQ1_BASE + 24) ++#define INTERRUPT_DMA9 (ARM_IRQ1_BASE + 25) ++#define INTERRUPT_DMA10 (ARM_IRQ1_BASE + 26) ++#define INTERRUPT_DMA11 (ARM_IRQ1_BASE + 27) ++#define INTERRUPT_DMA12 (ARM_IRQ1_BASE + 28) ++#define INTERRUPT_AUX (ARM_IRQ1_BASE + 29) ++#define INTERRUPT_ARM (ARM_IRQ1_BASE + 30) ++#define INTERRUPT_VPUDMA (ARM_IRQ1_BASE + 31) ++ ++#define ARM_IRQ2_BASE 32 ++#define INTERRUPT_HOSTPORT (ARM_IRQ2_BASE + 0) ++#define INTERRUPT_VIDEOSCALER (ARM_IRQ2_BASE + 1) ++#define INTERRUPT_CCP2TX (ARM_IRQ2_BASE + 2) ++#define INTERRUPT_SDC (ARM_IRQ2_BASE + 3) ++#define INTERRUPT_DSI0 (ARM_IRQ2_BASE + 4) ++#define INTERRUPT_AVE (ARM_IRQ2_BASE + 5) ++#define INTERRUPT_CAM0 (ARM_IRQ2_BASE + 6) ++#define INTERRUPT_CAM1 (ARM_IRQ2_BASE + 7) ++#define INTERRUPT_HDMI0 (ARM_IRQ2_BASE + 8) ++#define INTERRUPT_HDMI1 (ARM_IRQ2_BASE + 9) ++#define INTERRUPT_PIXELVALVE1 (ARM_IRQ2_BASE + 10) ++#define INTERRUPT_I2CSPISLV (ARM_IRQ2_BASE + 11) ++#define INTERRUPT_DSI1 (ARM_IRQ2_BASE + 12) ++#define INTERRUPT_PWA0 (ARM_IRQ2_BASE + 13) ++#define INTERRUPT_PWA1 (ARM_IRQ2_BASE + 14) ++#define INTERRUPT_CPR (ARM_IRQ2_BASE + 15) ++#define INTERRUPT_SMI (ARM_IRQ2_BASE + 16) ++#define INTERRUPT_GPIO0 (ARM_IRQ2_BASE + 17) ++#define INTERRUPT_GPIO1 (ARM_IRQ2_BASE + 18) ++#define INTERRUPT_GPIO2 (ARM_IRQ2_BASE + 19) ++#define INTERRUPT_GPIO3 (ARM_IRQ2_BASE + 20) ++#define INTERRUPT_VC_I2C (ARM_IRQ2_BASE + 21) ++#define INTERRUPT_VC_SPI (ARM_IRQ2_BASE + 22) ++#define INTERRUPT_VC_I2SPCM (ARM_IRQ2_BASE + 23) ++#define INTERRUPT_VC_SDIO (ARM_IRQ2_BASE + 24) ++#define INTERRUPT_VC_UART (ARM_IRQ2_BASE + 25) ++#define INTERRUPT_SLIMBUS (ARM_IRQ2_BASE + 26) ++#define INTERRUPT_VEC (ARM_IRQ2_BASE + 27) ++#define INTERRUPT_CPG (ARM_IRQ2_BASE + 28) ++#define INTERRUPT_RNG (ARM_IRQ2_BASE + 29) ++#define INTERRUPT_VC_ARASANSDIO (ARM_IRQ2_BASE + 30) ++#define INTERRUPT_AVSPMON (ARM_IRQ2_BASE + 31) ++ ++#define ARM_IRQ0_BASE 64 ++#define INTERRUPT_ARM_TIMER (ARM_IRQ0_BASE + 0) ++#define INTERRUPT_ARM_MAILBOX (ARM_IRQ0_BASE + 1) ++#define INTERRUPT_ARM_DOORBELL_0 (ARM_IRQ0_BASE + 2) ++#define INTERRUPT_ARM_DOORBELL_1 (ARM_IRQ0_BASE + 3) ++#define INTERRUPT_VPU0_HALTED (ARM_IRQ0_BASE + 4) ++#define INTERRUPT_VPU1_HALTED (ARM_IRQ0_BASE + 5) ++#define INTERRUPT_ILLEGAL_TYPE0 (ARM_IRQ0_BASE + 6) ++#define INTERRUPT_ILLEGAL_TYPE1 (ARM_IRQ0_BASE + 7) ++#define INTERRUPT_PENDING1 (ARM_IRQ0_BASE + 8) ++#define INTERRUPT_PENDING2 (ARM_IRQ0_BASE + 9) ++#define INTERRUPT_JPEG (ARM_IRQ0_BASE + 10) ++#define INTERRUPT_USB (ARM_IRQ0_BASE + 11) ++#define INTERRUPT_3D (ARM_IRQ0_BASE + 12) ++#define INTERRUPT_DMA2 (ARM_IRQ0_BASE + 13) ++#define INTERRUPT_DMA3 (ARM_IRQ0_BASE + 14) ++#define INTERRUPT_I2C (ARM_IRQ0_BASE + 15) ++#define INTERRUPT_SPI (ARM_IRQ0_BASE + 16) ++#define INTERRUPT_I2SPCM (ARM_IRQ0_BASE + 17) ++#define INTERRUPT_SDIO (ARM_IRQ0_BASE + 18) ++#define INTERRUPT_UART (ARM_IRQ0_BASE + 19) ++#define INTERRUPT_ARASANSDIO (ARM_IRQ0_BASE + 20) ++ ++#define MAXIRQNUM (32 + 32 + 20) ++#define MAXFIQNUM (32 + 32 + 20) ++ ++#define MAX_TIMER 2 ++#define MAX_PERIOD 699050 ++#define TICKS_PER_uSEC 1 ++ ++/* ++ * These are useconds NOT ticks. ++ * ++ */ ++#define mSEC_1 1000 ++#define mSEC_5 (mSEC_1 * 5) ++#define mSEC_10 (mSEC_1 * 10) ++#define mSEC_25 (mSEC_1 * 25) ++#define SEC_1 (mSEC_1 * 1000) ++ ++/* ++ * Watchdog ++ */ ++#define PM_RSTC (PM_BASE+0x1c) ++#define PM_RSTS (PM_BASE+0x20) ++#define PM_WDOG (PM_BASE+0x24) ++ ++#define PM_WDOG_RESET 0000000000 ++#define PM_PASSWORD 0x5a000000 ++#define PM_WDOG_TIME_SET 0x000fffff ++#define PM_RSTC_WRCFG_CLR 0xffffffcf ++#define PM_RSTC_WRCFG_SET 0x00000030 ++#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 ++#define PM_RSTC_RESET 0x00000102 ++ ++#define PM_RSTS_HADPOR_SET 0x00001000 ++#define PM_RSTS_HADSRH_SET 0x00000400 ++#define PM_RSTS_HADSRF_SET 0x00000200 ++#define PM_RSTS_HADSRQ_SET 0x00000100 ++#define PM_RSTS_HADWRH_SET 0x00000040 ++#define PM_RSTS_HADWRF_SET 0x00000020 ++#define PM_RSTS_HADWRQ_SET 0x00000010 ++#define PM_RSTS_HADDRH_SET 0x00000004 ++#define PM_RSTS_HADDRF_SET 0x00000002 ++#define PM_RSTS_HADDRQ_SET 0x00000001 ++ ++#define UART0_CLOCK 3000000 ++ ++#endif ++ ++/* END */ +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/power.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/power.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,26 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/power.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#ifndef _MACH_BCM2708_POWER_H ++#define _MACH_BCM2708_POWER_H ++ ++#include ++#include ++ ++typedef unsigned int BCM_POWER_HANDLE_T; ++ ++extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); ++extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); ++extern int bcm_power_close(BCM_POWER_HANDLE_T handle); ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/system.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/system.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,38 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/system.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2003 ARM Limited ++ * Copyright (C) 2000 Deep Blue Solutions Ltd ++ * ++ * 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 __ASM_ARCH_SYSTEM_H ++#define __ASM_ARCH_SYSTEM_H ++ ++#include ++#include ++#include ++ ++static inline void arch_idle(void) ++{ ++ /* ++ * This should do all the clock switching ++ * and wait for interrupt tricks ++ */ ++ cpu_do_idle(); ++} ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/timex.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/timex.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,23 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/timex.h ++ * ++ * BCM2708 sysem clock frequency ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 ++ */ ++ ++#define CLOCK_TICK_RATE (1000000) +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/uncompress.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/uncompress.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,85 @@ ++/* ++ * arch/arm/mach-bcn2708/include/mach/uncompress.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2003 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++ ++#define UART_BAUD 115200 ++ ++#define BCM2708_UART_DR __io(UART0_BASE + UART01x_DR) ++#define BCM2708_UART_FR __io(UART0_BASE + UART01x_FR) ++#define BCM2708_UART_IBRD __io(UART0_BASE + UART011_IBRD) ++#define BCM2708_UART_FBRD __io(UART0_BASE + UART011_FBRD) ++#define BCM2708_UART_LCRH __io(UART0_BASE + UART011_LCRH) ++#define BCM2708_UART_CR __io(UART0_BASE + UART011_CR) ++ ++/* ++ * This does not append a newline ++ */ ++static inline void putc(int c) ++{ ++ while (__raw_readl(BCM2708_UART_FR) & UART01x_FR_TXFF) ++ barrier(); ++ ++ __raw_writel(c, BCM2708_UART_DR); ++} ++ ++static inline void flush(void) ++{ ++ int fr; ++ ++ do { ++ fr = __raw_readl(BCM2708_UART_FR); ++ barrier(); ++ } while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE); ++} ++ ++static inline void arch_decomp_setup(void) ++{ ++ int temp, div, rem, frac; ++ ++ temp = 16 * UART_BAUD; ++ div = UART0_CLOCK / temp; ++ rem = UART0_CLOCK % temp; ++ temp = (8 * rem) / UART_BAUD; ++ frac = (temp >> 1) + (temp & 1); ++ ++ /* Make sure the UART is disabled before we start */ ++ __raw_writel(0, BCM2708_UART_CR); ++ ++ /* Set the baud rate */ ++ __raw_writel(div, BCM2708_UART_IBRD); ++ __raw_writel(frac, BCM2708_UART_FBRD); ++ ++ /* Set the UART to 8n1, FIFO enabled */ ++ __raw_writel(UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN, BCM2708_UART_LCRH); ++ ++ /* Enable the UART */ ++ __raw_writel(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE, ++ BCM2708_UART_CR); ++} ++ ++/* ++ * nothing to do ++ */ ++#define arch_decomp_wdog() ++ +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/vc_mem.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/vc_mem.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,36 @@ ++/***************************************************************************** ++* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#if !defined( VC_MEM_H ) ++#define VC_MEM_H ++ ++#include ++ ++#define VC_MEM_IOC_MAGIC 'v' ++ ++#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long ) ++#define VC_MEM_IOC_MEM_SIZE _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int ) ++#define VC_MEM_IOC_MEM_BASE _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int ) ++#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) ++ ++#if defined( __KERNEL__ ) ++#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF ++ ++extern unsigned long mm_vc_mem_phys_addr; ++extern unsigned int mm_vc_mem_size; ++extern int vc_mem_get_current_size( void ); ++#endif ++ ++#endif /* VC_MEM_H */ ++ +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/vcio.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/vcio.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,141 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/vcio.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 _MACH_BCM2708_VCIO_H ++#define _MACH_BCM2708_VCIO_H ++ ++/* Routines to handle I/O via the VideoCore "ARM control" registers ++ * (semaphores, doorbells, mailboxes) ++ */ ++ ++#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" ++ ++/* Constants shared with the ARM identifying separate mailbox channels */ ++#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ ++#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ ++#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ ++#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ ++#define MBOX_CHAN_COUNT 9 ++ ++/* Mailbox property tags */ ++enum { ++ VCMSG_PROPERTY_END = 0x00000000, ++ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, ++ VCMSG_GET_BOARD_MODEL = 0x00010001, ++ VCMSG_GET_BOARD_REVISION = 0x00020002, ++ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00020003, ++ VCMSG_GET_BOARD_SERIAL = 0x00020004, ++ VCMSG_GET_ARM_MEMORY = 0x00020005, ++ VCMSG_GET_VC_MEMORY = 0x00020006, ++ VCMSG_GET_CLOCKS = 0x00020007, ++ VCMSG_GET_COMMAND_LINE = 0x00050001, ++ VCMSG_GET_DMA_CHANNELS = 0x00060001, ++ VCMSG_GET_POWER_STATE = 0x00020001, ++ VCMSG_GET_TIMING = 0x00020002, ++ VCMSG_SET_POWER_STATE = 0x00028001, ++ VCMSG_GET_CLOCK_STATE = 0x00030001, ++ VCMSG_SET_CLOCK_STATE = 0x00038001, ++ VCMSG_GET_CLOCK_RATE = 0x00030002, ++ VCMSG_SET_CLOCK_RATE = 0x00038002, ++ VCMSG_GET_VOLTAGE = 0x00030003, ++ VCMSG_SET_VOLTAGE = 0x00038003, ++ VCMSG_GET_MAX_CLOCK = 0x00030004, ++ VCMSG_GET_MAX_VOLTAGE = 0x00030005, ++ VCMSG_GET_TEMPERATURE = 0x00030006, ++ VCMSG_GET_MIN_CLOCK = 0x00030007, ++ VCMSG_GET_MIN_VOLTAGE = 0x00030008, ++ VCMSG_GET_TURBO = 0x00030009, ++ VCMSG_SET_TURBO = 0x00038009, ++ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, ++ VCMSG_SET_RELEASE_BUFFER = 0x00048001, ++ VCMSG_SET_BLANK_SCREEN = 0x00040002, ++ VCMSG_TST_BLANK_SCREEN = 0x00044002, ++ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, ++ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, ++ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, ++ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, ++ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, ++ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, ++ VCMSG_GET_DEPTH = 0x00040005, ++ VCMSG_TST_DEPTH = 0x00044005, ++ VCMSG_SET_DEPTH = 0x00048005, ++ VCMSG_GET_PIXEL_ORDER = 0x00040006, ++ VCMSG_TST_PIXEL_ORDER = 0x00044006, ++ VCMSG_SET_PIXEL_ORDER = 0x00048006, ++ VCMSG_GET_ALPHA_MODE = 0x00040007, ++ VCMSG_TST_ALPHA_MODE = 0x00044007, ++ VCMSG_SET_ALPHA_MODE = 0x00048007, ++ VCMSG_GET_PITCH = 0x00040008, ++ VCMSG_TST_PITCH = 0x00044008, ++ VCMSG_SET_PITCH = 0x00048008, ++ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, ++ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, ++ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, ++ VCMSG_GET_OVERSCAN = 0x0004000a, ++ VCMSG_TST_OVERSCAN = 0x0004400a, ++ VCMSG_SET_OVERSCAN = 0x0004800a, ++ VCMSG_GET_PALETTE = 0x0004000b, ++ VCMSG_TST_PALETTE = 0x0004400b, ++ VCMSG_SET_PALETTE = 0x0004800b, ++ VCMSG_GET_LAYER = 0x0004000c, ++ VCMSG_TST_LAYER = 0x0004400c, ++ VCMSG_SET_LAYER = 0x0004800c, ++ VCMSG_GET_TRANSFORM = 0x0004000d, ++ VCMSG_TST_TRANSFORM = 0x0004400d, ++ VCMSG_SET_TRANSFORM = 0x0004800d, ++}; ++ ++extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); ++extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); ++extern int /*rc*/ bcm_mailbox_property(void *data, int size); ++ ++#include ++ ++/* ++ * The major device number. We can't rely on dynamic ++ * registration any more, because ioctls need to know ++ * it. ++ */ ++#define MAJOR_NUM 100 ++ ++/* ++ * Set the message of the device driver ++ */ ++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) ++/* ++ * _IOWR means that we're creating an ioctl command ++ * number for passing information from a user process ++ * to the kernel module and from the kernel module to user process ++ * ++ * The first arguments, MAJOR_NUM, is the major device ++ * number we're using. ++ * ++ * The second argument is the number of the command ++ * (there could be several with different meanings). ++ * ++ * The third argument is the type we want to get from ++ * the process to the kernel. ++ */ ++ ++/* ++ * The name of the device file ++ */ ++#define DEVICE_FILE_NAME "char_dev" ++ ++#endif +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/vmalloc.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/include/mach/vmalloc.h 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,20 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/vmalloc.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 ++ */ ++#define VMALLOC_END (0xe8000000) +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/power.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/power.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,194 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/power.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "bcm2708_power" ++ ++#define BCM_POWER_MAXCLIENTS 4 ++#define BCM_POWER_NOCLIENT (1<<31) ++ ++/* Some drivers expect there devices to be permanently powered */ ++#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) ++ ++#if 1 ++#define DPRINTK printk ++#else ++#define DPRINTK if (0) printk ++#endif ++ ++struct state_struct { ++ uint32_t global_request; ++ uint32_t client_request[BCM_POWER_MAXCLIENTS]; ++ struct semaphore client_mutex; ++ struct semaphore mutex; ++} g_state; ++ ++int bcm_power_open(BCM_POWER_HANDLE_T *handle) ++{ ++ BCM_POWER_HANDLE_T i; ++ int ret = -EBUSY; ++ ++ down(&g_state.client_mutex); ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { ++ g_state.client_request[i] = BCM_POWER_NONE; ++ *handle = i; ++ ret = 0; ++ break; ++ } ++ } ++ ++ up(&g_state.client_mutex); ++ ++ DPRINTK("bcm_power_open() -> %d\n", *handle); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(bcm_power_open); ++ ++int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) ++{ ++ int rc = 0; ++ ++ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); ++ ++ if ((handle < BCM_POWER_MAXCLIENTS) && ++ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { ++ if (down_interruptible(&g_state.mutex) != 0) { ++ DPRINTK("bcm_power_request -> interrupted\n"); ++ return -EINTR; ++ } ++ ++ if (request != g_state.client_request[handle]) { ++ uint32_t others_request = 0; ++ uint32_t global_request; ++ BCM_POWER_HANDLE_T i; ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (i != handle) ++ others_request |= ++ g_state.client_request[i]; ++ } ++ others_request &= ~BCM_POWER_NOCLIENT; ++ ++ global_request = request | others_request; ++ if (global_request != g_state.global_request) { ++ uint32_t actual; ++ ++ /* Send a request to VideoCore */ ++ bcm_mailbox_write(MBOX_CHAN_POWER, ++ global_request << 4); ++ ++ /* Wait for a response during power-up */ ++ if (global_request & ~g_state.global_request) { ++ rc = bcm_mailbox_read(MBOX_CHAN_POWER, ++ &actual); ++ DPRINTK ++ ("bcm_mailbox_read -> %08x, %d\n", ++ actual, rc); ++ actual >>= 4; ++ } else { ++ rc = 0; ++ actual = global_request; ++ } ++ ++ if (rc == 0) { ++ if (actual != global_request) { ++ printk(KERN_ERR ++ "%s: prev global %x, new global %x, actual %x, request %x, others_request %x\n", ++ __func__, ++ g_state.global_request, ++ global_request, actual, request, others_request); ++ /* A failure */ ++ BUG_ON((others_request & actual) ++ != others_request); ++ request &= actual; ++ rc = -EIO; ++ } ++ ++ g_state.global_request = actual; ++ g_state.client_request[handle] = ++ request; ++ } ++ } ++ } ++ up(&g_state.mutex); ++ } else { ++ rc = -EINVAL; ++ } ++ DPRINTK("bcm_power_request -> %d\n", rc); ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_request); ++ ++int bcm_power_close(BCM_POWER_HANDLE_T handle) ++{ ++ int rc; ++ ++ DPRINTK("bcm_power_close(%d)\n", handle); ++ ++ rc = bcm_power_request(handle, BCM_POWER_NONE); ++ if (rc == 0) ++ g_state.client_request[handle] = BCM_POWER_NOCLIENT; ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_close); ++ ++static int __init bcm_power_init(void) ++{ ++#if defined(BCM_POWER_ALWAYS_ON) ++ BCM_POWER_HANDLE_T always_on_handle; ++#endif ++ int rc = 0; ++ int i; ++ ++ printk(KERN_INFO "bcm_power: Broadcom power driver\n"); ++ bcm_mailbox_write(MBOX_CHAN_POWER, 0); ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) ++ g_state.client_request[i] = BCM_POWER_NOCLIENT; ++ ++ sema_init(&g_state.client_mutex, 1); ++ sema_init(&g_state.mutex, 1); ++ ++ g_state.global_request = 0; ++ ++#if defined(BCM_POWER_ALWAYS_ON) ++ if (BCM_POWER_ALWAYS_ON) { ++ bcm_power_open(&always_on_handle); ++ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); ++ } ++#endif ++ ++ return rc; ++} ++ ++static void __exit bcm_power_exit(void) ++{ ++ bcm_mailbox_write(MBOX_CHAN_POWER, 0); ++} ++ ++arch_initcall(bcm_power_init); /* Initialize early */ ++module_exit(bcm_power_exit); ++ ++MODULE_AUTHOR("Phil Elwell"); ++MODULE_DESCRIPTION("Interface to BCM2708 power management"); ++MODULE_LICENSE("GPL"); +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/vc_mem.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/vc_mem.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,462 @@ ++/***************************************************************************** ++* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_ARCH_KONA ++#include ++#elif CONFIG_ARCH_BCM2708 ++#else ++#include ++#endif ++ ++#include "mach/vc_mem.h" ++#include ++ ++#define DRIVER_NAME "vc-mem" ++ ++// Uncomment to enable debug logging ++// #define ENABLE_DBG ++ ++#if defined(ENABLE_DBG) ++#define LOG_DBG( fmt, ... ) printk( KERN_INFO fmt "\n", ##__VA_ARGS__ ) ++#else ++#define LOG_DBG( fmt, ... ) ++#endif ++#define LOG_ERR( fmt, ... ) printk( KERN_ERR fmt "\n", ##__VA_ARGS__ ) ++ ++// Device (/dev) related variables ++static dev_t vc_mem_devnum = 0; ++static struct class *vc_mem_class = NULL; ++static struct cdev vc_mem_cdev; ++static int vc_mem_inited = 0; ++ ++// Proc entry ++static struct proc_dir_entry *vc_mem_proc_entry; ++ ++/* ++ * Videocore memory addresses and size ++ * ++ * Drivers that wish to know the videocore memory addresses and sizes should ++ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in ++ * headers. This allows the other drivers to not be tied down to a a certain ++ * address/size at compile time. ++ * ++ * In the future, the goal is to have the videocore memory virtual address and ++ * size be calculated at boot time rather than at compile time. The decision of ++ * where the videocore memory resides and its size would be in the hands of the ++ * bootloader (and/or kernel). When that happens, the values of these variables ++ * would be calculated and assigned in the init function. ++ */ ++// in the 2835 VC in mapped above ARM, but ARM has full access to VC space ++unsigned long mm_vc_mem_phys_addr = 0x00000000; ++unsigned int mm_vc_mem_size = 0; ++unsigned int mm_vc_mem_base = 0; ++ ++EXPORT_SYMBOL(mm_vc_mem_phys_addr); ++EXPORT_SYMBOL(mm_vc_mem_size); ++EXPORT_SYMBOL(mm_vc_mem_base); ++ ++static uint phys_addr = 0; ++static uint mem_size = 0; ++static uint mem_base = 0; ++ ++ ++/**************************************************************************** ++* ++* vc_mem_open ++* ++***************************************************************************/ ++ ++static int ++vc_mem_open(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ LOG_DBG("%s: called file = 0x%p", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_release ++* ++***************************************************************************/ ++ ++static int ++vc_mem_release(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ LOG_DBG("%s: called file = 0x%p", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_size ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_size(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_base ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_base(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_current_size ++* ++***************************************************************************/ ++ ++int ++vc_mem_get_current_size(void) ++{ ++ return mm_vc_mem_size; ++} ++ ++EXPORT_SYMBOL_GPL(vc_mem_get_current_size); ++ ++/**************************************************************************** ++* ++* vc_mem_ioctl ++* ++***************************************************************************/ ++ ++static long ++vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int rc = 0; ++ ++ (void) cmd; ++ (void) arg; ++ ++ LOG_DBG("%s: called file = 0x%p", __func__, file); ++ ++ switch (cmd) { ++ case VC_MEM_IOC_MEM_PHYS_ADDR: ++ { ++ LOG_DBG("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p", ++ __func__, (void *) mm_vc_mem_phys_addr); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, ++ sizeof (mm_vc_mem_phys_addr)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_SIZE: ++ { ++ // Get the videocore memory size first ++ vc_mem_get_size(); ++ ++ LOG_DBG("%s: VC_MEM_IOC_MEM_SIZE=%u", __func__, ++ mm_vc_mem_size); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_size, ++ sizeof (mm_vc_mem_size)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_BASE: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ LOG_DBG("%s: VC_MEM_IOC_MEM_BASE=%u", __func__, ++ mm_vc_mem_base); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_base, ++ sizeof (mm_vc_mem_base)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_LOAD: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ LOG_DBG("%s: VC_MEM_IOC_MEM_LOAD=%u", __func__, ++ mm_vc_mem_base); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_base, ++ sizeof (mm_vc_mem_base)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ default: ++ { ++ return -ENOTTY; ++ } ++ } ++ LOG_DBG("%s: file = 0x%p returning %d", __func__, file, rc); ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_mmap ++* ++***************************************************************************/ ++ ++static int ++vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++ int rc = 0; ++ unsigned long length = vma->vm_end - vma->vm_start; ++ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; ++ ++ LOG_DBG("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx", ++ __func__, (long) vma->vm_start, (long) vma->vm_end, ++ (long) vma->vm_pgoff); ++ ++ if (offset + length > mm_vc_mem_size) { ++ LOG_ERR("%s: length %ld is too big", __func__, length); ++ return -EINVAL; ++ } ++ // Do not cache the memory map ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ ++ rc = remap_pfn_range(vma, vma->vm_start, ++ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + ++ vma->vm_pgoff, length, vma->vm_page_prot); ++ if (rc != 0) { ++ LOG_ERR("%s: remap_pfn_range failed (rc=%d)", __func__, rc); ++ } ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* File Operations for the driver. ++* ++***************************************************************************/ ++ ++static const struct file_operations vc_mem_fops = { ++ .owner = THIS_MODULE, ++ .open = vc_mem_open, ++ .release = vc_mem_release, ++ .unlocked_ioctl = vc_mem_ioctl, ++ .mmap = vc_mem_mmap, ++}; ++ ++/**************************************************************************** ++* ++* vc_mem_proc_read ++* ++***************************************************************************/ ++ ++static int ++vc_mem_proc_read(char *buf, char **start, off_t offset, int count, int *eof, ++ void *data) ++{ ++ char *p = buf; ++ ++ (void) start; ++ (void) count; ++ (void) data; ++ ++ if (offset > 0) { ++ *eof = 1; ++ return 0; ++ } ++ // Get the videocore memory size first ++ vc_mem_get_size(); ++ ++ p += sprintf(p, "Videocore memory:\n"); ++ if (mm_vc_mem_phys_addr != 0) ++ p += sprintf(p, " Physical address: 0x%p\n", ++ (void *) mm_vc_mem_phys_addr); ++ else ++ p += sprintf(p, " Physical address: 0x00000000\n"); ++ p += sprintf(p, " Length (bytes): %u\n", mm_vc_mem_size); ++ ++ *eof = 1; ++ return p - buf; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_proc_write ++* ++***************************************************************************/ ++ ++static int ++vc_mem_proc_write(struct file *file, const char __user * buffer, ++ unsigned long count, void *data) ++{ ++ int rc = -EFAULT; ++ char input_str[10]; ++ ++ memset(input_str, 0, sizeof (input_str)); ++ ++ if (count > sizeof (input_str)) { ++ LOG_ERR("%s: input string length too long", __func__); ++ goto out; ++ } ++ ++ if (copy_from_user(input_str, buffer, count - 1)) { ++ LOG_ERR("%s: failed to get input string", __func__); ++ goto out; ++ } ++ ++ if (strncmp(input_str, "connect", strlen("connect")) == 0) { ++ // Get the videocore memory size from the videocore ++ vc_mem_get_size(); ++ } ++ ++ out: ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_init ++* ++***************************************************************************/ ++ ++static int __init ++vc_mem_init(void) ++{ ++ int rc = -EFAULT; ++ struct device *dev; ++ ++ LOG_DBG("%s: called", __func__); ++ ++ mm_vc_mem_phys_addr = phys_addr; ++ mm_vc_mem_size = mem_size; ++ mm_vc_mem_base = mem_base; ++ ++ vc_mem_get_size(); ++ ++ printk("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", ++ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); ++ ++ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { ++ LOG_ERR("%s: alloc_chrdev_region failed (rc=%d)", __func__, rc); ++ goto out_err; ++ } ++ ++ cdev_init(&vc_mem_cdev, &vc_mem_fops); ++ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { ++ LOG_ERR("%s: cdev_add failed (rc=%d)", __func__, rc); ++ goto out_unregister; ++ } ++ ++ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); ++ if (IS_ERR(vc_mem_class)) { ++ rc = PTR_ERR(vc_mem_class); ++ LOG_ERR("%s: class_create failed (rc=%d)", __func__, rc); ++ goto out_cdev_del; ++ } ++ ++ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, ++ DRIVER_NAME); ++ if (IS_ERR(dev)) { ++ rc = PTR_ERR(dev); ++ LOG_ERR("%s: device_create failed (rc=%d)", __func__, rc); ++ goto out_class_destroy; ++ } ++ ++#if 0 ++ vc_mem_proc_entry = create_proc_entry(DRIVER_NAME, 0444, NULL); ++ if (vc_mem_proc_entry == NULL) { ++ rc = -EFAULT; ++ LOG_ERR("%s: create_proc_entry failed", __func__); ++ goto out_device_destroy; ++ } ++ vc_mem_proc_entry->read_proc = vc_mem_proc_read; ++ vc_mem_proc_entry->write_proc = vc_mem_proc_write; ++#endif ++ ++ vc_mem_inited = 1; ++ return 0; ++ ++ out_device_destroy: ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ ++ out_class_destroy: ++ class_destroy(vc_mem_class); ++ vc_mem_class = NULL; ++ ++ out_cdev_del: ++ cdev_del(&vc_mem_cdev); ++ ++ out_unregister: ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ ++ out_err: ++ return -1; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_exit ++* ++***************************************************************************/ ++ ++static void __exit ++vc_mem_exit(void) ++{ ++ LOG_DBG("%s: called", __func__); ++ ++ if (vc_mem_inited) { ++#if 0 ++ remove_proc_entry(vc_mem_proc_entry->name, NULL); ++#endif ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ class_destroy(vc_mem_class); ++ cdev_del(&vc_mem_cdev); ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ } ++} ++ ++module_init(vc_mem_init); ++module_exit(vc_mem_exit); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Broadcom Corporation"); ++ ++module_param(phys_addr, uint, 0644); ++module_param(mem_size, uint, 0644); ++module_param(mem_base, uint, 0644); ++ +Index: linux-3.10-3.10.11/arch/arm/mach-bcm2708/vcio.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mach-bcm2708/vcio.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,474 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/vcio.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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 device provides a shared mechanism for writing to the mailboxes, ++ * semaphores, doorbells etc. that are shared between the ARM and the ++ * VideoCore processor ++ */ ++ ++#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) ++#define SUPPORT_SYSRQ ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#include ++ ++ ++#define DRIVER_NAME BCM_VCIO_DRIVER_NAME ++ ++/* ---------------------------------------------------------------------- ++ * Mailbox ++ * -------------------------------------------------------------------- */ ++ ++/* offsets from a mail box base address */ ++#define MAIL_WRT 0x00 /* write - and next 4 words */ ++#define MAIL_RD 0x00 /* read - and next 4 words */ ++#define MAIL_POL 0x10 /* read without popping the fifo */ ++#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ ++#define MAIL_STA 0x18 /* status */ ++#define MAIL_CNF 0x1C /* configuration */ ++ ++#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) ++#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) ++#define MBOX_CHAN(msg) ((msg) & 0xf) ++#define MBOX_DATA28(msg) ((msg) & ~0xf) ++#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) ++ ++#define MBOX_MAGIC 0xd0d0c0de ++ ++struct vc_mailbox { ++ struct device *dev; /* parent device */ ++ void __iomem *status; ++ void __iomem *config; ++ void __iomem *read; ++ void __iomem *write; ++ uint32_t msg[MBOX_CHAN_COUNT]; ++ struct semaphore sema[MBOX_CHAN_COUNT]; ++ uint32_t magic; ++}; ++ ++static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, ++ uint32_t addr_mbox) ++{ ++ int i; ++ ++ mbox_out->dev = dev; ++ mbox_out->status = __io_address(addr_mbox + MAIL_STA); ++ mbox_out->config = __io_address(addr_mbox + MAIL_CNF); ++ mbox_out->read = __io_address(addr_mbox + MAIL_RD); ++ /* Write to the other mailbox */ ++ mbox_out->write = ++ __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + ++ MAIL_WRT); ++ ++ for (i = 0; i < MBOX_CHAN_COUNT; i++) { ++ mbox_out->msg[i] = 0; ++ sema_init(&mbox_out->sema[i], 0); ++ } ++ ++ /* Enable the interrupt on data reception */ ++ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); ++ ++ mbox_out->magic = MBOX_MAGIC; ++} ++ ++static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) ++{ ++ int rc; ++ ++ if (mbox->magic != MBOX_MAGIC) ++ rc = -EINVAL; ++ else { ++ /* wait for the mailbox FIFO to have some space in it */ ++ while (0 != (readl(mbox->status) & ARM_MS_FULL)) ++ cpu_relax(); ++ ++ writel(MBOX_MSG(chan, data28), mbox->write); ++ rc = 0; ++ } ++ return rc; ++} ++ ++static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) ++{ ++ int rc; ++ ++ if (mbox->magic != MBOX_MAGIC) ++ rc = -EINVAL; ++ else { ++ down(&mbox->sema[chan]); ++ *data28 = MBOX_DATA28(mbox->msg[chan]); ++ mbox->msg[chan] = 0; ++ rc = 0; ++ } ++ return rc; ++} ++ ++static irqreturn_t mbox_irq(int irq, void *dev_id) ++{ ++ /* wait for the mailbox FIFO to have some data in it */ ++ struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; ++ int status = readl(mbox->status); ++ int ret = IRQ_NONE; ++ ++ while (!(status & ARM_MS_EMPTY)) { ++ uint32_t msg = readl(mbox->read); ++ int chan = MBOX_CHAN(msg); ++ if (chan < MBOX_CHAN_COUNT) { ++ if (mbox->msg[chan]) { ++ /* Overflow */ ++ printk(KERN_ERR DRIVER_NAME ++ ": mbox chan %d overflow - drop %08x\n", ++ chan, msg); ++ } else { ++ mbox->msg[chan] = (msg | 0xf); ++ up(&mbox->sema[chan]); ++ } ++ } else { ++ printk(KERN_ERR DRIVER_NAME ++ ": invalid channel selector (msg %08x)\n", msg); ++ } ++ ret = IRQ_HANDLED; ++ status = readl(mbox->status); ++ } ++ return ret; ++} ++ ++static struct irqaction mbox_irqaction = { ++ .name = "ARM Mailbox IRQ", ++ .flags = IRQF_DISABLED | IRQF_IRQPOLL, ++ .handler = mbox_irq, ++}; ++ ++/* ---------------------------------------------------------------------- ++ * Mailbox Methods ++ * -------------------------------------------------------------------- */ ++ ++static struct device *mbox_dev; /* we assume there's only one! */ ++ ++static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) ++{ ++ int rc; ++ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ device_lock(dev); ++ rc = mbox_write(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) ++{ ++ int rc; ++ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ device_lock(dev); ++ rc = mbox_read(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++extern int bcm_mailbox_write(unsigned chan, uint32_t data28) ++{ ++ if (mbox_dev) ++ return dev_mbox_write(mbox_dev, chan, data28); ++ else ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_write); ++ ++extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) ++{ ++ if (mbox_dev) ++ return dev_mbox_read(mbox_dev, chan, data28); ++ else ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_read); ++ ++static void dev_mbox_register(const char *dev_name, struct device *dev) ++{ ++ mbox_dev = dev; ++} ++ ++static int mbox_copy_from_user(void *dst, const void *src, int size) ++{ ++ if ( (uint32_t)src < TASK_SIZE) ++ { ++ return copy_from_user(dst, src, size); ++ } ++ else ++ { ++ memcpy( dst, src, size ); ++ return 0; ++ } ++} ++ ++static int mbox_copy_to_user(void *dst, const void *src, int size) ++{ ++ if ( (uint32_t)dst < TASK_SIZE) ++ { ++ return copy_to_user(dst, src, size); ++ } ++ else ++ { ++ memcpy( dst, src, size ); ++ return 0; ++ } ++} ++ ++static DEFINE_MUTEX(mailbox_lock); ++extern int bcm_mailbox_property(void *data, int size) ++{ ++ uint32_t success; ++ dma_addr_t mem_bus; /* the memory address accessed from videocore */ ++ void *mem_kern; /* the memory address accessed from driver */ ++ int s = 0; ++ ++ mutex_lock(&mailbox_lock); ++ /* allocate some memory for the messages communicating with GPU */ ++ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); ++ if (mem_kern) { ++ /* create the message */ ++ mbox_copy_from_user(mem_kern, data, size); ++ ++ /* send the message */ ++ wmb(); ++ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); ++ if (s == 0) { ++ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); ++ } ++ if (s == 0) { ++ /* copy the response */ ++ rmb(); ++ mbox_copy_to_user(data, mem_kern, size); ++ } ++ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); ++ } else { ++ s = -ENOMEM; ++ } ++ if (s != 0) ++ printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); ++ ++ mutex_unlock(&mailbox_lock); ++ return s; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_property); ++ ++/* ---------------------------------------------------------------------- ++ * Platform Device for Mailbox ++ * -------------------------------------------------------------------- */ ++ ++/* ++ * Is the device open right now? Used to prevent ++ * concurent access into the same device ++ */ ++static int Device_Open = 0; ++ ++/* ++ * This is called whenever a process attempts to open the device file ++ */ ++static int device_open(struct inode *inode, struct file *file) ++{ ++ /* ++ * We don't want to talk to two processes at the same time ++ */ ++ if (Device_Open) ++ return -EBUSY; ++ ++ Device_Open++; ++ /* ++ * Initialize the message ++ */ ++ try_module_get(THIS_MODULE); ++ return 0; ++} ++ ++static int device_release(struct inode *inode, struct file *file) ++{ ++ /* ++ * We're now ready for our next caller ++ */ ++ Device_Open--; ++ ++ module_put(THIS_MODULE); ++ return 0; ++} ++ ++/* ++ * This function is called whenever a process tries to do an ioctl on our ++ * device file. We get two extra parameters (additional to the inode and file ++ * structures, which all device functions get): the number of the ioctl called ++ * and the parameter given to the ioctl function. ++ * ++ * If the ioctl is write or read/write (meaning output is returned to the ++ * calling process), the ioctl call returns the output of this function. ++ * ++ */ ++static long device_ioctl(struct file *file, /* see include/linux/fs.h */ ++ unsigned int ioctl_num, /* number and param for ioctl */ ++ unsigned long ioctl_param) ++{ ++ unsigned size; ++ /* ++ * Switch according to the ioctl called ++ */ ++ switch (ioctl_num) { ++ case IOCTL_MBOX_PROPERTY: ++ /* ++ * Receive a pointer to a message (in user space) and set that ++ * to be the device's message. Get the parameter given to ++ * ioctl by the process. ++ */ ++ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); ++ return bcm_mailbox_property((void *)ioctl_param, size); ++ break; ++ default: ++ printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Module Declarations */ ++ ++/* ++ * This structure will hold the functions to be called ++ * when a process does something to the device we ++ * created. Since a pointer to this structure is kept in ++ * the devices table, it can't be local to ++ * init_module. NULL is for unimplemented functios. ++ */ ++struct file_operations fops = { ++ .unlocked_ioctl = device_ioctl, ++ .open = device_open, ++ .release = device_release, /* a.k.a. close */ ++}; ++ ++static int bcm_vcio_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct vc_mailbox *mailbox; ++ ++ mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); ++ if (NULL == mailbox) { ++ printk(KERN_ERR DRIVER_NAME ": failed to allocate " ++ "mailbox memory\n"); ++ ret = -ENOMEM; ++ } else { ++ struct resource *res; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (res == NULL) { ++ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " ++ "resource\n"); ++ ret = -ENODEV; ++ kfree(mailbox); ++ } else { ++ /* should be based on the registers from res really */ ++ mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); ++ ++ platform_set_drvdata(pdev, mailbox); ++ dev_mbox_register(DRIVER_NAME, &pdev->dev); ++ ++ mbox_irqaction.dev_id = mailbox; ++ setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); ++ printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", ++ __io_address(ARM_0_MAIL0_RD)); ++ } ++ } ++ ++ if (ret == 0) { ++ /* ++ * Register the character device ++ */ ++ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); ++ ++ /* ++ * Negative values signify an error ++ */ ++ if (ret < 0) { ++ printk(KERN_ERR DRIVER_NAME ++ "Failed registering the character device %d\n", ret); ++ return ret; ++ } ++ } ++ return ret; ++} ++ ++static int bcm_vcio_remove(struct platform_device *pdev) ++{ ++ struct vc_mailbox *mailbox = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ kfree(mailbox); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm_mbox_driver = { ++ .probe = bcm_vcio_probe, ++ .remove = bcm_vcio_remove, ++ ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init bcm_mbox_init(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); ++ ++ ret = platform_driver_register(&bcm_mbox_driver); ++ if (ret != 0) { ++ printk(KERN_ERR DRIVER_NAME ": failed to register " ++ "on platform\n"); ++ } ++ ++ return ret; ++} ++ ++static void __exit bcm_mbox_exit(void) ++{ ++ platform_driver_unregister(&bcm_mbox_driver); ++} ++ ++arch_initcall(bcm_mbox_init); /* Initialize early */ ++module_exit(bcm_mbox_exit); ++ ++MODULE_AUTHOR("Gray Girling"); ++MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:bcm-mbox"); +Index: linux-3.10-3.10.11/arch/arm/mm/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mm/Kconfig 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mm/Kconfig 2014-05-05 12:51:09.000000000 +0000 +@@ -358,7 +358,7 @@ + + # ARMv6 + config CPU_V6 +- bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX ++ bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708 + select CPU_32v6 + select CPU_ABRT_EV6 + select CPU_CACHE_V6 +Index: linux-3.10-3.10.11/arch/arm/mm/proc-v6.S +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/mm/proc-v6.S 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/mm/proc-v6.S 2014-05-05 12:51:09.000000000 +0000 +@@ -73,10 +73,19 @@ + * + * IRQs are already disabled. + */ ++ ++/* See jira SW-5991 for details of this workaround */ + ENTRY(cpu_v6_do_idle) +- mov r1, #0 +- mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode +- mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ .align 5 ++ mov r1, #2 ++1: subs r1, #1 ++ nop ++ mcreq p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode ++ mcreq p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ nop ++ nop ++ nop ++ bne 1b + mov pc, lr + + ENTRY(cpu_v6_dcache_clean_area) +Index: linux-3.10-3.10.11/arch/arm/tools/mach-types +=================================================================== +--- linux-3.10-3.10.11.orig/arch/arm/tools/mach-types 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/arch/arm/tools/mach-types 2014-05-05 12:51:09.000000000 +0000 +@@ -522,6 +522,7 @@ + prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 + paz00 MACH_PAZ00 PAZ00 3128 + acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 ++bcm2708 MACH_BCM2708 BCM2708 3138 + ag5evm MACH_AG5EVM AG5EVM 3189 + ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 + wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 +Index: linux-3.10-3.10.11/drivers/mmc/host/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/mmc/host/Kconfig 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mmc/host/Kconfig 2014-05-05 12:51:09.000000000 +0000 +@@ -249,6 +249,27 @@ + + YMMV. + ++config MMC_SDHCI_BCM2708 ++ tristate "SDHCI support on BCM2708" ++ depends on MMC_SDHCI && MACH_BCM2708 ++ select MMC_SDHCI_IO_ACCESSORS ++ help ++ This selects the Secure Digital Host Controller Interface (SDHCI) ++ often referrered to as the eMMC block. ++ ++ If you have a controller with this interface, say Y or M here. ++ ++ If unsure, say N. ++ ++config MMC_SDHCI_BCM2708_DMA ++ bool "DMA support on BCM2708 Arasan controller" ++ depends on MMC_SDHCI_BCM2708 ++ help ++ Enable DMA support on the Arasan SDHCI controller in Broadcom 2708 ++ based chips. ++ ++ If unsure, say N. ++ + config MMC_SDHCI_BCM2835 + tristate "SDHCI platform support for the BCM2835 SD/MMC Controller" + depends on ARCH_BCM2835 +Index: linux-3.10-3.10.11/drivers/mmc/host/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/mmc/host/Makefile 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mmc/host/Makefile 2014-05-05 12:51:09.000000000 +0000 +@@ -15,6 +15,7 @@ + obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o + obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o + obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o ++obj-$(CONFIG_MMC_SDHCI_BCM2708) += sdhci-bcm2708.o + obj-$(CONFIG_MMC_WBSD) += wbsd.o + obj-$(CONFIG_MMC_AU1X) += au1xmmc.o + obj-$(CONFIG_MMC_OMAP) += omap.o +Index: linux-3.10-3.10.11/drivers/mmc/host/sdhci-bcm2708.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mmc/host/sdhci-bcm2708.c 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1,1425 @@ ++/* ++ * sdhci-bcm2708.c Support for SDHCI device on BCM2708 ++ * Copyright (c) 2010 Broadcom ++ * ++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++/* Supports: ++ * SDHCI platform device - Arasan SD controller in BCM2708 ++ * ++ * Inspired by sdhci-pci.c, by Pierre Ossman ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "sdhci.h" ++ ++/*****************************************************************************\ ++ * * ++ * Configuration * ++ * * ++\*****************************************************************************/ ++ ++#define DRIVER_NAME "bcm2708_sdhci" ++ ++/* for the time being insist on DMA mode - PIO seems not to work */ ++#ifndef CONFIG_MMC_SDHCI_BCM2708_DMA ++#warning Non-DMA (PIO) version of this driver currently unavailable ++#endif ++#undef CONFIG_MMC_SDHCI_BCM2708_DMA ++#define CONFIG_MMC_SDHCI_BCM2708_DMA y ++ ++#define USE_SYNC_AFTER_DMA ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++/* #define CHECK_DMA_USE */ ++#endif ++//#define LOG_REGISTERS ++ ++#define USE_SCHED_TIME ++#define USE_SPACED_WRITES_2CLK 1 /* space consecutive register writes */ ++#define USE_SOFTWARE_TIMEOUTS 1 /* not hardware timeouts */ ++#define SOFTWARE_ERASE_TIMEOUT_SEC 30 ++ ++#define SDHCI_BCM_DMA_CHAN 4 /* this default is normally overriden */ ++#define SDHCI_BCM_DMA_WAITS 0 /* delays slowing DMA transfers: 0-31 */ ++/* We are worried that SD card DMA use may be blocking the AXI bus for others */ ++ ++/*! TODO: obtain these from the physical address */ ++#define DMA_SDHCI_BASE 0x7e300000 /* EMMC register block on Videocore */ ++#define DMA_SDHCI_BUFFER (DMA_SDHCI_BASE + SDHCI_BUFFER) ++ ++#define BCM2708_SDHCI_SLEEP_TIMEOUT 1000 /* msecs */ ++ ++/* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */ ++#define BCM2708_EMMC_CLOCK_FREQ 80000000 ++ ++/*****************************************************************************\ ++ * * ++ * Debug * ++ * * ++\*****************************************************************************/ ++ ++ ++ ++#define DBG(f, x...) \ ++ pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) ++// printk(KERN_INFO DRIVER_NAME " [%s()]: " f, __func__,## x)//GRAYG ++ ++ ++/*****************************************************************************\ ++ * * ++ * High Precision Time * ++ * * ++\*****************************************************************************/ ++ ++#ifdef USE_SCHED_TIME ++ ++#include ++ ++typedef unsigned long hptime_t; ++ ++#define FMT_HPT "lu" ++ ++static inline hptime_t hptime(void) ++{ ++ return frc_clock_ticks32(); ++} ++ ++#define HPTIME_CLK_NS 1000ul ++ ++#else ++ ++typedef unsigned long hptime_t; ++ ++#define FMT_HPT "lu" ++ ++static inline hptime_t hptime(void) ++{ ++ return jiffies; ++} ++ ++#define HPTIME_CLK_NS (1000000000ul/HZ) ++ ++#endif ++ ++static inline unsigned long int since_ns(hptime_t t) ++{ ++ return (unsigned long)((hptime() - t) * HPTIME_CLK_NS); ++} ++ ++#if 0 ++static void hptime_test(void) ++{ ++ hptime_t now; ++ hptime_t later; ++ ++ now = hptime(); ++ msleep(10); ++ later = hptime(); ++ ++ printk(KERN_INFO DRIVER_NAME": 10ms = %"FMT_HPT" clks " ++ "(from %"FMT_HPT" to %"FMT_HPT") = %luns\n", ++ later-now, now, later, ++ (unsigned long)(HPTIME_CLK_NS * (later - now))); ++ ++ now = hptime(); ++ msleep(1000); ++ later = hptime(); ++ ++ printk(KERN_INFO DRIVER_NAME": 1s = %"FMT_HPT" clks " ++ "(from %"FMT_HPT" to %"FMT_HPT") = %luns\n", ++ later-now, now, later, ++ (unsigned long)(HPTIME_CLK_NS * (later - now))); ++} ++#endif ++ ++/*****************************************************************************\ ++ * * ++ * SDHCI core callbacks * ++ * * ++\*****************************************************************************/ ++ ++ ++#ifdef CHECK_DMA_USE ++/*#define CHECK_DMA_REG_USE*/ ++#endif ++ ++#ifdef CHECK_DMA_REG_USE ++/* we don't expect anything to be using these registers during a ++ DMA (except the IRQ status) - so check */ ++static void check_dma_reg_use(struct sdhci_host *host, int reg); ++#else ++#define check_dma_reg_use(host, reg) ++#endif ++ ++ ++static inline u32 sdhci_bcm2708_raw_readl(struct sdhci_host *host, int reg) ++{ ++ return readl(host->ioaddr + reg); ++} ++ ++u32 sdhci_bcm2708_readl(struct sdhci_host *host, int reg) ++{ ++ u32 l = sdhci_bcm2708_raw_readl(host, reg); ++ ++#ifdef LOG_REGISTERS ++ printk(KERN_ERR "%s: readl from 0x%02x, value 0x%08x\n", ++ mmc_hostname(host->mmc), reg, l); ++#endif ++ check_dma_reg_use(host, reg); ++ ++ return l; ++} ++ ++u16 sdhci_bcm2708_readw(struct sdhci_host *host, int reg) ++{ ++ u32 l = sdhci_bcm2708_raw_readl(host, reg & ~3); ++ u32 w = l >> (reg << 3 & 0x18) & 0xffff; ++ ++#ifdef LOG_REGISTERS ++ printk(KERN_ERR "%s: readw from 0x%02x, value 0x%04x\n", ++ mmc_hostname(host->mmc), reg, w); ++#endif ++ check_dma_reg_use(host, reg); ++ ++ return (u16)w; ++} ++ ++u8 sdhci_bcm2708_readb(struct sdhci_host *host, int reg) ++{ ++ u32 l = sdhci_bcm2708_raw_readl(host, reg & ~3); ++ u32 b = l >> (reg << 3 & 0x18) & 0xff; ++ ++#ifdef LOG_REGISTERS ++ printk(KERN_ERR "%s: readb from 0x%02x, value 0x%02x\n", ++ mmc_hostname(host->mmc), reg, b); ++#endif ++ check_dma_reg_use(host, reg); ++ ++ return (u8)b; ++} ++ ++ ++static void sdhci_bcm2708_raw_writel(struct sdhci_host *host, u32 val, int reg) ++{ ++ u32 ier; ++ ++#if USE_SPACED_WRITES_2CLK ++ static bool timeout_disabled = false; ++ unsigned int ns_2clk = 0; ++ ++ /* The Arasan has a bugette whereby it may lose the content of ++ * successive writes to registers that are within two SD-card clock ++ * cycles of each other (a clock domain crossing problem). ++ * It seems, however, that the data register does not have this problem. ++ * (Which is just as well - otherwise we'd have to nobble the DMA engine ++ * too) ++ */ ++ if (reg != SDHCI_BUFFER && host->clock != 0) { ++ /* host->clock is the clock freq in Hz */ ++ static hptime_t last_write_hpt; ++ hptime_t now = hptime(); ++ ns_2clk = 2000000000/host->clock; ++ ++ if (now == last_write_hpt || now == last_write_hpt+1) { ++ /* we can't guarantee any significant time has ++ * passed - we'll have to wait anyway ! */ ++ udelay((ns_2clk+1000-1)/1000); ++ } else ++ { ++ /* we must have waited at least this many ns: */ ++ unsigned int ns_wait = HPTIME_CLK_NS * ++ (last_write_hpt - now - 1); ++ if (ns_wait < ns_2clk) ++ udelay((ns_2clk-ns_wait+500)/1000); ++ } ++ last_write_hpt = now; ++ } ++#if USE_SOFTWARE_TIMEOUTS ++ /* The Arasan is clocked for timeouts using the SD clock which is too ++ * fast for ERASE commands and causes issues. So we disable timeouts ++ * for ERASE */ ++ if (host->cmd != NULL && host->cmd->opcode == MMC_ERASE && ++ reg == (SDHCI_COMMAND & ~3)) { ++ mod_timer(&host->timer, ++ jiffies + SOFTWARE_ERASE_TIMEOUT_SEC * HZ); ++ ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ ier &= ~SDHCI_INT_DATA_TIMEOUT; ++ writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ timeout_disabled = true; ++ udelay((ns_2clk+1000-1)/1000); ++ } else if (timeout_disabled) { ++ ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ ier |= SDHCI_INT_DATA_TIMEOUT; ++ writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); ++ timeout_disabled = false; ++ udelay((ns_2clk+1000-1)/1000); ++ } ++#endif ++ writel(val, host->ioaddr + reg); ++#else ++ void __iomem * regaddr = host->ioaddr + reg; ++ ++ writel(val, regaddr); ++ ++ if (reg != SDHCI_BUFFER && reg != SDHCI_INT_STATUS && host->clock != 0) ++ { ++ int timeout = 100000; ++ while (val != readl(regaddr) && --timeout > 0) ++ continue; ++ ++ if (timeout <= 0) ++ printk(KERN_ERR "%s: writing 0x%X to reg 0x%X " ++ "always gives 0x%X\n", ++ mmc_hostname(host->mmc), ++ val, reg, readl(regaddr)); ++ BUG_ON(timeout <= 0); ++ } ++#endif ++} ++ ++ ++void sdhci_bcm2708_writel(struct sdhci_host *host, u32 val, int reg) ++{ ++#ifdef LOG_REGISTERS ++ printk(KERN_ERR "%s: writel to 0x%02x, value 0x%08x\n", ++ mmc_hostname(host->mmc), reg, val); ++#endif ++ check_dma_reg_use(host, reg); ++ ++ sdhci_bcm2708_raw_writel(host, val, reg); ++} ++ ++void sdhci_bcm2708_writew(struct sdhci_host *host, u16 val, int reg) ++{ ++ static u32 shadow = 0; ++ ++ u32 p = reg == SDHCI_COMMAND ? shadow : ++ sdhci_bcm2708_raw_readl(host, reg & ~3); ++ u32 s = reg << 3 & 0x18; ++ u32 l = val << s; ++ u32 m = 0xffff << s; ++ ++#ifdef LOG_REGISTERS ++ printk(KERN_ERR "%s: writew to 0x%02x, value 0x%04x\n", ++ mmc_hostname(host->mmc), reg, val); ++#endif ++ ++ if (reg == SDHCI_TRANSFER_MODE) ++ shadow = (p & ~m) | l; ++ else { ++ check_dma_reg_use(host, reg); ++ sdhci_bcm2708_raw_writel(host, (p & ~m) | l, reg & ~3); ++ } ++} ++ ++void sdhci_bcm2708_writeb(struct sdhci_host *host, u8 val, int reg) ++{ ++ u32 p = sdhci_bcm2708_raw_readl(host, reg & ~3); ++ u32 s = reg << 3 & 0x18; ++ u32 l = val << s; ++ u32 m = 0xff << s; ++ ++#ifdef LOG_REGISTERS ++ printk(KERN_ERR "%s: writeb to 0x%02x, value 0x%02x\n", ++ mmc_hostname(host->mmc), reg, val); ++#endif ++ ++ check_dma_reg_use(host, reg); ++ sdhci_bcm2708_raw_writel(host, (p & ~m) | l, reg & ~3); ++} ++ ++static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host) ++{ ++ return 20000000; // this value is in Hz (20MHz) ++} ++ ++static unsigned int sdhci_bcm2708_get_timeout_clock(struct sdhci_host *host) ++{ ++ if(host->clock) ++ return (host->clock / 1000); // this value is in kHz (100MHz) ++ else ++ return (sdhci_bcm2708_get_max_clock(host) / 1000); ++} ++ ++static void sdhci_bcm2708_set_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ int div = 0; ++ u16 clk = 0; ++ unsigned long timeout; ++ ++ if (clock == host->clock) ++ return; ++ ++ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); ++ ++ if (clock == 0) ++ goto out; ++ ++ if (BCM2708_EMMC_CLOCK_FREQ <= clock) ++ div = 1; ++ else { ++ for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { ++ if ((BCM2708_EMMC_CLOCK_FREQ / div) <= clock) ++ break; ++ } ++ } ++ ++ DBG( "desired SD clock: %d, actual: %d\n", ++ clock, BCM2708_EMMC_CLOCK_FREQ / div); ++ ++ clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; ++ clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) ++ << SDHCI_DIVIDER_HI_SHIFT; ++ clk |= SDHCI_CLOCK_INT_EN; ++ ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++ ++ timeout = 20; ++ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) ++ & SDHCI_CLOCK_INT_STABLE)) { ++ if (timeout == 0) { ++ printk(KERN_ERR "%s: Internal clock never " ++ "stabilised.\n", mmc_hostname(host->mmc)); ++ return; ++ } ++ timeout--; ++ mdelay(1); ++ } ++ ++ clk |= SDHCI_CLOCK_CARD_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++out: ++ host->clock = clock; ++ } ++ ++/*****************************************************************************\ ++ * * ++ * DMA Operation * ++ * * ++\*****************************************************************************/ ++ ++struct sdhci_bcm2708_priv { ++ int dma_chan; ++ int dma_irq; ++ void __iomem *dma_chan_base; ++ struct bcm2708_dma_cb *cb_base; /* DMA control blocks */ ++ dma_addr_t cb_handle; ++ /* tracking scatter gather progress */ ++ unsigned sg_ix; /* scatter gather list index */ ++ unsigned sg_done; /* bytes in current sg_ix done */ ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ unsigned char dma_wanted; /* DMA transfer requested */ ++ unsigned char dma_waits; /* wait states in DMAs */ ++#ifdef CHECK_DMA_USE ++ unsigned char dmas_pending; /* no of unfinished DMAs */ ++ hptime_t when_started; ++ hptime_t when_reset; ++ hptime_t when_stopped; ++#endif ++#endif ++ /* signalling the end of a transfer */ ++ void (*complete)(struct sdhci_host *); ++}; ++ ++#define SDHCI_HOST_PRIV(host) \ ++ (struct sdhci_bcm2708_priv *)((struct sdhci_host *)(host)+1) ++ ++ ++ ++#ifdef CHECK_DMA_REG_USE ++static void check_dma_reg_use(struct sdhci_host *host, int reg) ++{ ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ if (host_priv->dma_wanted && reg != SDHCI_INT_STATUS) { ++ printk(KERN_INFO"%s: accessing register 0x%x during DMA\n", ++ mmc_hostname(host->mmc), reg); ++ } ++} ++#endif ++ ++ ++ ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ ++static void sdhci_clear_set_irqgen(struct sdhci_host *host, u32 clear, u32 set) ++{ ++ u32 ier; ++ ++ ier = sdhci_bcm2708_raw_readl(host, SDHCI_SIGNAL_ENABLE); ++ ier &= ~clear; ++ ier |= set; ++ /* change which requests generate IRQs - makes no difference to ++ the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */ ++ sdhci_bcm2708_raw_writel(host, ier, SDHCI_SIGNAL_ENABLE); ++} ++ ++static void sdhci_signal_irqs(struct sdhci_host *host, u32 irqs) ++{ ++ sdhci_clear_set_irqgen(host, 0, irqs); ++} ++ ++static void sdhci_unsignal_irqs(struct sdhci_host *host, u32 irqs) ++{ ++ sdhci_clear_set_irqgen(host, irqs, 0); ++} ++ ++ ++ ++static void schci_bcm2708_cb_read(struct sdhci_bcm2708_priv *host, ++ int ix, ++ dma_addr_t dma_addr, unsigned len, ++ int /*bool*/ is_last) ++{ ++ struct bcm2708_dma_cb *cb = &host->cb_base[ix]; ++ unsigned char dmawaits = host->dma_waits; ++ ++ cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | ++ BCM2708_DMA_WAITS(dmawaits) | ++ BCM2708_DMA_S_DREQ | ++ BCM2708_DMA_D_WIDTH | ++ BCM2708_DMA_D_INC; ++ cb->src = DMA_SDHCI_BUFFER; /* DATA register DMA address */ ++ cb->dst = dma_addr; ++ cb->length = len; ++ cb->stride = 0; ++ ++ if (is_last) { ++ cb->info |= BCM2708_DMA_INT_EN | ++ BCM2708_DMA_WAIT_RESP; ++ cb->next = 0; ++ } else ++ cb->next = host->cb_handle + ++ (ix+1)*sizeof(struct bcm2708_dma_cb); ++ ++ cb->pad[0] = 0; ++ cb->pad[1] = 0; ++} ++ ++static void schci_bcm2708_cb_write(struct sdhci_bcm2708_priv *host, ++ int ix, ++ dma_addr_t dma_addr, unsigned len, ++ int /*bool*/ is_last) ++{ ++ struct bcm2708_dma_cb *cb = &host->cb_base[ix]; ++ unsigned char dmawaits = host->dma_waits; ++ ++ /* We can make arbitrarily large writes as long as we specify DREQ to ++ pace the delivery of bytes to the Arasan hardware */ ++ cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | ++ BCM2708_DMA_WAITS(dmawaits) | ++ BCM2708_DMA_D_DREQ | ++ BCM2708_DMA_S_WIDTH | ++ BCM2708_DMA_S_INC; ++ cb->src = dma_addr; ++ cb->dst = DMA_SDHCI_BUFFER; /* DATA register DMA address */ ++ cb->length = len; ++ cb->stride = 0; ++ ++ if (is_last) { ++ cb->info |= BCM2708_DMA_INT_EN | ++ BCM2708_DMA_WAIT_RESP; ++ cb->next = 0; ++ } else ++ cb->next = host->cb_handle + ++ (ix+1)*sizeof(struct bcm2708_dma_cb); ++ ++ cb->pad[0] = 0; ++ cb->pad[1] = 0; ++} ++ ++ ++static void schci_bcm2708_dma_go(struct sdhci_host *host) ++{ ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ void __iomem *dma_chan_base = host_priv->dma_chan_base; ++ ++ BUG_ON(host_priv->dma_wanted); ++#ifdef CHECK_DMA_USE ++ if (host_priv->dma_wanted) ++ printk(KERN_ERR "%s: DMA already in progress - " ++ "now %"FMT_HPT", last started %lu " ++ "reset %lu stopped %lu\n", ++ mmc_hostname(host->mmc), ++ hptime(), since_ns(host_priv->when_started), ++ since_ns(host_priv->when_reset), ++ since_ns(host_priv->when_stopped)); ++ else if (host_priv->dmas_pending > 0) ++ printk(KERN_INFO "%s: note - new DMA when %d reset DMAs " ++ "already in progress - " ++ "now %"FMT_HPT", started %lu reset %lu stopped %lu\n", ++ mmc_hostname(host->mmc), ++ host_priv->dmas_pending, ++ hptime(), since_ns(host_priv->when_started), ++ since_ns(host_priv->when_reset), ++ since_ns(host_priv->when_stopped)); ++ host_priv->dmas_pending += 1; ++ host_priv->when_started = hptime(); ++#endif ++ host_priv->dma_wanted = 1; ++ DBG("PDMA go - base %p handle %08X\n", dma_chan_base, ++ host_priv->cb_handle); ++ bcm_dma_start(dma_chan_base, host_priv->cb_handle); ++} ++ ++ ++static void ++sdhci_platdma_read(struct sdhci_host *host, dma_addr_t dma_addr, size_t len) ++{ ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ ++ DBG("PDMA to read %d bytes\n", len); ++ host_priv->sg_done += len; ++ schci_bcm2708_cb_read(host_priv, 0, dma_addr, len, 1/*TRUE*/); ++ schci_bcm2708_dma_go(host); ++} ++ ++ ++static void ++sdhci_platdma_write(struct sdhci_host *host, dma_addr_t dma_addr, size_t len) ++{ ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ ++ DBG("PDMA to write %d bytes\n", len); ++ //BUG_ON(0 != (len & 0x1ff)); ++ ++ host_priv->sg_done += len; ++ schci_bcm2708_cb_write(host_priv, 0, dma_addr, len, 1/*TRUE*/); ++ schci_bcm2708_dma_go(host); ++} ++ ++/*! space is avaiable to receive into or data is available to write ++ Platform DMA exported function ++*/ ++void ++sdhci_bcm2708_platdma_avail(struct sdhci_host *host, unsigned int *ref_intmask, ++ void(*completion_callback)(struct sdhci_host *host)) ++{ ++ struct mmc_data *data = host->data; ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ int sg_ix; ++ size_t bytes; ++ dma_addr_t addr; ++ ++ BUG_ON(NULL == data); ++ BUG_ON(0 == data->blksz); ++ ++ host_priv->complete = completion_callback; ++ ++ sg_ix = host_priv->sg_ix; ++ BUG_ON(sg_ix >= data->sg_len); ++ ++ /* we can DMA blocks larger than blksz - it may hang the DMA ++ channel but we are its only user */ ++ bytes = sg_dma_len(&data->sg[sg_ix]) - host_priv->sg_done; ++ addr = sg_dma_address(&data->sg[sg_ix]) + host_priv->sg_done; ++ ++ if (bytes > 0) { ++ /* We're going to poll for read/write available state until ++ we finish this DMA ++ */ ++ ++ if (data->flags & MMC_DATA_READ) { ++ if (*ref_intmask & SDHCI_INT_DATA_AVAIL) { ++ sdhci_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | ++ SDHCI_INT_SPACE_AVAIL); ++ sdhci_platdma_read(host, addr, bytes); ++ } ++ } else { ++ if (*ref_intmask & SDHCI_INT_SPACE_AVAIL) { ++ sdhci_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | ++ SDHCI_INT_SPACE_AVAIL); ++ sdhci_platdma_write(host, addr, bytes); ++ } ++ } ++ } ++ /* else: ++ we have run out of bytes that need transferring (e.g. we may be in ++ the middle of the last DMA transfer), or ++ it is also possible that we've been called when another IRQ is ++ signalled, even though we've turned off signalling of our own IRQ */ ++ ++ *ref_intmask &= ~SDHCI_INT_DATA_END; ++ /* don't let the main sdhci driver act on this .. we'll deal with it ++ when we respond to the DMA - if one is currently in progress */ ++} ++ ++/* is it possible to DMA the given mmc_data structure? ++ Platform DMA exported function ++*/ ++int /*bool*/ ++sdhci_bcm2708_platdma_dmaable(struct sdhci_host *host, struct mmc_data *data) ++{ ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ int ok = bcm_sg_suitable_for_dma(data->sg, data->sg_len); ++ ++ if (!ok) ++ DBG("Reverting to PIO - bad cache alignment\n"); ++ ++ else { ++ host_priv->sg_ix = 0; /* first SG index */ ++ host_priv->sg_done = 0; /* no bytes done */ ++ } ++ ++ return ok; ++} ++ ++#include //GRAYG ++/*! the current SD transacton has been abandonned ++ We need to tidy up if we were in the middle of a DMA ++ Platform DMA exported function ++*/ ++void ++sdhci_bcm2708_platdma_reset(struct sdhci_host *host, struct mmc_data *data) ++{ ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ unsigned long flags; ++ ++ BUG_ON(NULL == host); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (host_priv->dma_wanted) { ++ if (NULL == data) { ++ printk(KERN_ERR "%s: ongoing DMA reset - no data!\n", ++ mmc_hostname(host->mmc)); ++ BUG_ON(NULL == data); ++ } else { ++ struct scatterlist *sg; ++ int sg_len; ++ int sg_todo; ++ int rc; ++ unsigned long cs; ++ ++ sg = data->sg; ++ sg_len = data->sg_len; ++ sg_todo = sg_dma_len(&sg[host_priv->sg_ix]); ++ ++ cs = readl(host_priv->dma_chan_base + BCM2708_DMA_CS); ++ ++ if (!(BCM2708_DMA_ACTIVE & cs)) ++ printk(KERN_INFO "%s: missed completion of " ++ "cmd %d DMA (%d/%d [%d]/[%d]) - " ++ "ignoring it\n", ++ mmc_hostname(host->mmc), ++ host->last_cmdop, ++ host_priv->sg_done, sg_todo, ++ host_priv->sg_ix+1, sg_len); ++ else ++ printk(KERN_INFO "%s: resetting ongoing cmd %d" ++ "DMA before %d/%d [%d]/[%d] complete\n", ++ mmc_hostname(host->mmc), ++ host->last_cmdop, ++ host_priv->sg_done, sg_todo, ++ host_priv->sg_ix+1, sg_len); ++#ifdef CHECK_DMA_USE ++ printk(KERN_INFO "%s: now %"FMT_HPT" started %lu " ++ "last reset %lu last stopped %lu\n", ++ mmc_hostname(host->mmc), ++ hptime(), since_ns(host_priv->when_started), ++ since_ns(host_priv->when_reset), ++ since_ns(host_priv->when_stopped)); ++ { unsigned long info, debug; ++ void __iomem *base; ++ unsigned long pend0, pend1, pend2; ++ ++ base = host_priv->dma_chan_base; ++ cs = readl(base + BCM2708_DMA_CS); ++ info = readl(base + BCM2708_DMA_INFO); ++ debug = readl(base + BCM2708_DMA_DEBUG); ++ printk(KERN_INFO "%s: DMA%d CS=%08lX TI=%08lX " ++ "DEBUG=%08lX\n", ++ mmc_hostname(host->mmc), ++ host_priv->dma_chan, ++ cs, info, debug); ++ pend0 = readl(__io_address(ARM_IRQ_PEND0)); ++ pend1 = readl(__io_address(ARM_IRQ_PEND1)); ++ pend2 = readl(__io_address(ARM_IRQ_PEND2)); ++ ++ printk(KERN_INFO "%s: PEND0=%08lX " ++ "PEND1=%08lX PEND2=%08lX\n", ++ mmc_hostname(host->mmc), ++ pend0, pend1, pend2); ++ ++ //gintsts = readl(__io_address(GINTSTS)); ++ //gintmsk = readl(__io_address(GINTMSK)); ++ //printk(KERN_INFO "%s: USB GINTSTS=%08lX" ++ // "GINTMSK=%08lX\n", ++ // mmc_hostname(host->mmc), gintsts, gintmsk); ++ } ++#endif ++ rc = bcm_dma_abort(host_priv->dma_chan_base); ++ BUG_ON(rc != 0); ++ } ++ host_priv->dma_wanted = 0; ++#ifdef CHECK_DMA_USE ++ host_priv->when_reset = hptime(); ++#endif ++ } ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++ ++static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host, ++ u32 dma_cs) ++{ ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ struct mmc_data *data; ++ struct scatterlist *sg; ++ int sg_len; ++ int sg_ix; ++ int sg_todo; ++ unsigned long flags; ++ ++ BUG_ON(NULL == host); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ data = host->data; ++ ++#ifdef CHECK_DMA_USE ++ if (host_priv->dmas_pending <= 0) ++ DBG("on completion no DMA in progress - " ++ "now %"FMT_HPT" started %lu reset %lu stopped %lu\n", ++ hptime(), since_ns(host_priv->when_started), ++ since_ns(host_priv->when_reset), ++ since_ns(host_priv->when_stopped)); ++ else if (host_priv->dmas_pending > 1) ++ DBG("still %d DMA in progress after completion - " ++ "now %"FMT_HPT" started %lu reset %lu stopped %lu\n", ++ host_priv->dmas_pending - 1, ++ hptime(), since_ns(host_priv->when_started), ++ since_ns(host_priv->when_reset), ++ since_ns(host_priv->when_stopped)); ++ BUG_ON(host_priv->dmas_pending <= 0); ++ host_priv->dmas_pending -= 1; ++ host_priv->when_stopped = hptime(); ++#endif ++ host_priv->dma_wanted = 0; ++ ++ if (NULL == data) { ++ DBG("PDMA unused completion - status 0x%X\n", dma_cs); ++ spin_unlock_irqrestore(&host->lock, flags); ++ return; ++ } ++ sg = data->sg; ++ sg_len = data->sg_len; ++ sg_todo = sg_dma_len(&sg[host_priv->sg_ix]); ++ ++ DBG("PDMA complete %d/%d [%d]/[%d]..\n", ++ host_priv->sg_done, sg_todo, ++ host_priv->sg_ix+1, sg_len); ++ ++ BUG_ON(host_priv->sg_done > sg_todo); ++ ++ if (host_priv->sg_done >= sg_todo) { ++ host_priv->sg_ix++; ++ host_priv->sg_done = 0; ++ } ++ ++ sg_ix = host_priv->sg_ix; ++ if (sg_ix < sg_len) { ++ u32 irq_mask; ++ /* Set off next DMA if we've got the capacity */ ++ ++ if (data->flags & MMC_DATA_READ) ++ irq_mask = SDHCI_INT_DATA_AVAIL; ++ else ++ irq_mask = SDHCI_INT_SPACE_AVAIL; ++ ++ /* We have to use the interrupt status register on the BCM2708 ++ rather than the SDHCI_PRESENT_STATE register because latency ++ in the glue logic means that the information retrieved from ++ the latter is not always up-to-date w.r.t the DMA engine - ++ it may not indicate that a read or a write is ready yet */ ++ if (sdhci_bcm2708_raw_readl(host, SDHCI_INT_STATUS) & ++ irq_mask) { ++ size_t bytes = sg_dma_len(&sg[sg_ix]) - ++ host_priv->sg_done; ++ dma_addr_t addr = sg_dma_address(&data->sg[sg_ix]) + ++ host_priv->sg_done; ++ ++ /* acknowledge interrupt */ ++ sdhci_bcm2708_raw_writel(host, irq_mask, ++ SDHCI_INT_STATUS); ++ ++ BUG_ON(0 == bytes); ++ ++ if (data->flags & MMC_DATA_READ) ++ sdhci_platdma_read(host, addr, bytes); ++ else ++ sdhci_platdma_write(host, addr, bytes); ++ } else { ++ DBG("PDMA - wait avail\n"); ++ /* may generate an IRQ if already present */ ++ sdhci_signal_irqs(host, SDHCI_INT_DATA_AVAIL | ++ SDHCI_INT_SPACE_AVAIL); ++ } ++ } else { ++#ifdef USE_SYNC_AFTER_DMA ++ /* On the Arasan controller the stop command (which will be ++ scheduled after this completes) does not seem to work ++ properly if we allow it to be issued when we are ++ transferring data to/from the SD card. ++ We get CRC and DEND errors unless we wait for ++ the SD controller to finish reading/writing to the card. */ ++ u32 state_mask; ++ int timeout=1000000; ++ hptime_t now = hptime(); ++ ++ DBG("PDMA over - sync card\n"); ++ if (data->flags & MMC_DATA_READ) ++ state_mask = SDHCI_DOING_READ; ++ else ++ state_mask = SDHCI_DOING_WRITE; ++ ++ while (0 != (sdhci_bcm2708_raw_readl(host, ++ SDHCI_PRESENT_STATE) & ++ state_mask) && --timeout > 0) ++ continue; ++ ++ if (1000000-timeout > 4000) /*ave. is about 3250*/ ++ DBG("%s: note - long %s sync %luns - " ++ "%d its.\n", ++ mmc_hostname(host->mmc), ++ data->flags & MMC_DATA_READ? "read": "write", ++ since_ns(now), 1000000-timeout); ++ if (timeout <= 0) ++ printk(KERN_ERR"%s: final %s to SD card still " ++ "running\n", ++ mmc_hostname(host->mmc), ++ data->flags & MMC_DATA_READ? "read": "write"); ++#endif ++ if (host_priv->complete) { ++ (*host_priv->complete)(host); ++ DBG("PDMA %s complete\n", ++ data->flags & MMC_DATA_READ?"read":"write"); ++ sdhci_signal_irqs(host, SDHCI_INT_DATA_AVAIL | ++ SDHCI_INT_SPACE_AVAIL); ++ } ++ } ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static irqreturn_t sdhci_bcm2708_dma_irq(int irq, void *dev_id) ++{ ++ irqreturn_t result = IRQ_NONE; ++ struct sdhci_host *host = dev_id; ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ u32 dma_cs; /* control and status register */ ++ unsigned long flags; ++ ++ BUG_ON(NULL == dev_id); ++ BUG_ON(NULL == host_priv->dma_chan_base); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ dma_cs = readl(host_priv->dma_chan_base + BCM2708_DMA_CS); ++ ++ if (dma_cs & BCM2708_DMA_ERR) { ++ unsigned long debug; ++ debug = readl(host_priv->dma_chan_base + ++ BCM2708_DMA_DEBUG); ++ printk(KERN_ERR "%s: DMA error - CS %lX DEBUG %lX\n", ++ mmc_hostname(host->mmc), (unsigned long)dma_cs, ++ (unsigned long)debug); ++ /* reset error */ ++ writel(debug, host_priv->dma_chan_base + ++ BCM2708_DMA_DEBUG); ++ } ++ if (dma_cs & BCM2708_DMA_INT) { ++ /* acknowledge interrupt */ ++ writel(BCM2708_DMA_INT, ++ host_priv->dma_chan_base + BCM2708_DMA_CS); ++ ++ dsb(); /* ARM data synchronization (push) operation */ ++ ++ if (!host_priv->dma_wanted) { ++ /* ignore this interrupt - it was reset */ ++ printk(KERN_INFO "%s: DMA IRQ %X ignored - " ++ "results were reset\n", ++ mmc_hostname(host->mmc), dma_cs); ++#ifdef CHECK_DMA_USE ++ printk(KERN_INFO "%s: now %"FMT_HPT ++ " started %lu reset %lu stopped %lu\n", ++ mmc_hostname(host->mmc), hptime(), ++ since_ns(host_priv->when_started), ++ since_ns(host_priv->when_reset), ++ since_ns(host_priv->when_stopped)); ++ host_priv->dmas_pending--; ++#endif ++ } else ++ sdhci_bcm2708_dma_complete_irq(host, dma_cs); ++ ++ result = IRQ_HANDLED; ++ } ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ return result; ++} ++#endif /* CONFIG_MMC_SDHCI_BCM2708_DMA */ ++ ++ ++/***************************************************************************** \ ++ * * ++ * Device Attributes * ++ * * ++\*****************************************************************************/ ++ ++ ++/** ++ * Show the DMA-using status ++ */ ++static ssize_t attr_dma_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev); ++ ++ if (host) { ++ int use_dma = (host->flags & SDHCI_USE_PLATDMA? 1:0); ++ return sprintf(buf, "%d\n", use_dma); ++ } else ++ return -EINVAL; ++} ++ ++/** ++ * Set the DMA-using status ++ */ ++static ssize_t attr_dma_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev); ++ ++ if (host) { ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ int on = simple_strtol(buf, NULL, 0); ++ if (on) { ++ host->flags |= SDHCI_USE_PLATDMA; ++ printk(KERN_INFO "%s: DMA enabled\n", ++ mmc_hostname(host->mmc)); ++ } else { ++ host->flags &= ~(SDHCI_USE_PLATDMA | SDHCI_REQ_USE_DMA); ++ printk(KERN_INFO "%s: DMA disabled\n", ++ mmc_hostname(host->mmc)); ++ } ++#endif ++ return count; ++ } else ++ return -EINVAL; ++} ++ ++static DEVICE_ATTR(use_dma, S_IRUGO | S_IWUGO, attr_dma_show, attr_dma_store); ++ ++ ++/** ++ * Show the DMA wait states used ++ */ ++static ssize_t attr_dmawait_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev); ++ ++ if (host) { ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ int dmawait = host_priv->dma_waits; ++ return sprintf(buf, "%d\n", dmawait); ++ } else ++ return -EINVAL; ++} ++ ++/** ++ * Set the DMA wait state used ++ */ ++static ssize_t attr_dmawait_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev); ++ ++ if (host) { ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ int dma_waits = simple_strtol(buf, NULL, 0); ++ if (dma_waits >= 0 && dma_waits < 32) ++ host_priv->dma_waits = dma_waits; ++ else ++ printk(KERN_ERR "%s: illegal dma_waits value - %d", ++ mmc_hostname(host->mmc), dma_waits); ++#endif ++ return count; ++ } else ++ return -EINVAL; ++} ++ ++static DEVICE_ATTR(dma_wait, S_IRUGO | S_IWUGO, ++ attr_dmawait_show, attr_dmawait_store); ++ ++ ++/** ++ * Show the DMA-using status ++ */ ++static ssize_t attr_status_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev); ++ ++ if (host) { ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ return sprintf(buf, ++ "present: yes\n" ++ "power: %s\n" ++ "clock: %u Hz\n" ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ "dma: %s (%d waits)\n", ++#else ++ "dma: unconfigured\n", ++#endif ++ "always on", ++ host->clock ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ , (host->flags & SDHCI_USE_PLATDMA)? "on": "off" ++ , host_priv->dma_waits ++#endif ++ ); ++ } else ++ return -EINVAL; ++} ++ ++static DEVICE_ATTR(status, S_IRUGO, attr_status_show, NULL); ++ ++/***************************************************************************** \ ++ * * ++ * Power Management * ++ * * ++\*****************************************************************************/ ++ ++ ++#ifdef CONFIG_PM ++static int sdhci_bcm2708_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ struct sdhci_host *host = (struct sdhci_host *) ++ platform_get_drvdata(dev); ++ int ret = 0; ++ ++ if (host->mmc) { ++ ret = mmc_suspend_host(host->mmc); ++ } ++ ++ return ret; ++} ++ ++static int sdhci_bcm2708_resume(struct platform_device *dev) ++{ ++ struct sdhci_host *host = (struct sdhci_host *) ++ platform_get_drvdata(dev); ++ int ret = 0; ++ ++ if (host->mmc) { ++ ret = mmc_resume_host(host->mmc); ++ } ++ ++ return ret; ++} ++#endif ++ ++ ++/*****************************************************************************\ ++ * * ++ * Device quirk functions. Implemented as local ops because the flags * ++ * field is out of space with newer kernels. This implementation can be * ++ * back ported to older kernels as well. * ++\****************************************************************************/ ++static unsigned int sdhci_bcm2708_quirk_extra_ints(struct sdhci_host *host) ++{ ++ return 1; ++} ++ ++static unsigned int sdhci_bcm2708_quirk_spurious_crc(struct sdhci_host *host) ++{ ++ return 1; ++} ++ ++static unsigned int sdhci_bcm2708_quirk_voltage_broken(struct sdhci_host *host) ++{ ++ return 1; ++} ++ ++static unsigned int sdhci_bcm2708_uhs_broken(struct sdhci_host *host) ++{ ++ return 1; ++} ++ ++/***************************************************************************** \ ++ * * ++ * Device ops * ++ * * ++\*****************************************************************************/ ++ ++static struct sdhci_ops sdhci_bcm2708_ops = { ++#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS ++ .read_l = sdhci_bcm2708_readl, ++ .read_w = sdhci_bcm2708_readw, ++ .read_b = sdhci_bcm2708_readb, ++ .write_l = sdhci_bcm2708_writel, ++ .write_w = sdhci_bcm2708_writew, ++ .write_b = sdhci_bcm2708_writeb, ++#else ++#error The BCM2708 SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set ++#endif ++ //.enable_dma = NULL, ++ .set_clock = sdhci_bcm2708_set_clock, ++ .get_max_clock = sdhci_bcm2708_get_max_clock, ++ //.get_min_clock = NULL, ++ .get_timeout_clock = sdhci_bcm2708_get_timeout_clock, ++ ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ // Platform DMA operations ++ .pdma_able = sdhci_bcm2708_platdma_dmaable, ++ .pdma_avail = sdhci_bcm2708_platdma_avail, ++ .pdma_reset = sdhci_bcm2708_platdma_reset, ++#endif ++ .extra_ints = sdhci_bcm2708_quirk_extra_ints, ++ .spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc, ++ .voltage_broken = sdhci_bcm2708_quirk_voltage_broken, ++ .uhs_broken = sdhci_bcm2708_uhs_broken, ++}; ++ ++/*****************************************************************************\ ++ * * ++ * Device probing/removal * ++ * * ++\*****************************************************************************/ ++ ++static int sdhci_bcm2708_probe(struct platform_device *pdev) ++{ ++ struct sdhci_host *host; ++ struct resource *iomem; ++ struct sdhci_bcm2708_priv *host_priv; ++ int ret; ++ ++ BUG_ON(pdev == NULL); ++ ++ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!iomem) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ if (resource_size(iomem) != 0x100) ++ dev_err(&pdev->dev, "Invalid iomem size. You may " ++ "experience problems.\n"); ++ ++ if (pdev->dev.parent) ++ host = sdhci_alloc_host(pdev->dev.parent, ++ sizeof(struct sdhci_bcm2708_priv)); ++ else ++ host = sdhci_alloc_host(&pdev->dev, ++ sizeof(struct sdhci_bcm2708_priv)); ++ ++ if (IS_ERR(host)) { ++ ret = PTR_ERR(host); ++ goto err; ++ } ++ ++ host->hw_name = "BCM2708_Arasan"; ++ host->ops = &sdhci_bcm2708_ops; ++ host->irq = platform_get_irq(pdev, 0); ++ ++ host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | ++ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | ++ SDHCI_QUIRK_NONSTANDARD_CLOCK; ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ host->flags = SDHCI_USE_PLATDMA; ++#endif ++ ++ if (!request_mem_region(iomem->start, resource_size(iomem), ++ mmc_hostname(host->mmc))) { ++ dev_err(&pdev->dev, "cannot request region\n"); ++ ret = -EBUSY; ++ goto err_request; ++ } ++ ++ host->ioaddr = ioremap(iomem->start, resource_size(iomem)); ++ if (!host->ioaddr) { ++ dev_err(&pdev->dev, "failed to remap registers\n"); ++ ret = -ENOMEM; ++ goto err_remap; ++ } ++ ++ host_priv = SDHCI_HOST_PRIV(host); ++ ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ host_priv->dma_wanted = 0; ++#ifdef CHECK_DMA_USE ++ host_priv->dmas_pending = 0; ++ host_priv->when_started = 0; ++ host_priv->when_reset = 0; ++ host_priv->when_stopped = 0; ++#endif ++ host_priv->sg_ix = 0; ++ host_priv->sg_done = 0; ++ host_priv->complete = NULL; ++ host_priv->dma_waits = SDHCI_BCM_DMA_WAITS; ++ ++ host_priv->cb_base = dma_alloc_writecombine(&pdev->dev, SZ_4K, ++ &host_priv->cb_handle, ++ GFP_KERNEL); ++ if (!host_priv->cb_base) { ++ dev_err(&pdev->dev, "cannot allocate DMA CBs\n"); ++ ret = -ENOMEM; ++ goto err_alloc_cb; ++ } ++ ++ ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_FAST, ++ &host_priv->dma_chan_base, ++ &host_priv->dma_irq); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "couldn't allocate a DMA channel\n"); ++ goto err_add_dma; ++ } ++ host_priv->dma_chan = ret; ++ ++ ret = request_irq(host_priv->dma_irq, sdhci_bcm2708_dma_irq, ++ IRQF_SHARED, DRIVER_NAME " (dma)", host); ++ if (ret) { ++ dev_err(&pdev->dev, "cannot set DMA IRQ\n"); ++ goto err_add_dma_irq; ++ } ++ DBG("DMA CBs %p handle %08X DMA%d %p DMA IRQ %d\n", ++ host_priv->cb_base, (unsigned)host_priv->cb_handle, ++ host_priv->dma_chan, host_priv->dma_chan_base, ++ host_priv->dma_irq); ++ ++ host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; ++#endif ++ ++ ret = sdhci_add_host(host); ++ if (ret) ++ goto err_add_host; ++ ++ platform_set_drvdata(pdev, host); ++ ret = device_create_file(&pdev->dev, &dev_attr_use_dma); ++ ret = device_create_file(&pdev->dev, &dev_attr_dma_wait); ++ ret = device_create_file(&pdev->dev, &dev_attr_status); ++ ++ printk(KERN_INFO "%s: BCM2708 SDHC host at 0x%08llx DMA %d IRQ %d\n", ++ mmc_hostname(host->mmc), (unsigned long long)iomem->start, ++ host_priv->dma_chan, host_priv->dma_irq); ++ ++ return 0; ++ ++err_add_host: ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ free_irq(host_priv->dma_irq, host); ++err_add_dma_irq: ++ bcm_dma_chan_free(host_priv->dma_chan); ++err_add_dma: ++ dma_free_writecombine(&pdev->dev, SZ_4K, host_priv->cb_base, ++ host_priv->cb_handle); ++err_alloc_cb: ++#endif ++ iounmap(host->ioaddr); ++err_remap: ++ release_mem_region(iomem->start, resource_size(iomem)); ++err_request: ++ sdhci_free_host(host); ++err: ++ dev_err(&pdev->dev, "probe failed, err %d\n", ret); ++ return ret; ++} ++ ++static int sdhci_bcm2708_remove(struct platform_device *pdev) ++{ ++ struct sdhci_host *host = platform_get_drvdata(pdev); ++ struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host); ++ int dead; ++ u32 scratch; ++ ++ dead = 0; ++ scratch = sdhci_bcm2708_readl(host, SDHCI_INT_STATUS); ++ if (scratch == (u32)-1) ++ dead = 1; ++ ++ device_remove_file(&pdev->dev, &dev_attr_status); ++ device_remove_file(&pdev->dev, &dev_attr_dma_wait); ++ device_remove_file(&pdev->dev, &dev_attr_use_dma); ++ ++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA ++ free_irq(host_priv->dma_irq, host); ++ dma_free_writecombine(&pdev->dev, SZ_4K, host_priv->cb_base, ++ host_priv->cb_handle); ++#endif ++ sdhci_remove_host(host, dead); ++ iounmap(host->ioaddr); ++ release_mem_region(iomem->start, resource_size(iomem)); ++ sdhci_free_host(host); ++ platform_set_drvdata(pdev, NULL); ++ ++ return 0; ++} ++ ++static struct platform_driver sdhci_bcm2708_driver = { ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++ .probe = sdhci_bcm2708_probe, ++ .remove = sdhci_bcm2708_remove, ++ ++#ifdef CONFIG_PM ++ .suspend = sdhci_bcm2708_suspend, ++ .resume = sdhci_bcm2708_resume, ++#endif ++ ++}; ++ ++/*****************************************************************************\ ++ * * ++ * Driver init/exit * ++ * * ++\*****************************************************************************/ ++ ++static int __init sdhci_drv_init(void) ++{ ++ return platform_driver_register(&sdhci_bcm2708_driver); ++} ++ ++static void __exit sdhci_drv_exit(void) ++{ ++ platform_driver_unregister(&sdhci_bcm2708_driver); ++} ++ ++module_init(sdhci_drv_init); ++module_exit(sdhci_drv_exit); ++ ++MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver"); ++MODULE_AUTHOR("Broadcom "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:"DRIVER_NAME); ++ +Index: linux-3.10-3.10.11/drivers/mmc/host/sdhci.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/mmc/host/sdhci.c 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mmc/host/sdhci.c 2014-05-05 12:51:09.000000000 +0000 +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + + #include "sdhci.h" +@@ -315,7 +316,7 @@ + u32 uninitialized_var(scratch); + u8 *buf; + +- DBG("PIO reading\n"); ++ DBG("PIO reading %db\n", host->data->blksz); + + blksize = host->data->blksz; + chunk = 0; +@@ -360,7 +361,7 @@ + u32 scratch; + u8 *buf; + +- DBG("PIO writing\n"); ++ DBG("PIO writing %db\n", host->data->blksz); + + blksize = host->data->blksz; + chunk = 0; +@@ -399,19 +400,28 @@ + local_irq_restore(flags); + } + +-static void sdhci_transfer_pio(struct sdhci_host *host) ++static void sdhci_transfer_pio(struct sdhci_host *host, u32 intstate) + { + u32 mask; ++ u32 state = 0; ++ u32 intmask; ++ int available; + + BUG_ON(!host->data); + + if (host->blocks == 0) + return; + +- if (host->data->flags & MMC_DATA_READ) ++ if (host->data->flags & MMC_DATA_READ) { + mask = SDHCI_DATA_AVAILABLE; +- else ++ intmask = SDHCI_INT_DATA_AVAIL; ++ } else { + mask = SDHCI_SPACE_AVAILABLE; ++ intmask = SDHCI_INT_SPACE_AVAIL; ++ } ++ ++ /* initially we can see whether we can procede using intstate */ ++ available = (intstate & intmask); + + /* + * Some controllers (JMicron JMB38x) mess up the buffer bits +@@ -422,7 +432,7 @@ + (host->data->blocks == 1)) + mask = ~0; + +- while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { ++ while (available) { + if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY) + udelay(100); + +@@ -434,9 +444,11 @@ + host->blocks--; + if (host->blocks == 0) + break; ++ state = sdhci_readl(host, SDHCI_PRESENT_STATE); ++ available = state & mask; + } + +- DBG("PIO transfer complete.\n"); ++ DBG("PIO transfer complete - %d blocks left.\n", host->blocks); + } + + static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) +@@ -709,7 +721,9 @@ + u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL; + u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR; + +- if (host->flags & SDHCI_REQ_USE_DMA) ++ /* platform DMA will begin on receipt of PIO irqs */ ++ if ((host->flags & SDHCI_REQ_USE_DMA) && ++ !(host->flags & SDHCI_USE_PLATDMA)) + sdhci_clear_set_irqs(host, pio_irqs, dma_irqs); + else + sdhci_clear_set_irqs(host, dma_irqs, pio_irqs); +@@ -741,44 +755,25 @@ + host->data_early = 0; + host->data->bytes_xfered = 0; + +- if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) ++ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA | SDHCI_USE_PLATDMA)) + host->flags |= SDHCI_REQ_USE_DMA; + + /* + * FIXME: This doesn't account for merging when mapping the + * scatterlist. + */ +- if (host->flags & SDHCI_REQ_USE_DMA) { +- int broken, i; +- struct scatterlist *sg; +- +- broken = 0; +- if (host->flags & SDHCI_USE_ADMA) { +- if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE) +- broken = 1; +- } else { +- if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) +- broken = 1; +- } +- +- if (unlikely(broken)) { +- for_each_sg(data->sg, sg, data->sg_len, i) { +- if (sg->length & 0x3) { +- DBG("Reverting to PIO because of " +- "transfer size (%d)\n", +- sg->length); +- host->flags &= ~SDHCI_REQ_USE_DMA; +- break; +- } +- } +- } +- } + + /* + * The assumption here being that alignment is the same after + * translation to device address space. + */ +- if (host->flags & SDHCI_REQ_USE_DMA) { ++ if ((host->flags & (SDHCI_REQ_USE_DMA | SDHCI_USE_PLATDMA)) == ++ (SDHCI_REQ_USE_DMA | SDHCI_USE_PLATDMA)) { ++ ++ if (! sdhci_platdma_dmaable(host, data)) ++ host->flags &= ~SDHCI_REQ_USE_DMA; ++ ++ } else if (host->flags & SDHCI_REQ_USE_DMA) { + int broken, i; + struct scatterlist *sg; + +@@ -837,7 +832,8 @@ + */ + WARN_ON(1); + host->flags &= ~SDHCI_REQ_USE_DMA; +- } else { ++ } else ++ if (!(host->flags & SDHCI_USE_PLATDMA)) { + WARN_ON(sg_cnt != 1); + sdhci_writel(host, sg_dma_address(data->sg), + SDHCI_DMA_ADDRESS); +@@ -853,11 +849,13 @@ + if (host->version >= SDHCI_SPEC_200) { + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + ctrl &= ~SDHCI_CTRL_DMA_MASK; ++ if (! (host->flags & SDHCI_USE_PLATDMA)) { + if ((host->flags & SDHCI_REQ_USE_DMA) && + (host->flags & SDHCI_USE_ADMA)) + ctrl |= SDHCI_CTRL_ADMA32; + else + ctrl |= SDHCI_CTRL_SDMA; ++ } + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + } + +@@ -909,7 +907,8 @@ + + if (data->flags & MMC_DATA_READ) + mode |= SDHCI_TRNS_READ; +- if (host->flags & SDHCI_REQ_USE_DMA) ++ if ((host->flags & SDHCI_REQ_USE_DMA) && ++ !(host->flags & SDHCI_USE_PLATDMA)) + mode |= SDHCI_TRNS_DMA; + + sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); +@@ -925,13 +924,16 @@ + host->data = NULL; + + if (host->flags & SDHCI_REQ_USE_DMA) { +- if (host->flags & SDHCI_USE_ADMA) +- sdhci_adma_table_post(host, data); +- else { ++ /* we may have to abandon an ongoing platform DMA */ ++ if (host->flags & SDHCI_USE_PLATDMA) ++ sdhci_platdma_reset(host, data); ++ ++ if (host->flags & (SDHCI_USE_PLATDMA | SDHCI_USE_SDMA)) { + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, (data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE : DMA_TO_DEVICE); +- } ++ } else if (host->flags & SDHCI_USE_ADMA) ++ sdhci_adma_table_post(host, data); + } + + /* +@@ -984,6 +986,12 @@ + if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) + mask |= SDHCI_DATA_INHIBIT; + ++ if(host->ops->missing_status && (cmd->opcode == MMC_SEND_STATUS)) { ++ timeout = 5000; // Really obscenely large delay to send the status, due to bug in controller ++ // which might cause the STATUS command to get stuck when a data operation is in flow ++ mask |= SDHCI_DATA_INHIBIT; ++ } ++ + /* We shouldn't wait for data inihibit for stop commands, even + though they might use busy signaling */ + if (host->mrq->data && (cmd == host->mrq->data->stop)) +@@ -1001,10 +1009,16 @@ + timeout--; + mdelay(1); + } ++ DBG("send cmd %d - wait 0x%X irq 0x%x\n", cmd->opcode, mask, ++ sdhci_readl(host, SDHCI_INT_STATUS)); + + mod_timer(&host->timer, jiffies + 10 * HZ); + + host->cmd = cmd; ++ if (host->last_cmdop == MMC_APP_CMD) ++ host->last_cmdop = -cmd->opcode; ++ else ++ host->last_cmdop = cmd->opcode; + + sdhci_prepare_data(host, cmd); + +@@ -1470,7 +1484,7 @@ + else + ctrl &= ~SDHCI_CTRL_HISPD; + +- if (host->version >= SDHCI_SPEC_300) { ++ if (host->version >= SDHCI_SPEC_300 && !(host->ops->uhs_broken)) { + u16 clk, ctrl_2; + + /* In case of UHS-I modes, set High Speed Enable */ +@@ -2164,7 +2178,7 @@ + + if (host->mrq) { + pr_err("%s: Timeout waiting for hardware " +- "interrupt.\n", mmc_hostname(host->mmc)); ++ "interrupt - cmd%d.\n", mmc_hostname(host->mmc), host->last_cmdop); + sdhci_dumpregs(host); + + if (host->data) { +@@ -2209,10 +2223,13 @@ + BUG_ON(intmask == 0); + + if (!host->cmd) { ++ if (!(host->ops->extra_ints)) { + pr_err("%s: Got command interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + sdhci_dumpregs(host); ++ } else ++ DBG("cmd irq 0x%08x cmd complete\n", (unsigned)intmask); + return; + } + +@@ -2282,6 +2299,19 @@ + static void sdhci_show_adma_error(struct sdhci_host *host) { } + #endif + ++static void sdhci_data_end(struct sdhci_host *host) ++{ ++ if (host->cmd) { ++ /* ++ * Data managed to finish before the ++ * command completed. Make sure we do ++ * things in the proper order. ++ */ ++ host->data_early = 1; ++ } else ++ sdhci_finish_data(host); ++} ++ + static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) + { + u32 command; +@@ -2311,23 +2341,39 @@ + } + } + ++ if (!(host->ops->extra_ints)) { + pr_err("%s: Got data interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + sdhci_dumpregs(host); ++ } else ++ DBG("data irq 0x%08x but no data\n", (unsigned)intmask); + + return; + } + + if (intmask & SDHCI_INT_DATA_TIMEOUT) + host->data->error = -ETIMEDOUT; +- else if (intmask & SDHCI_INT_DATA_END_BIT) ++ else if (intmask & SDHCI_INT_DATA_END_BIT) { ++ DBG("end error in cmd %d\n", host->last_cmdop); ++ if (host->ops->spurious_crc_acmd51 && ++ host->last_cmdop == -SD_APP_SEND_SCR) { ++ DBG("ignoring spurious data_end_bit error\n"); ++ intmask = SDHCI_INT_DATA_AVAIL|SDHCI_INT_DATA_END; ++ } else + host->data->error = -EILSEQ; +- else if ((intmask & SDHCI_INT_DATA_CRC) && ++ } else if ((intmask & SDHCI_INT_DATA_CRC) && + SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) +- != MMC_BUS_TEST_R) ++ != MMC_BUS_TEST_R) { ++ DBG("crc error in cmd %d\n", host->last_cmdop); ++ if (host->ops->spurious_crc_acmd51 && ++ host->last_cmdop == -SD_APP_SEND_SCR) { ++ DBG("ignoring spurious data_crc_bit error\n"); ++ intmask = SDHCI_INT_DATA_AVAIL|SDHCI_INT_DATA_END; ++ } else { + host->data->error = -EILSEQ; +- else if (intmask & SDHCI_INT_ADMA_ERROR) { ++ } ++ } else if (intmask & SDHCI_INT_ADMA_ERROR) { + pr_err("%s: ADMA error\n", mmc_hostname(host->mmc)); + sdhci_show_adma_error(host); + host->data->error = -EIO; +@@ -2335,11 +2381,18 @@ + host->ops->adma_workaround(host, intmask); + } + +- if (host->data->error) ++ if (host->data->error) { ++ DBG("finish request early on error %d\n", host->data->error); + sdhci_finish_data(host); +- else { +- if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) +- sdhci_transfer_pio(host); ++ } else { ++ if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) { ++ if (host->flags & SDHCI_REQ_USE_DMA) { ++ /* possible only in PLATDMA mode */ ++ sdhci_platdma_avail(host, &intmask, ++ &sdhci_data_end); ++ } else ++ sdhci_transfer_pio(host, intmask); ++ } + + /* + * We currently don't do anything fancy with DMA +@@ -2368,18 +2421,8 @@ + sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); + } + +- if (intmask & SDHCI_INT_DATA_END) { +- if (host->cmd) { +- /* +- * Data managed to finish before the +- * command completed. Make sure we do +- * things in the proper order. +- */ +- host->data_early = 1; +- } else { +- sdhci_finish_data(host); +- } +- } ++ if (intmask & SDHCI_INT_DATA_END) ++ sdhci_data_end(host); + } + } + +@@ -2435,6 +2478,22 @@ + tasklet_schedule(&host->card_tasklet); + } + ++ if (intmask & SDHCI_INT_ERROR_MASK & ~SDHCI_INT_ERROR) ++ DBG("controller reports error 0x%x -" ++ "%s%s%s%s%s%s%s%s%s%s", ++ intmask, ++ intmask & SDHCI_INT_TIMEOUT? " timeout": "", ++ intmask & SDHCI_INT_CRC ? " crc": "", ++ intmask & SDHCI_INT_END_BIT? " endbit": "", ++ intmask & SDHCI_INT_INDEX? " index": "", ++ intmask & SDHCI_INT_DATA_TIMEOUT? " data_timeout": "", ++ intmask & SDHCI_INT_DATA_CRC? " data_crc": "", ++ intmask & SDHCI_INT_DATA_END_BIT? " data_endbit": "", ++ intmask & SDHCI_INT_BUS_POWER? " buspower": "", ++ intmask & SDHCI_INT_ACMD12ERR? " acmd12": "", ++ intmask & SDHCI_INT_ADMA_ERROR? " adma": "" ++ ); ++ + if (intmask & SDHCI_INT_CMD_MASK) { + sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK, + SDHCI_INT_STATUS); +@@ -2449,7 +2508,13 @@ + + intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); + +- intmask &= ~SDHCI_INT_ERROR; ++ if (intmask & SDHCI_INT_ERROR_MASK) { ++ /* collect any uncovered errors */ ++ sdhci_writel(host, intmask & SDHCI_INT_ERROR_MASK, ++ SDHCI_INT_STATUS); ++ } ++ ++ intmask &= ~SDHCI_INT_ERROR_MASK; + + if (intmask & SDHCI_INT_BUS_POWER) { + pr_err("%s: Card is consuming too much power!\n", +@@ -2569,7 +2634,8 @@ + { + int ret; + +- if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { ++ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA | ++ SDHCI_USE_PLATDMA)) { + if (host->ops->enable_dma) + host->ops->enable_dma(host); + } +@@ -2785,14 +2851,16 @@ + host->flags &= ~SDHCI_USE_ADMA; + } + +- if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { ++ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA | ++ SDHCI_USE_PLATDMA)) { + if (host->ops->enable_dma) { + if (host->ops->enable_dma(host)) { + pr_warning("%s: No suitable DMA " + "available. Falling back to PIO.\n", + mmc_hostname(mmc)); + host->flags &= +- ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA); ++ ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA | ++ SDHCI_USE_PLATDMA); + } + } + } +@@ -3080,6 +3148,12 @@ + SDHCI_MAX_CURRENT_MULTIPLIER; + } + ++ if(host->ops->voltage_broken) { ++ ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; ++ // Cannot support UHS modes if we are stuck at 3.3V; ++ mmc->caps &= ~(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50); ++ } ++ + mmc->ocr_avail = ocr_avail; + mmc->ocr_avail_sdio = ocr_avail; + if (host->ocr_avail_sdio) +@@ -3210,6 +3284,7 @@ + + pr_info("%s: SDHCI controller on %s [%s] using %s\n", + mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), ++ (host->flags & SDHCI_USE_PLATDMA) ? "platform's DMA" : + (host->flags & SDHCI_USE_ADMA) ? "ADMA" : + (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); + +Index: linux-3.10-3.10.11/drivers/mmc/host/sdhci.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/mmc/host/sdhci.h 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/mmc/host/sdhci.h 2014-05-05 12:51:09.000000000 +0000 +@@ -289,6 +289,20 @@ + void (*platform_reset_enter)(struct sdhci_host *host, u8 mask); + void (*platform_reset_exit)(struct sdhci_host *host, u8 mask); + int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs); ++ ++ int (*pdma_able)(struct sdhci_host *host, ++ struct mmc_data *data); ++ void (*pdma_avail)(struct sdhci_host *host, ++ unsigned int *ref_intmask, ++ void(*complete)(struct sdhci_host *)); ++ void (*pdma_reset)(struct sdhci_host *host, ++ struct mmc_data *data); ++ unsigned int (*extra_ints)(struct sdhci_host *host); ++ unsigned int (*spurious_crc_acmd51)(struct sdhci_host *host); ++ unsigned int (*voltage_broken)(struct sdhci_host *host); ++ unsigned int (*uhs_broken)(struct sdhci_host *host); ++ unsigned int (*missing_status)(struct sdhci_host *host); ++ + void (*hw_reset)(struct sdhci_host *host); + void (*platform_suspend)(struct sdhci_host *host); + void (*platform_resume)(struct sdhci_host *host); +@@ -399,6 +413,29 @@ + extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); + #endif + ++static inline int /*bool*/ ++sdhci_platdma_dmaable(struct sdhci_host *host, struct mmc_data *data) ++{ ++ if (host->ops->pdma_able) ++ return host->ops->pdma_able(host, data); ++ else ++ return 1; ++} ++static inline void ++sdhci_platdma_avail(struct sdhci_host *host, unsigned int *ref_intmask, ++ void(*completion_callback)(struct sdhci_host *)) ++{ ++ if (host->ops->pdma_avail) ++ host->ops->pdma_avail(host, ref_intmask, completion_callback); ++} ++ ++static inline void ++sdhci_platdma_reset(struct sdhci_host *host, struct mmc_data *data) ++{ ++ if (host->ops->pdma_reset) ++ host->ops->pdma_reset(host, data); ++} ++ + #ifdef CONFIG_PM_RUNTIME + extern int sdhci_runtime_suspend_host(struct sdhci_host *host); + extern int sdhci_runtime_resume_host(struct sdhci_host *host); +Index: linux-3.10-3.10.11/include/linux/mmc/sdhci.h +=================================================================== +--- linux-3.10-3.10.11.orig/include/linux/mmc/sdhci.h 2014-05-05 11:48:38.000000000 +0000 ++++ linux-3.10-3.10.11/include/linux/mmc/sdhci.h 2014-05-05 12:51:09.000000000 +0000 +@@ -128,6 +128,7 @@ + #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ + #define SDHCI_HS200_NEEDS_TUNING (1<<10) /* HS200 needs tuning */ + #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ ++#define SDHCI_USE_PLATDMA (1<<12) /* Host uses 3rd party DMA */ + + unsigned int version; /* SDHCI spec. version */ + +@@ -142,6 +143,7 @@ + + struct mmc_request *mrq; /* Current request */ + struct mmc_command *cmd; /* Current command */ ++ int last_cmdop; /* Opcode of last cmd sent */ + struct mmc_data *data; /* Current data request */ + unsigned int data_early:1; /* Data finished before cmd */ + +Index: linux-3.10-3.10.11/dummy/rpi_1571_464ff6a40a8e684ebc730b5ede44c646b1d4e6c9.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1571_464ff6a40a8e684ebc730b5ede44c646b1d4e6c9.txt 2014-05-05 12:51:09.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1572_a0b25b587dfcc4c6816b655fa452eb4b03d55e33.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1572_a0b25b587dfcc4c6816b655fa452eb4b03d55e33.patch --- linux-3.10.11/debian/patches/rpi/rpi_1572_a0b25b587dfcc4c6816b655fa452eb4b03d55e33.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1572_a0b25b587dfcc4c6816b655fa452eb4b03d55e33.patch 2014-05-05 12:51:20.000000000 +0000 @@ -0,0 +1,56902 @@ +commit a0b25b587dfcc4c6816b655fa452eb4b03d55e33 +Author: popcornmix +Date: Wed May 1 19:46:17 2013 +0100 + + Add dwc_otg driver + + Signed-off-by: popcornmix + +Index: linux-3.10-3.10.11/drivers/usb/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/Makefile 2014-05-05 11:48:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/Makefile 2014-05-05 12:51:13.000000000 +0000 +@@ -23,6 +23,7 @@ + obj-$(CONFIG_USB_R8A66597_HCD) += host/ + obj-$(CONFIG_USB_HWA_HCD) += host/ + obj-$(CONFIG_USB_ISP1760_HCD) += host/ ++obj-$(CONFIG_USB_DWCOTG) += host/ + obj-$(CONFIG_USB_IMX21_HCD) += host/ + obj-$(CONFIG_USB_FSL_MPH_DR_OF) += host/ + +Index: linux-3.10-3.10.11/drivers/usb/core/generic.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/generic.c 2014-05-05 11:48:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/generic.c 2014-05-05 12:51:13.000000000 +0000 +@@ -152,6 +152,7 @@ + dev_warn(&udev->dev, + "no configuration chosen from %d choice%s\n", + num_configs, plural(num_configs)); ++ dev_warn(&udev->dev, "No support over %dmA\n", udev->bus_mA); + } + return i; + } +Index: linux-3.10-3.10.11/drivers/usb/core/message.c +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/message.c 2014-05-05 11:48:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/message.c 2014-05-05 12:51:13.000000000 +0000 +@@ -1875,6 +1875,85 @@ + if (cp->string == NULL && + !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) + cp->string = usb_cache_string(dev, cp->desc.iConfiguration); ++/* Uncomment this define to enable the HS Electrical Test support */ ++#define DWC_HS_ELECT_TST 1 ++#ifdef DWC_HS_ELECT_TST ++ /* Here we implement the HS Electrical Test support. The ++ * tester uses a vendor ID of 0x1A0A to indicate we should ++ * run a special test sequence. The product ID tells us ++ * which sequence to run. We invoke the test sequence by ++ * sending a non-standard SetFeature command to our root ++ * hub port. Our dwc_otg_hcd_hub_control() routine will ++ * recognize the command and perform the desired test ++ * sequence. ++ */ ++ if (dev->descriptor.idVendor == 0x1A0A) { ++ /* HSOTG Electrical Test */ ++ dev_warn(&dev->dev, "VID from HSOTG Electrical Test Fixture\n"); ++ ++ if (dev->bus && dev->bus->root_hub) { ++ struct usb_device *hdev = dev->bus->root_hub; ++ dev_warn(&dev->dev, "Got PID 0x%x\n", dev->descriptor.idProduct); ++ ++ switch (dev->descriptor.idProduct) { ++ case 0x0101: /* TEST_SE0_NAK */ ++ dev_warn(&dev->dev, "TEST_SE0_NAK\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x300, NULL, 0, HZ); ++ break; ++ ++ case 0x0102: /* TEST_J */ ++ dev_warn(&dev->dev, "TEST_J\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x100, NULL, 0, HZ); ++ break; ++ ++ case 0x0103: /* TEST_K */ ++ dev_warn(&dev->dev, "TEST_K\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x200, NULL, 0, HZ); ++ break; ++ ++ case 0x0104: /* TEST_PACKET */ ++ dev_warn(&dev->dev, "TEST_PACKET\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x400, NULL, 0, HZ); ++ break; ++ ++ case 0x0105: /* TEST_FORCE_ENABLE */ ++ dev_warn(&dev->dev, "TEST_FORCE_ENABLE\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x500, NULL, 0, HZ); ++ break; ++ ++ case 0x0106: /* HS_HOST_PORT_SUSPEND_RESUME */ ++ dev_warn(&dev->dev, "HS_HOST_PORT_SUSPEND_RESUME\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x600, NULL, 0, 40 * HZ); ++ break; ++ ++ case 0x0107: /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */ ++ dev_warn(&dev->dev, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x700, NULL, 0, 40 * HZ); ++ break; ++ ++ case 0x0108: /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */ ++ dev_warn(&dev->dev, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute\n"); ++ usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ USB_REQ_SET_FEATURE, USB_RT_PORT, ++ USB_PORT_FEAT_TEST, 0x800, NULL, 0, 40 * HZ); ++ } ++ } ++ } ++#endif /* DWC_HS_ELECT_TST */ + + /* Now that the interfaces are installed, re-enable LPM. */ + usb_unlocked_enable_lpm(dev); +Index: linux-3.10-3.10.11/drivers/usb/core/otg_whitelist.h +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/core/otg_whitelist.h 2014-05-05 11:48:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/core/otg_whitelist.h 2014-05-05 12:51:13.000000000 +0000 +@@ -19,33 +19,82 @@ + static struct usb_device_id whitelist_table [] = { + + /* hubs are optional in OTG, but very handy ... */ ++#define CERT_WITHOUT_HUBS ++#if defined(CERT_WITHOUT_HUBS) ++{ USB_DEVICE( 0x0000, 0x0000 ), }, /* Root HUB Only*/ ++#else + { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 0), }, + { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 1), }, ++{ USB_DEVICE_INFO(USB_CLASS_HUB, 0, 2), }, ++#endif + + #ifdef CONFIG_USB_PRINTER /* ignoring nonstatic linkage! */ + /* FIXME actually, printers are NOT supposed to use device classes; + * they're supposed to use interface classes... + */ +-{ USB_DEVICE_INFO(7, 1, 1) }, +-{ USB_DEVICE_INFO(7, 1, 2) }, +-{ USB_DEVICE_INFO(7, 1, 3) }, ++//{ USB_DEVICE_INFO(7, 1, 1) }, ++//{ USB_DEVICE_INFO(7, 1, 2) }, ++//{ USB_DEVICE_INFO(7, 1, 3) }, + #endif + + #ifdef CONFIG_USB_NET_CDCETHER + /* Linux-USB CDC Ethernet gadget */ +-{ USB_DEVICE(0x0525, 0xa4a1), }, ++//{ USB_DEVICE(0x0525, 0xa4a1), }, + /* Linux-USB CDC Ethernet + RNDIS gadget */ +-{ USB_DEVICE(0x0525, 0xa4a2), }, ++//{ USB_DEVICE(0x0525, 0xa4a2), }, + #endif + + #if defined(CONFIG_USB_TEST) || defined(CONFIG_USB_TEST_MODULE) + /* gadget zero, for testing */ +-{ USB_DEVICE(0x0525, 0xa4a0), }, ++//{ USB_DEVICE(0x0525, 0xa4a0), }, + #endif ++ ++/* OPT Tester */ ++{ USB_DEVICE( 0x1a0a, 0x0101 ), }, /* TEST_SE0_NAK */ ++{ USB_DEVICE( 0x1a0a, 0x0102 ), }, /* Test_J */ ++{ USB_DEVICE( 0x1a0a, 0x0103 ), }, /* Test_K */ ++{ USB_DEVICE( 0x1a0a, 0x0104 ), }, /* Test_PACKET */ ++{ USB_DEVICE( 0x1a0a, 0x0105 ), }, /* Test_FORCE_ENABLE */ ++{ USB_DEVICE( 0x1a0a, 0x0106 ), }, /* HS_PORT_SUSPEND_RESUME */ ++{ USB_DEVICE( 0x1a0a, 0x0107 ), }, /* SINGLE_STEP_GET_DESCRIPTOR setup */ ++{ USB_DEVICE( 0x1a0a, 0x0108 ), }, /* SINGLE_STEP_GET_DESCRIPTOR execute */ ++ ++/* Sony cameras */ ++{ USB_DEVICE_VER(0x054c,0x0010,0x0410, 0x0500), }, ++ ++/* Memory Devices */ ++//{ USB_DEVICE( 0x0781, 0x5150 ), }, /* SanDisk */ ++//{ USB_DEVICE( 0x05DC, 0x0080 ), }, /* Lexar */ ++//{ USB_DEVICE( 0x4146, 0x9281 ), }, /* IOMEGA */ ++//{ USB_DEVICE( 0x067b, 0x2507 ), }, /* Hammer 20GB External HD */ ++{ USB_DEVICE( 0x0EA0, 0x2168 ), }, /* Ours Technology Inc. (BUFFALO ClipDrive)*/ ++//{ USB_DEVICE( 0x0457, 0x0150 ), }, /* Silicon Integrated Systems Corp. */ ++ ++/* HP Printers */ ++//{ USB_DEVICE( 0x03F0, 0x1102 ), }, /* HP Photosmart 245 */ ++//{ USB_DEVICE( 0x03F0, 0x1302 ), }, /* HP Photosmart 370 Series */ ++ ++/* Speakers */ ++//{ USB_DEVICE( 0x0499, 0x3002 ), }, /* YAMAHA YST-MS35D USB Speakers */ ++//{ USB_DEVICE( 0x0672, 0x1041 ), }, /* Labtec USB Headset */ + + { } /* Terminating entry */ + }; + ++static inline void report_errors(struct usb_device *dev) ++{ ++ /* OTG MESSAGE: report errors here, customize to match your product */ ++ dev_info(&dev->dev, "device Vendor:%04x Product:%04x is not supported\n", ++ le16_to_cpu(dev->descriptor.idVendor), ++ le16_to_cpu(dev->descriptor.idProduct)); ++ if (USB_CLASS_HUB == dev->descriptor.bDeviceClass){ ++ dev_printk(KERN_CRIT, &dev->dev, "Unsupported Hub Topology\n"); ++ } else { ++ dev_printk(KERN_CRIT, &dev->dev, "Attached Device is not Supported\n"); ++ } ++} ++ ++ + static int is_targeted(struct usb_device *dev) + { + struct usb_device_id *id = whitelist_table; +@@ -55,58 +104,83 @@ + return 1; + + /* HNP test device is _never_ targeted (see OTG spec 6.6.6) */ +- if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && +- le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) +- return 0; ++ if (dev->descriptor.idVendor == 0x1a0a && ++ dev->descriptor.idProduct == 0xbadd) { ++ return 0; ++ } else if (!enable_whitelist) { ++ return 1; ++ } else { + +- /* NOTE: can't use usb_match_id() since interface caches +- * aren't set up yet. this is cut/paste from that code. +- */ +- for (id = whitelist_table; id->match_flags; id++) { +- if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && +- id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) +- continue; +- +- if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && +- id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) +- continue; +- +- /* No need to test id->bcdDevice_lo != 0, since 0 is never +- greater than any unsigned number. */ +- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && +- (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) +- continue; +- +- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && +- (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) +- continue; +- +- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && +- (id->bDeviceClass != dev->descriptor.bDeviceClass)) +- continue; +- +- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && +- (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass)) +- continue; +- +- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && +- (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) +- continue; ++#ifdef DEBUG ++ dev_dbg(&dev->dev, "device V:%04x P:%04x DC:%04x SC:%04x PR:%04x \n", ++ dev->descriptor.idVendor, ++ dev->descriptor.idProduct, ++ dev->descriptor.bDeviceClass, ++ dev->descriptor.bDeviceSubClass, ++ dev->descriptor.bDeviceProtocol); ++#endif + + return 1; ++ /* NOTE: can't use usb_match_id() since interface caches ++ * aren't set up yet. this is cut/paste from that code. ++ */ ++ for (id = whitelist_table; id->match_flags; id++) { ++#ifdef DEBUG ++ dev_dbg(&dev->dev, ++ "ID: V:%04x P:%04x DC:%04x SC:%04x PR:%04x \n", ++ id->idVendor, ++ id->idProduct, ++ id->bDeviceClass, ++ id->bDeviceSubClass, ++ id->bDeviceProtocol); ++#endif ++ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && ++ id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) ++ continue; ++ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && ++ id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) ++ continue; ++ ++ /* No need to test id->bcdDevice_lo != 0, since 0 is never ++ greater than any unsigned number. */ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && ++ (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) ++ continue; ++ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && ++ (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) ++ continue; ++ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && ++ (id->bDeviceClass != dev->descriptor.bDeviceClass)) ++ continue; ++ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && ++ (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass)) ++ continue; ++ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && ++ (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) ++ continue; ++ ++ return 1; ++ } + } + + /* add other match criteria here ... */ + +- +- /* OTG MESSAGE: report errors here, customize to match your product */ +- dev_err(&dev->dev, "device v%04x p%04x is not supported\n", +- le16_to_cpu(dev->descriptor.idVendor), +- le16_to_cpu(dev->descriptor.idProduct)); + #ifdef CONFIG_USB_OTG_WHITELIST ++ report_errors(dev); + return 0; + #else +- return 1; ++ if (enable_whitelist) { ++ report_errors(dev); ++ return 0; ++ } else { ++ return 1; ++ } + #endif + } + +Index: linux-3.10-3.10.11/drivers/usb/gadget/file_storage.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/gadget/file_storage.c 2014-05-05 12:51:13.000000000 +0000 +@@ -0,0 +1,3676 @@ ++/* ++ * file_storage.c -- File-backed USB Storage Gadget, for USB development ++ * ++ * Copyright (C) 2003-2008 Alan Stern ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") as published by the Free Software ++ * Foundation, either version 2 of that License or (at your option) any ++ * later version. ++ * ++ * 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. ++ */ ++ ++ ++/* ++ * The File-backed Storage Gadget acts as a USB Mass Storage device, ++ * appearing to the host as a disk drive or as a CD-ROM drive. In addition ++ * to providing an example of a genuinely useful gadget driver for a USB ++ * device, it also illustrates a technique of double-buffering for increased ++ * throughput. Last but not least, it gives an easy way to probe the ++ * behavior of the Mass Storage drivers in a USB host. ++ * ++ * Backing storage is provided by a regular file or a block device, specified ++ * by the "file" module parameter. Access can be limited to read-only by ++ * setting the optional "ro" module parameter. (For CD-ROM emulation, ++ * access is always read-only.) The gadget will indicate that it has ++ * removable media if the optional "removable" module parameter is set. ++ * ++ * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI), ++ * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected ++ * by the optional "transport" module parameter. It also supports the ++ * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03), ++ * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by ++ * the optional "protocol" module parameter. In addition, the default ++ * Vendor ID, Product ID, release number and serial number can be overridden. ++ * ++ * There is support for multiple logical units (LUNs), each of which has ++ * its own backing file. The number of LUNs can be set using the optional ++ * "luns" module parameter (anywhere from 1 to 8), and the corresponding ++ * files are specified using comma-separated lists for "file" and "ro". ++ * The default number of LUNs is taken from the number of "file" elements; ++ * it is 1 if "file" is not given. If "removable" is not set then a backing ++ * file must be specified for each LUN. If it is set, then an unspecified ++ * or empty backing filename means the LUN's medium is not loaded. Ideally ++ * each LUN would be settable independently as a disk drive or a CD-ROM ++ * drive, but currently all LUNs have to be the same type. The CD-ROM ++ * emulation includes a single data track and no audio tracks; hence there ++ * need be only one backing file per LUN. ++ * ++ * Requirements are modest; only a bulk-in and a bulk-out endpoint are ++ * needed (an interrupt-out endpoint is also needed for CBI). The memory ++ * requirement amounts to two 16K buffers, size configurable by a parameter. ++ * Support is included for both full-speed and high-speed operation. ++ * ++ * Note that the driver is slightly non-portable in that it assumes a ++ * single memory/DMA buffer will be useable for bulk-in, bulk-out, and ++ * interrupt-in endpoints. With most device controllers this isn't an ++ * issue, but there may be some with hardware restrictions that prevent ++ * a buffer from being used by more than one endpoint. ++ * ++ * Module options: ++ * ++ * file=filename[,filename...] ++ * Required if "removable" is not set, names of ++ * the files or block devices used for ++ * backing storage ++ * serial=HHHH... Required serial number (string of hex chars) ++ * ro=b[,b...] Default false, booleans for read-only access ++ * removable Default false, boolean for removable media ++ * luns=N Default N = number of filenames, number of ++ * LUNs to support ++ * nofua=b[,b...] Default false, booleans for ignore FUA flag ++ * in SCSI WRITE(10,12) commands ++ * stall Default determined according to the type of ++ * USB device controller (usually true), ++ * boolean to permit the driver to halt ++ * bulk endpoints ++ * cdrom Default false, boolean for whether to emulate ++ * a CD-ROM drive ++ * transport=XXX Default BBB, transport name (CB, CBI, or BBB) ++ * protocol=YYY Default SCSI, protocol name (RBC, 8020 or ++ * ATAPI, QIC, UFI, 8070, or SCSI; ++ * also 1 - 6) ++ * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID ++ * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID ++ * release=0xRRRR Override the USB release number (bcdDevice) ++ * buflen=N Default N=16384, buffer size used (will be ++ * rounded down to a multiple of ++ * PAGE_CACHE_SIZE) ++ * ++ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro", ++ * "removable", "luns", "nofua", "stall", and "cdrom" options are available; ++ * default values are used for everything else. ++ * ++ * The pathnames of the backing files and the ro settings are available in ++ * the attribute files "file", "nofua", and "ro" in the lun subdirectory of ++ * the gadget's sysfs directory. If the "removable" option is set, writing to ++ * these files will simulate ejecting/loading the medium (writing an empty ++ * line means eject) and adjusting a write-enable tab. Changes to the ro ++ * setting are not allowed when the medium is loaded or if CD-ROM emulation ++ * is being used. ++ * ++ * This gadget driver is heavily based on "Gadget Zero" by David Brownell. ++ * The driver's SCSI command interface was based on the "Information ++ * technology - Small Computer System Interface - 2" document from ++ * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at ++ * . The single exception ++ * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the ++ * "Universal Serial Bus Mass Storage Class UFI Command Specification" ++ * document, Revision 1.0, December 14, 1998, available at ++ * . ++ */ ++ ++ ++/* ++ * Driver Design ++ * ++ * The FSG driver is fairly straightforward. There is a main kernel ++ * thread that handles most of the work. Interrupt routines field ++ * callbacks from the controller driver: bulk- and interrupt-request ++ * completion notifications, endpoint-0 events, and disconnect events. ++ * Completion events are passed to the main thread by wakeup calls. Many ++ * ep0 requests are handled at interrupt time, but SetInterface, ++ * SetConfiguration, and device reset requests are forwarded to the ++ * thread in the form of "exceptions" using SIGUSR1 signals (since they ++ * should interrupt any ongoing file I/O operations). ++ * ++ * The thread's main routine implements the standard command/data/status ++ * parts of a SCSI interaction. It and its subroutines are full of tests ++ * for pending signals/exceptions -- all this polling is necessary since ++ * the kernel has no setjmp/longjmp equivalents. (Maybe this is an ++ * indication that the driver really wants to be running in userspace.) ++ * An important point is that so long as the thread is alive it keeps an ++ * open reference to the backing file. This will prevent unmounting ++ * the backing file's underlying filesystem and could cause problems ++ * during system shutdown, for example. To prevent such problems, the ++ * thread catches INT, TERM, and KILL signals and converts them into ++ * an EXIT exception. ++ * ++ * In normal operation the main thread is started during the gadget's ++ * fsg_bind() callback and stopped during fsg_unbind(). But it can also ++ * exit when it receives a signal, and there's no point leaving the ++ * gadget running when the thread is dead. So just before the thread ++ * exits, it deregisters the gadget driver. This makes things a little ++ * tricky: The driver is deregistered at two places, and the exiting ++ * thread can indirectly call fsg_unbind() which in turn can tell the ++ * thread to exit. The first problem is resolved through the use of the ++ * REGISTERED atomic bitflag; the driver will only be deregistered once. ++ * The second problem is resolved by having fsg_unbind() check ++ * fsg->state; it won't try to stop the thread if the state is already ++ * FSG_STATE_TERMINATED. ++ * ++ * To provide maximum throughput, the driver uses a circular pipeline of ++ * buffer heads (struct fsg_buffhd). In principle the pipeline can be ++ * arbitrarily long; in practice the benefits don't justify having more ++ * than 2 stages (i.e., double buffering). But it helps to think of the ++ * pipeline as being a long one. Each buffer head contains a bulk-in and ++ * a bulk-out request pointer (since the buffer can be used for both ++ * output and input -- directions always are given from the host's ++ * point of view) as well as a pointer to the buffer and various state ++ * variables. ++ * ++ * Use of the pipeline follows a simple protocol. There is a variable ++ * (fsg->next_buffhd_to_fill) that points to the next buffer head to use. ++ * At any time that buffer head may still be in use from an earlier ++ * request, so each buffer head has a state variable indicating whether ++ * it is EMPTY, FULL, or BUSY. Typical use involves waiting for the ++ * buffer head to be EMPTY, filling the buffer either by file I/O or by ++ * USB I/O (during which the buffer head is BUSY), and marking the buffer ++ * head FULL when the I/O is complete. Then the buffer will be emptied ++ * (again possibly by USB I/O, during which it is marked BUSY) and ++ * finally marked EMPTY again (possibly by a completion routine). ++ * ++ * A module parameter tells the driver to avoid stalling the bulk ++ * endpoints wherever the transport specification allows. This is ++ * necessary for some UDCs like the SuperH, which cannot reliably clear a ++ * halt on a bulk endpoint. However, under certain circumstances the ++ * Bulk-only specification requires a stall. In such cases the driver ++ * will halt the endpoint and set a flag indicating that it should clear ++ * the halt in software during the next device reset. Hopefully this ++ * will permit everything to work correctly. Furthermore, although the ++ * specification allows the bulk-out endpoint to halt when the host sends ++ * too much data, implementing this would cause an unavoidable race. ++ * The driver will always use the "no-stall" approach for OUT transfers. ++ * ++ * One subtle point concerns sending status-stage responses for ep0 ++ * requests. Some of these requests, such as device reset, can involve ++ * interrupting an ongoing file I/O operation, which might take an ++ * arbitrarily long time. During that delay the host might give up on ++ * the original ep0 request and issue a new one. When that happens the ++ * driver should not notify the host about completion of the original ++ * request, as the host will no longer be waiting for it. So the driver ++ * assigns to each ep0 request a unique tag, and it keeps track of the ++ * tag value of the request associated with a long-running exception ++ * (device-reset, interface-change, or configuration-change). When the ++ * exception handler is finished, the status-stage response is submitted ++ * only if the current ep0 request tag is equal to the exception request ++ * tag. Thus only the most recently received ep0 request will get a ++ * status-stage response. ++ * ++ * Warning: This driver source file is too long. It ought to be split up ++ * into a header file plus about 3 separate .c files, to handle the details ++ * of the Gadget, USB Mass Storage, and SCSI protocols. ++ */ ++ ++ ++/* #define VERBOSE_DEBUG */ ++/* #define DUMP_MSGS */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "gadget_chips.h" ++ ++ ++ ++/* ++ * Kbuild is not very cooperative with respect to linking separately ++ * compiled library objects into one module. So for now we won't use ++ * separate compilation ... ensuring init/exit sections work to shrink ++ * the runtime footprint, and giving us at least some parts of what ++ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. ++ */ ++#include "usbstring.c" ++#include "config.c" ++#include "epautoconf.c" ++ ++/*-------------------------------------------------------------------------*/ ++ ++#define DRIVER_DESC "File-backed Storage Gadget" ++#define DRIVER_NAME "g_file_storage" ++#define DRIVER_VERSION "1 September 2010" ++ ++static char fsg_string_manufacturer[64]; ++static const char fsg_string_product[] = DRIVER_DESC; ++static const char fsg_string_config[] = "Self-powered"; ++static const char fsg_string_interface[] = "Mass Storage"; ++ ++ ++#include "storage_common.c" ++ ++ ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_AUTHOR("Alan Stern"); ++MODULE_LICENSE("Dual BSD/GPL"); ++ ++/* ++ * This driver assumes self-powered hardware and has no way for users to ++ * trigger remote wakeup. It uses autoconfiguration to select endpoints ++ * and endpoint addresses. ++ */ ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++ ++/* Encapsulate the module parameter settings */ ++ ++static struct { ++ char *file[FSG_MAX_LUNS]; ++ char *serial; ++ bool ro[FSG_MAX_LUNS]; ++ bool nofua[FSG_MAX_LUNS]; ++ unsigned int num_filenames; ++ unsigned int num_ros; ++ unsigned int num_nofuas; ++ unsigned int nluns; ++ ++ bool removable; ++ bool can_stall; ++ bool cdrom; ++ ++ char *transport_parm; ++ char *protocol_parm; ++ unsigned short vendor; ++ unsigned short product; ++ unsigned short release; ++ unsigned int buflen; ++ ++ int transport_type; ++ char *transport_name; ++ int protocol_type; ++ char *protocol_name; ++ ++} mod_data = { // Default values ++ .transport_parm = "BBB", ++ .protocol_parm = "SCSI", ++ .removable = 0, ++ .can_stall = 1, ++ .cdrom = 0, ++ .vendor = FSG_VENDOR_ID, ++ .product = FSG_PRODUCT_ID, ++ .release = 0xffff, // Use controller chip type ++ .buflen = 16384, ++ }; ++ ++ ++module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, ++ S_IRUGO); ++MODULE_PARM_DESC(file, "names of backing files or devices"); ++ ++module_param_named(serial, mod_data.serial, charp, S_IRUGO); ++MODULE_PARM_DESC(serial, "USB serial number"); ++ ++module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); ++MODULE_PARM_DESC(ro, "true to force read-only"); ++ ++module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas, ++ S_IRUGO); ++MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit"); ++ ++module_param_named(luns, mod_data.nluns, uint, S_IRUGO); ++MODULE_PARM_DESC(luns, "number of LUNs"); ++ ++module_param_named(removable, mod_data.removable, bool, S_IRUGO); ++MODULE_PARM_DESC(removable, "true to simulate removable media"); ++ ++module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); ++MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); ++ ++module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); ++MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); ++ ++/* In the non-TEST version, only the module parameters listed above ++ * are available. */ ++#ifdef CONFIG_USB_FILE_STORAGE_TEST ++ ++module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO); ++MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)"); ++ ++module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO); ++MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, " ++ "8070, or SCSI)"); ++ ++module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO); ++MODULE_PARM_DESC(vendor, "USB Vendor ID"); ++ ++module_param_named(product, mod_data.product, ushort, S_IRUGO); ++MODULE_PARM_DESC(product, "USB Product ID"); ++ ++module_param_named(release, mod_data.release, ushort, S_IRUGO); ++MODULE_PARM_DESC(release, "USB release number"); ++ ++module_param_named(buflen, mod_data.buflen, uint, S_IRUGO); ++MODULE_PARM_DESC(buflen, "I/O buffer size"); ++ ++#endif /* CONFIG_USB_FILE_STORAGE_TEST */ ++ ++ ++/* ++ * These definitions will permit the compiler to avoid generating code for ++ * parts of the driver that aren't used in the non-TEST version. Even gcc ++ * can recognize when a test of a constant expression yields a dead code ++ * path. ++ */ ++ ++#ifdef CONFIG_USB_FILE_STORAGE_TEST ++ ++#define transport_is_bbb() (mod_data.transport_type == USB_PR_BULK) ++#define transport_is_cbi() (mod_data.transport_type == USB_PR_CBI) ++#define protocol_is_scsi() (mod_data.protocol_type == USB_SC_SCSI) ++ ++#else ++ ++#define transport_is_bbb() 1 ++#define transport_is_cbi() 0 ++#define protocol_is_scsi() 1 ++ ++#endif /* CONFIG_USB_FILE_STORAGE_TEST */ ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++ ++struct fsg_dev { ++ /* lock protects: state, all the req_busy's, and cbbuf_cmnd */ ++ spinlock_t lock; ++ struct usb_gadget *gadget; ++ ++ /* filesem protects: backing files in use */ ++ struct rw_semaphore filesem; ++ ++ /* reference counting: wait until all LUNs are released */ ++ struct kref ref; ++ ++ struct usb_ep *ep0; // Handy copy of gadget->ep0 ++ struct usb_request *ep0req; // For control responses ++ unsigned int ep0_req_tag; ++ const char *ep0req_name; ++ ++ struct usb_request *intreq; // For interrupt responses ++ int intreq_busy; ++ struct fsg_buffhd *intr_buffhd; ++ ++ unsigned int bulk_out_maxpacket; ++ enum fsg_state state; // For exception handling ++ unsigned int exception_req_tag; ++ ++ u8 config, new_config; ++ ++ unsigned int running : 1; ++ unsigned int bulk_in_enabled : 1; ++ unsigned int bulk_out_enabled : 1; ++ unsigned int intr_in_enabled : 1; ++ unsigned int phase_error : 1; ++ unsigned int short_packet_received : 1; ++ unsigned int bad_lun_okay : 1; ++ ++ unsigned long atomic_bitflags; ++#define REGISTERED 0 ++#define IGNORE_BULK_OUT 1 ++#define SUSPENDED 2 ++ ++ struct usb_ep *bulk_in; ++ struct usb_ep *bulk_out; ++ struct usb_ep *intr_in; ++ ++ struct fsg_buffhd *next_buffhd_to_fill; ++ struct fsg_buffhd *next_buffhd_to_drain; ++ ++ int thread_wakeup_needed; ++ struct completion thread_notifier; ++ struct task_struct *thread_task; ++ ++ int cmnd_size; ++ u8 cmnd[MAX_COMMAND_SIZE]; ++ enum data_direction data_dir; ++ u32 data_size; ++ u32 data_size_from_cmnd; ++ u32 tag; ++ unsigned int lun; ++ u32 residue; ++ u32 usb_amount_left; ++ ++ /* The CB protocol offers no way for a host to know when a command ++ * has completed. As a result the next command may arrive early, ++ * and we will still have to handle it. For that reason we need ++ * a buffer to store new commands when using CB (or CBI, which ++ * does not oblige a host to wait for command completion either). */ ++ int cbbuf_cmnd_size; ++ u8 cbbuf_cmnd[MAX_COMMAND_SIZE]; ++ ++ unsigned int nluns; ++ struct fsg_lun *luns; ++ struct fsg_lun *curlun; ++ /* Must be the last entry */ ++ struct fsg_buffhd buffhds[]; ++}; ++ ++typedef void (*fsg_routine_t)(struct fsg_dev *); ++ ++static int exception_in_progress(struct fsg_dev *fsg) ++{ ++ return (fsg->state > FSG_STATE_IDLE); ++} ++ ++/* Make bulk-out requests be divisible by the maxpacket size */ ++static void set_bulk_out_req_length(struct fsg_dev *fsg, ++ struct fsg_buffhd *bh, unsigned int length) ++{ ++ unsigned int rem; ++ ++ bh->bulk_out_intended_length = length; ++ rem = length % fsg->bulk_out_maxpacket; ++ if (rem > 0) ++ length += fsg->bulk_out_maxpacket - rem; ++ bh->outreq->length = length; ++} ++ ++static struct fsg_dev *the_fsg; ++static struct usb_gadget_driver fsg_driver; ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) ++{ ++ const char *name; ++ ++ if (ep == fsg->bulk_in) ++ name = "bulk-in"; ++ else if (ep == fsg->bulk_out) ++ name = "bulk-out"; ++ else ++ name = ep->name; ++ DBG(fsg, "%s set halt\n", name); ++ return usb_ep_set_halt(ep); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * DESCRIPTORS ... most are static, but strings and (full) configuration ++ * descriptors are built on demand. Also the (static) config and interface ++ * descriptors are adjusted during fsg_bind(). ++ */ ++ ++/* There is only one configuration. */ ++#define CONFIG_VALUE 1 ++ ++static struct usb_device_descriptor ++device_desc = { ++ .bLength = sizeof device_desc, ++ .bDescriptorType = USB_DT_DEVICE, ++ ++ .bcdUSB = cpu_to_le16(0x0200), ++ .bDeviceClass = USB_CLASS_PER_INTERFACE, ++ ++ /* The next three values can be overridden by module parameters */ ++ .idVendor = cpu_to_le16(FSG_VENDOR_ID), ++ .idProduct = cpu_to_le16(FSG_PRODUCT_ID), ++ .bcdDevice = cpu_to_le16(0xffff), ++ ++ .iManufacturer = FSG_STRING_MANUFACTURER, ++ .iProduct = FSG_STRING_PRODUCT, ++ .iSerialNumber = FSG_STRING_SERIAL, ++ .bNumConfigurations = 1, ++}; ++ ++static struct usb_config_descriptor ++config_desc = { ++ .bLength = sizeof config_desc, ++ .bDescriptorType = USB_DT_CONFIG, ++ ++ /* wTotalLength computed by usb_gadget_config_buf() */ ++ .bNumInterfaces = 1, ++ .bConfigurationValue = CONFIG_VALUE, ++ .iConfiguration = FSG_STRING_CONFIG, ++ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, ++ .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, ++}; ++ ++ ++static struct usb_qualifier_descriptor ++dev_qualifier = { ++ .bLength = sizeof dev_qualifier, ++ .bDescriptorType = USB_DT_DEVICE_QUALIFIER, ++ ++ .bcdUSB = cpu_to_le16(0x0200), ++ .bDeviceClass = USB_CLASS_PER_INTERFACE, ++ ++ .bNumConfigurations = 1, ++}; ++ ++static int populate_bos(struct fsg_dev *fsg, u8 *buf) ++{ ++ memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE); ++ buf += USB_DT_BOS_SIZE; ++ ++ memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE); ++ buf += USB_DT_USB_EXT_CAP_SIZE; ++ ++ memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE); ++ ++ return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE ++ + USB_DT_USB_EXT_CAP_SIZE; ++} ++ ++/* ++ * Config descriptors must agree with the code that sets configurations ++ * and with code managing interfaces and their altsettings. They must ++ * also handle different speeds and other-speed requests. ++ */ ++static int populate_config_buf(struct usb_gadget *gadget, ++ u8 *buf, u8 type, unsigned index) ++{ ++ enum usb_device_speed speed = gadget->speed; ++ int len; ++ const struct usb_descriptor_header **function; ++ ++ if (index > 0) ++ return -EINVAL; ++ ++ if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) ++ speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; ++ function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH ++ ? (const struct usb_descriptor_header **)fsg_hs_function ++ : (const struct usb_descriptor_header **)fsg_fs_function; ++ ++ /* for now, don't advertise srp-only devices */ ++ if (!gadget_is_otg(gadget)) ++ function++; ++ ++ len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); ++ ((struct usb_config_descriptor *) buf)->bDescriptorType = type; ++ return len; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* These routines may be called in process context or in_irq */ ++ ++/* Caller must hold fsg->lock */ ++static void wakeup_thread(struct fsg_dev *fsg) ++{ ++ /* Tell the main thread that something has happened */ ++ fsg->thread_wakeup_needed = 1; ++ if (fsg->thread_task) ++ wake_up_process(fsg->thread_task); ++} ++ ++ ++static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) ++{ ++ unsigned long flags; ++ ++ /* Do nothing if a higher-priority exception is already in progress. ++ * If a lower-or-equal priority exception is in progress, preempt it ++ * and notify the main thread by sending it a signal. */ ++ spin_lock_irqsave(&fsg->lock, flags); ++ if (fsg->state <= new_state) { ++ fsg->exception_req_tag = fsg->ep0_req_tag; ++ fsg->state = new_state; ++ if (fsg->thread_task) ++ send_sig_info(SIGUSR1, SEND_SIG_FORCED, ++ fsg->thread_task); ++ } ++ spin_unlock_irqrestore(&fsg->lock, flags); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* The disconnect callback and ep0 routines. These always run in_irq, ++ * except that ep0_queue() is called in the main thread to acknowledge ++ * completion of various requests: set config, set interface, and ++ * Bulk-only device reset. */ ++ ++static void fsg_disconnect(struct usb_gadget *gadget) ++{ ++ struct fsg_dev *fsg = get_gadget_data(gadget); ++ ++ DBG(fsg, "disconnect or port reset\n"); ++ raise_exception(fsg, FSG_STATE_DISCONNECT); ++} ++ ++ ++static int ep0_queue(struct fsg_dev *fsg) ++{ ++ int rc; ++ ++ rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC); ++ if (rc != 0 && rc != -ESHUTDOWN) { ++ ++ /* We can't do much more than wait for a reset */ ++ WARNING(fsg, "error in submission: %s --> %d\n", ++ fsg->ep0->name, rc); ++ } ++ return rc; ++} ++ ++static void ep0_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct fsg_dev *fsg = ep->driver_data; ++ ++ if (req->actual > 0) ++ dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); ++ if (req->status || req->actual != req->length) ++ DBG(fsg, "%s --> %d, %u/%u\n", __func__, ++ req->status, req->actual, req->length); ++ if (req->status == -ECONNRESET) // Request was cancelled ++ usb_ep_fifo_flush(ep); ++ ++ if (req->status == 0 && req->context) ++ ((fsg_routine_t) (req->context))(fsg); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Bulk and interrupt endpoint completion handlers. ++ * These always run in_irq. */ ++ ++static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct fsg_dev *fsg = ep->driver_data; ++ struct fsg_buffhd *bh = req->context; ++ ++ if (req->status || req->actual != req->length) ++ DBG(fsg, "%s --> %d, %u/%u\n", __func__, ++ req->status, req->actual, req->length); ++ if (req->status == -ECONNRESET) // Request was cancelled ++ usb_ep_fifo_flush(ep); ++ ++ /* Hold the lock while we update the request and buffer states */ ++ smp_wmb(); ++ spin_lock(&fsg->lock); ++ bh->inreq_busy = 0; ++ bh->state = BUF_STATE_EMPTY; ++ wakeup_thread(fsg); ++ spin_unlock(&fsg->lock); ++} ++ ++static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct fsg_dev *fsg = ep->driver_data; ++ struct fsg_buffhd *bh = req->context; ++ ++ dump_msg(fsg, "bulk-out", req->buf, req->actual); ++ if (req->status || req->actual != bh->bulk_out_intended_length) ++ DBG(fsg, "%s --> %d, %u/%u\n", __func__, ++ req->status, req->actual, ++ bh->bulk_out_intended_length); ++ if (req->status == -ECONNRESET) // Request was cancelled ++ usb_ep_fifo_flush(ep); ++ ++ /* Hold the lock while we update the request and buffer states */ ++ smp_wmb(); ++ spin_lock(&fsg->lock); ++ bh->outreq_busy = 0; ++ bh->state = BUF_STATE_FULL; ++ wakeup_thread(fsg); ++ spin_unlock(&fsg->lock); ++} ++ ++ ++#ifdef CONFIG_USB_FILE_STORAGE_TEST ++static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct fsg_dev *fsg = ep->driver_data; ++ struct fsg_buffhd *bh = req->context; ++ ++ if (req->status || req->actual != req->length) ++ DBG(fsg, "%s --> %d, %u/%u\n", __func__, ++ req->status, req->actual, req->length); ++ if (req->status == -ECONNRESET) // Request was cancelled ++ usb_ep_fifo_flush(ep); ++ ++ /* Hold the lock while we update the request and buffer states */ ++ smp_wmb(); ++ spin_lock(&fsg->lock); ++ fsg->intreq_busy = 0; ++ bh->state = BUF_STATE_EMPTY; ++ wakeup_thread(fsg); ++ spin_unlock(&fsg->lock); ++} ++ ++#else ++static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) ++{} ++#endif /* CONFIG_USB_FILE_STORAGE_TEST */ ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Ep0 class-specific handlers. These always run in_irq. */ ++ ++#ifdef CONFIG_USB_FILE_STORAGE_TEST ++static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct usb_request *req = fsg->ep0req; ++ static u8 cbi_reset_cmnd[6] = { ++ SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff}; ++ ++ /* Error in command transfer? */ ++ if (req->status || req->length != req->actual || ++ req->actual < 6 || req->actual > MAX_COMMAND_SIZE) { ++ ++ /* Not all controllers allow a protocol stall after ++ * receiving control-out data, but we'll try anyway. */ ++ fsg_set_halt(fsg, fsg->ep0); ++ return; // Wait for reset ++ } ++ ++ /* Is it the special reset command? */ ++ if (req->actual >= sizeof cbi_reset_cmnd && ++ memcmp(req->buf, cbi_reset_cmnd, ++ sizeof cbi_reset_cmnd) == 0) { ++ ++ /* Raise an exception to stop the current operation ++ * and reinitialize our state. */ ++ DBG(fsg, "cbi reset request\n"); ++ raise_exception(fsg, FSG_STATE_RESET); ++ return; ++ } ++ ++ VDBG(fsg, "CB[I] accept device-specific command\n"); ++ spin_lock(&fsg->lock); ++ ++ /* Save the command for later */ ++ if (fsg->cbbuf_cmnd_size) ++ WARNING(fsg, "CB[I] overwriting previous command\n"); ++ fsg->cbbuf_cmnd_size = req->actual; ++ memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); ++ ++ wakeup_thread(fsg); ++ spin_unlock(&fsg->lock); ++} ++ ++#else ++static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{} ++#endif /* CONFIG_USB_FILE_STORAGE_TEST */ ++ ++ ++static int class_setup_req(struct fsg_dev *fsg, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct usb_request *req = fsg->ep0req; ++ int value = -EOPNOTSUPP; ++ u16 w_index = le16_to_cpu(ctrl->wIndex); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ u16 w_length = le16_to_cpu(ctrl->wLength); ++ ++ if (!fsg->config) ++ return value; ++ ++ /* Handle Bulk-only class-specific requests */ ++ if (transport_is_bbb()) { ++ switch (ctrl->bRequest) { ++ ++ case US_BULK_RESET_REQUEST: ++ if (ctrl->bRequestType != (USB_DIR_OUT | ++ USB_TYPE_CLASS | USB_RECIP_INTERFACE)) ++ break; ++ if (w_index != 0 || w_value != 0 || w_length != 0) { ++ value = -EDOM; ++ break; ++ } ++ ++ /* Raise an exception to stop the current operation ++ * and reinitialize our state. */ ++ DBG(fsg, "bulk reset request\n"); ++ raise_exception(fsg, FSG_STATE_RESET); ++ value = DELAYED_STATUS; ++ break; ++ ++ case US_BULK_GET_MAX_LUN: ++ if (ctrl->bRequestType != (USB_DIR_IN | ++ USB_TYPE_CLASS | USB_RECIP_INTERFACE)) ++ break; ++ if (w_index != 0 || w_value != 0 || w_length != 1) { ++ value = -EDOM; ++ break; ++ } ++ VDBG(fsg, "get max LUN\n"); ++ *(u8 *) req->buf = fsg->nluns - 1; ++ value = 1; ++ break; ++ } ++ } ++ ++ /* Handle CBI class-specific requests */ ++ else { ++ switch (ctrl->bRequest) { ++ ++ case USB_CBI_ADSC_REQUEST: ++ if (ctrl->bRequestType != (USB_DIR_OUT | ++ USB_TYPE_CLASS | USB_RECIP_INTERFACE)) ++ break; ++ if (w_index != 0 || w_value != 0) { ++ value = -EDOM; ++ break; ++ } ++ if (w_length > MAX_COMMAND_SIZE) { ++ value = -EOVERFLOW; ++ break; ++ } ++ value = w_length; ++ fsg->ep0req->context = received_cbi_adsc; ++ break; ++ } ++ } ++ ++ if (value == -EOPNOTSUPP) ++ VDBG(fsg, ++ "unknown class-specific control req " ++ "%02x.%02x v%04x i%04x l%u\n", ++ ctrl->bRequestType, ctrl->bRequest, ++ le16_to_cpu(ctrl->wValue), w_index, w_length); ++ return value; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Ep0 standard request handlers. These always run in_irq. */ ++ ++static int standard_setup_req(struct fsg_dev *fsg, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct usb_request *req = fsg->ep0req; ++ int value = -EOPNOTSUPP; ++ u16 w_index = le16_to_cpu(ctrl->wIndex); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ ++ /* Usually this just stores reply data in the pre-allocated ep0 buffer, ++ * but config change events will also reconfigure hardware. */ ++ switch (ctrl->bRequest) { ++ ++ case USB_REQ_GET_DESCRIPTOR: ++ if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | ++ USB_RECIP_DEVICE)) ++ break; ++ switch (w_value >> 8) { ++ ++ case USB_DT_DEVICE: ++ VDBG(fsg, "get device descriptor\n"); ++ device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket; ++ value = sizeof device_desc; ++ memcpy(req->buf, &device_desc, value); ++ break; ++ case USB_DT_DEVICE_QUALIFIER: ++ VDBG(fsg, "get device qualifier\n"); ++ if (!gadget_is_dualspeed(fsg->gadget) || ++ fsg->gadget->speed == USB_SPEED_SUPER) ++ break; ++ /* ++ * Assume ep0 uses the same maxpacket value for both ++ * speeds ++ */ ++ dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; ++ value = sizeof dev_qualifier; ++ memcpy(req->buf, &dev_qualifier, value); ++ break; ++ ++ case USB_DT_OTHER_SPEED_CONFIG: ++ VDBG(fsg, "get other-speed config descriptor\n"); ++ if (!gadget_is_dualspeed(fsg->gadget) || ++ fsg->gadget->speed == USB_SPEED_SUPER) ++ break; ++ goto get_config; ++ case USB_DT_CONFIG: ++ VDBG(fsg, "get configuration descriptor\n"); ++get_config: ++ value = populate_config_buf(fsg->gadget, ++ req->buf, ++ w_value >> 8, ++ w_value & 0xff); ++ break; ++ ++ case USB_DT_STRING: ++ VDBG(fsg, "get string descriptor\n"); ++ ++ /* wIndex == language code */ ++ value = usb_gadget_get_string(&fsg_stringtab, ++ w_value & 0xff, req->buf); ++ break; ++ ++ case USB_DT_BOS: ++ VDBG(fsg, "get bos descriptor\n"); ++ ++ if (gadget_is_superspeed(fsg->gadget)) ++ value = populate_bos(fsg, req->buf); ++ break; ++ } ++ ++ break; ++ ++ /* One config, two speeds */ ++ case USB_REQ_SET_CONFIGURATION: ++ if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | ++ USB_RECIP_DEVICE)) ++ break; ++ VDBG(fsg, "set configuration\n"); ++ if (w_value == CONFIG_VALUE || w_value == 0) { ++ fsg->new_config = w_value; ++ ++ /* Raise an exception to wipe out previous transaction ++ * state (queued bufs, etc) and set the new config. */ ++ raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); ++ value = DELAYED_STATUS; ++ } ++ break; ++ case USB_REQ_GET_CONFIGURATION: ++ if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | ++ USB_RECIP_DEVICE)) ++ break; ++ VDBG(fsg, "get configuration\n"); ++ *(u8 *) req->buf = fsg->config; ++ value = 1; ++ break; ++ ++ case USB_REQ_SET_INTERFACE: ++ if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD | ++ USB_RECIP_INTERFACE)) ++ break; ++ if (fsg->config && w_index == 0) { ++ ++ /* Raise an exception to wipe out previous transaction ++ * state (queued bufs, etc) and install the new ++ * interface altsetting. */ ++ raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE); ++ value = DELAYED_STATUS; ++ } ++ break; ++ case USB_REQ_GET_INTERFACE: ++ if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | ++ USB_RECIP_INTERFACE)) ++ break; ++ if (!fsg->config) ++ break; ++ if (w_index != 0) { ++ value = -EDOM; ++ break; ++ } ++ VDBG(fsg, "get interface\n"); ++ *(u8 *) req->buf = 0; ++ value = 1; ++ break; ++ ++ default: ++ VDBG(fsg, ++ "unknown control req %02x.%02x v%04x i%04x l%u\n", ++ ctrl->bRequestType, ctrl->bRequest, ++ w_value, w_index, le16_to_cpu(ctrl->wLength)); ++ } ++ ++ return value; ++} ++ ++ ++static int fsg_setup(struct usb_gadget *gadget, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct fsg_dev *fsg = get_gadget_data(gadget); ++ int rc; ++ int w_length = le16_to_cpu(ctrl->wLength); ++ ++ ++fsg->ep0_req_tag; // Record arrival of a new request ++ fsg->ep0req->context = NULL; ++ fsg->ep0req->length = 0; ++ dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); ++ ++ if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) ++ rc = class_setup_req(fsg, ctrl); ++ else ++ rc = standard_setup_req(fsg, ctrl); ++ ++ /* Respond with data/status or defer until later? */ ++ if (rc >= 0 && rc != DELAYED_STATUS) { ++ rc = min(rc, w_length); ++ fsg->ep0req->length = rc; ++ fsg->ep0req->zero = rc < w_length; ++ fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? ++ "ep0-in" : "ep0-out"); ++ rc = ep0_queue(fsg); ++ } ++ ++ /* Device either stalls (rc < 0) or reports success */ ++ return rc; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* All the following routines run in process context */ ++ ++ ++/* Use this for bulk or interrupt transfers, not ep0 */ ++static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, ++ struct usb_request *req, int *pbusy, ++ enum fsg_buffer_state *state) ++{ ++ int rc; ++ ++ if (ep == fsg->bulk_in) ++ dump_msg(fsg, "bulk-in", req->buf, req->length); ++ else if (ep == fsg->intr_in) ++ dump_msg(fsg, "intr-in", req->buf, req->length); ++ ++ spin_lock_irq(&fsg->lock); ++ *pbusy = 1; ++ *state = BUF_STATE_BUSY; ++ spin_unlock_irq(&fsg->lock); ++ rc = usb_ep_queue(ep, req, GFP_KERNEL); ++ if (rc != 0) { ++ *pbusy = 0; ++ *state = BUF_STATE_EMPTY; ++ ++ /* We can't do much more than wait for a reset */ ++ ++ /* Note: currently the net2280 driver fails zero-length ++ * submissions if DMA is enabled. */ ++ if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP && ++ req->length == 0)) ++ WARNING(fsg, "error in submission: %s --> %d\n", ++ ep->name, rc); ++ } ++} ++ ++ ++static int sleep_thread(struct fsg_dev *fsg) ++{ ++ int rc = 0; ++ ++ /* Wait until a signal arrives or we are woken up */ ++ for (;;) { ++ try_to_freeze(); ++ set_current_state(TASK_INTERRUPTIBLE); ++ if (signal_pending(current)) { ++ rc = -EINTR; ++ break; ++ } ++ if (fsg->thread_wakeup_needed) ++ break; ++ schedule(); ++ } ++ __set_current_state(TASK_RUNNING); ++ fsg->thread_wakeup_needed = 0; ++ return rc; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int do_read(struct fsg_dev *fsg) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ u32 lba; ++ struct fsg_buffhd *bh; ++ int rc; ++ u32 amount_left; ++ loff_t file_offset, file_offset_tmp; ++ unsigned int amount; ++ ssize_t nread; ++ ++ /* Get the starting Logical Block Address and check that it's ++ * not too big */ ++ if (fsg->cmnd[0] == READ_6) ++ lba = get_unaligned_be24(&fsg->cmnd[1]); ++ else { ++ lba = get_unaligned_be32(&fsg->cmnd[2]); ++ ++ /* We allow DPO (Disable Page Out = don't save data in the ++ * cache) and FUA (Force Unit Access = don't read from the ++ * cache), but we don't implement them. */ ++ if ((fsg->cmnd[1] & ~0x18) != 0) { ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ } ++ if (lba >= curlun->num_sectors) { ++ curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ++ return -EINVAL; ++ } ++ file_offset = ((loff_t) lba) << curlun->blkbits; ++ ++ /* Carry out the file reads */ ++ amount_left = fsg->data_size_from_cmnd; ++ if (unlikely(amount_left == 0)) ++ return -EIO; // No default reply ++ ++ for (;;) { ++ ++ /* Figure out how much we need to read: ++ * Try to read the remaining amount. ++ * But don't read more than the buffer size. ++ * And don't try to read past the end of the file. ++ */ ++ amount = min((unsigned int) amount_left, mod_data.buflen); ++ amount = min((loff_t) amount, ++ curlun->file_length - file_offset); ++ ++ /* Wait for the next buffer to become available */ ++ bh = fsg->next_buffhd_to_fill; ++ while (bh->state != BUF_STATE_EMPTY) { ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ ++ /* If we were asked to read past the end of file, ++ * end with an empty buffer. */ ++ if (amount == 0) { ++ curlun->sense_data = ++ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ++ curlun->sense_data_info = file_offset >> curlun->blkbits; ++ curlun->info_valid = 1; ++ bh->inreq->length = 0; ++ bh->state = BUF_STATE_FULL; ++ break; ++ } ++ ++ /* Perform the read */ ++ file_offset_tmp = file_offset; ++ nread = vfs_read(curlun->filp, ++ (char __user *) bh->buf, ++ amount, &file_offset_tmp); ++ VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, ++ (unsigned long long) file_offset, ++ (int) nread); ++ if (signal_pending(current)) ++ return -EINTR; ++ ++ if (nread < 0) { ++ LDBG(curlun, "error in file read: %d\n", ++ (int) nread); ++ nread = 0; ++ } else if (nread < amount) { ++ LDBG(curlun, "partial file read: %d/%u\n", ++ (int) nread, amount); ++ nread = round_down(nread, curlun->blksize); ++ } ++ file_offset += nread; ++ amount_left -= nread; ++ fsg->residue -= nread; ++ ++ /* Except at the end of the transfer, nread will be ++ * equal to the buffer size, which is divisible by the ++ * bulk-in maxpacket size. ++ */ ++ bh->inreq->length = nread; ++ bh->state = BUF_STATE_FULL; ++ ++ /* If an error occurred, report it and its position */ ++ if (nread < amount) { ++ curlun->sense_data = SS_UNRECOVERED_READ_ERROR; ++ curlun->sense_data_info = file_offset >> curlun->blkbits; ++ curlun->info_valid = 1; ++ break; ++ } ++ ++ if (amount_left == 0) ++ break; // No more left to read ++ ++ /* Send this buffer and go read some more */ ++ bh->inreq->zero = 0; ++ start_transfer(fsg, fsg->bulk_in, bh->inreq, ++ &bh->inreq_busy, &bh->state); ++ fsg->next_buffhd_to_fill = bh->next; ++ } ++ ++ return -EIO; // No default reply ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int do_write(struct fsg_dev *fsg) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ u32 lba; ++ struct fsg_buffhd *bh; ++ int get_some_more; ++ u32 amount_left_to_req, amount_left_to_write; ++ loff_t usb_offset, file_offset, file_offset_tmp; ++ unsigned int amount; ++ ssize_t nwritten; ++ int rc; ++ ++ if (curlun->ro) { ++ curlun->sense_data = SS_WRITE_PROTECTED; ++ return -EINVAL; ++ } ++ spin_lock(&curlun->filp->f_lock); ++ curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait ++ spin_unlock(&curlun->filp->f_lock); ++ ++ /* Get the starting Logical Block Address and check that it's ++ * not too big */ ++ if (fsg->cmnd[0] == WRITE_6) ++ lba = get_unaligned_be24(&fsg->cmnd[1]); ++ else { ++ lba = get_unaligned_be32(&fsg->cmnd[2]); ++ ++ /* We allow DPO (Disable Page Out = don't save data in the ++ * cache) and FUA (Force Unit Access = write directly to the ++ * medium). We don't implement DPO; we implement FUA by ++ * performing synchronous output. */ ++ if ((fsg->cmnd[1] & ~0x18) != 0) { ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ /* FUA */ ++ if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) { ++ spin_lock(&curlun->filp->f_lock); ++ curlun->filp->f_flags |= O_DSYNC; ++ spin_unlock(&curlun->filp->f_lock); ++ } ++ } ++ if (lba >= curlun->num_sectors) { ++ curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ++ return -EINVAL; ++ } ++ ++ /* Carry out the file writes */ ++ get_some_more = 1; ++ file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits; ++ amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd; ++ ++ while (amount_left_to_write > 0) { ++ ++ /* Queue a request for more data from the host */ ++ bh = fsg->next_buffhd_to_fill; ++ if (bh->state == BUF_STATE_EMPTY && get_some_more) { ++ ++ /* Figure out how much we want to get: ++ * Try to get the remaining amount, ++ * but not more than the buffer size. ++ */ ++ amount = min(amount_left_to_req, mod_data.buflen); ++ ++ /* Beyond the end of the backing file? */ ++ if (usb_offset >= curlun->file_length) { ++ get_some_more = 0; ++ curlun->sense_data = ++ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ++ curlun->sense_data_info = usb_offset >> curlun->blkbits; ++ curlun->info_valid = 1; ++ continue; ++ } ++ ++ /* Get the next buffer */ ++ usb_offset += amount; ++ fsg->usb_amount_left -= amount; ++ amount_left_to_req -= amount; ++ if (amount_left_to_req == 0) ++ get_some_more = 0; ++ ++ /* Except at the end of the transfer, amount will be ++ * equal to the buffer size, which is divisible by ++ * the bulk-out maxpacket size. ++ */ ++ set_bulk_out_req_length(fsg, bh, amount); ++ start_transfer(fsg, fsg->bulk_out, bh->outreq, ++ &bh->outreq_busy, &bh->state); ++ fsg->next_buffhd_to_fill = bh->next; ++ continue; ++ } ++ ++ /* Write the received data to the backing file */ ++ bh = fsg->next_buffhd_to_drain; ++ if (bh->state == BUF_STATE_EMPTY && !get_some_more) ++ break; // We stopped early ++ if (bh->state == BUF_STATE_FULL) { ++ smp_rmb(); ++ fsg->next_buffhd_to_drain = bh->next; ++ bh->state = BUF_STATE_EMPTY; ++ ++ /* Did something go wrong with the transfer? */ ++ if (bh->outreq->status != 0) { ++ curlun->sense_data = SS_COMMUNICATION_FAILURE; ++ curlun->sense_data_info = file_offset >> curlun->blkbits; ++ curlun->info_valid = 1; ++ break; ++ } ++ ++ amount = bh->outreq->actual; ++ if (curlun->file_length - file_offset < amount) { ++ LERROR(curlun, ++ "write %u @ %llu beyond end %llu\n", ++ amount, (unsigned long long) file_offset, ++ (unsigned long long) curlun->file_length); ++ amount = curlun->file_length - file_offset; ++ } ++ ++ /* Don't accept excess data. The spec doesn't say ++ * what to do in this case. We'll ignore the error. ++ */ ++ amount = min(amount, bh->bulk_out_intended_length); ++ ++ /* Don't write a partial block */ ++ amount = round_down(amount, curlun->blksize); ++ if (amount == 0) ++ goto empty_write; ++ ++ /* Perform the write */ ++ file_offset_tmp = file_offset; ++ nwritten = vfs_write(curlun->filp, ++ (char __user *) bh->buf, ++ amount, &file_offset_tmp); ++ VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, ++ (unsigned long long) file_offset, ++ (int) nwritten); ++ if (signal_pending(current)) ++ return -EINTR; // Interrupted! ++ ++ if (nwritten < 0) { ++ LDBG(curlun, "error in file write: %d\n", ++ (int) nwritten); ++ nwritten = 0; ++ } else if (nwritten < amount) { ++ LDBG(curlun, "partial file write: %d/%u\n", ++ (int) nwritten, amount); ++ nwritten = round_down(nwritten, curlun->blksize); ++ } ++ file_offset += nwritten; ++ amount_left_to_write -= nwritten; ++ fsg->residue -= nwritten; ++ ++ /* If an error occurred, report it and its position */ ++ if (nwritten < amount) { ++ curlun->sense_data = SS_WRITE_ERROR; ++ curlun->sense_data_info = file_offset >> curlun->blkbits; ++ curlun->info_valid = 1; ++ break; ++ } ++ ++ empty_write: ++ /* Did the host decide to stop early? */ ++ if (bh->outreq->actual < bh->bulk_out_intended_length) { ++ fsg->short_packet_received = 1; ++ break; ++ } ++ continue; ++ } ++ ++ /* Wait for something to happen */ ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ ++ return -EIO; // No default reply ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int do_synchronize_cache(struct fsg_dev *fsg) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ int rc; ++ ++ /* We ignore the requested LBA and write out all file's ++ * dirty data buffers. */ ++ rc = fsg_lun_fsync_sub(curlun); ++ if (rc) ++ curlun->sense_data = SS_WRITE_ERROR; ++ return 0; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void invalidate_sub(struct fsg_lun *curlun) ++{ ++ struct file *filp = curlun->filp; ++ struct inode *inode = filp->f_path.dentry->d_inode; ++ unsigned long rc; ++ ++ rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); ++ VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); ++} ++ ++static int do_verify(struct fsg_dev *fsg) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ u32 lba; ++ u32 verification_length; ++ struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; ++ loff_t file_offset, file_offset_tmp; ++ u32 amount_left; ++ unsigned int amount; ++ ssize_t nread; ++ ++ /* Get the starting Logical Block Address and check that it's ++ * not too big */ ++ lba = get_unaligned_be32(&fsg->cmnd[2]); ++ if (lba >= curlun->num_sectors) { ++ curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ++ return -EINVAL; ++ } ++ ++ /* We allow DPO (Disable Page Out = don't save data in the ++ * cache) but we don't implement it. */ ++ if ((fsg->cmnd[1] & ~0x10) != 0) { ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ ++ verification_length = get_unaligned_be16(&fsg->cmnd[7]); ++ if (unlikely(verification_length == 0)) ++ return -EIO; // No default reply ++ ++ /* Prepare to carry out the file verify */ ++ amount_left = verification_length << curlun->blkbits; ++ file_offset = ((loff_t) lba) << curlun->blkbits; ++ ++ /* Write out all the dirty buffers before invalidating them */ ++ fsg_lun_fsync_sub(curlun); ++ if (signal_pending(current)) ++ return -EINTR; ++ ++ invalidate_sub(curlun); ++ if (signal_pending(current)) ++ return -EINTR; ++ ++ /* Just try to read the requested blocks */ ++ while (amount_left > 0) { ++ ++ /* Figure out how much we need to read: ++ * Try to read the remaining amount, but not more than ++ * the buffer size. ++ * And don't try to read past the end of the file. ++ */ ++ amount = min((unsigned int) amount_left, mod_data.buflen); ++ amount = min((loff_t) amount, ++ curlun->file_length - file_offset); ++ if (amount == 0) { ++ curlun->sense_data = ++ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ++ curlun->sense_data_info = file_offset >> curlun->blkbits; ++ curlun->info_valid = 1; ++ break; ++ } ++ ++ /* Perform the read */ ++ file_offset_tmp = file_offset; ++ nread = vfs_read(curlun->filp, ++ (char __user *) bh->buf, ++ amount, &file_offset_tmp); ++ VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, ++ (unsigned long long) file_offset, ++ (int) nread); ++ if (signal_pending(current)) ++ return -EINTR; ++ ++ if (nread < 0) { ++ LDBG(curlun, "error in file verify: %d\n", ++ (int) nread); ++ nread = 0; ++ } else if (nread < amount) { ++ LDBG(curlun, "partial file verify: %d/%u\n", ++ (int) nread, amount); ++ nread = round_down(nread, curlun->blksize); ++ } ++ if (nread == 0) { ++ curlun->sense_data = SS_UNRECOVERED_READ_ERROR; ++ curlun->sense_data_info = file_offset >> curlun->blkbits; ++ curlun->info_valid = 1; ++ break; ++ } ++ file_offset += nread; ++ amount_left -= nread; ++ } ++ return 0; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ u8 *buf = (u8 *) bh->buf; ++ ++ static char vendor_id[] = "Linux "; ++ static char product_disk_id[] = "File-Stor Gadget"; ++ static char product_cdrom_id[] = "File-CD Gadget "; ++ ++ if (!fsg->curlun) { // Unsupported LUNs are okay ++ fsg->bad_lun_okay = 1; ++ memset(buf, 0, 36); ++ buf[0] = 0x7f; // Unsupported, no device-type ++ buf[4] = 31; // Additional length ++ return 36; ++ } ++ ++ memset(buf, 0, 8); ++ buf[0] = (mod_data.cdrom ? TYPE_ROM : TYPE_DISK); ++ if (mod_data.removable) ++ buf[1] = 0x80; ++ buf[2] = 2; // ANSI SCSI level 2 ++ buf[3] = 2; // SCSI-2 INQUIRY data format ++ buf[4] = 31; // Additional length ++ // No special options ++ sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, ++ (mod_data.cdrom ? product_cdrom_id : ++ product_disk_id), ++ mod_data.release); ++ return 36; ++} ++ ++ ++static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ u8 *buf = (u8 *) bh->buf; ++ u32 sd, sdinfo; ++ int valid; ++ ++ /* ++ * From the SCSI-2 spec., section 7.9 (Unit attention condition): ++ * ++ * If a REQUEST SENSE command is received from an initiator ++ * with a pending unit attention condition (before the target ++ * generates the contingent allegiance condition), then the ++ * target shall either: ++ * a) report any pending sense data and preserve the unit ++ * attention condition on the logical unit, or, ++ * b) report the unit attention condition, may discard any ++ * pending sense data, and clear the unit attention ++ * condition on the logical unit for that initiator. ++ * ++ * FSG normally uses option a); enable this code to use option b). ++ */ ++#if 0 ++ if (curlun && curlun->unit_attention_data != SS_NO_SENSE) { ++ curlun->sense_data = curlun->unit_attention_data; ++ curlun->unit_attention_data = SS_NO_SENSE; ++ } ++#endif ++ ++ if (!curlun) { // Unsupported LUNs are okay ++ fsg->bad_lun_okay = 1; ++ sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; ++ sdinfo = 0; ++ valid = 0; ++ } else { ++ sd = curlun->sense_data; ++ sdinfo = curlun->sense_data_info; ++ valid = curlun->info_valid << 7; ++ curlun->sense_data = SS_NO_SENSE; ++ curlun->sense_data_info = 0; ++ curlun->info_valid = 0; ++ } ++ ++ memset(buf, 0, 18); ++ buf[0] = valid | 0x70; // Valid, current error ++ buf[2] = SK(sd); ++ put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */ ++ buf[7] = 18 - 8; // Additional sense length ++ buf[12] = ASC(sd); ++ buf[13] = ASCQ(sd); ++ return 18; ++} ++ ++ ++static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ u32 lba = get_unaligned_be32(&fsg->cmnd[2]); ++ int pmi = fsg->cmnd[8]; ++ u8 *buf = (u8 *) bh->buf; ++ ++ /* Check the PMI and LBA fields */ ++ if (pmi > 1 || (pmi == 0 && lba != 0)) { ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ ++ put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); ++ /* Max logical block */ ++ put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ ++ return 8; ++} ++ ++ ++static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ int msf = fsg->cmnd[1] & 0x02; ++ u32 lba = get_unaligned_be32(&fsg->cmnd[2]); ++ u8 *buf = (u8 *) bh->buf; ++ ++ if ((fsg->cmnd[1] & ~0x02) != 0) { /* Mask away MSF */ ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ if (lba >= curlun->num_sectors) { ++ curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ++ return -EINVAL; ++ } ++ ++ memset(buf, 0, 8); ++ buf[0] = 0x01; /* 2048 bytes of user data, rest is EC */ ++ store_cdrom_address(&buf[4], msf, lba); ++ return 8; ++} ++ ++ ++static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ int msf = fsg->cmnd[1] & 0x02; ++ int start_track = fsg->cmnd[6]; ++ u8 *buf = (u8 *) bh->buf; ++ ++ if ((fsg->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ ++ start_track > 1) { ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ ++ memset(buf, 0, 20); ++ buf[1] = (20-2); /* TOC data length */ ++ buf[2] = 1; /* First track number */ ++ buf[3] = 1; /* Last track number */ ++ buf[5] = 0x16; /* Data track, copying allowed */ ++ buf[6] = 0x01; /* Only track is number 1 */ ++ store_cdrom_address(&buf[8], msf, 0); ++ ++ buf[13] = 0x16; /* Lead-out track is data */ ++ buf[14] = 0xAA; /* Lead-out track number */ ++ store_cdrom_address(&buf[16], msf, curlun->num_sectors); ++ return 20; ++} ++ ++ ++static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ int mscmnd = fsg->cmnd[0]; ++ u8 *buf = (u8 *) bh->buf; ++ u8 *buf0 = buf; ++ int pc, page_code; ++ int changeable_values, all_pages; ++ int valid_page = 0; ++ int len, limit; ++ ++ if ((fsg->cmnd[1] & ~0x08) != 0) { // Mask away DBD ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ pc = fsg->cmnd[2] >> 6; ++ page_code = fsg->cmnd[2] & 0x3f; ++ if (pc == 3) { ++ curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; ++ return -EINVAL; ++ } ++ changeable_values = (pc == 1); ++ all_pages = (page_code == 0x3f); ++ ++ /* Write the mode parameter header. Fixed values are: default ++ * medium type, no cache control (DPOFUA), and no block descriptors. ++ * The only variable value is the WriteProtect bit. We will fill in ++ * the mode data length later. */ ++ memset(buf, 0, 8); ++ if (mscmnd == MODE_SENSE) { ++ buf[2] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA ++ buf += 4; ++ limit = 255; ++ } else { // MODE_SENSE_10 ++ buf[3] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA ++ buf += 8; ++ limit = 65535; // Should really be mod_data.buflen ++ } ++ ++ /* No block descriptors */ ++ ++ /* The mode pages, in numerical order. The only page we support ++ * is the Caching page. */ ++ if (page_code == 0x08 || all_pages) { ++ valid_page = 1; ++ buf[0] = 0x08; // Page code ++ buf[1] = 10; // Page length ++ memset(buf+2, 0, 10); // None of the fields are changeable ++ ++ if (!changeable_values) { ++ buf[2] = 0x04; // Write cache enable, ++ // Read cache not disabled ++ // No cache retention priorities ++ put_unaligned_be16(0xffff, &buf[4]); ++ /* Don't disable prefetch */ ++ /* Minimum prefetch = 0 */ ++ put_unaligned_be16(0xffff, &buf[8]); ++ /* Maximum prefetch */ ++ put_unaligned_be16(0xffff, &buf[10]); ++ /* Maximum prefetch ceiling */ ++ } ++ buf += 12; ++ } ++ ++ /* Check that a valid page was requested and the mode data length ++ * isn't too long. */ ++ len = buf - buf0; ++ if (!valid_page || len > limit) { ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ ++ /* Store the mode data length */ ++ if (mscmnd == MODE_SENSE) ++ buf0[0] = len - 1; ++ else ++ put_unaligned_be16(len - 2, buf0); ++ return len; ++} ++ ++ ++static int do_start_stop(struct fsg_dev *fsg) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ int loej, start; ++ ++ if (!mod_data.removable) { ++ curlun->sense_data = SS_INVALID_COMMAND; ++ return -EINVAL; ++ } ++ ++ // int immed = fsg->cmnd[1] & 0x01; ++ loej = fsg->cmnd[4] & 0x02; ++ start = fsg->cmnd[4] & 0x01; ++ ++#ifdef CONFIG_USB_FILE_STORAGE_TEST ++ if ((fsg->cmnd[1] & ~0x01) != 0 || // Mask away Immed ++ (fsg->cmnd[4] & ~0x03) != 0) { // Mask LoEj, Start ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ ++ if (!start) { ++ ++ /* Are we allowed to unload the media? */ ++ if (curlun->prevent_medium_removal) { ++ LDBG(curlun, "unload attempt prevented\n"); ++ curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED; ++ return -EINVAL; ++ } ++ if (loej) { // Simulate an unload/eject ++ up_read(&fsg->filesem); ++ down_write(&fsg->filesem); ++ fsg_lun_close(curlun); ++ up_write(&fsg->filesem); ++ down_read(&fsg->filesem); ++ } ++ } else { ++ ++ /* Our emulation doesn't support mounting; the medium is ++ * available for use as soon as it is loaded. */ ++ if (!fsg_lun_is_open(curlun)) { ++ curlun->sense_data = SS_MEDIUM_NOT_PRESENT; ++ return -EINVAL; ++ } ++ } ++#endif ++ return 0; ++} ++ ++ ++static int do_prevent_allow(struct fsg_dev *fsg) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ int prevent; ++ ++ if (!mod_data.removable) { ++ curlun->sense_data = SS_INVALID_COMMAND; ++ return -EINVAL; ++ } ++ ++ prevent = fsg->cmnd[4] & 0x01; ++ if ((fsg->cmnd[4] & ~0x01) != 0) { // Mask away Prevent ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ ++ if (curlun->prevent_medium_removal && !prevent) ++ fsg_lun_fsync_sub(curlun); ++ curlun->prevent_medium_removal = prevent; ++ return 0; ++} ++ ++ ++static int do_read_format_capacities(struct fsg_dev *fsg, ++ struct fsg_buffhd *bh) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ u8 *buf = (u8 *) bh->buf; ++ ++ buf[0] = buf[1] = buf[2] = 0; ++ buf[3] = 8; // Only the Current/Maximum Capacity Descriptor ++ buf += 4; ++ ++ put_unaligned_be32(curlun->num_sectors, &buf[0]); ++ /* Number of blocks */ ++ put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ ++ buf[4] = 0x02; /* Current capacity */ ++ return 12; ++} ++ ++ ++static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ ++ /* We don't support MODE SELECT */ ++ curlun->sense_data = SS_INVALID_COMMAND; ++ return -EINVAL; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int halt_bulk_in_endpoint(struct fsg_dev *fsg) ++{ ++ int rc; ++ ++ rc = fsg_set_halt(fsg, fsg->bulk_in); ++ if (rc == -EAGAIN) ++ VDBG(fsg, "delayed bulk-in endpoint halt\n"); ++ while (rc != 0) { ++ if (rc != -EAGAIN) { ++ WARNING(fsg, "usb_ep_set_halt -> %d\n", rc); ++ rc = 0; ++ break; ++ } ++ ++ /* Wait for a short time and then try again */ ++ if (msleep_interruptible(100) != 0) ++ return -EINTR; ++ rc = usb_ep_set_halt(fsg->bulk_in); ++ } ++ return rc; ++} ++ ++static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) ++{ ++ int rc; ++ ++ DBG(fsg, "bulk-in set wedge\n"); ++ rc = usb_ep_set_wedge(fsg->bulk_in); ++ if (rc == -EAGAIN) ++ VDBG(fsg, "delayed bulk-in endpoint wedge\n"); ++ while (rc != 0) { ++ if (rc != -EAGAIN) { ++ WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc); ++ rc = 0; ++ break; ++ } ++ ++ /* Wait for a short time and then try again */ ++ if (msleep_interruptible(100) != 0) ++ return -EINTR; ++ rc = usb_ep_set_wedge(fsg->bulk_in); ++ } ++ return rc; ++} ++ ++static int throw_away_data(struct fsg_dev *fsg) ++{ ++ struct fsg_buffhd *bh; ++ u32 amount; ++ int rc; ++ ++ while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY || ++ fsg->usb_amount_left > 0) { ++ ++ /* Throw away the data in a filled buffer */ ++ if (bh->state == BUF_STATE_FULL) { ++ smp_rmb(); ++ bh->state = BUF_STATE_EMPTY; ++ fsg->next_buffhd_to_drain = bh->next; ++ ++ /* A short packet or an error ends everything */ ++ if (bh->outreq->actual < bh->bulk_out_intended_length || ++ bh->outreq->status != 0) { ++ raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); ++ return -EINTR; ++ } ++ continue; ++ } ++ ++ /* Try to submit another request if we need one */ ++ bh = fsg->next_buffhd_to_fill; ++ if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) { ++ amount = min(fsg->usb_amount_left, ++ (u32) mod_data.buflen); ++ ++ /* Except at the end of the transfer, amount will be ++ * equal to the buffer size, which is divisible by ++ * the bulk-out maxpacket size. ++ */ ++ set_bulk_out_req_length(fsg, bh, amount); ++ start_transfer(fsg, fsg->bulk_out, bh->outreq, ++ &bh->outreq_busy, &bh->state); ++ fsg->next_buffhd_to_fill = bh->next; ++ fsg->usb_amount_left -= amount; ++ continue; ++ } ++ ++ /* Otherwise wait for something to happen */ ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ return 0; ++} ++ ++ ++static int finish_reply(struct fsg_dev *fsg) ++{ ++ struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; ++ int rc = 0; ++ ++ switch (fsg->data_dir) { ++ case DATA_DIR_NONE: ++ break; // Nothing to send ++ ++ /* If we don't know whether the host wants to read or write, ++ * this must be CB or CBI with an unknown command. We mustn't ++ * try to send or receive any data. So stall both bulk pipes ++ * if we can and wait for a reset. */ ++ case DATA_DIR_UNKNOWN: ++ if (mod_data.can_stall) { ++ fsg_set_halt(fsg, fsg->bulk_out); ++ rc = halt_bulk_in_endpoint(fsg); ++ } ++ break; ++ ++ /* All but the last buffer of data must have already been sent */ ++ case DATA_DIR_TO_HOST: ++ if (fsg->data_size == 0) ++ ; // Nothing to send ++ ++ /* If there's no residue, simply send the last buffer */ ++ else if (fsg->residue == 0) { ++ bh->inreq->zero = 0; ++ start_transfer(fsg, fsg->bulk_in, bh->inreq, ++ &bh->inreq_busy, &bh->state); ++ fsg->next_buffhd_to_fill = bh->next; ++ } ++ ++ /* There is a residue. For CB and CBI, simply mark the end ++ * of the data with a short packet. However, if we are ++ * allowed to stall, there was no data at all (residue == ++ * data_size), and the command failed (invalid LUN or ++ * sense data is set), then halt the bulk-in endpoint ++ * instead. */ ++ else if (!transport_is_bbb()) { ++ if (mod_data.can_stall && ++ fsg->residue == fsg->data_size && ++ (!fsg->curlun || fsg->curlun->sense_data != SS_NO_SENSE)) { ++ bh->state = BUF_STATE_EMPTY; ++ rc = halt_bulk_in_endpoint(fsg); ++ } else { ++ bh->inreq->zero = 1; ++ start_transfer(fsg, fsg->bulk_in, bh->inreq, ++ &bh->inreq_busy, &bh->state); ++ fsg->next_buffhd_to_fill = bh->next; ++ } ++ } ++ ++ /* ++ * For Bulk-only, mark the end of the data with a short ++ * packet. If we are allowed to stall, halt the bulk-in ++ * endpoint. (Note: This violates the Bulk-Only Transport ++ * specification, which requires us to pad the data if we ++ * don't halt the endpoint. Presumably nobody will mind.) ++ */ ++ else { ++ bh->inreq->zero = 1; ++ start_transfer(fsg, fsg->bulk_in, bh->inreq, ++ &bh->inreq_busy, &bh->state); ++ fsg->next_buffhd_to_fill = bh->next; ++ if (mod_data.can_stall) ++ rc = halt_bulk_in_endpoint(fsg); ++ } ++ break; ++ ++ /* We have processed all we want from the data the host has sent. ++ * There may still be outstanding bulk-out requests. */ ++ case DATA_DIR_FROM_HOST: ++ if (fsg->residue == 0) ++ ; // Nothing to receive ++ ++ /* Did the host stop sending unexpectedly early? */ ++ else if (fsg->short_packet_received) { ++ raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); ++ rc = -EINTR; ++ } ++ ++ /* We haven't processed all the incoming data. Even though ++ * we may be allowed to stall, doing so would cause a race. ++ * The controller may already have ACK'ed all the remaining ++ * bulk-out packets, in which case the host wouldn't see a ++ * STALL. Not realizing the endpoint was halted, it wouldn't ++ * clear the halt -- leading to problems later on. */ ++#if 0 ++ else if (mod_data.can_stall) { ++ fsg_set_halt(fsg, fsg->bulk_out); ++ raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); ++ rc = -EINTR; ++ } ++#endif ++ ++ /* We can't stall. Read in the excess data and throw it ++ * all away. */ ++ else ++ rc = throw_away_data(fsg); ++ break; ++ } ++ return rc; ++} ++ ++ ++static int send_status(struct fsg_dev *fsg) ++{ ++ struct fsg_lun *curlun = fsg->curlun; ++ struct fsg_buffhd *bh; ++ int rc; ++ u8 status = US_BULK_STAT_OK; ++ u32 sd, sdinfo = 0; ++ ++ /* Wait for the next buffer to become available */ ++ bh = fsg->next_buffhd_to_fill; ++ while (bh->state != BUF_STATE_EMPTY) { ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ ++ if (curlun) { ++ sd = curlun->sense_data; ++ sdinfo = curlun->sense_data_info; ++ } else if (fsg->bad_lun_okay) ++ sd = SS_NO_SENSE; ++ else ++ sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; ++ ++ if (fsg->phase_error) { ++ DBG(fsg, "sending phase-error status\n"); ++ status = US_BULK_STAT_PHASE; ++ sd = SS_INVALID_COMMAND; ++ } else if (sd != SS_NO_SENSE) { ++ DBG(fsg, "sending command-failure status\n"); ++ status = US_BULK_STAT_FAIL; ++ VDBG(fsg, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" ++ " info x%x\n", ++ SK(sd), ASC(sd), ASCQ(sd), sdinfo); ++ } ++ ++ if (transport_is_bbb()) { ++ struct bulk_cs_wrap *csw = bh->buf; ++ ++ /* Store and send the Bulk-only CSW */ ++ csw->Signature = cpu_to_le32(US_BULK_CS_SIGN); ++ csw->Tag = fsg->tag; ++ csw->Residue = cpu_to_le32(fsg->residue); ++ csw->Status = status; ++ ++ bh->inreq->length = US_BULK_CS_WRAP_LEN; ++ bh->inreq->zero = 0; ++ start_transfer(fsg, fsg->bulk_in, bh->inreq, ++ &bh->inreq_busy, &bh->state); ++ ++ } else if (mod_data.transport_type == USB_PR_CB) { ++ ++ /* Control-Bulk transport has no status phase! */ ++ return 0; ++ ++ } else { // USB_PR_CBI ++ struct interrupt_data *buf = bh->buf; ++ ++ /* Store and send the Interrupt data. UFI sends the ASC ++ * and ASCQ bytes. Everything else sends a Type (which ++ * is always 0) and the status Value. */ ++ if (mod_data.protocol_type == USB_SC_UFI) { ++ buf->bType = ASC(sd); ++ buf->bValue = ASCQ(sd); ++ } else { ++ buf->bType = 0; ++ buf->bValue = status; ++ } ++ fsg->intreq->length = CBI_INTERRUPT_DATA_LEN; ++ ++ fsg->intr_buffhd = bh; // Point to the right buffhd ++ fsg->intreq->buf = bh->inreq->buf; ++ fsg->intreq->context = bh; ++ start_transfer(fsg, fsg->intr_in, fsg->intreq, ++ &fsg->intreq_busy, &bh->state); ++ } ++ ++ fsg->next_buffhd_to_fill = bh->next; ++ return 0; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Check whether the command is properly formed and whether its data size ++ * and direction agree with the values we already have. */ ++static int check_command(struct fsg_dev *fsg, int cmnd_size, ++ enum data_direction data_dir, unsigned int mask, ++ int needs_medium, const char *name) ++{ ++ int i; ++ int lun = fsg->cmnd[1] >> 5; ++ static const char dirletter[4] = {'u', 'o', 'i', 'n'}; ++ char hdlen[20]; ++ struct fsg_lun *curlun; ++ ++ /* Adjust the expected cmnd_size for protocol encapsulation padding. ++ * Transparent SCSI doesn't pad. */ ++ if (protocol_is_scsi()) ++ ; ++ ++ /* There's some disagreement as to whether RBC pads commands or not. ++ * We'll play it safe and accept either form. */ ++ else if (mod_data.protocol_type == USB_SC_RBC) { ++ if (fsg->cmnd_size == 12) ++ cmnd_size = 12; ++ ++ /* All the other protocols pad to 12 bytes */ ++ } else ++ cmnd_size = 12; ++ ++ hdlen[0] = 0; ++ if (fsg->data_dir != DATA_DIR_UNKNOWN) ++ sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir], ++ fsg->data_size); ++ VDBG(fsg, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", ++ name, cmnd_size, dirletter[(int) data_dir], ++ fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen); ++ ++ /* We can't reply at all until we know the correct data direction ++ * and size. */ ++ if (fsg->data_size_from_cmnd == 0) ++ data_dir = DATA_DIR_NONE; ++ if (fsg->data_dir == DATA_DIR_UNKNOWN) { // CB or CBI ++ fsg->data_dir = data_dir; ++ fsg->data_size = fsg->data_size_from_cmnd; ++ ++ } else { // Bulk-only ++ if (fsg->data_size < fsg->data_size_from_cmnd) { ++ ++ /* Host data size < Device data size is a phase error. ++ * Carry out the command, but only transfer as much ++ * as we are allowed. */ ++ fsg->data_size_from_cmnd = fsg->data_size; ++ fsg->phase_error = 1; ++ } ++ } ++ fsg->residue = fsg->usb_amount_left = fsg->data_size; ++ ++ /* Conflicting data directions is a phase error */ ++ if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) { ++ fsg->phase_error = 1; ++ return -EINVAL; ++ } ++ ++ /* Verify the length of the command itself */ ++ if (cmnd_size != fsg->cmnd_size) { ++ ++ /* Special case workaround: There are plenty of buggy SCSI ++ * implementations. Many have issues with cbw->Length ++ * field passing a wrong command size. For those cases we ++ * always try to work around the problem by using the length ++ * sent by the host side provided it is at least as large ++ * as the correct command length. ++ * Examples of such cases would be MS-Windows, which issues ++ * REQUEST SENSE with cbw->Length == 12 where it should ++ * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and ++ * REQUEST SENSE with cbw->Length == 10 where it should ++ * be 6 as well. ++ */ ++ if (cmnd_size <= fsg->cmnd_size) { ++ DBG(fsg, "%s is buggy! Expected length %d " ++ "but we got %d\n", name, ++ cmnd_size, fsg->cmnd_size); ++ cmnd_size = fsg->cmnd_size; ++ } else { ++ fsg->phase_error = 1; ++ return -EINVAL; ++ } ++ } ++ ++ /* Check that the LUN values are consistent */ ++ if (transport_is_bbb()) { ++ if (fsg->lun != lun) ++ DBG(fsg, "using LUN %d from CBW, " ++ "not LUN %d from CDB\n", ++ fsg->lun, lun); ++ } ++ ++ /* Check the LUN */ ++ curlun = fsg->curlun; ++ if (curlun) { ++ if (fsg->cmnd[0] != REQUEST_SENSE) { ++ curlun->sense_data = SS_NO_SENSE; ++ curlun->sense_data_info = 0; ++ curlun->info_valid = 0; ++ } ++ } else { ++ fsg->bad_lun_okay = 0; ++ ++ /* INQUIRY and REQUEST SENSE commands are explicitly allowed ++ * to use unsupported LUNs; all others may not. */ ++ if (fsg->cmnd[0] != INQUIRY && ++ fsg->cmnd[0] != REQUEST_SENSE) { ++ DBG(fsg, "unsupported LUN %d\n", fsg->lun); ++ return -EINVAL; ++ } ++ } ++ ++ /* If a unit attention condition exists, only INQUIRY and ++ * REQUEST SENSE commands are allowed; anything else must fail. */ ++ if (curlun && curlun->unit_attention_data != SS_NO_SENSE && ++ fsg->cmnd[0] != INQUIRY && ++ fsg->cmnd[0] != REQUEST_SENSE) { ++ curlun->sense_data = curlun->unit_attention_data; ++ curlun->unit_attention_data = SS_NO_SENSE; ++ return -EINVAL; ++ } ++ ++ /* Check that only command bytes listed in the mask are non-zero */ ++ fsg->cmnd[1] &= 0x1f; // Mask away the LUN ++ for (i = 1; i < cmnd_size; ++i) { ++ if (fsg->cmnd[i] && !(mask & (1 << i))) { ++ if (curlun) ++ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; ++ return -EINVAL; ++ } ++ } ++ ++ /* If the medium isn't mounted and the command needs to access ++ * it, return an error. */ ++ if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { ++ curlun->sense_data = SS_MEDIUM_NOT_PRESENT; ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* wrapper of check_command for data size in blocks handling */ ++static int check_command_size_in_blocks(struct fsg_dev *fsg, int cmnd_size, ++ enum data_direction data_dir, unsigned int mask, ++ int needs_medium, const char *name) ++{ ++ if (fsg->curlun) ++ fsg->data_size_from_cmnd <<= fsg->curlun->blkbits; ++ return check_command(fsg, cmnd_size, data_dir, ++ mask, needs_medium, name); ++} ++ ++static int do_scsi_command(struct fsg_dev *fsg) ++{ ++ struct fsg_buffhd *bh; ++ int rc; ++ int reply = -EINVAL; ++ int i; ++ static char unknown[16]; ++ ++ dump_cdb(fsg); ++ ++ /* Wait for the next buffer to become available for data or status */ ++ bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; ++ while (bh->state != BUF_STATE_EMPTY) { ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ fsg->phase_error = 0; ++ fsg->short_packet_received = 0; ++ ++ down_read(&fsg->filesem); // We're using the backing file ++ switch (fsg->cmnd[0]) { ++ ++ case INQUIRY: ++ fsg->data_size_from_cmnd = fsg->cmnd[4]; ++ if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, ++ (1<<4), 0, ++ "INQUIRY")) == 0) ++ reply = do_inquiry(fsg, bh); ++ break; ++ ++ case MODE_SELECT: ++ fsg->data_size_from_cmnd = fsg->cmnd[4]; ++ if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, ++ (1<<1) | (1<<4), 0, ++ "MODE SELECT(6)")) == 0) ++ reply = do_mode_select(fsg, bh); ++ break; ++ ++ case MODE_SELECT_10: ++ fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); ++ if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, ++ (1<<1) | (3<<7), 0, ++ "MODE SELECT(10)")) == 0) ++ reply = do_mode_select(fsg, bh); ++ break; ++ ++ case MODE_SENSE: ++ fsg->data_size_from_cmnd = fsg->cmnd[4]; ++ if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, ++ (1<<1) | (1<<2) | (1<<4), 0, ++ "MODE SENSE(6)")) == 0) ++ reply = do_mode_sense(fsg, bh); ++ break; ++ ++ case MODE_SENSE_10: ++ fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); ++ if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, ++ (1<<1) | (1<<2) | (3<<7), 0, ++ "MODE SENSE(10)")) == 0) ++ reply = do_mode_sense(fsg, bh); ++ break; ++ ++ case ALLOW_MEDIUM_REMOVAL: ++ fsg->data_size_from_cmnd = 0; ++ if ((reply = check_command(fsg, 6, DATA_DIR_NONE, ++ (1<<4), 0, ++ "PREVENT-ALLOW MEDIUM REMOVAL")) == 0) ++ reply = do_prevent_allow(fsg); ++ break; ++ ++ case READ_6: ++ i = fsg->cmnd[4]; ++ fsg->data_size_from_cmnd = (i == 0) ? 256 : i; ++ if ((reply = check_command_size_in_blocks(fsg, 6, ++ DATA_DIR_TO_HOST, ++ (7<<1) | (1<<4), 1, ++ "READ(6)")) == 0) ++ reply = do_read(fsg); ++ break; ++ ++ case READ_10: ++ fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); ++ if ((reply = check_command_size_in_blocks(fsg, 10, ++ DATA_DIR_TO_HOST, ++ (1<<1) | (0xf<<2) | (3<<7), 1, ++ "READ(10)")) == 0) ++ reply = do_read(fsg); ++ break; ++ ++ case READ_12: ++ fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); ++ if ((reply = check_command_size_in_blocks(fsg, 12, ++ DATA_DIR_TO_HOST, ++ (1<<1) | (0xf<<2) | (0xf<<6), 1, ++ "READ(12)")) == 0) ++ reply = do_read(fsg); ++ break; ++ ++ case READ_CAPACITY: ++ fsg->data_size_from_cmnd = 8; ++ if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, ++ (0xf<<2) | (1<<8), 1, ++ "READ CAPACITY")) == 0) ++ reply = do_read_capacity(fsg, bh); ++ break; ++ ++ case READ_HEADER: ++ if (!mod_data.cdrom) ++ goto unknown_cmnd; ++ fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); ++ if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, ++ (3<<7) | (0x1f<<1), 1, ++ "READ HEADER")) == 0) ++ reply = do_read_header(fsg, bh); ++ break; ++ ++ case READ_TOC: ++ if (!mod_data.cdrom) ++ goto unknown_cmnd; ++ fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); ++ if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, ++ (7<<6) | (1<<1), 1, ++ "READ TOC")) == 0) ++ reply = do_read_toc(fsg, bh); ++ break; ++ ++ case READ_FORMAT_CAPACITIES: ++ fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); ++ if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, ++ (3<<7), 1, ++ "READ FORMAT CAPACITIES")) == 0) ++ reply = do_read_format_capacities(fsg, bh); ++ break; ++ ++ case REQUEST_SENSE: ++ fsg->data_size_from_cmnd = fsg->cmnd[4]; ++ if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, ++ (1<<4), 0, ++ "REQUEST SENSE")) == 0) ++ reply = do_request_sense(fsg, bh); ++ break; ++ ++ case START_STOP: ++ fsg->data_size_from_cmnd = 0; ++ if ((reply = check_command(fsg, 6, DATA_DIR_NONE, ++ (1<<1) | (1<<4), 0, ++ "START-STOP UNIT")) == 0) ++ reply = do_start_stop(fsg); ++ break; ++ ++ case SYNCHRONIZE_CACHE: ++ fsg->data_size_from_cmnd = 0; ++ if ((reply = check_command(fsg, 10, DATA_DIR_NONE, ++ (0xf<<2) | (3<<7), 1, ++ "SYNCHRONIZE CACHE")) == 0) ++ reply = do_synchronize_cache(fsg); ++ break; ++ ++ case TEST_UNIT_READY: ++ fsg->data_size_from_cmnd = 0; ++ reply = check_command(fsg, 6, DATA_DIR_NONE, ++ 0, 1, ++ "TEST UNIT READY"); ++ break; ++ ++ /* Although optional, this command is used by MS-Windows. We ++ * support a minimal version: BytChk must be 0. */ ++ case VERIFY: ++ fsg->data_size_from_cmnd = 0; ++ if ((reply = check_command(fsg, 10, DATA_DIR_NONE, ++ (1<<1) | (0xf<<2) | (3<<7), 1, ++ "VERIFY")) == 0) ++ reply = do_verify(fsg); ++ break; ++ ++ case WRITE_6: ++ i = fsg->cmnd[4]; ++ fsg->data_size_from_cmnd = (i == 0) ? 256 : i; ++ if ((reply = check_command_size_in_blocks(fsg, 6, ++ DATA_DIR_FROM_HOST, ++ (7<<1) | (1<<4), 1, ++ "WRITE(6)")) == 0) ++ reply = do_write(fsg); ++ break; ++ ++ case WRITE_10: ++ fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); ++ if ((reply = check_command_size_in_blocks(fsg, 10, ++ DATA_DIR_FROM_HOST, ++ (1<<1) | (0xf<<2) | (3<<7), 1, ++ "WRITE(10)")) == 0) ++ reply = do_write(fsg); ++ break; ++ ++ case WRITE_12: ++ fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); ++ if ((reply = check_command_size_in_blocks(fsg, 12, ++ DATA_DIR_FROM_HOST, ++ (1<<1) | (0xf<<2) | (0xf<<6), 1, ++ "WRITE(12)")) == 0) ++ reply = do_write(fsg); ++ break; ++ ++ /* Some mandatory commands that we recognize but don't implement. ++ * They don't mean much in this setting. It's left as an exercise ++ * for anyone interested to implement RESERVE and RELEASE in terms ++ * of Posix locks. */ ++ case FORMAT_UNIT: ++ case RELEASE: ++ case RESERVE: ++ case SEND_DIAGNOSTIC: ++ // Fall through ++ ++ default: ++ unknown_cmnd: ++ fsg->data_size_from_cmnd = 0; ++ sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); ++ if ((reply = check_command(fsg, fsg->cmnd_size, ++ DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) { ++ fsg->curlun->sense_data = SS_INVALID_COMMAND; ++ reply = -EINVAL; ++ } ++ break; ++ } ++ up_read(&fsg->filesem); ++ ++ if (reply == -EINTR || signal_pending(current)) ++ return -EINTR; ++ ++ /* Set up the single reply buffer for finish_reply() */ ++ if (reply == -EINVAL) ++ reply = 0; // Error reply length ++ if (reply >= 0 && fsg->data_dir == DATA_DIR_TO_HOST) { ++ reply = min((u32) reply, fsg->data_size_from_cmnd); ++ bh->inreq->length = reply; ++ bh->state = BUF_STATE_FULL; ++ fsg->residue -= reply; ++ } // Otherwise it's already set ++ ++ return 0; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) ++{ ++ struct usb_request *req = bh->outreq; ++ struct bulk_cb_wrap *cbw = req->buf; ++ ++ /* Was this a real packet? Should it be ignored? */ ++ if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) ++ return -EINVAL; ++ ++ /* Is the CBW valid? */ ++ if (req->actual != US_BULK_CB_WRAP_LEN || ++ cbw->Signature != cpu_to_le32( ++ US_BULK_CB_SIGN)) { ++ DBG(fsg, "invalid CBW: len %u sig 0x%x\n", ++ req->actual, ++ le32_to_cpu(cbw->Signature)); ++ ++ /* The Bulk-only spec says we MUST stall the IN endpoint ++ * (6.6.1), so it's unavoidable. It also says we must ++ * retain this state until the next reset, but there's ++ * no way to tell the controller driver it should ignore ++ * Clear-Feature(HALT) requests. ++ * ++ * We aren't required to halt the OUT endpoint; instead ++ * we can simply accept and discard any data received ++ * until the next reset. */ ++ wedge_bulk_in_endpoint(fsg); ++ set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); ++ return -EINVAL; ++ } ++ ++ /* Is the CBW meaningful? */ ++ if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN || ++ cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { ++ DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " ++ "cmdlen %u\n", ++ cbw->Lun, cbw->Flags, cbw->Length); ++ ++ /* We can do anything we want here, so let's stall the ++ * bulk pipes if we are allowed to. */ ++ if (mod_data.can_stall) { ++ fsg_set_halt(fsg, fsg->bulk_out); ++ halt_bulk_in_endpoint(fsg); ++ } ++ return -EINVAL; ++ } ++ ++ /* Save the command for later */ ++ fsg->cmnd_size = cbw->Length; ++ memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size); ++ if (cbw->Flags & US_BULK_FLAG_IN) ++ fsg->data_dir = DATA_DIR_TO_HOST; ++ else ++ fsg->data_dir = DATA_DIR_FROM_HOST; ++ fsg->data_size = le32_to_cpu(cbw->DataTransferLength); ++ if (fsg->data_size == 0) ++ fsg->data_dir = DATA_DIR_NONE; ++ fsg->lun = cbw->Lun; ++ fsg->tag = cbw->Tag; ++ return 0; ++} ++ ++ ++static int get_next_command(struct fsg_dev *fsg) ++{ ++ struct fsg_buffhd *bh; ++ int rc = 0; ++ ++ if (transport_is_bbb()) { ++ ++ /* Wait for the next buffer to become available */ ++ bh = fsg->next_buffhd_to_fill; ++ while (bh->state != BUF_STATE_EMPTY) { ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ ++ /* Queue a request to read a Bulk-only CBW */ ++ set_bulk_out_req_length(fsg, bh, US_BULK_CB_WRAP_LEN); ++ start_transfer(fsg, fsg->bulk_out, bh->outreq, ++ &bh->outreq_busy, &bh->state); ++ ++ /* We will drain the buffer in software, which means we ++ * can reuse it for the next filling. No need to advance ++ * next_buffhd_to_fill. */ ++ ++ /* Wait for the CBW to arrive */ ++ while (bh->state != BUF_STATE_FULL) { ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ smp_rmb(); ++ rc = received_cbw(fsg, bh); ++ bh->state = BUF_STATE_EMPTY; ++ ++ } else { // USB_PR_CB or USB_PR_CBI ++ ++ /* Wait for the next command to arrive */ ++ while (fsg->cbbuf_cmnd_size == 0) { ++ rc = sleep_thread(fsg); ++ if (rc) ++ return rc; ++ } ++ ++ /* Is the previous status interrupt request still busy? ++ * The host is allowed to skip reading the status, ++ * so we must cancel it. */ ++ if (fsg->intreq_busy) ++ usb_ep_dequeue(fsg->intr_in, fsg->intreq); ++ ++ /* Copy the command and mark the buffer empty */ ++ fsg->data_dir = DATA_DIR_UNKNOWN; ++ spin_lock_irq(&fsg->lock); ++ fsg->cmnd_size = fsg->cbbuf_cmnd_size; ++ memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); ++ fsg->cbbuf_cmnd_size = 0; ++ spin_unlock_irq(&fsg->lock); ++ ++ /* Use LUN from the command */ ++ fsg->lun = fsg->cmnd[1] >> 5; ++ } ++ ++ /* Update current lun */ ++ if (fsg->lun >= 0 && fsg->lun < fsg->nluns) ++ fsg->curlun = &fsg->luns[fsg->lun]; ++ else ++ fsg->curlun = NULL; ++ ++ return rc; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep, ++ const struct usb_endpoint_descriptor *d) ++{ ++ int rc; ++ ++ ep->driver_data = fsg; ++ ep->desc = d; ++ rc = usb_ep_enable(ep); ++ if (rc) ++ ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc); ++ return rc; ++} ++ ++static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep, ++ struct usb_request **preq) ++{ ++ *preq = usb_ep_alloc_request(ep, GFP_ATOMIC); ++ if (*preq) ++ return 0; ++ ERROR(fsg, "can't allocate request for %s\n", ep->name); ++ return -ENOMEM; ++} ++ ++/* ++ * Reset interface setting and re-init endpoint state (toggle etc). ++ * Call with altsetting < 0 to disable the interface. The only other ++ * available altsetting is 0, which enables the interface. ++ */ ++static int do_set_interface(struct fsg_dev *fsg, int altsetting) ++{ ++ int rc = 0; ++ int i; ++ const struct usb_endpoint_descriptor *d; ++ ++ if (fsg->running) ++ DBG(fsg, "reset interface\n"); ++ ++reset: ++ /* Deallocate the requests */ ++ for (i = 0; i < fsg_num_buffers; ++i) { ++ struct fsg_buffhd *bh = &fsg->buffhds[i]; ++ ++ if (bh->inreq) { ++ usb_ep_free_request(fsg->bulk_in, bh->inreq); ++ bh->inreq = NULL; ++ } ++ if (bh->outreq) { ++ usb_ep_free_request(fsg->bulk_out, bh->outreq); ++ bh->outreq = NULL; ++ } ++ } ++ if (fsg->intreq) { ++ usb_ep_free_request(fsg->intr_in, fsg->intreq); ++ fsg->intreq = NULL; ++ } ++ ++ /* Disable the endpoints */ ++ if (fsg->bulk_in_enabled) { ++ usb_ep_disable(fsg->bulk_in); ++ fsg->bulk_in_enabled = 0; ++ } ++ if (fsg->bulk_out_enabled) { ++ usb_ep_disable(fsg->bulk_out); ++ fsg->bulk_out_enabled = 0; ++ } ++ if (fsg->intr_in_enabled) { ++ usb_ep_disable(fsg->intr_in); ++ fsg->intr_in_enabled = 0; ++ } ++ ++ fsg->running = 0; ++ if (altsetting < 0 || rc != 0) ++ return rc; ++ ++ DBG(fsg, "set interface %d\n", altsetting); ++ ++ /* Enable the endpoints */ ++ d = fsg_ep_desc(fsg->gadget, ++ &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc, ++ &fsg_ss_bulk_in_desc); ++ if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) ++ goto reset; ++ fsg->bulk_in_enabled = 1; ++ ++ d = fsg_ep_desc(fsg->gadget, ++ &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc, ++ &fsg_ss_bulk_out_desc); ++ if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) ++ goto reset; ++ fsg->bulk_out_enabled = 1; ++ fsg->bulk_out_maxpacket = usb_endpoint_maxp(d); ++ clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); ++ ++ if (transport_is_cbi()) { ++ d = fsg_ep_desc(fsg->gadget, ++ &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc, ++ &fsg_ss_intr_in_desc); ++ if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) ++ goto reset; ++ fsg->intr_in_enabled = 1; ++ } ++ ++ /* Allocate the requests */ ++ for (i = 0; i < fsg_num_buffers; ++i) { ++ struct fsg_buffhd *bh = &fsg->buffhds[i]; ++ ++ if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) ++ goto reset; ++ if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) ++ goto reset; ++ bh->inreq->buf = bh->outreq->buf = bh->buf; ++ bh->inreq->context = bh->outreq->context = bh; ++ bh->inreq->complete = bulk_in_complete; ++ bh->outreq->complete = bulk_out_complete; ++ } ++ if (transport_is_cbi()) { ++ if ((rc = alloc_request(fsg, fsg->intr_in, &fsg->intreq)) != 0) ++ goto reset; ++ fsg->intreq->complete = intr_in_complete; ++ } ++ ++ fsg->running = 1; ++ for (i = 0; i < fsg->nluns; ++i) ++ fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; ++ return rc; ++} ++ ++ ++/* ++ * Change our operational configuration. This code must agree with the code ++ * that returns config descriptors, and with interface altsetting code. ++ * ++ * It's also responsible for power management interactions. Some ++ * configurations might not work with our current power sources. ++ * For now we just assume the gadget is always self-powered. ++ */ ++static int do_set_config(struct fsg_dev *fsg, u8 new_config) ++{ ++ int rc = 0; ++ ++ /* Disable the single interface */ ++ if (fsg->config != 0) { ++ DBG(fsg, "reset config\n"); ++ fsg->config = 0; ++ rc = do_set_interface(fsg, -1); ++ } ++ ++ /* Enable the interface */ ++ if (new_config != 0) { ++ fsg->config = new_config; ++ if ((rc = do_set_interface(fsg, 0)) != 0) ++ fsg->config = 0; // Reset on errors ++ else ++ INFO(fsg, "%s config #%d\n", ++ usb_speed_string(fsg->gadget->speed), ++ fsg->config); ++ } ++ return rc; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void handle_exception(struct fsg_dev *fsg) ++{ ++ siginfo_t info; ++ int sig; ++ int i; ++ int num_active; ++ struct fsg_buffhd *bh; ++ enum fsg_state old_state; ++ u8 new_config; ++ struct fsg_lun *curlun; ++ unsigned int exception_req_tag; ++ int rc; ++ ++ /* Clear the existing signals. Anything but SIGUSR1 is converted ++ * into a high-priority EXIT exception. */ ++ for (;;) { ++ sig = dequeue_signal_lock(current, ¤t->blocked, &info); ++ if (!sig) ++ break; ++ if (sig != SIGUSR1) { ++ if (fsg->state < FSG_STATE_EXIT) ++ DBG(fsg, "Main thread exiting on signal\n"); ++ raise_exception(fsg, FSG_STATE_EXIT); ++ } ++ } ++ ++ /* Cancel all the pending transfers */ ++ if (fsg->intreq_busy) ++ usb_ep_dequeue(fsg->intr_in, fsg->intreq); ++ for (i = 0; i < fsg_num_buffers; ++i) { ++ bh = &fsg->buffhds[i]; ++ if (bh->inreq_busy) ++ usb_ep_dequeue(fsg->bulk_in, bh->inreq); ++ if (bh->outreq_busy) ++ usb_ep_dequeue(fsg->bulk_out, bh->outreq); ++ } ++ ++ /* Wait until everything is idle */ ++ for (;;) { ++ num_active = fsg->intreq_busy; ++ for (i = 0; i < fsg_num_buffers; ++i) { ++ bh = &fsg->buffhds[i]; ++ num_active += bh->inreq_busy + bh->outreq_busy; ++ } ++ if (num_active == 0) ++ break; ++ if (sleep_thread(fsg)) ++ return; ++ } ++ ++ /* Clear out the controller's fifos */ ++ if (fsg->bulk_in_enabled) ++ usb_ep_fifo_flush(fsg->bulk_in); ++ if (fsg->bulk_out_enabled) ++ usb_ep_fifo_flush(fsg->bulk_out); ++ if (fsg->intr_in_enabled) ++ usb_ep_fifo_flush(fsg->intr_in); ++ ++ /* Reset the I/O buffer states and pointers, the SCSI ++ * state, and the exception. Then invoke the handler. */ ++ spin_lock_irq(&fsg->lock); ++ ++ for (i = 0; i < fsg_num_buffers; ++i) { ++ bh = &fsg->buffhds[i]; ++ bh->state = BUF_STATE_EMPTY; ++ } ++ fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain = ++ &fsg->buffhds[0]; ++ ++ exception_req_tag = fsg->exception_req_tag; ++ new_config = fsg->new_config; ++ old_state = fsg->state; ++ ++ if (old_state == FSG_STATE_ABORT_BULK_OUT) ++ fsg->state = FSG_STATE_STATUS_PHASE; ++ else { ++ for (i = 0; i < fsg->nluns; ++i) { ++ curlun = &fsg->luns[i]; ++ curlun->prevent_medium_removal = 0; ++ curlun->sense_data = curlun->unit_attention_data = ++ SS_NO_SENSE; ++ curlun->sense_data_info = 0; ++ curlun->info_valid = 0; ++ } ++ fsg->state = FSG_STATE_IDLE; ++ } ++ spin_unlock_irq(&fsg->lock); ++ ++ /* Carry out any extra actions required for the exception */ ++ switch (old_state) { ++ default: ++ break; ++ ++ case FSG_STATE_ABORT_BULK_OUT: ++ send_status(fsg); ++ spin_lock_irq(&fsg->lock); ++ if (fsg->state == FSG_STATE_STATUS_PHASE) ++ fsg->state = FSG_STATE_IDLE; ++ spin_unlock_irq(&fsg->lock); ++ break; ++ ++ case FSG_STATE_RESET: ++ /* In case we were forced against our will to halt a ++ * bulk endpoint, clear the halt now. (The SuperH UDC ++ * requires this.) */ ++ if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) ++ usb_ep_clear_halt(fsg->bulk_in); ++ ++ if (transport_is_bbb()) { ++ if (fsg->ep0_req_tag == exception_req_tag) ++ ep0_queue(fsg); // Complete the status stage ++ ++ } else if (transport_is_cbi()) ++ send_status(fsg); // Status by interrupt pipe ++ ++ /* Technically this should go here, but it would only be ++ * a waste of time. Ditto for the INTERFACE_CHANGE and ++ * CONFIG_CHANGE cases. */ ++ // for (i = 0; i < fsg->nluns; ++i) ++ // fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; ++ break; ++ ++ case FSG_STATE_INTERFACE_CHANGE: ++ rc = do_set_interface(fsg, 0); ++ if (fsg->ep0_req_tag != exception_req_tag) ++ break; ++ if (rc != 0) // STALL on errors ++ fsg_set_halt(fsg, fsg->ep0); ++ else // Complete the status stage ++ ep0_queue(fsg); ++ break; ++ ++ case FSG_STATE_CONFIG_CHANGE: ++ rc = do_set_config(fsg, new_config); ++ if (fsg->ep0_req_tag != exception_req_tag) ++ break; ++ if (rc != 0) // STALL on errors ++ fsg_set_halt(fsg, fsg->ep0); ++ else // Complete the status stage ++ ep0_queue(fsg); ++ break; ++ ++ case FSG_STATE_DISCONNECT: ++ for (i = 0; i < fsg->nluns; ++i) ++ fsg_lun_fsync_sub(fsg->luns + i); ++ do_set_config(fsg, 0); // Unconfigured state ++ break; ++ ++ case FSG_STATE_EXIT: ++ case FSG_STATE_TERMINATED: ++ do_set_config(fsg, 0); // Free resources ++ spin_lock_irq(&fsg->lock); ++ fsg->state = FSG_STATE_TERMINATED; // Stop the thread ++ spin_unlock_irq(&fsg->lock); ++ break; ++ } ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int fsg_main_thread(void *fsg_) ++{ ++ struct fsg_dev *fsg = fsg_; ++ ++ /* Allow the thread to be killed by a signal, but set the signal mask ++ * to block everything but INT, TERM, KILL, and USR1. */ ++ allow_signal(SIGINT); ++ allow_signal(SIGTERM); ++ allow_signal(SIGKILL); ++ allow_signal(SIGUSR1); ++ ++ /* Allow the thread to be frozen */ ++ set_freezable(); ++ ++ /* Arrange for userspace references to be interpreted as kernel ++ * pointers. That way we can pass a kernel pointer to a routine ++ * that expects a __user pointer and it will work okay. */ ++ set_fs(get_ds()); ++ ++ /* The main loop */ ++ while (fsg->state != FSG_STATE_TERMINATED) { ++ if (exception_in_progress(fsg) || signal_pending(current)) { ++ handle_exception(fsg); ++ continue; ++ } ++ ++ if (!fsg->running) { ++ sleep_thread(fsg); ++ continue; ++ } ++ ++ if (get_next_command(fsg)) ++ continue; ++ ++ spin_lock_irq(&fsg->lock); ++ if (!exception_in_progress(fsg)) ++ fsg->state = FSG_STATE_DATA_PHASE; ++ spin_unlock_irq(&fsg->lock); ++ ++ if (do_scsi_command(fsg) || finish_reply(fsg)) ++ continue; ++ ++ spin_lock_irq(&fsg->lock); ++ if (!exception_in_progress(fsg)) ++ fsg->state = FSG_STATE_STATUS_PHASE; ++ spin_unlock_irq(&fsg->lock); ++ ++ if (send_status(fsg)) ++ continue; ++ ++ spin_lock_irq(&fsg->lock); ++ if (!exception_in_progress(fsg)) ++ fsg->state = FSG_STATE_IDLE; ++ spin_unlock_irq(&fsg->lock); ++ } ++ ++ spin_lock_irq(&fsg->lock); ++ fsg->thread_task = NULL; ++ spin_unlock_irq(&fsg->lock); ++ ++ /* If we are exiting because of a signal, unregister the ++ * gadget driver. */ ++ if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) ++ usb_gadget_unregister_driver(&fsg_driver); ++ ++ /* Let the unbind and cleanup routines know the thread has exited */ ++ complete_and_exit(&fsg->thread_notifier, 0); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++ ++/* The write permissions and store_xxx pointers are set in fsg_bind() */ ++static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); ++static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL); ++static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void fsg_release(struct kref *ref) ++{ ++ struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); ++ ++ kfree(fsg->luns); ++ kfree(fsg); ++} ++ ++static void lun_release(struct device *dev) ++{ ++ struct rw_semaphore *filesem = dev_get_drvdata(dev); ++ struct fsg_dev *fsg = ++ container_of(filesem, struct fsg_dev, filesem); ++ ++ kref_put(&fsg->ref, fsg_release); ++} ++ ++static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) ++{ ++ struct fsg_dev *fsg = get_gadget_data(gadget); ++ int i; ++ struct fsg_lun *curlun; ++ struct usb_request *req = fsg->ep0req; ++ ++ DBG(fsg, "unbind\n"); ++ clear_bit(REGISTERED, &fsg->atomic_bitflags); ++ ++ /* If the thread isn't already dead, tell it to exit now */ ++ if (fsg->state != FSG_STATE_TERMINATED) { ++ raise_exception(fsg, FSG_STATE_EXIT); ++ wait_for_completion(&fsg->thread_notifier); ++ ++ /* The cleanup routine waits for this completion also */ ++ complete(&fsg->thread_notifier); ++ } ++ ++ /* Unregister the sysfs attribute files and the LUNs */ ++ for (i = 0; i < fsg->nluns; ++i) { ++ curlun = &fsg->luns[i]; ++ if (curlun->registered) { ++ device_remove_file(&curlun->dev, &dev_attr_nofua); ++ device_remove_file(&curlun->dev, &dev_attr_ro); ++ device_remove_file(&curlun->dev, &dev_attr_file); ++ fsg_lun_close(curlun); ++ device_unregister(&curlun->dev); ++ curlun->registered = 0; ++ } ++ } ++ ++ /* Free the data buffers */ ++ for (i = 0; i < fsg_num_buffers; ++i) ++ kfree(fsg->buffhds[i].buf); ++ ++ /* Free the request and buffer for endpoint 0 */ ++ if (req) { ++ kfree(req->buf); ++ usb_ep_free_request(fsg->ep0, req); ++ } ++ ++ set_gadget_data(gadget, NULL); ++} ++ ++ ++static int __init check_parameters(struct fsg_dev *fsg) ++{ ++ int prot; ++ int gcnum; ++ ++ /* Store the default values */ ++ mod_data.transport_type = USB_PR_BULK; ++ mod_data.transport_name = "Bulk-only"; ++ mod_data.protocol_type = USB_SC_SCSI; ++ mod_data.protocol_name = "Transparent SCSI"; ++ ++ /* Some peripheral controllers are known not to be able to ++ * halt bulk endpoints correctly. If one of them is present, ++ * disable stalls. ++ */ ++ if (gadget_is_at91(fsg->gadget)) ++ mod_data.can_stall = 0; ++ ++ if (mod_data.release == 0xffff) { // Parameter wasn't set ++ gcnum = usb_gadget_controller_number(fsg->gadget); ++ if (gcnum >= 0) ++ mod_data.release = 0x0300 + gcnum; ++ else { ++ WARNING(fsg, "controller '%s' not recognized\n", ++ fsg->gadget->name); ++ mod_data.release = 0x0399; ++ } ++ } ++ ++ prot = simple_strtol(mod_data.protocol_parm, NULL, 0); ++ ++#ifdef CONFIG_USB_FILE_STORAGE_TEST ++ if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) { ++ ; // Use default setting ++ } else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) { ++ mod_data.transport_type = USB_PR_CB; ++ mod_data.transport_name = "Control-Bulk"; ++ } else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) { ++ mod_data.transport_type = USB_PR_CBI; ++ mod_data.transport_name = "Control-Bulk-Interrupt"; ++ } else { ++ ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm); ++ return -EINVAL; ++ } ++ ++ if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 || ++ prot == USB_SC_SCSI) { ++ ; // Use default setting ++ } else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 || ++ prot == USB_SC_RBC) { ++ mod_data.protocol_type = USB_SC_RBC; ++ mod_data.protocol_name = "RBC"; ++ } else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 || ++ strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 || ++ prot == USB_SC_8020) { ++ mod_data.protocol_type = USB_SC_8020; ++ mod_data.protocol_name = "8020i (ATAPI)"; ++ } else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 || ++ prot == USB_SC_QIC) { ++ mod_data.protocol_type = USB_SC_QIC; ++ mod_data.protocol_name = "QIC-157"; ++ } else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 || ++ prot == USB_SC_UFI) { ++ mod_data.protocol_type = USB_SC_UFI; ++ mod_data.protocol_name = "UFI"; ++ } else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 || ++ prot == USB_SC_8070) { ++ mod_data.protocol_type = USB_SC_8070; ++ mod_data.protocol_name = "8070i"; ++ } else { ++ ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm); ++ return -EINVAL; ++ } ++ ++ mod_data.buflen &= PAGE_CACHE_MASK; ++ if (mod_data.buflen <= 0) { ++ ERROR(fsg, "invalid buflen\n"); ++ return -ETOOSMALL; ++ } ++ ++#endif /* CONFIG_USB_FILE_STORAGE_TEST */ ++ ++ /* Serial string handling. ++ * On a real device, the serial string would be loaded ++ * from permanent storage. */ ++ if (mod_data.serial) { ++ const char *ch; ++ unsigned len = 0; ++ ++ /* Sanity check : ++ * The CB[I] specification limits the serial string to ++ * 12 uppercase hexadecimal characters. ++ * BBB need at least 12 uppercase hexadecimal characters, ++ * with a maximum of 126. */ ++ for (ch = mod_data.serial; *ch; ++ch) { ++ ++len; ++ if ((*ch < '0' || *ch > '9') && ++ (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */ ++ WARNING(fsg, ++ "Invalid serial string character: %c\n", ++ *ch); ++ goto no_serial; ++ } ++ } ++ if (len > 126 || ++ (mod_data.transport_type == USB_PR_BULK && len < 12) || ++ (mod_data.transport_type != USB_PR_BULK && len > 12)) { ++ WARNING(fsg, "Invalid serial string length!\n"); ++ goto no_serial; ++ } ++ fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial; ++ } else { ++ WARNING(fsg, "No serial-number string provided!\n"); ++ no_serial: ++ device_desc.iSerialNumber = 0; ++ } ++ ++ return 0; ++} ++ ++ ++static int __init fsg_bind(struct usb_gadget *gadget) ++{ ++ struct fsg_dev *fsg = the_fsg; ++ int rc; ++ int i; ++ struct fsg_lun *curlun; ++ struct usb_ep *ep; ++ struct usb_request *req; ++ char *pathbuf, *p; ++ ++ fsg->gadget = gadget; ++ set_gadget_data(gadget, fsg); ++ fsg->ep0 = gadget->ep0; ++ fsg->ep0->driver_data = fsg; ++ ++ if ((rc = check_parameters(fsg)) != 0) ++ goto out; ++ ++ if (mod_data.removable) { // Enable the store_xxx attributes ++ dev_attr_file.attr.mode = 0644; ++ dev_attr_file.store = fsg_store_file; ++ if (!mod_data.cdrom) { ++ dev_attr_ro.attr.mode = 0644; ++ dev_attr_ro.store = fsg_store_ro; ++ } ++ } ++ ++ /* Only for removable media? */ ++ dev_attr_nofua.attr.mode = 0644; ++ dev_attr_nofua.store = fsg_store_nofua; ++ ++ /* Find out how many LUNs there should be */ ++ i = mod_data.nluns; ++ if (i == 0) ++ i = max(mod_data.num_filenames, 1u); ++ if (i > FSG_MAX_LUNS) { ++ ERROR(fsg, "invalid number of LUNs: %d\n", i); ++ rc = -EINVAL; ++ goto out; ++ } ++ ++ /* Create the LUNs, open their backing files, and register the ++ * LUN devices in sysfs. */ ++ fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL); ++ if (!fsg->luns) { ++ rc = -ENOMEM; ++ goto out; ++ } ++ fsg->nluns = i; ++ ++ for (i = 0; i < fsg->nluns; ++i) { ++ curlun = &fsg->luns[i]; ++ curlun->cdrom = !!mod_data.cdrom; ++ curlun->ro = mod_data.cdrom || mod_data.ro[i]; ++ curlun->initially_ro = curlun->ro; ++ curlun->removable = mod_data.removable; ++ curlun->nofua = mod_data.nofua[i]; ++ curlun->dev.release = lun_release; ++ curlun->dev.parent = &gadget->dev; ++ curlun->dev.driver = &fsg_driver.driver; ++ dev_set_drvdata(&curlun->dev, &fsg->filesem); ++ dev_set_name(&curlun->dev,"%s-lun%d", ++ dev_name(&gadget->dev), i); ++ ++ kref_get(&fsg->ref); ++ rc = device_register(&curlun->dev); ++ if (rc) { ++ INFO(fsg, "failed to register LUN%d: %d\n", i, rc); ++ put_device(&curlun->dev); ++ goto out; ++ } ++ curlun->registered = 1; ++ ++ rc = device_create_file(&curlun->dev, &dev_attr_ro); ++ if (rc) ++ goto out; ++ rc = device_create_file(&curlun->dev, &dev_attr_nofua); ++ if (rc) ++ goto out; ++ rc = device_create_file(&curlun->dev, &dev_attr_file); ++ if (rc) ++ goto out; ++ ++ if (mod_data.file[i] && *mod_data.file[i]) { ++ rc = fsg_lun_open(curlun, mod_data.file[i]); ++ if (rc) ++ goto out; ++ } else if (!mod_data.removable) { ++ ERROR(fsg, "no file given for LUN%d\n", i); ++ rc = -EINVAL; ++ goto out; ++ } ++ } ++ ++ /* Find all the endpoints we will use */ ++ usb_ep_autoconfig_reset(gadget); ++ ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); ++ if (!ep) ++ goto autoconf_fail; ++ ep->driver_data = fsg; // claim the endpoint ++ fsg->bulk_in = ep; ++ ++ ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); ++ if (!ep) ++ goto autoconf_fail; ++ ep->driver_data = fsg; // claim the endpoint ++ fsg->bulk_out = ep; ++ ++ if (transport_is_cbi()) { ++ ep = usb_ep_autoconfig(gadget, &fsg_fs_intr_in_desc); ++ if (!ep) ++ goto autoconf_fail; ++ ep->driver_data = fsg; // claim the endpoint ++ fsg->intr_in = ep; ++ } ++ ++ /* Fix up the descriptors */ ++ device_desc.idVendor = cpu_to_le16(mod_data.vendor); ++ device_desc.idProduct = cpu_to_le16(mod_data.product); ++ device_desc.bcdDevice = cpu_to_le16(mod_data.release); ++ ++ i = (transport_is_cbi() ? 3 : 2); // Number of endpoints ++ fsg_intf_desc.bNumEndpoints = i; ++ fsg_intf_desc.bInterfaceSubClass = mod_data.protocol_type; ++ fsg_intf_desc.bInterfaceProtocol = mod_data.transport_type; ++ fsg_fs_function[i + FSG_FS_FUNCTION_PRE_EP_ENTRIES] = NULL; ++ ++ if (gadget_is_dualspeed(gadget)) { ++ fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL; ++ ++ /* Assume endpoint addresses are the same for both speeds */ ++ fsg_hs_bulk_in_desc.bEndpointAddress = ++ fsg_fs_bulk_in_desc.bEndpointAddress; ++ fsg_hs_bulk_out_desc.bEndpointAddress = ++ fsg_fs_bulk_out_desc.bEndpointAddress; ++ fsg_hs_intr_in_desc.bEndpointAddress = ++ fsg_fs_intr_in_desc.bEndpointAddress; ++ } ++ ++ if (gadget_is_superspeed(gadget)) { ++ unsigned max_burst; ++ ++ fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL; ++ ++ /* Calculate bMaxBurst, we know packet size is 1024 */ ++ max_burst = min_t(unsigned, mod_data.buflen / 1024, 15); ++ ++ /* Assume endpoint addresses are the same for both speeds */ ++ fsg_ss_bulk_in_desc.bEndpointAddress = ++ fsg_fs_bulk_in_desc.bEndpointAddress; ++ fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; ++ ++ fsg_ss_bulk_out_desc.bEndpointAddress = ++ fsg_fs_bulk_out_desc.bEndpointAddress; ++ fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; ++ } ++ ++ if (gadget_is_otg(gadget)) ++ fsg_otg_desc.bmAttributes |= USB_OTG_HNP; ++ ++ rc = -ENOMEM; ++ ++ /* Allocate the request and buffer for endpoint 0 */ ++ fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL); ++ if (!req) ++ goto out; ++ req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL); ++ if (!req->buf) ++ goto out; ++ req->complete = ep0_complete; ++ ++ /* Allocate the data buffers */ ++ for (i = 0; i < fsg_num_buffers; ++i) { ++ struct fsg_buffhd *bh = &fsg->buffhds[i]; ++ ++ /* Allocate for the bulk-in endpoint. We assume that ++ * the buffer will also work with the bulk-out (and ++ * interrupt-in) endpoint. */ ++ bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL); ++ if (!bh->buf) ++ goto out; ++ bh->next = bh + 1; ++ } ++ fsg->buffhds[fsg_num_buffers - 1].next = &fsg->buffhds[0]; ++ ++ /* This should reflect the actual gadget power source */ ++ usb_gadget_set_selfpowered(gadget); ++ ++ snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer, ++ "%s %s with %s", ++ init_utsname()->sysname, init_utsname()->release, ++ gadget->name); ++ ++ fsg->thread_task = kthread_create(fsg_main_thread, fsg, ++ "file-storage-gadget"); ++ if (IS_ERR(fsg->thread_task)) { ++ rc = PTR_ERR(fsg->thread_task); ++ goto out; ++ } ++ ++ INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); ++ INFO(fsg, "NOTE: This driver is deprecated. " ++ "Consider using g_mass_storage instead.\n"); ++ INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); ++ ++ pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); ++ for (i = 0; i < fsg->nluns; ++i) { ++ curlun = &fsg->luns[i]; ++ if (fsg_lun_is_open(curlun)) { ++ p = NULL; ++ if (pathbuf) { ++ p = d_path(&curlun->filp->f_path, ++ pathbuf, PATH_MAX); ++ if (IS_ERR(p)) ++ p = NULL; ++ } ++ LINFO(curlun, "ro=%d, nofua=%d, file: %s\n", ++ curlun->ro, curlun->nofua, (p ? p : "(error)")); ++ } ++ } ++ kfree(pathbuf); ++ ++ DBG(fsg, "transport=%s (x%02x)\n", ++ mod_data.transport_name, mod_data.transport_type); ++ DBG(fsg, "protocol=%s (x%02x)\n", ++ mod_data.protocol_name, mod_data.protocol_type); ++ DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", ++ mod_data.vendor, mod_data.product, mod_data.release); ++ DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n", ++ mod_data.removable, mod_data.can_stall, ++ mod_data.cdrom, mod_data.buflen); ++ DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); ++ ++ set_bit(REGISTERED, &fsg->atomic_bitflags); ++ ++ /* Tell the thread to start working */ ++ wake_up_process(fsg->thread_task); ++ return 0; ++ ++autoconf_fail: ++ ERROR(fsg, "unable to autoconfigure all endpoints\n"); ++ rc = -ENOTSUPP; ++ ++out: ++ fsg->state = FSG_STATE_TERMINATED; // The thread is dead ++ fsg_unbind(gadget); ++ complete(&fsg->thread_notifier); ++ return rc; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void fsg_suspend(struct usb_gadget *gadget) ++{ ++ struct fsg_dev *fsg = get_gadget_data(gadget); ++ ++ DBG(fsg, "suspend\n"); ++ set_bit(SUSPENDED, &fsg->atomic_bitflags); ++} ++ ++static void fsg_resume(struct usb_gadget *gadget) ++{ ++ struct fsg_dev *fsg = get_gadget_data(gadget); ++ ++ DBG(fsg, "resume\n"); ++ clear_bit(SUSPENDED, &fsg->atomic_bitflags); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static struct usb_gadget_driver fsg_driver = { ++ .max_speed = USB_SPEED_SUPER, ++ .function = (char *) fsg_string_product, ++ .unbind = fsg_unbind, ++ .disconnect = fsg_disconnect, ++ .setup = fsg_setup, ++ .suspend = fsg_suspend, ++ .resume = fsg_resume, ++ ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ // .release = ... ++ // .suspend = ... ++ // .resume = ... ++ }, ++}; ++ ++ ++static int __init fsg_alloc(void) ++{ ++ struct fsg_dev *fsg; ++ ++ fsg = kzalloc(sizeof *fsg + ++ fsg_num_buffers * sizeof *(fsg->buffhds), GFP_KERNEL); ++ ++ if (!fsg) ++ return -ENOMEM; ++ spin_lock_init(&fsg->lock); ++ init_rwsem(&fsg->filesem); ++ kref_init(&fsg->ref); ++ init_completion(&fsg->thread_notifier); ++ ++ the_fsg = fsg; ++ return 0; ++} ++ ++ ++static int __init fsg_init(void) ++{ ++ int rc; ++ struct fsg_dev *fsg; ++ ++ rc = fsg_num_buffers_validate(); ++ if (rc != 0) ++ return rc; ++ ++ if ((rc = fsg_alloc()) != 0) ++ return rc; ++ fsg = the_fsg; ++ if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0) ++ kref_put(&fsg->ref, fsg_release); ++ return rc; ++} ++module_init(fsg_init); ++ ++ ++static void __exit fsg_cleanup(void) ++{ ++ struct fsg_dev *fsg = the_fsg; ++ ++ /* Unregister the driver iff the thread hasn't already done so */ ++ if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) ++ usb_gadget_unregister_driver(&fsg_driver); ++ ++ /* Wait for the thread to finish up */ ++ wait_for_completion(&fsg->thread_notifier); ++ ++ kref_put(&fsg->ref, fsg_release); ++} ++module_exit(fsg_cleanup); +Index: linux-3.10-3.10.11/drivers/usb/host/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/Kconfig 2014-05-05 11:48:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/Kconfig 2014-05-05 12:51:13.000000000 +0000 +@@ -663,6 +663,19 @@ + To compile this driver a module, choose M here: the module + will be called "hwa-hc". + ++config USB_DWCOTG ++ tristate "Synopsis DWC host support" ++ depends on USB ++ help ++ The Synopsis DWC controller is a dual-role ++ host/peripheral/OTG ("On The Go") USB controllers. ++ ++ Enable this option to support this IP in host controller mode. ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ modules built will be called dwc_otg and dwc_common_port. ++ + config USB_IMX21_HCD + tristate "i.MX21 HCD support" + depends on ARM && ARCH_MXC +Index: linux-3.10-3.10.11/drivers/usb/host/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/usb/host/Makefile 2014-05-05 11:48:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/Makefile 2014-05-05 12:51:13.000000000 +0000 +@@ -47,6 +47,8 @@ + obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o + obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o + obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o ++ ++obj-$(CONFIG_USB_DWCOTG) += dwc_otg/ dwc_common_port/ + obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o + obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o + obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/Makefile 2014-05-05 12:51:13.000000000 +0000 +@@ -0,0 +1,58 @@ ++# ++# Makefile for DWC_common library ++# ++ ++ifneq ($(KERNELRELEASE),) ++ ++EXTRA_CFLAGS += -DDWC_LINUX ++#EXTRA_CFLAGS += -DDEBUG ++#EXTRA_CFLAGS += -DDWC_DEBUG_REGS ++#EXTRA_CFLAGS += -DDWC_DEBUG_MEMORY ++ ++EXTRA_CFLAGS += -DDWC_LIBMODULE ++EXTRA_CFLAGS += -DDWC_CCLIB ++#EXTRA_CFLAGS += -DDWC_CRYPTOLIB ++EXTRA_CFLAGS += -DDWC_NOTIFYLIB ++EXTRA_CFLAGS += -DDWC_UTFLIB ++ ++obj-$(CONFIG_USB_DWCOTG) += dwc_common_port_lib.o ++dwc_common_port_lib-objs := dwc_cc.o dwc_modpow.o dwc_dh.o \ ++ dwc_crypto.o dwc_notifier.o \ ++ dwc_common_linux.o dwc_mem.o ++ ++kernrelwd := $(subst ., ,$(KERNELRELEASE)) ++kernrel3 := $(word 1,$(kernrelwd)).$(word 2,$(kernrelwd)).$(word 3,$(kernrelwd)) ++ ++ifneq ($(kernrel3),2.6.20) ++# grayg - I only know that we use EXTRA_CFLAGS in 2.6.31 actually ++EXTRA_CFLAGS += $(CPPFLAGS) ++endif ++ ++else ++ ++#ifeq ($(KDIR),) ++#$(error Must give "KDIR=/path/to/kernel/source" on command line or in environment) ++#endif ++ ++ifeq ($(ARCH),) ++$(error Must give "ARCH=" on command line or in environment. Also, if \ ++ cross-compiling, must give "CROSS_COMPILE=/path/to/compiler/plus/tool-prefix-") ++endif ++ ++ifeq ($(DOXYGEN),) ++DOXYGEN := doxygen ++endif ++ ++default: ++ $(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules ++ ++docs: $(wildcard *.[hc]) doc/doxygen.cfg ++ $(DOXYGEN) doc/doxygen.cfg ++ ++tags: $(wildcard *.[hc]) ++ $(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h) ++ ++endif ++ ++clean: ++ rm -rf *.o *.ko .*.cmd *.mod.c .*.o.d .*.o.tmp modules.order Module.markers Module.symvers .tmp_versions/ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/Makefile.fbsd +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/Makefile.fbsd 2014-05-05 12:51:13.000000000 +0000 +@@ -0,0 +1,17 @@ ++CFLAGS += -I/sys/i386/compile/GENERIC -I/sys/i386/include -I/usr/include ++CFLAGS += -DDWC_FREEBSD ++CFLAGS += -DDEBUG ++#CFLAGS += -DDWC_DEBUG_REGS ++#CFLAGS += -DDWC_DEBUG_MEMORY ++ ++#CFLAGS += -DDWC_LIBMODULE ++#CFLAGS += -DDWC_CCLIB ++#CFLAGS += -DDWC_CRYPTOLIB ++#CFLAGS += -DDWC_NOTIFYLIB ++#CFLAGS += -DDWC_UTFLIB ++ ++KMOD = dwc_common_port_lib ++SRCS = dwc_cc.c dwc_modpow.c dwc_dh.c dwc_crypto.c dwc_notifier.c \ ++ dwc_common_fbsd.c dwc_mem.c ++ ++.include +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/Makefile.linux +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/Makefile.linux 2014-05-05 12:51:13.000000000 +0000 +@@ -0,0 +1,49 @@ ++# ++# Makefile for DWC_common library ++# ++ifneq ($(KERNELRELEASE),) ++ ++EXTRA_CFLAGS += -DDWC_LINUX ++#EXTRA_CFLAGS += -DDEBUG ++#EXTRA_CFLAGS += -DDWC_DEBUG_REGS ++#EXTRA_CFLAGS += -DDWC_DEBUG_MEMORY ++ ++EXTRA_CFLAGS += -DDWC_LIBMODULE ++EXTRA_CFLAGS += -DDWC_CCLIB ++EXTRA_CFLAGS += -DDWC_CRYPTOLIB ++EXTRA_CFLAGS += -DDWC_NOTIFYLIB ++EXTRA_CFLAGS += -DDWC_UTFLIB ++ ++obj-m := dwc_common_port_lib.o ++dwc_common_port_lib-objs := dwc_cc.o dwc_modpow.o dwc_dh.o \ ++ dwc_crypto.o dwc_notifier.o \ ++ dwc_common_linux.o dwc_mem.o ++ ++else ++ ++ifeq ($(KDIR),) ++$(error Must give "KDIR=/path/to/kernel/source" on command line or in environment) ++endif ++ ++ifeq ($(ARCH),) ++$(error Must give "ARCH=" on command line or in environment. Also, if \ ++ cross-compiling, must give "CROSS_COMPILE=/path/to/compiler/plus/tool-prefix-") ++endif ++ ++ifeq ($(DOXYGEN),) ++DOXYGEN := doxygen ++endif ++ ++default: ++ $(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules ++ ++docs: $(wildcard *.[hc]) doc/doxygen.cfg ++ $(DOXYGEN) doc/doxygen.cfg ++ ++tags: $(wildcard *.[hc]) ++ $(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h) ++ ++endif ++ ++clean: ++ rm -rf *.o *.ko .*.cmd *.mod.c .*.o.d .*.o.tmp modules.order Module.markers Module.symvers .tmp_versions/ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/changes.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/changes.txt 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,174 @@ ++ ++dwc_read_reg32() and friends now take an additional parameter, a pointer to an ++IO context struct. The IO context struct should live in an os-dependent struct ++in your driver. As an example, the dwc_usb3 driver has an os-dependent struct ++named 'os_dep' embedded in the main device struct. So there these calls look ++like this: ++ ++ dwc_read_reg32(&usb3_dev->os_dep.ioctx, &pcd->dev_global_regs->dcfg); ++ ++ dwc_write_reg32(&usb3_dev->os_dep.ioctx, ++ &pcd->dev_global_regs->dcfg, 0); ++ ++Note that for the existing Linux driver ports, it is not necessary to actually ++define the 'ioctx' member in the os-dependent struct. Since Linux does not ++require an IO context, its macros for dwc_read_reg32() and friends do not ++use the context pointer, so it is optimized away by the compiler. But it is ++necessary to add the pointer parameter to all of the call sites, to be ready ++for any future ports (such as FreeBSD) which do require an IO context. ++ ++ ++Similarly, dwc_alloc(), dwc_alloc_atomic(), dwc_strdup(), and dwc_free() now ++take an additional parameter, a pointer to a memory context. Examples: ++ ++ addr = dwc_alloc(&usb3_dev->os_dep.memctx, size); ++ ++ dwc_free(&usb3_dev->os_dep.memctx, addr); ++ ++Again, for the Linux ports, it is not necessary to actually define the memctx ++member, but it is necessary to add the pointer parameter to all of the call ++sites. ++ ++ ++Same for dwc_dma_alloc() and dwc_dma_free(). Examples: ++ ++ virt_addr = dwc_dma_alloc(&usb3_dev->os_dep.dmactx, size, &phys_addr); ++ ++ dwc_dma_free(&usb3_dev->os_dep.dmactx, size, virt_addr, phys_addr); ++ ++ ++Same for dwc_mutex_alloc() and dwc_mutex_free(). Examples: ++ ++ mutex = dwc_mutex_alloc(&usb3_dev->os_dep.mtxctx); ++ ++ dwc_mutex_free(&usb3_dev->os_dep.mtxctx, mutex); ++ ++ ++Same for dwc_spinlock_alloc() and dwc_spinlock_free(). Examples: ++ ++ lock = dwc_spinlock_alloc(&usb3_dev->osdep.splctx); ++ ++ dwc_spinlock_free(&usb3_dev->osdep.splctx, lock); ++ ++ ++Same for dwc_timer_alloc(). Example: ++ ++ timer = dwc_timer_alloc(&usb3_dev->os_dep.tmrctx, "dwc_usb3_tmr1", ++ cb_func, cb_data); ++ ++ ++Same for dwc_waitq_alloc(). Example: ++ ++ waitq = dwc_waitq_alloc(&usb3_dev->os_dep.wtqctx); ++ ++ ++Same for dwc_thread_run(). Example: ++ ++ thread = dwc_thread_run(&usb3_dev->os_dep.thdctx, func, ++ "dwc_usb3_thd1", data); ++ ++ ++Same for dwc_workq_alloc(). Example: ++ ++ workq = dwc_workq_alloc(&usb3_dev->osdep.wkqctx, "dwc_usb3_wkq1"); ++ ++ ++Same for dwc_task_alloc(). Example: ++ ++ task = dwc_task_alloc(&usb3_dev->os_dep.tskctx, "dwc_usb3_tsk1", ++ cb_func, cb_data); ++ ++ ++In addition to the context pointer additions, a few core functions have had ++other changes made to their parameters: ++ ++The 'flags' parameter to dwc_spinlock_irqsave() and dwc_spinunlock_irqrestore() ++has been changed from a uint64_t to a dwc_irqflags_t. ++ ++dwc_thread_should_stop() now takes a 'dwc_thread_t *' parameter, because the ++FreeBSD equivalent of that function requires it. ++ ++And, in addition to the context pointer, dwc_task_alloc() also adds a ++'char *name' parameter, to be consistent with dwc_thread_run() and ++dwc_workq_alloc(), and because the FreeBSD equivalent of that function ++requires a unique name. ++ ++ ++Here is a complete list of the core functions that now take a pointer to a ++context as their first parameter: ++ ++ dwc_read_reg32 ++ dwc_read_reg64 ++ dwc_write_reg32 ++ dwc_write_reg64 ++ dwc_modify_reg32 ++ dwc_modify_reg64 ++ dwc_alloc ++ dwc_alloc_atomic ++ dwc_strdup ++ dwc_free ++ dwc_dma_alloc ++ dwc_dma_free ++ dwc_mutex_alloc ++ dwc_mutex_free ++ dwc_spinlock_alloc ++ dwc_spinlock_free ++ dwc_timer_alloc ++ dwc_waitq_alloc ++ dwc_thread_run ++ dwc_workq_alloc ++ dwc_task_alloc Also adds a 'char *name' as its 2nd parameter ++ ++And here are the core functions that have other changes to their parameters: ++ ++ dwc_spinlock_irqsave 'flags' param is now a 'dwc_irqflags_t *' ++ dwc_spinunlock_irqrestore 'flags' param is now a 'dwc_irqflags_t' ++ dwc_thread_should_stop Adds a 'dwc_thread_t *' parameter ++ ++ ++ ++The changes to the core functions also require some of the other library ++functions to change: ++ ++ dwc_cc_if_alloc() and dwc_cc_if_free() now take a 'void *memctx' ++ (for memory allocation) as the 1st param and a 'void *mtxctx' ++ (for mutex allocation) as the 2nd param. ++ ++ dwc_cc_clear(), dwc_cc_add(), dwc_cc_change(), dwc_cc_remove(), ++ dwc_cc_data_for_save(), and dwc_cc_restore_from_data() now take a ++ 'void *memctx' as the 1st param. ++ ++ dwc_dh_modpow(), dwc_dh_pk(), and dwc_dh_derive_keys() now take a ++ 'void *memctx' as the 1st param. ++ ++ dwc_modpow() now takes a 'void *memctx' as the 1st param. ++ ++ dwc_alloc_notification_manager() now takes a 'void *memctx' as the ++ 1st param and a 'void *wkqctx' (for work queue allocation) as the 2nd ++ param, and also now returns an integer value that is non-zero if ++ allocation of its data structures or work queue fails. ++ ++ dwc_register_notifier() now takes a 'void *memctx' as the 1st param. ++ ++ dwc_memory_debug_start() now takes a 'void *mem_ctx' as the first ++ param, and also now returns an integer value that is non-zero if ++ allocation of its data structures fails. ++ ++ ++ ++Other miscellaneous changes: ++ ++The DEBUG_MEMORY and DEBUG_REGS #define's have been renamed to ++DWC_DEBUG_MEMORY and DWC_DEBUG_REGS. ++ ++The following #define's have been added to allow selectively compiling library ++features: ++ ++ DWC_CCLIB ++ DWC_CRYPTOLIB ++ DWC_NOTIFYLIB ++ DWC_UTFLIB ++ ++A DWC_LIBMODULE #define has also been added. If this is not defined, then the ++module code in dwc_common_linux.c is not compiled in. This allows linking the ++library code directly into a driver module, instead of as a standalone module. +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/doc/doxygen.cfg +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/doc/doxygen.cfg 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,270 @@ ++# Doxyfile 1.4.5 ++ ++#--------------------------------------------------------------------------- ++# Project related configuration options ++#--------------------------------------------------------------------------- ++PROJECT_NAME = "Synopsys DWC Portability and Common Library for UWB" ++PROJECT_NUMBER = ++OUTPUT_DIRECTORY = doc ++CREATE_SUBDIRS = NO ++OUTPUT_LANGUAGE = English ++BRIEF_MEMBER_DESC = YES ++REPEAT_BRIEF = YES ++ABBREVIATE_BRIEF = "The $name class" \ ++ "The $name widget" \ ++ "The $name file" \ ++ is \ ++ provides \ ++ specifies \ ++ contains \ ++ represents \ ++ a \ ++ an \ ++ the ++ALWAYS_DETAILED_SEC = YES ++INLINE_INHERITED_MEMB = NO ++FULL_PATH_NAMES = NO ++STRIP_FROM_PATH = .. ++STRIP_FROM_INC_PATH = ++SHORT_NAMES = NO ++JAVADOC_AUTOBRIEF = YES ++MULTILINE_CPP_IS_BRIEF = NO ++DETAILS_AT_TOP = YES ++INHERIT_DOCS = YES ++SEPARATE_MEMBER_PAGES = NO ++TAB_SIZE = 8 ++ALIASES = ++OPTIMIZE_OUTPUT_FOR_C = YES ++OPTIMIZE_OUTPUT_JAVA = NO ++BUILTIN_STL_SUPPORT = NO ++DISTRIBUTE_GROUP_DOC = NO ++SUBGROUPING = NO ++#--------------------------------------------------------------------------- ++# Build related configuration options ++#--------------------------------------------------------------------------- ++EXTRACT_ALL = NO ++EXTRACT_PRIVATE = NO ++EXTRACT_STATIC = YES ++EXTRACT_LOCAL_CLASSES = NO ++EXTRACT_LOCAL_METHODS = NO ++HIDE_UNDOC_MEMBERS = NO ++HIDE_UNDOC_CLASSES = NO ++HIDE_FRIEND_COMPOUNDS = NO ++HIDE_IN_BODY_DOCS = NO ++INTERNAL_DOCS = NO ++CASE_SENSE_NAMES = YES ++HIDE_SCOPE_NAMES = NO ++SHOW_INCLUDE_FILES = NO ++INLINE_INFO = YES ++SORT_MEMBER_DOCS = NO ++SORT_BRIEF_DOCS = NO ++SORT_BY_SCOPE_NAME = NO ++GENERATE_TODOLIST = YES ++GENERATE_TESTLIST = YES ++GENERATE_BUGLIST = YES ++GENERATE_DEPRECATEDLIST= YES ++ENABLED_SECTIONS = ++MAX_INITIALIZER_LINES = 30 ++SHOW_USED_FILES = YES ++SHOW_DIRECTORIES = YES ++FILE_VERSION_FILTER = ++#--------------------------------------------------------------------------- ++# configuration options related to warning and progress messages ++#--------------------------------------------------------------------------- ++QUIET = YES ++WARNINGS = YES ++WARN_IF_UNDOCUMENTED = NO ++WARN_IF_DOC_ERROR = YES ++WARN_NO_PARAMDOC = YES ++WARN_FORMAT = "$file:$line: $text" ++WARN_LOGFILE = ++#--------------------------------------------------------------------------- ++# configuration options related to the input files ++#--------------------------------------------------------------------------- ++INPUT = . ++FILE_PATTERNS = *.c \ ++ *.cc \ ++ *.cxx \ ++ *.cpp \ ++ *.c++ \ ++ *.d \ ++ *.java \ ++ *.ii \ ++ *.ixx \ ++ *.ipp \ ++ *.i++ \ ++ *.inl \ ++ *.h \ ++ *.hh \ ++ *.hxx \ ++ *.hpp \ ++ *.h++ \ ++ *.idl \ ++ *.odl \ ++ *.cs \ ++ *.php \ ++ *.php3 \ ++ *.inc \ ++ *.m \ ++ *.mm \ ++ *.dox \ ++ *.py \ ++ *.C \ ++ *.CC \ ++ *.C++ \ ++ *.II \ ++ *.I++ \ ++ *.H \ ++ *.HH \ ++ *.H++ \ ++ *.CS \ ++ *.PHP \ ++ *.PHP3 \ ++ *.M \ ++ *.MM \ ++ *.PY ++RECURSIVE = NO ++EXCLUDE = ++EXCLUDE_SYMLINKS = NO ++EXCLUDE_PATTERNS = ++EXAMPLE_PATH = ++EXAMPLE_PATTERNS = * ++EXAMPLE_RECURSIVE = NO ++IMAGE_PATH = ++INPUT_FILTER = ++FILTER_PATTERNS = ++FILTER_SOURCE_FILES = NO ++#--------------------------------------------------------------------------- ++# configuration options related to source browsing ++#--------------------------------------------------------------------------- ++SOURCE_BROWSER = NO ++INLINE_SOURCES = NO ++STRIP_CODE_COMMENTS = YES ++REFERENCED_BY_RELATION = YES ++REFERENCES_RELATION = YES ++USE_HTAGS = NO ++VERBATIM_HEADERS = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the alphabetical class index ++#--------------------------------------------------------------------------- ++ALPHABETICAL_INDEX = NO ++COLS_IN_ALPHA_INDEX = 5 ++IGNORE_PREFIX = ++#--------------------------------------------------------------------------- ++# configuration options related to the HTML output ++#--------------------------------------------------------------------------- ++GENERATE_HTML = YES ++HTML_OUTPUT = html ++HTML_FILE_EXTENSION = .html ++HTML_HEADER = ++HTML_FOOTER = ++HTML_STYLESHEET = ++HTML_ALIGN_MEMBERS = YES ++GENERATE_HTMLHELP = NO ++CHM_FILE = ++HHC_LOCATION = ++GENERATE_CHI = NO ++BINARY_TOC = NO ++TOC_EXPAND = NO ++DISABLE_INDEX = NO ++ENUM_VALUES_PER_LINE = 4 ++GENERATE_TREEVIEW = YES ++TREEVIEW_WIDTH = 250 ++#--------------------------------------------------------------------------- ++# configuration options related to the LaTeX output ++#--------------------------------------------------------------------------- ++GENERATE_LATEX = NO ++LATEX_OUTPUT = latex ++LATEX_CMD_NAME = latex ++MAKEINDEX_CMD_NAME = makeindex ++COMPACT_LATEX = NO ++PAPER_TYPE = a4wide ++EXTRA_PACKAGES = ++LATEX_HEADER = ++PDF_HYPERLINKS = NO ++USE_PDFLATEX = NO ++LATEX_BATCHMODE = NO ++LATEX_HIDE_INDICES = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the RTF output ++#--------------------------------------------------------------------------- ++GENERATE_RTF = NO ++RTF_OUTPUT = rtf ++COMPACT_RTF = NO ++RTF_HYPERLINKS = NO ++RTF_STYLESHEET_FILE = ++RTF_EXTENSIONS_FILE = ++#--------------------------------------------------------------------------- ++# configuration options related to the man page output ++#--------------------------------------------------------------------------- ++GENERATE_MAN = NO ++MAN_OUTPUT = man ++MAN_EXTENSION = .3 ++MAN_LINKS = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the XML output ++#--------------------------------------------------------------------------- ++GENERATE_XML = NO ++XML_OUTPUT = xml ++XML_SCHEMA = ++XML_DTD = ++XML_PROGRAMLISTING = YES ++#--------------------------------------------------------------------------- ++# configuration options for the AutoGen Definitions output ++#--------------------------------------------------------------------------- ++GENERATE_AUTOGEN_DEF = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the Perl module output ++#--------------------------------------------------------------------------- ++GENERATE_PERLMOD = NO ++PERLMOD_LATEX = NO ++PERLMOD_PRETTY = YES ++PERLMOD_MAKEVAR_PREFIX = ++#--------------------------------------------------------------------------- ++# Configuration options related to the preprocessor ++#--------------------------------------------------------------------------- ++ENABLE_PREPROCESSING = YES ++MACRO_EXPANSION = NO ++EXPAND_ONLY_PREDEF = NO ++SEARCH_INCLUDES = YES ++INCLUDE_PATH = ++INCLUDE_FILE_PATTERNS = ++PREDEFINED = DEBUG DEBUG_MEMORY ++EXPAND_AS_DEFINED = ++SKIP_FUNCTION_MACROS = YES ++#--------------------------------------------------------------------------- ++# Configuration::additions related to external references ++#--------------------------------------------------------------------------- ++TAGFILES = ++GENERATE_TAGFILE = ++ALLEXTERNALS = NO ++EXTERNAL_GROUPS = YES ++PERL_PATH = /usr/bin/perl ++#--------------------------------------------------------------------------- ++# Configuration options related to the dot tool ++#--------------------------------------------------------------------------- ++CLASS_DIAGRAMS = YES ++HIDE_UNDOC_RELATIONS = YES ++HAVE_DOT = NO ++CLASS_GRAPH = YES ++COLLABORATION_GRAPH = YES ++GROUP_GRAPHS = YES ++UML_LOOK = NO ++TEMPLATE_RELATIONS = NO ++INCLUDE_GRAPH = NO ++INCLUDED_BY_GRAPH = YES ++CALL_GRAPH = NO ++GRAPHICAL_HIERARCHY = YES ++DIRECTORY_GRAPH = YES ++DOT_IMAGE_FORMAT = png ++DOT_PATH = ++DOTFILE_DIRS = ++MAX_DOT_GRAPH_DEPTH = 1000 ++DOT_TRANSPARENT = NO ++DOT_MULTI_TARGETS = NO ++GENERATE_LEGEND = YES ++DOT_CLEANUP = YES ++#--------------------------------------------------------------------------- ++# Configuration::additions related to the search engine ++#--------------------------------------------------------------------------- ++SEARCHENGINE = NO +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_cc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_cc.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,532 @@ ++/* ========================================================================= ++ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_cc.c $ ++ * $Revision: #4 $ ++ * $Date: 2010/11/04 $ ++ * $Change: 1621692 $ ++ * ++ * Synopsys Portability Library Software and documentation ++ * (hereinafter, "Software") is an Unsupported proprietary work of ++ * Synopsys, Inc. unless otherwise expressly agreed to in writing ++ * between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product ++ * under any End User Software License Agreement or Agreement for ++ * Licensed Product with Synopsys or any supplement thereto. You are ++ * permitted to use and redistribute this Software in source and binary ++ * forms, with or without modification, provided that redistributions ++ * of source code must retain this notice. You may not view, use, ++ * disclose, copy or distribute this file or any information contained ++ * herein except pursuant to this license grant from Synopsys. If you ++ * do not agree with this notice, including the disclaimer below, then ++ * you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" ++ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL ++ * SYNOPSYS 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. ++ * ========================================================================= */ ++#ifdef DWC_CCLIB ++ ++#include "dwc_cc.h" ++ ++typedef struct dwc_cc ++{ ++ uint32_t uid; ++ uint8_t chid[16]; ++ uint8_t cdid[16]; ++ uint8_t ck[16]; ++ uint8_t *name; ++ uint8_t length; ++ DWC_CIRCLEQ_ENTRY(dwc_cc) list_entry; ++} dwc_cc_t; ++ ++DWC_CIRCLEQ_HEAD(context_list, dwc_cc); ++ ++/** The main structure for CC management. */ ++struct dwc_cc_if ++{ ++ dwc_mutex_t *mutex; ++ char *filename; ++ ++ unsigned is_host:1; ++ ++ dwc_notifier_t *notifier; ++ ++ struct context_list list; ++}; ++ ++#ifdef DEBUG ++static inline void dump_bytes(char *name, uint8_t *bytes, int len) ++{ ++ int i; ++ DWC_PRINTF("%s: ", name); ++ for (i=0; ilength = length; ++ cc->name = dwc_alloc(mem_ctx, length); ++ if (!cc->name) { ++ dwc_free(mem_ctx, cc); ++ return NULL; ++ } ++ ++ DWC_MEMCPY(cc->name, name, length); ++ } ++ ++ return cc; ++} ++ ++static void free_cc(void *mem_ctx, dwc_cc_t *cc) ++{ ++ if (cc->name) { ++ dwc_free(mem_ctx, cc->name); ++ } ++ dwc_free(mem_ctx, cc); ++} ++ ++static uint32_t next_uid(dwc_cc_if_t *cc_if) ++{ ++ uint32_t uid = 0; ++ dwc_cc_t *cc; ++ DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) { ++ if (cc->uid > uid) { ++ uid = cc->uid; ++ } ++ } ++ ++ if (uid == 0) { ++ uid = 255; ++ } ++ ++ return uid + 1; ++} ++ ++static dwc_cc_t *cc_find(dwc_cc_if_t *cc_if, uint32_t uid) ++{ ++ dwc_cc_t *cc; ++ DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) { ++ if (cc->uid == uid) { ++ return cc; ++ } ++ } ++ return NULL; ++} ++ ++static unsigned int cc_data_size(dwc_cc_if_t *cc_if) ++{ ++ unsigned int size = 0; ++ dwc_cc_t *cc; ++ DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) { ++ size += (48 + 1); ++ if (cc->name) { ++ size += cc->length; ++ } ++ } ++ return size; ++} ++ ++static uint32_t cc_match_chid(dwc_cc_if_t *cc_if, uint8_t *chid) ++{ ++ uint32_t uid = 0; ++ dwc_cc_t *cc; ++ ++ DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) { ++ if (DWC_MEMCMP(cc->chid, chid, 16) == 0) { ++ uid = cc->uid; ++ break; ++ } ++ } ++ return uid; ++} ++static uint32_t cc_match_cdid(dwc_cc_if_t *cc_if, uint8_t *cdid) ++{ ++ uint32_t uid = 0; ++ dwc_cc_t *cc; ++ ++ DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) { ++ if (DWC_MEMCMP(cc->cdid, cdid, 16) == 0) { ++ uid = cc->uid; ++ break; ++ } ++ } ++ return uid; ++} ++ ++/* Internal cc_add */ ++static int32_t cc_add(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *chid, ++ uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length) ++{ ++ dwc_cc_t *cc; ++ uint32_t uid; ++ ++ if (cc_if->is_host) { ++ uid = cc_match_cdid(cc_if, cdid); ++ } ++ else { ++ uid = cc_match_chid(cc_if, chid); ++ } ++ ++ if (uid) { ++ DWC_DEBUGC("Replacing previous connection context id=%d name=%p name_len=%d", uid, name, length); ++ cc = cc_find(cc_if, uid); ++ } ++ else { ++ cc = alloc_cc(mem_ctx, name, length); ++ cc->uid = next_uid(cc_if); ++ DWC_CIRCLEQ_INSERT_TAIL(&cc_if->list, cc, list_entry); ++ } ++ ++ DWC_MEMCPY(&(cc->chid[0]), chid, 16); ++ DWC_MEMCPY(&(cc->cdid[0]), cdid, 16); ++ DWC_MEMCPY(&(cc->ck[0]), ck, 16); ++ ++ DWC_DEBUGC("Added connection context id=%d name=%p name_len=%d", cc->uid, name, length); ++ dump_bytes("CHID", cc->chid, 16); ++ dump_bytes("CDID", cc->cdid, 16); ++ dump_bytes("CK", cc->ck, 16); ++ return cc->uid; ++} ++ ++/* Internal cc_clear */ ++static void cc_clear(void *mem_ctx, dwc_cc_if_t *cc_if) ++{ ++ while (!DWC_CIRCLEQ_EMPTY(&cc_if->list)) { ++ dwc_cc_t *cc = DWC_CIRCLEQ_FIRST(&cc_if->list); ++ DWC_CIRCLEQ_REMOVE_INIT(&cc_if->list, cc, list_entry); ++ free_cc(mem_ctx, cc); ++ } ++} ++ ++dwc_cc_if_t *dwc_cc_if_alloc(void *mem_ctx, void *mtx_ctx, ++ dwc_notifier_t *notifier, unsigned is_host) ++{ ++ dwc_cc_if_t *cc_if = NULL; ++ ++ /* Allocate a common_cc_if structure */ ++ cc_if = dwc_alloc(mem_ctx, sizeof(dwc_cc_if_t)); ++ ++ if (!cc_if) ++ return NULL; ++ ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)) ++ DWC_MUTEX_ALLOC_LINUX_DEBUG(cc_if->mutex); ++#else ++ cc_if->mutex = dwc_mutex_alloc(mtx_ctx); ++#endif ++ if (!cc_if->mutex) { ++ dwc_free(mem_ctx, cc_if); ++ return NULL; ++ } ++ ++ DWC_CIRCLEQ_INIT(&cc_if->list); ++ cc_if->is_host = is_host; ++ cc_if->notifier = notifier; ++ return cc_if; ++} ++ ++void dwc_cc_if_free(void *mem_ctx, void *mtx_ctx, dwc_cc_if_t *cc_if) ++{ ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)) ++ DWC_MUTEX_FREE(cc_if->mutex); ++#else ++ dwc_mutex_free(mtx_ctx, cc_if->mutex); ++#endif ++ cc_clear(mem_ctx, cc_if); ++ dwc_free(mem_ctx, cc_if); ++} ++ ++static void cc_changed(dwc_cc_if_t *cc_if) ++{ ++ if (cc_if->notifier) { ++ dwc_notify(cc_if->notifier, DWC_CC_LIST_CHANGED_NOTIFICATION, cc_if); ++ } ++} ++ ++void dwc_cc_clear(void *mem_ctx, dwc_cc_if_t *cc_if) ++{ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ cc_clear(mem_ctx, cc_if); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ cc_changed(cc_if); ++} ++ ++int32_t dwc_cc_add(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *chid, ++ uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length) ++{ ++ uint32_t uid; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ uid = cc_add(mem_ctx, cc_if, chid, cdid, ck, name, length); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ cc_changed(cc_if); ++ ++ return uid; ++} ++ ++void dwc_cc_change(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id, uint8_t *chid, ++ uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length) ++{ ++ dwc_cc_t* cc; ++ ++ DWC_DEBUGC("Change connection context %d", id); ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ cc = cc_find(cc_if, id); ++ if (!cc) { ++ DWC_ERROR("Uid %d not found in cc list\n", id); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ return; ++ } ++ ++ if (chid) { ++ DWC_MEMCPY(&(cc->chid[0]), chid, 16); ++ } ++ if (cdid) { ++ DWC_MEMCPY(&(cc->cdid[0]), cdid, 16); ++ } ++ if (ck) { ++ DWC_MEMCPY(&(cc->ck[0]), ck, 16); ++ } ++ ++ if (name) { ++ if (cc->name) { ++ dwc_free(mem_ctx, cc->name); ++ } ++ cc->name = dwc_alloc(mem_ctx, length); ++ if (!cc->name) { ++ DWC_ERROR("Out of memory in dwc_cc_change()\n"); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ return; ++ } ++ cc->length = length; ++ DWC_MEMCPY(cc->name, name, length); ++ } ++ ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ ++ cc_changed(cc_if); ++ ++ DWC_DEBUGC("Changed connection context id=%d\n", id); ++ dump_bytes("New CHID", cc->chid, 16); ++ dump_bytes("New CDID", cc->cdid, 16); ++ dump_bytes("New CK", cc->ck, 16); ++} ++ ++void dwc_cc_remove(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id) ++{ ++ dwc_cc_t *cc; ++ ++ DWC_DEBUGC("Removing connection context %d", id); ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ cc = cc_find(cc_if, id); ++ if (!cc) { ++ DWC_ERROR("Uid %d not found in cc list\n", id); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ return; ++ } ++ ++ DWC_CIRCLEQ_REMOVE_INIT(&cc_if->list, cc, list_entry); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ free_cc(mem_ctx, cc); ++ ++ cc_changed(cc_if); ++} ++ ++uint8_t *dwc_cc_data_for_save(void *mem_ctx, dwc_cc_if_t *cc_if, unsigned int *length) ++{ ++ uint8_t *buf, *x; ++ uint8_t zero = 0; ++ dwc_cc_t *cc; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ *length = cc_data_size(cc_if); ++ if (!(*length)) { ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ return NULL; ++ } ++ ++ DWC_DEBUGC("Creating data for saving (length=%d)", *length); ++ ++ buf = dwc_alloc(mem_ctx, *length); ++ if (!buf) { ++ *length = 0; ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ return NULL; ++ } ++ ++ x = buf; ++ DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) { ++ DWC_MEMCPY(x, cc->chid, 16); ++ x += 16; ++ DWC_MEMCPY(x, cc->cdid, 16); ++ x += 16; ++ DWC_MEMCPY(x, cc->ck, 16); ++ x += 16; ++ if (cc->name) { ++ DWC_MEMCPY(x, &cc->length, 1); ++ x += 1; ++ DWC_MEMCPY(x, cc->name, cc->length); ++ x += cc->length; ++ } ++ else { ++ DWC_MEMCPY(x, &zero, 1); ++ x += 1; ++ } ++ } ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ ++ return buf; ++} ++ ++void dwc_cc_restore_from_data(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *data, uint32_t length) ++{ ++ uint8_t name_length; ++ uint8_t *name; ++ uint8_t *chid; ++ uint8_t *cdid; ++ uint8_t *ck; ++ uint32_t i = 0; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ cc_clear(mem_ctx, cc_if); ++ ++ while (i < length) { ++ chid = &data[i]; ++ i += 16; ++ cdid = &data[i]; ++ i += 16; ++ ck = &data[i]; ++ i += 16; ++ ++ name_length = data[i]; ++ i ++; ++ ++ if (name_length) { ++ name = &data[i]; ++ i += name_length; ++ } ++ else { ++ name = NULL; ++ } ++ ++ /* check to see if we haven't overflown the buffer */ ++ if (i > length) { ++ DWC_ERROR("Data format error while attempting to load CCs " ++ "(nlen=%d, iter=%d, buflen=%d).\n", name_length, i, length); ++ break; ++ } ++ ++ cc_add(mem_ctx, cc_if, chid, cdid, ck, name, name_length); ++ } ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ ++ cc_changed(cc_if); ++} ++ ++uint32_t dwc_cc_match_chid(dwc_cc_if_t *cc_if, uint8_t *chid) ++{ ++ uint32_t uid = 0; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ uid = cc_match_chid(cc_if, chid); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ return uid; ++} ++uint32_t dwc_cc_match_cdid(dwc_cc_if_t *cc_if, uint8_t *cdid) ++{ ++ uint32_t uid = 0; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ uid = cc_match_cdid(cc_if, cdid); ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ return uid; ++} ++ ++uint8_t *dwc_cc_ck(dwc_cc_if_t *cc_if, int32_t id) ++{ ++ uint8_t *ck = NULL; ++ dwc_cc_t *cc; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ cc = cc_find(cc_if, id); ++ if (cc) { ++ ck = cc->ck; ++ } ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ ++ return ck; ++ ++} ++ ++uint8_t *dwc_cc_chid(dwc_cc_if_t *cc_if, int32_t id) ++{ ++ uint8_t *retval = NULL; ++ dwc_cc_t *cc; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ cc = cc_find(cc_if, id); ++ if (cc) { ++ retval = cc->chid; ++ } ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ ++ return retval; ++} ++ ++uint8_t *dwc_cc_cdid(dwc_cc_if_t *cc_if, int32_t id) ++{ ++ uint8_t *retval = NULL; ++ dwc_cc_t *cc; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ cc = cc_find(cc_if, id); ++ if (cc) { ++ retval = cc->cdid; ++ } ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ ++ return retval; ++} ++ ++uint8_t *dwc_cc_name(dwc_cc_if_t *cc_if, int32_t id, uint8_t *length) ++{ ++ uint8_t *retval = NULL; ++ dwc_cc_t *cc; ++ ++ DWC_MUTEX_LOCK(cc_if->mutex); ++ *length = 0; ++ cc = cc_find(cc_if, id); ++ if (cc) { ++ *length = cc->length; ++ retval = cc->name; ++ } ++ DWC_MUTEX_UNLOCK(cc_if->mutex); ++ ++ return retval; ++} ++ ++#endif /* DWC_CCLIB */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_cc.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_cc.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,225 @@ ++/* ========================================================================= ++ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_cc.h $ ++ * $Revision: #4 $ ++ * $Date: 2010/09/28 $ ++ * $Change: 1596182 $ ++ * ++ * Synopsys Portability Library Software and documentation ++ * (hereinafter, "Software") is an Unsupported proprietary work of ++ * Synopsys, Inc. unless otherwise expressly agreed to in writing ++ * between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product ++ * under any End User Software License Agreement or Agreement for ++ * Licensed Product with Synopsys or any supplement thereto. You are ++ * permitted to use and redistribute this Software in source and binary ++ * forms, with or without modification, provided that redistributions ++ * of source code must retain this notice. You may not view, use, ++ * disclose, copy or distribute this file or any information contained ++ * herein except pursuant to this license grant from Synopsys. If you ++ * do not agree with this notice, including the disclaimer below, then ++ * you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" ++ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL ++ * SYNOPSYS 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. ++ * ========================================================================= */ ++#ifndef _DWC_CC_H_ ++#define _DWC_CC_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/** @file ++ * ++ * This file defines the Context Context library. ++ * ++ * The main data structure is dwc_cc_if_t which is returned by either the ++ * dwc_cc_if_alloc function or returned by the module to the user via a provided ++ * function. The data structure is opaque and should only be manipulated via the ++ * functions provied in this API. ++ * ++ * It manages a list of connection contexts and operations can be performed to ++ * add, remove, query, search, and change, those contexts. Additionally, ++ * a dwc_notifier_t object can be requested from the manager so that ++ * the user can be notified whenever the context list has changed. ++ */ ++ ++#include "dwc_os.h" ++#include "dwc_list.h" ++#include "dwc_notifier.h" ++ ++ ++/* Notifications */ ++#define DWC_CC_LIST_CHANGED_NOTIFICATION "DWC_CC_LIST_CHANGED_NOTIFICATION" ++ ++struct dwc_cc_if; ++typedef struct dwc_cc_if dwc_cc_if_t; ++ ++ ++/** @name Connection Context Operations */ ++/** @{ */ ++ ++/** This function allocates memory for a dwc_cc_if_t structure, initializes ++ * fields to default values, and returns a pointer to the structure or NULL on ++ * error. */ ++extern dwc_cc_if_t *dwc_cc_if_alloc(void *mem_ctx, void *mtx_ctx, ++ dwc_notifier_t *notifier, unsigned is_host); ++ ++/** Frees the memory for the specified CC structure allocated from ++ * dwc_cc_if_alloc(). */ ++extern void dwc_cc_if_free(void *mem_ctx, void *mtx_ctx, dwc_cc_if_t *cc_if); ++ ++/** Removes all contexts from the connection context list */ ++extern void dwc_cc_clear(void *mem_ctx, dwc_cc_if_t *cc_if); ++ ++/** Adds a connection context (CHID, CK, CDID, Name) to the connection context list. ++ * If a CHID already exists, the CK and name are overwritten. Statistics are ++ * not overwritten. ++ * ++ * @param cc_if The cc_if structure. ++ * @param chid A pointer to the 16-byte CHID. This value will be copied. ++ * @param ck A pointer to the 16-byte CK. This value will be copied. ++ * @param cdid A pointer to the 16-byte CDID. This value will be copied. ++ * @param name An optional host friendly name as defined in the association model ++ * spec. Must be a UTF16-LE unicode string. Can be NULL to indicated no name. ++ * @param length The length othe unicode string. ++ * @return A unique identifier used to refer to this context that is valid for ++ * as long as this context is still in the list. */ ++extern int32_t dwc_cc_add(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *chid, ++ uint8_t *cdid, uint8_t *ck, uint8_t *name, ++ uint8_t length); ++ ++/** Changes the CHID, CK, CDID, or Name values of a connection context in the ++ * list, preserving any accumulated statistics. This would typically be called ++ * if the host decideds to change the context with a SET_CONNECTION request. ++ * ++ * @param cc_if The cc_if structure. ++ * @param id The identifier of the connection context. ++ * @param chid A pointer to the 16-byte CHID. This value will be copied. NULL ++ * indicates no change. ++ * @param cdid A pointer to the 16-byte CDID. This value will be copied. NULL ++ * indicates no change. ++ * @param ck A pointer to the 16-byte CK. This value will be copied. NULL ++ * indicates no change. ++ * @param name Host friendly name UTF16-LE. NULL indicates no change. ++ * @param length Length of name. */ ++extern void dwc_cc_change(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id, ++ uint8_t *chid, uint8_t *cdid, uint8_t *ck, ++ uint8_t *name, uint8_t length); ++ ++/** Remove the specified connection context. ++ * @param cc_if The cc_if structure. ++ * @param id The identifier of the connection context to remove. */ ++extern void dwc_cc_remove(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id); ++ ++/** Get a binary block of data for the connection context list and attributes. ++ * This data can be used by the OS specific driver to save the connection ++ * context list into non-volatile memory. ++ * ++ * @param cc_if The cc_if structure. ++ * @param length Return the length of the data buffer. ++ * @return A pointer to the data buffer. The memory for this buffer should be ++ * freed with DWC_FREE() after use. */ ++extern uint8_t *dwc_cc_data_for_save(void *mem_ctx, dwc_cc_if_t *cc_if, ++ unsigned int *length); ++ ++/** Restore the connection context list from the binary data that was previously ++ * returned from a call to dwc_cc_data_for_save. This can be used by the OS specific ++ * driver to load a connection context list from non-volatile memory. ++ * ++ * @param cc_if The cc_if structure. ++ * @param data The data bytes as returned from dwc_cc_data_for_save. ++ * @param length The length of the data. */ ++extern void dwc_cc_restore_from_data(void *mem_ctx, dwc_cc_if_t *cc_if, ++ uint8_t *data, unsigned int length); ++ ++/** Find the connection context from the specified CHID. ++ * ++ * @param cc_if The cc_if structure. ++ * @param chid A pointer to the CHID data. ++ * @return A non-zero identifier of the connection context if the CHID matches. ++ * Otherwise returns 0. */ ++extern uint32_t dwc_cc_match_chid(dwc_cc_if_t *cc_if, uint8_t *chid); ++ ++/** Find the connection context from the specified CDID. ++ * ++ * @param cc_if The cc_if structure. ++ * @param cdid A pointer to the CDID data. ++ * @return A non-zero identifier of the connection context if the CHID matches. ++ * Otherwise returns 0. */ ++extern uint32_t dwc_cc_match_cdid(dwc_cc_if_t *cc_if, uint8_t *cdid); ++ ++/** Retrieve the CK from the specified connection context. ++ * ++ * @param cc_if The cc_if structure. ++ * @param id The identifier of the connection context. ++ * @return A pointer to the CK data. The memory does not need to be freed. */ ++extern uint8_t *dwc_cc_ck(dwc_cc_if_t *cc_if, int32_t id); ++ ++/** Retrieve the CHID from the specified connection context. ++ * ++ * @param cc_if The cc_if structure. ++ * @param id The identifier of the connection context. ++ * @return A pointer to the CHID data. The memory does not need to be freed. */ ++extern uint8_t *dwc_cc_chid(dwc_cc_if_t *cc_if, int32_t id); ++ ++/** Retrieve the CDID from the specified connection context. ++ * ++ * @param cc_if The cc_if structure. ++ * @param id The identifier of the connection context. ++ * @return A pointer to the CDID data. The memory does not need to be freed. */ ++extern uint8_t *dwc_cc_cdid(dwc_cc_if_t *cc_if, int32_t id); ++ ++extern uint8_t *dwc_cc_name(dwc_cc_if_t *cc_if, int32_t id, uint8_t *length); ++ ++/** Checks a buffer for non-zero. ++ * @param id A pointer to a 16 byte buffer. ++ * @return true if the 16 byte value is non-zero. */ ++static inline unsigned dwc_assoc_is_not_zero_id(uint8_t *id) { ++ int i; ++ for (i=0; i<16; i++) { ++ if (id[i]) return 1; ++ } ++ return 0; ++} ++ ++/** Checks a buffer for zero. ++ * @param id A pointer to a 16 byte buffer. ++ * @return true if the 16 byte value is zero. */ ++static inline unsigned dwc_assoc_is_zero_id(uint8_t *id) { ++ return !dwc_assoc_is_not_zero_id(id); ++} ++ ++/** Prints an ASCII representation for the 16-byte chid, cdid, or ck, into ++ * buffer. */ ++static inline int dwc_print_id_string(char *buffer, uint8_t *id) { ++ char *ptr = buffer; ++ int i; ++ for (i=0; i<16; i++) { ++ ptr += DWC_SPRINTF(ptr, "%02x", id[i]); ++ if (i < 15) { ++ ptr += DWC_SPRINTF(ptr, " "); ++ } ++ } ++ return ptr - buffer; ++} ++ ++/** @} */ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _DWC_CC_H_ */ ++ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_common_fbsd.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_common_fbsd.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1308 @@ ++#include "dwc_os.h" ++#include "dwc_list.h" ++ ++#ifdef DWC_CCLIB ++# include "dwc_cc.h" ++#endif ++ ++#ifdef DWC_CRYPTOLIB ++# include "dwc_modpow.h" ++# include "dwc_dh.h" ++# include "dwc_crypto.h" ++#endif ++ ++#ifdef DWC_NOTIFYLIB ++# include "dwc_notifier.h" ++#endif ++ ++/* OS-Level Implementations */ ++ ++/* This is the FreeBSD 7.0 kernel implementation of the DWC platform library. */ ++ ++ ++/* MISC */ ++ ++void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size) ++{ ++ return memset(dest, byte, size); ++} ++ ++void *DWC_MEMCPY(void *dest, void const *src, uint32_t size) ++{ ++ return memcpy(dest, src, size); ++} ++ ++void *DWC_MEMMOVE(void *dest, void *src, uint32_t size) ++{ ++ bcopy(src, dest, size); ++ return dest; ++} ++ ++int DWC_MEMCMP(void *m1, void *m2, uint32_t size) ++{ ++ return memcmp(m1, m2, size); ++} ++ ++int DWC_STRNCMP(void *s1, void *s2, uint32_t size) ++{ ++ return strncmp(s1, s2, size); ++} ++ ++int DWC_STRCMP(void *s1, void *s2) ++{ ++ return strcmp(s1, s2); ++} ++ ++int DWC_STRLEN(char const *str) ++{ ++ return strlen(str); ++} ++ ++char *DWC_STRCPY(char *to, char const *from) ++{ ++ return strcpy(to, from); ++} ++ ++char *DWC_STRDUP(char const *str) ++{ ++ int len = DWC_STRLEN(str) + 1; ++ char *new = DWC_ALLOC_ATOMIC(len); ++ ++ if (!new) { ++ return NULL; ++ } ++ ++ DWC_MEMCPY(new, str, len); ++ return new; ++} ++ ++int DWC_ATOI(char *str, int32_t *value) ++{ ++ char *end = NULL; ++ ++ *value = strtol(str, &end, 0); ++ if (*end == '\0') { ++ return 0; ++ } ++ ++ return -1; ++} ++ ++int DWC_ATOUI(char *str, uint32_t *value) ++{ ++ char *end = NULL; ++ ++ *value = strtoul(str, &end, 0); ++ if (*end == '\0') { ++ return 0; ++ } ++ ++ return -1; ++} ++ ++ ++#ifdef DWC_UTFLIB ++/* From usbstring.c */ ++ ++int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len) ++{ ++ int count = 0; ++ u8 c; ++ u16 uchar; ++ ++ /* this insists on correct encodings, though not minimal ones. ++ * BUT it currently rejects legit 4-byte UTF-8 code points, ++ * which need surrogate pairs. (Unicode 3.1 can use them.) ++ */ ++ while (len != 0 && (c = (u8) *s++) != 0) { ++ if (unlikely(c & 0x80)) { ++ // 2-byte sequence: ++ // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx ++ if ((c & 0xe0) == 0xc0) { ++ uchar = (c & 0x1f) << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ // 3-byte sequence (most CJKV characters): ++ // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx ++ } else if ((c & 0xf0) == 0xe0) { ++ uchar = (c & 0x0f) << 12; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ /* no bogus surrogates */ ++ if (0xd800 <= uchar && uchar <= 0xdfff) ++ goto fail; ++ ++ // 4-byte sequence (surrogate pairs, currently rare): ++ // 11101110wwwwzzzzyy + 110111yyyyxxxxxx ++ // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ++ // (uuuuu = wwww + 1) ++ // FIXME accept the surrogate code points (only) ++ } else ++ goto fail; ++ } else ++ uchar = c; ++ put_unaligned (cpu_to_le16 (uchar), cp++); ++ count++; ++ len--; ++ } ++ return count; ++fail: ++ return -1; ++} ++ ++#endif /* DWC_UTFLIB */ ++ ++ ++/* dwc_debug.h */ ++ ++dwc_bool_t DWC_IN_IRQ(void) ++{ ++// return in_irq(); ++ return 0; ++} ++ ++dwc_bool_t DWC_IN_BH(void) ++{ ++// return in_softirq(); ++ return 0; ++} ++ ++void DWC_VPRINTF(char *format, va_list args) ++{ ++ vprintf(format, args); ++} ++ ++int DWC_VSNPRINTF(char *str, int size, char *format, va_list args) ++{ ++ return vsnprintf(str, size, format, args); ++} ++ ++void DWC_PRINTF(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++int DWC_SPRINTF(char *buffer, char *format, ...) ++{ ++ int retval; ++ va_list args; ++ ++ va_start(args, format); ++ retval = vsprintf(buffer, format, args); ++ va_end(args); ++ return retval; ++} ++ ++int DWC_SNPRINTF(char *buffer, int size, char *format, ...) ++{ ++ int retval; ++ va_list args; ++ ++ va_start(args, format); ++ retval = vsnprintf(buffer, size, format, args); ++ va_end(args); ++ return retval; ++} ++ ++void __DWC_WARN(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++void __DWC_ERROR(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++void DWC_EXCEPTION(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++// BUG_ON(1); ??? ++} ++ ++#ifdef DEBUG ++void __DWC_DEBUG(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++#endif ++ ++ ++/* dwc_mem.h */ ++ ++#if 0 ++dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size, ++ uint32_t align, ++ uint32_t alloc) ++{ ++ struct dma_pool *pool = dma_pool_create("Pool", NULL, ++ size, align, alloc); ++ return (dwc_pool_t *)pool; ++} ++ ++void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool) ++{ ++ dma_pool_destroy((struct dma_pool *)pool); ++} ++ ++void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr) ++{ ++// return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr); ++ return dma_pool_alloc((struct dma_pool *)pool, M_WAITOK, dma_addr); ++} ++ ++void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr) ++{ ++ void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr); ++ memset(..); ++} ++ ++void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr) ++{ ++ dma_pool_free(pool, vaddr, daddr); ++} ++#endif ++ ++static void dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) ++{ ++ if (error) ++ return; ++ *(bus_addr_t *)arg = segs[0].ds_addr; ++} ++ ++void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr) ++{ ++ dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx; ++ int error; ++ ++ error = bus_dma_tag_create( ++#if __FreeBSD_version >= 700000 ++ bus_get_dma_tag(dma->dev), /* parent */ ++#else ++ NULL, /* parent */ ++#endif ++ 4, 0, /* alignment, bounds */ ++ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ ++ BUS_SPACE_MAXADDR, /* highaddr */ ++ NULL, NULL, /* filter, filterarg */ ++ size, /* maxsize */ ++ 1, /* nsegments */ ++ size, /* maxsegsize */ ++ 0, /* flags */ ++ NULL, /* lockfunc */ ++ NULL, /* lockarg */ ++ &dma->dma_tag); ++ if (error) { ++ device_printf(dma->dev, "%s: bus_dma_tag_create failed: %d\n", ++ __func__, error); ++ goto fail_0; ++ } ++ ++ error = bus_dmamem_alloc(dma->dma_tag, &dma->dma_vaddr, ++ BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dma->dma_map); ++ if (error) { ++ device_printf(dma->dev, "%s: bus_dmamem_alloc(%ju) failed: %d\n", ++ __func__, (uintmax_t)size, error); ++ goto fail_1; ++ } ++ ++ dma->dma_paddr = 0; ++ error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr, size, ++ dmamap_cb, &dma->dma_paddr, BUS_DMA_NOWAIT); ++ if (error || dma->dma_paddr == 0) { ++ device_printf(dma->dev, "%s: bus_dmamap_load failed: %d\n", ++ __func__, error); ++ goto fail_2; ++ } ++ ++ *dma_addr = dma->dma_paddr; ++ return dma->dma_vaddr; ++ ++fail_2: ++ bus_dmamap_unload(dma->dma_tag, dma->dma_map); ++fail_1: ++ bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); ++ bus_dma_tag_destroy(dma->dma_tag); ++fail_0: ++ dma->dma_map = NULL; ++ dma->dma_tag = NULL; ++ ++ return NULL; ++} ++ ++void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr) ++{ ++ dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx; ++ ++ if (dma->dma_tag == NULL) ++ return; ++ if (dma->dma_map != NULL) { ++ bus_dmamap_sync(dma->dma_tag, dma->dma_map, ++ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); ++ bus_dmamap_unload(dma->dma_tag, dma->dma_map); ++ bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); ++ dma->dma_map = NULL; ++ } ++ ++ bus_dma_tag_destroy(dma->dma_tag); ++ dma->dma_tag = NULL; ++} ++ ++void *__DWC_ALLOC(void *mem_ctx, uint32_t size) ++{ ++ return malloc(size, M_DEVBUF, M_WAITOK | M_ZERO); ++} ++ ++void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size) ++{ ++ return malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); ++} ++ ++void __DWC_FREE(void *mem_ctx, void *addr) ++{ ++ free(addr, M_DEVBUF); ++} ++ ++ ++#ifdef DWC_CRYPTOLIB ++/* dwc_crypto.h */ ++ ++void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length) ++{ ++ get_random_bytes(buffer, length); ++} ++ ++int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out) ++{ ++ struct crypto_blkcipher *tfm; ++ struct blkcipher_desc desc; ++ struct scatterlist sgd; ++ struct scatterlist sgs; ++ ++ tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); ++ if (tfm == NULL) { ++ printk("failed to load transform for aes CBC\n"); ++ return -1; ++ } ++ ++ crypto_blkcipher_setkey(tfm, key, keylen); ++ crypto_blkcipher_set_iv(tfm, iv, 16); ++ ++ sg_init_one(&sgd, out, messagelen); ++ sg_init_one(&sgs, message, messagelen); ++ ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) { ++ crypto_free_blkcipher(tfm); ++ DWC_ERROR("AES CBC encryption failed"); ++ return -1; ++ } ++ ++ crypto_free_blkcipher(tfm); ++ return 0; ++} ++ ++int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out) ++{ ++ struct crypto_hash *tfm; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) { ++ DWC_ERROR("Failed to load transform for sha256: %ld", PTR_ERR(tfm)); ++ return 0; ++ } ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ sg_init_one(&sg, message, len); ++ crypto_hash_digest(&desc, &sg, len, out); ++ crypto_free_hash(tfm); ++ ++ return 1; ++} ++ ++int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen, ++ uint8_t *key, uint32_t keylen, uint8_t *out) ++{ ++ struct crypto_hash *tfm; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ ++ tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) { ++ DWC_ERROR("Failed to load transform for hmac(sha256): %ld", PTR_ERR(tfm)); ++ return 0; ++ } ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ sg_init_one(&sg, message, messagelen); ++ crypto_hash_setkey(tfm, key, keylen); ++ crypto_hash_digest(&desc, &sg, messagelen, out); ++ crypto_free_hash(tfm); ++ ++ return 1; ++} ++ ++#endif /* DWC_CRYPTOLIB */ ++ ++ ++/* Byte Ordering Conversions */ ++ ++uint32_t DWC_CPU_TO_LE32(uint32_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_CPU_TO_BE32(uint32_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_LE32_TO_CPU(uint32_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_BE32_TO_CPU(uint32_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint16_t DWC_CPU_TO_LE16(uint16_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_CPU_TO_BE16(uint16_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_LE16_TO_CPU(uint16_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_BE16_TO_CPU(uint16_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++ ++/* Registers */ ++ ++uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ return bus_space_read_4(io->iot, io->ioh, ior); ++} ++ ++#if 0 ++uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ return bus_space_read_8(io->iot, io->ioh, ior); ++} ++#endif ++ ++void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_4(io->iot, io->ioh, ior, value); ++} ++ ++#if 0 ++void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_8(io->iot, io->ioh, ior, value); ++} ++#endif ++ ++void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask, ++ uint32_t set_mask) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_4(io->iot, io->ioh, ior, ++ (bus_space_read_4(io->iot, io->ioh, ior) & ++ ~clear_mask) | set_mask); ++} ++ ++#if 0 ++void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask, ++ uint64_t set_mask) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_8(io->iot, io->ioh, ior, ++ (bus_space_read_8(io->iot, io->ioh, ior) & ++ ~clear_mask) | set_mask); ++} ++#endif ++ ++ ++/* Locking */ ++ ++dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void) ++{ ++ struct mtx *sl = DWC_ALLOC(sizeof(*sl)); ++ ++ if (!sl) { ++ DWC_ERROR("Cannot allocate memory for spinlock"); ++ return NULL; ++ } ++ ++ mtx_init(sl, "dw3spn", NULL, MTX_SPIN); ++ return (dwc_spinlock_t *)sl; ++} ++ ++void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock) ++{ ++ struct mtx *sl = (struct mtx *)lock; ++ ++ mtx_destroy(sl); ++ DWC_FREE(sl); ++} ++ ++void DWC_SPINLOCK(dwc_spinlock_t *lock) ++{ ++ mtx_lock_spin((struct mtx *)lock); // ??? ++} ++ ++void DWC_SPINUNLOCK(dwc_spinlock_t *lock) ++{ ++ mtx_unlock_spin((struct mtx *)lock); // ??? ++} ++ ++void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags) ++{ ++ mtx_lock_spin((struct mtx *)lock); ++} ++ ++void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags) ++{ ++ mtx_unlock_spin((struct mtx *)lock); ++} ++ ++dwc_mutex_t *DWC_MUTEX_ALLOC(void) ++{ ++ struct mtx *m; ++ dwc_mutex_t *mutex = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mtx)); ++ ++ if (!mutex) { ++ DWC_ERROR("Cannot allocate memory for mutex"); ++ return NULL; ++ } ++ ++ m = (struct mtx *)mutex; ++ mtx_init(m, "dw3mtx", NULL, MTX_DEF); ++ return mutex; ++} ++ ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)) ++#else ++void DWC_MUTEX_FREE(dwc_mutex_t *mutex) ++{ ++ mtx_destroy((struct mtx *)mutex); ++ DWC_FREE(mutex); ++} ++#endif ++ ++void DWC_MUTEX_LOCK(dwc_mutex_t *mutex) ++{ ++ struct mtx *m = (struct mtx *)mutex; ++ ++ mtx_lock(m); ++} ++ ++int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex) ++{ ++ struct mtx *m = (struct mtx *)mutex; ++ ++ return mtx_trylock(m); ++} ++ ++void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex) ++{ ++ struct mtx *m = (struct mtx *)mutex; ++ ++ mtx_unlock(m); ++} ++ ++ ++/* Timing */ ++ ++void DWC_UDELAY(uint32_t usecs) ++{ ++ DELAY(usecs); ++} ++ ++void DWC_MDELAY(uint32_t msecs) ++{ ++ do { ++ DELAY(1000); ++ } while (--msecs); ++} ++ ++void DWC_MSLEEP(uint32_t msecs) ++{ ++ struct timeval tv; ++ ++ tv.tv_sec = msecs / 1000; ++ tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000; ++ pause("dw3slp", tvtohz(&tv)); ++} ++ ++uint32_t DWC_TIME(void) ++{ ++ struct timeval tv; ++ ++ microuptime(&tv); // or getmicrouptime? (less precise, but faster) ++ return tv.tv_sec * 1000 + tv.tv_usec / 1000; ++} ++ ++ ++/* Timers */ ++ ++struct dwc_timer { ++ struct callout t; ++ char *name; ++ dwc_spinlock_t *lock; ++ dwc_timer_callback_t cb; ++ void *data; ++}; ++ ++dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data) ++{ ++ dwc_timer_t *t = DWC_ALLOC(sizeof(*t)); ++ ++ if (!t) { ++ DWC_ERROR("Cannot allocate memory for timer"); ++ return NULL; ++ } ++ ++ callout_init(&t->t, 1); ++ ++ t->name = DWC_STRDUP(name); ++ if (!t->name) { ++ DWC_ERROR("Cannot allocate memory for timer->name"); ++ goto no_name; ++ } ++ ++ t->lock = DWC_SPINLOCK_ALLOC(); ++ if (!t->lock) { ++ DWC_ERROR("Cannot allocate memory for lock"); ++ goto no_lock; ++ } ++ ++ t->cb = cb; ++ t->data = data; ++ ++ return t; ++ ++ no_lock: ++ DWC_FREE(t->name); ++ no_name: ++ DWC_FREE(t); ++ ++ return NULL; ++} ++ ++void DWC_TIMER_FREE(dwc_timer_t *timer) ++{ ++ callout_stop(&timer->t); ++ DWC_SPINLOCK_FREE(timer->lock); ++ DWC_FREE(timer->name); ++ DWC_FREE(timer); ++} ++ ++void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time) ++{ ++ struct timeval tv; ++ ++ tv.tv_sec = time / 1000; ++ tv.tv_usec = (time - tv.tv_sec * 1000) * 1000; ++ callout_reset(&timer->t, tvtohz(&tv), timer->cb, timer->data); ++} ++ ++void DWC_TIMER_CANCEL(dwc_timer_t *timer) ++{ ++ callout_stop(&timer->t); ++} ++ ++ ++/* Wait Queues */ ++ ++struct dwc_waitq { ++ struct mtx lock; ++ int abort; ++}; ++ ++dwc_waitq_t *DWC_WAITQ_ALLOC(void) ++{ ++ dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq)); ++ ++ if (!wq) { ++ DWC_ERROR("Cannot allocate memory for waitqueue"); ++ return NULL; ++ } ++ ++ mtx_init(&wq->lock, "dw3wtq", NULL, MTX_DEF); ++ wq->abort = 0; ++ ++ return wq; ++} ++ ++void DWC_WAITQ_FREE(dwc_waitq_t *wq) ++{ ++ mtx_destroy(&wq->lock); ++ DWC_FREE(wq); ++} ++ ++int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data) ++{ ++// intrmask_t ipl; ++ int result = 0; ++ ++ mtx_lock(&wq->lock); ++// ipl = splbio(); ++ ++ /* Skip the sleep if already aborted or triggered */ ++ if (!wq->abort && !cond(data)) { ++// splx(ipl); ++ result = msleep(wq, &wq->lock, PCATCH, "dw3wat", 0); // infinite timeout ++// ipl = splbio(); ++ } ++ ++ if (result == ERESTART) { // signaled - restart ++ result = -DWC_E_RESTART; ++ ++ } else if (result == EINTR) { // signaled - interrupt ++ result = -DWC_E_ABORT; ++ ++ } else if (wq->abort) { ++ result = -DWC_E_ABORT; ++ ++ } else { ++ result = 0; ++ } ++ ++ wq->abort = 0; ++// splx(ipl); ++ mtx_unlock(&wq->lock); ++ return result; ++} ++ ++int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, ++ void *data, int32_t msecs) ++{ ++ struct timeval tv, tv1, tv2; ++// intrmask_t ipl; ++ int result = 0; ++ ++ tv.tv_sec = msecs / 1000; ++ tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000; ++ ++ mtx_lock(&wq->lock); ++// ipl = splbio(); ++ ++ /* Skip the sleep if already aborted or triggered */ ++ if (!wq->abort && !cond(data)) { ++// splx(ipl); ++ getmicrouptime(&tv1); ++ result = msleep(wq, &wq->lock, PCATCH, "dw3wto", tvtohz(&tv)); ++ getmicrouptime(&tv2); ++// ipl = splbio(); ++ } ++ ++ if (result == 0) { // awoken ++ if (wq->abort) { ++ result = -DWC_E_ABORT; ++ } else { ++ tv2.tv_usec -= tv1.tv_usec; ++ if (tv2.tv_usec < 0) { ++ tv2.tv_usec += 1000000; ++ tv2.tv_sec--; ++ } ++ ++ tv2.tv_sec -= tv1.tv_sec; ++ result = tv2.tv_sec * 1000 + tv2.tv_usec / 1000; ++ result = msecs - result; ++ if (result <= 0) ++ result = 1; ++ } ++ } else if (result == ERESTART) { // signaled - restart ++ result = -DWC_E_RESTART; ++ ++ } else if (result == EINTR) { // signaled - interrupt ++ result = -DWC_E_ABORT; ++ ++ } else { // timed out ++ result = -DWC_E_TIMEOUT; ++ } ++ ++ wq->abort = 0; ++// splx(ipl); ++ mtx_unlock(&wq->lock); ++ return result; ++} ++ ++void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq) ++{ ++ wakeup(wq); ++} ++ ++void DWC_WAITQ_ABORT(dwc_waitq_t *wq) ++{ ++// intrmask_t ipl; ++ ++ mtx_lock(&wq->lock); ++// ipl = splbio(); ++ wq->abort = 1; ++ wakeup(wq); ++// splx(ipl); ++ mtx_unlock(&wq->lock); ++} ++ ++ ++/* Threading */ ++ ++struct dwc_thread { ++ struct proc *proc; ++ int abort; ++}; ++ ++dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data) ++{ ++ int retval; ++ dwc_thread_t *thread = DWC_ALLOC(sizeof(*thread)); ++ ++ if (!thread) { ++ return NULL; ++ } ++ ++ thread->abort = 0; ++ retval = kthread_create((void (*)(void *))func, data, &thread->proc, ++ RFPROC | RFNOWAIT, 0, "%s", name); ++ if (retval) { ++ DWC_FREE(thread); ++ return NULL; ++ } ++ ++ return thread; ++} ++ ++int DWC_THREAD_STOP(dwc_thread_t *thread) ++{ ++ int retval; ++ ++ thread->abort = 1; ++ retval = tsleep(&thread->abort, 0, "dw3stp", 60 * hz); ++ ++ if (retval == 0) { ++ /* DWC_THREAD_EXIT() will free the thread struct */ ++ return 0; ++ } ++ ++ /* NOTE: We leak the thread struct if thread doesn't die */ ++ ++ if (retval == EWOULDBLOCK) { ++ return -DWC_E_TIMEOUT; ++ } ++ ++ return -DWC_E_UNKNOWN; ++} ++ ++dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread) ++{ ++ return thread->abort; ++} ++ ++void DWC_THREAD_EXIT(dwc_thread_t *thread) ++{ ++ wakeup(&thread->abort); ++ DWC_FREE(thread); ++ kthread_exit(0); ++} ++ ++ ++/* tasklets ++ - Runs in interrupt context (cannot sleep) ++ - Each tasklet runs on a single CPU [ How can we ensure this on FreeBSD? Does it matter? ] ++ - Different tasklets can be running simultaneously on different CPUs [ shouldn't matter ] ++ */ ++struct dwc_tasklet { ++ struct task t; ++ dwc_tasklet_callback_t cb; ++ void *data; ++}; ++ ++static void tasklet_callback(void *data, int pending) // what to do with pending ??? ++{ ++ dwc_tasklet_t *task = (dwc_tasklet_t *)data; ++ ++ task->cb(task->data); ++} ++ ++dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data) ++{ ++ dwc_tasklet_t *task = DWC_ALLOC(sizeof(*task)); ++ ++ if (task) { ++ task->cb = cb; ++ task->data = data; ++ TASK_INIT(&task->t, 0, tasklet_callback, task); ++ } else { ++ DWC_ERROR("Cannot allocate memory for tasklet"); ++ } ++ ++ return task; ++} ++ ++void DWC_TASK_FREE(dwc_tasklet_t *task) ++{ ++ taskqueue_drain(taskqueue_fast, &task->t); // ??? ++ DWC_FREE(task); ++} ++ ++void DWC_TASK_SCHEDULE(dwc_tasklet_t *task) ++{ ++ /* Uses predefined system queue */ ++ taskqueue_enqueue_fast(taskqueue_fast, &task->t); ++} ++ ++ ++/* workqueues ++ - Runs in process context (can sleep) ++ */ ++typedef struct work_container { ++ dwc_work_callback_t cb; ++ void *data; ++ dwc_workq_t *wq; ++ char *name; ++ int hz; ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_ENTRY(work_container) entry; ++#endif ++ struct task task; ++} work_container_t; ++ ++#ifdef DEBUG ++DWC_CIRCLEQ_HEAD(work_container_queue, work_container); ++#endif ++ ++struct dwc_workq { ++ struct taskqueue *taskq; ++ dwc_spinlock_t *lock; ++ dwc_waitq_t *waitq; ++ int pending; ++ ++#ifdef DEBUG ++ struct work_container_queue entries; ++#endif ++}; ++ ++static void do_work(void *data, int pending) // what to do with pending ??? ++{ ++ work_container_t *container = (work_container_t *)data; ++ dwc_workq_t *wq = container->wq; ++ dwc_irqflags_t flags; ++ ++ if (container->hz) { ++ pause("dw3wrk", container->hz); ++ } ++ ++ container->cb(container->data); ++ DWC_DEBUG("Work done: %s, container=%p", container->name, container); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_REMOVE(&wq->entries, container, entry); ++#endif ++ if (container->name) ++ DWC_FREE(container->name); ++ DWC_FREE(container); ++ wq->pending--; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++} ++ ++static int work_done(void *data) ++{ ++ dwc_workq_t *workq = (dwc_workq_t *)data; ++ ++ return workq->pending == 0; ++} ++ ++int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout) ++{ ++ return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout); ++} ++ ++dwc_workq_t *DWC_WORKQ_ALLOC(char *name) ++{ ++ dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq)); ++ ++ if (!wq) { ++ DWC_ERROR("Cannot allocate memory for workqueue"); ++ return NULL; ++ } ++ ++ wq->taskq = taskqueue_create(name, M_NOWAIT, taskqueue_thread_enqueue, &wq->taskq); ++ if (!wq->taskq) { ++ DWC_ERROR("Cannot allocate memory for taskqueue"); ++ goto no_taskq; ++ } ++ ++ wq->pending = 0; ++ ++ wq->lock = DWC_SPINLOCK_ALLOC(); ++ if (!wq->lock) { ++ DWC_ERROR("Cannot allocate memory for spinlock"); ++ goto no_lock; ++ } ++ ++ wq->waitq = DWC_WAITQ_ALLOC(); ++ if (!wq->waitq) { ++ DWC_ERROR("Cannot allocate memory for waitqueue"); ++ goto no_waitq; ++ } ++ ++ taskqueue_start_threads(&wq->taskq, 1, PWAIT, "%s taskq", "dw3tsk"); ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_INIT(&wq->entries); ++#endif ++ return wq; ++ ++ no_waitq: ++ DWC_SPINLOCK_FREE(wq->lock); ++ no_lock: ++ taskqueue_free(wq->taskq); ++ no_taskq: ++ DWC_FREE(wq); ++ ++ return NULL; ++} ++ ++void DWC_WORKQ_FREE(dwc_workq_t *wq) ++{ ++#ifdef DEBUG ++ dwc_irqflags_t flags; ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ ++ if (wq->pending != 0) { ++ struct work_container *container; ++ ++ DWC_ERROR("Destroying work queue with pending work"); ++ ++ DWC_CIRCLEQ_FOREACH(container, &wq->entries, entry) { ++ DWC_ERROR("Work %s still pending", container->name); ++ } ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++#endif ++ DWC_WAITQ_FREE(wq->waitq); ++ DWC_SPINLOCK_FREE(wq->lock); ++ taskqueue_free(wq->taskq); ++ DWC_FREE(wq); ++} ++ ++void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data, ++ char *format, ...) ++{ ++ dwc_irqflags_t flags; ++ work_container_t *container; ++ static char name[128]; ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VSNPRINTF(name, 128, format, args); ++ va_end(args); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ wq->pending++; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++ ++ container = DWC_ALLOC_ATOMIC(sizeof(*container)); ++ if (!container) { ++ DWC_ERROR("Cannot allocate memory for container"); ++ return; ++ } ++ ++ container->name = DWC_STRDUP(name); ++ if (!container->name) { ++ DWC_ERROR("Cannot allocate memory for container->name"); ++ DWC_FREE(container); ++ return; ++ } ++ ++ container->cb = cb; ++ container->data = data; ++ container->wq = wq; ++ container->hz = 0; ++ ++ DWC_DEBUG("Queueing work: %s, container=%p", container->name, container); ++ ++ TASK_INIT(&container->task, 0, do_work, container); ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry); ++#endif ++ taskqueue_enqueue_fast(wq->taskq, &container->task); ++} ++ ++void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb, ++ void *data, uint32_t time, char *format, ...) ++{ ++ dwc_irqflags_t flags; ++ work_container_t *container; ++ static char name[128]; ++ struct timeval tv; ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VSNPRINTF(name, 128, format, args); ++ va_end(args); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ wq->pending++; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++ ++ container = DWC_ALLOC_ATOMIC(sizeof(*container)); ++ if (!container) { ++ DWC_ERROR("Cannot allocate memory for container"); ++ return; ++ } ++ ++ container->name = DWC_STRDUP(name); ++ if (!container->name) { ++ DWC_ERROR("Cannot allocate memory for container->name"); ++ DWC_FREE(container); ++ return; ++ } ++ ++ container->cb = cb; ++ container->data = data; ++ container->wq = wq; ++ ++ tv.tv_sec = time / 1000; ++ tv.tv_usec = (time - tv.tv_sec * 1000) * 1000; ++ container->hz = tvtohz(&tv); ++ ++ DWC_DEBUG("Queueing work: %s, container=%p", container->name, container); ++ ++ TASK_INIT(&container->task, 0, do_work, container); ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry); ++#endif ++ taskqueue_enqueue_fast(wq->taskq, &container->task); ++} ++ ++int DWC_WORKQ_PENDING(dwc_workq_t *wq) ++{ ++ return wq->pending; ++} +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_common_linux.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_common_linux.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1421 @@ ++#include ++#include ++#include ++#include ++ ++#ifdef DWC_CCLIB ++# include "dwc_cc.h" ++#endif ++ ++#ifdef DWC_CRYPTOLIB ++# include "dwc_modpow.h" ++# include "dwc_dh.h" ++# include "dwc_crypto.h" ++#endif ++ ++#ifdef DWC_NOTIFYLIB ++# include "dwc_notifier.h" ++#endif ++ ++/* OS-Level Implementations */ ++ ++/* This is the Linux kernel implementation of the DWC platform library. */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++# include ++#else ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#include "dwc_os.h" ++#include "dwc_list.h" ++ ++ ++/* MISC */ ++ ++void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size) ++{ ++ return memset(dest, byte, size); ++} ++ ++void *DWC_MEMCPY(void *dest, void const *src, uint32_t size) ++{ ++ return memcpy(dest, src, size); ++} ++ ++void *DWC_MEMMOVE(void *dest, void *src, uint32_t size) ++{ ++ return memmove(dest, src, size); ++} ++ ++int DWC_MEMCMP(void *m1, void *m2, uint32_t size) ++{ ++ return memcmp(m1, m2, size); ++} ++ ++int DWC_STRNCMP(void *s1, void *s2, uint32_t size) ++{ ++ return strncmp(s1, s2, size); ++} ++ ++int DWC_STRCMP(void *s1, void *s2) ++{ ++ return strcmp(s1, s2); ++} ++ ++int DWC_STRLEN(char const *str) ++{ ++ return strlen(str); ++} ++ ++char *DWC_STRCPY(char *to, char const *from) ++{ ++ return strcpy(to, from); ++} ++ ++char *DWC_STRDUP(char const *str) ++{ ++ int len = DWC_STRLEN(str) + 1; ++ char *new = DWC_ALLOC_ATOMIC(len); ++ ++ if (!new) { ++ return NULL; ++ } ++ ++ DWC_MEMCPY(new, str, len); ++ return new; ++} ++ ++int DWC_ATOI(const char *str, int32_t *value) ++{ ++ char *end = NULL; ++ ++ *value = simple_strtol(str, &end, 0); ++ if (*end == '\0') { ++ return 0; ++ } ++ ++ return -1; ++} ++ ++int DWC_ATOUI(const char *str, uint32_t *value) ++{ ++ char *end = NULL; ++ ++ *value = simple_strtoul(str, &end, 0); ++ if (*end == '\0') { ++ return 0; ++ } ++ ++ return -1; ++} ++ ++ ++#ifdef DWC_UTFLIB ++/* From usbstring.c */ ++ ++int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len) ++{ ++ int count = 0; ++ u8 c; ++ u16 uchar; ++ ++ /* this insists on correct encodings, though not minimal ones. ++ * BUT it currently rejects legit 4-byte UTF-8 code points, ++ * which need surrogate pairs. (Unicode 3.1 can use them.) ++ */ ++ while (len != 0 && (c = (u8) *s++) != 0) { ++ if (unlikely(c & 0x80)) { ++ // 2-byte sequence: ++ // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx ++ if ((c & 0xe0) == 0xc0) { ++ uchar = (c & 0x1f) << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ // 3-byte sequence (most CJKV characters): ++ // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx ++ } else if ((c & 0xf0) == 0xe0) { ++ uchar = (c & 0x0f) << 12; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ /* no bogus surrogates */ ++ if (0xd800 <= uchar && uchar <= 0xdfff) ++ goto fail; ++ ++ // 4-byte sequence (surrogate pairs, currently rare): ++ // 11101110wwwwzzzzyy + 110111yyyyxxxxxx ++ // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ++ // (uuuuu = wwww + 1) ++ // FIXME accept the surrogate code points (only) ++ } else ++ goto fail; ++ } else ++ uchar = c; ++ put_unaligned (cpu_to_le16 (uchar), cp++); ++ count++; ++ len--; ++ } ++ return count; ++fail: ++ return -1; ++} ++#endif /* DWC_UTFLIB */ ++ ++ ++/* dwc_debug.h */ ++ ++dwc_bool_t DWC_IN_IRQ(void) ++{ ++ return in_irq(); ++} ++ ++dwc_bool_t DWC_IN_BH(void) ++{ ++ return in_softirq(); ++} ++ ++void DWC_VPRINTF(char *format, va_list args) ++{ ++ vprintk(format, args); ++} ++ ++int DWC_VSNPRINTF(char *str, int size, char *format, va_list args) ++{ ++ return vsnprintf(str, size, format, args); ++} ++ ++void DWC_PRINTF(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++int DWC_SPRINTF(char *buffer, char *format, ...) ++{ ++ int retval; ++ va_list args; ++ ++ va_start(args, format); ++ retval = vsprintf(buffer, format, args); ++ va_end(args); ++ return retval; ++} ++ ++int DWC_SNPRINTF(char *buffer, int size, char *format, ...) ++{ ++ int retval; ++ va_list args; ++ ++ va_start(args, format); ++ retval = vsnprintf(buffer, size, format, args); ++ va_end(args); ++ return retval; ++} ++ ++void __DWC_WARN(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_PRINTF(KERN_WARNING); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++void __DWC_ERROR(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_PRINTF(KERN_ERR); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++void DWC_EXCEPTION(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_PRINTF(KERN_ERR); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++ BUG_ON(1); ++} ++ ++#ifdef DEBUG ++void __DWC_DEBUG(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_PRINTF(KERN_DEBUG); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++#endif ++ ++ ++/* dwc_mem.h */ ++ ++#if 0 ++dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size, ++ uint32_t align, ++ uint32_t alloc) ++{ ++ struct dma_pool *pool = dma_pool_create("Pool", NULL, ++ size, align, alloc); ++ return (dwc_pool_t *)pool; ++} ++ ++void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool) ++{ ++ dma_pool_destroy((struct dma_pool *)pool); ++} ++ ++void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr) ++{ ++ return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr); ++} ++ ++void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr) ++{ ++ void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr); ++ memset(..); ++} ++ ++void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr) ++{ ++ dma_pool_free(pool, vaddr, daddr); ++} ++#endif ++ ++void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr) ++{ ++#ifdef xxCOSIM /* Only works for 32-bit cosim */ ++ void *buf = dma_alloc_coherent(dma_ctx, (size_t)size, dma_addr, GFP_KERNEL); ++#else ++ void *buf = dma_alloc_coherent(dma_ctx, (size_t)size, dma_addr, GFP_KERNEL | GFP_DMA32); ++#endif ++ if (!buf) { ++ return NULL; ++ } ++ ++ memset(buf, 0, (size_t)size); ++ return buf; ++} ++ ++void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr) ++{ ++ void *buf = dma_alloc_coherent(NULL, (size_t)size, dma_addr, GFP_ATOMIC); ++ if (!buf) { ++ return NULL; ++ } ++ memset(buf, 0, (size_t)size); ++ return buf; ++} ++ ++void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr) ++{ ++ dma_free_coherent(dma_ctx, size, virt_addr, dma_addr); ++} ++ ++void *__DWC_ALLOC(void *mem_ctx, uint32_t size) ++{ ++ return kzalloc(size, GFP_KERNEL); ++} ++ ++void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size) ++{ ++ return kzalloc(size, GFP_ATOMIC); ++} ++ ++void __DWC_FREE(void *mem_ctx, void *addr) ++{ ++ kfree(addr); ++} ++ ++ ++#ifdef DWC_CRYPTOLIB ++/* dwc_crypto.h */ ++ ++void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length) ++{ ++ get_random_bytes(buffer, length); ++} ++ ++int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out) ++{ ++ struct crypto_blkcipher *tfm; ++ struct blkcipher_desc desc; ++ struct scatterlist sgd; ++ struct scatterlist sgs; ++ ++ tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); ++ if (tfm == NULL) { ++ printk("failed to load transform for aes CBC\n"); ++ return -1; ++ } ++ ++ crypto_blkcipher_setkey(tfm, key, keylen); ++ crypto_blkcipher_set_iv(tfm, iv, 16); ++ ++ sg_init_one(&sgd, out, messagelen); ++ sg_init_one(&sgs, message, messagelen); ++ ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) { ++ crypto_free_blkcipher(tfm); ++ DWC_ERROR("AES CBC encryption failed"); ++ return -1; ++ } ++ ++ crypto_free_blkcipher(tfm); ++ return 0; ++} ++ ++int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out) ++{ ++ struct crypto_hash *tfm; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) { ++ DWC_ERROR("Failed to load transform for sha256: %ld\n", PTR_ERR(tfm)); ++ return 0; ++ } ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ sg_init_one(&sg, message, len); ++ crypto_hash_digest(&desc, &sg, len, out); ++ crypto_free_hash(tfm); ++ ++ return 1; ++} ++ ++int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen, ++ uint8_t *key, uint32_t keylen, uint8_t *out) ++{ ++ struct crypto_hash *tfm; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ ++ tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) { ++ DWC_ERROR("Failed to load transform for hmac(sha256): %ld\n", PTR_ERR(tfm)); ++ return 0; ++ } ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ sg_init_one(&sg, message, messagelen); ++ crypto_hash_setkey(tfm, key, keylen); ++ crypto_hash_digest(&desc, &sg, messagelen, out); ++ crypto_free_hash(tfm); ++ ++ return 1; ++} ++#endif /* DWC_CRYPTOLIB */ ++ ++ ++/* Byte Ordering Conversions */ ++ ++uint32_t DWC_CPU_TO_LE32(uint32_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_CPU_TO_BE32(uint32_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_LE32_TO_CPU(uint32_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_BE32_TO_CPU(uint32_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint16_t DWC_CPU_TO_LE16(uint16_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_CPU_TO_BE16(uint16_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_LE16_TO_CPU(uint16_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_BE16_TO_CPU(uint16_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++ ++/* Registers */ ++ ++uint32_t DWC_READ_REG32(uint32_t volatile *reg) ++{ ++ return readl(reg); ++} ++ ++#if 0 ++uint64_t DWC_READ_REG64(uint64_t volatile *reg) ++{ ++} ++#endif ++ ++void DWC_WRITE_REG32(uint32_t volatile *reg, uint32_t value) ++{ ++ writel(value, reg); ++} ++ ++#if 0 ++void DWC_WRITE_REG64(uint64_t volatile *reg, uint64_t value) ++{ ++} ++#endif ++ ++void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask) ++{ ++ writel((readl(reg) & ~clear_mask) | set_mask, reg); ++} ++ ++#if 0 ++void DWC_MODIFY_REG64(uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask) ++{ ++} ++#endif ++ ++ ++/* Locking */ ++ ++dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void) ++{ ++ spinlock_t *sl = (spinlock_t *)1; ++ ++#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP) ++ sl = DWC_ALLOC(sizeof(*sl)); ++ if (!sl) { ++ DWC_ERROR("Cannot allocate memory for spinlock\n"); ++ return NULL; ++ } ++ ++ spin_lock_init(sl); ++#endif ++ return (dwc_spinlock_t *)sl; ++} ++ ++void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock) ++{ ++#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP) ++ DWC_FREE(lock); ++#endif ++} ++ ++void DWC_SPINLOCK(dwc_spinlock_t *lock) ++{ ++#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP) ++ spin_lock((spinlock_t *)lock); ++#endif ++} ++ ++void DWC_SPINUNLOCK(dwc_spinlock_t *lock) ++{ ++#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP) ++ spin_unlock((spinlock_t *)lock); ++#endif ++} ++ ++void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags) ++{ ++ dwc_irqflags_t f; ++ ++#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP) ++ spin_lock_irqsave((spinlock_t *)lock, f); ++#else ++ local_irq_save(f); ++#endif ++ *flags = f; ++} ++ ++void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags) ++{ ++#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP) ++ spin_unlock_irqrestore((spinlock_t *)lock, flags); ++#else ++ local_irq_restore(flags); ++#endif ++} ++ ++dwc_mutex_t *DWC_MUTEX_ALLOC(void) ++{ ++ struct mutex *m; ++ dwc_mutex_t *mutex = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex)); ++ ++ if (!mutex) { ++ DWC_ERROR("Cannot allocate memory for mutex\n"); ++ return NULL; ++ } ++ ++ m = (struct mutex *)mutex; ++ mutex_init(m); ++ return mutex; ++} ++ ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)) ++#else ++void DWC_MUTEX_FREE(dwc_mutex_t *mutex) ++{ ++ mutex_destroy((struct mutex *)mutex); ++ DWC_FREE(mutex); ++} ++#endif ++ ++void DWC_MUTEX_LOCK(dwc_mutex_t *mutex) ++{ ++ struct mutex *m = (struct mutex *)mutex; ++ mutex_lock(m); ++} ++ ++int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex) ++{ ++ struct mutex *m = (struct mutex *)mutex; ++ return mutex_trylock(m); ++} ++ ++void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex) ++{ ++ struct mutex *m = (struct mutex *)mutex; ++ mutex_unlock(m); ++} ++ ++ ++/* Timing */ ++ ++void DWC_UDELAY(uint32_t usecs) ++{ ++ udelay(usecs); ++} ++ ++void DWC_MDELAY(uint32_t msecs) ++{ ++ mdelay(msecs); ++} ++ ++void DWC_MSLEEP(uint32_t msecs) ++{ ++ msleep(msecs); ++} ++ ++uint32_t DWC_TIME(void) ++{ ++ return jiffies_to_msecs(jiffies); ++} ++ ++ ++/* Timers */ ++ ++struct dwc_timer { ++ struct timer_list *t; ++ char *name; ++ dwc_timer_callback_t cb; ++ void *data; ++ uint8_t scheduled; ++ dwc_spinlock_t *lock; ++}; ++ ++static void timer_callback(unsigned long data) ++{ ++ dwc_timer_t *timer = (dwc_timer_t *)data; ++ dwc_irqflags_t flags; ++ ++ DWC_SPINLOCK_IRQSAVE(timer->lock, &flags); ++ timer->scheduled = 0; ++ DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags); ++ DWC_DEBUGC("Timer %s callback", timer->name); ++ timer->cb(timer->data); ++} ++ ++dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data) ++{ ++ dwc_timer_t *t = DWC_ALLOC(sizeof(*t)); ++ ++ if (!t) { ++ DWC_ERROR("Cannot allocate memory for timer"); ++ return NULL; ++ } ++ ++ t->t = DWC_ALLOC(sizeof(*t->t)); ++ if (!t->t) { ++ DWC_ERROR("Cannot allocate memory for timer->t"); ++ goto no_timer; ++ } ++ ++ t->name = DWC_STRDUP(name); ++ if (!t->name) { ++ DWC_ERROR("Cannot allocate memory for timer->name"); ++ goto no_name; ++ } ++ ++ t->lock = DWC_SPINLOCK_ALLOC(); ++ if (!t->lock) { ++ DWC_ERROR("Cannot allocate memory for lock"); ++ goto no_lock; ++ } ++ ++ t->scheduled = 0; ++ t->t->base = &boot_tvec_bases; ++ t->t->expires = jiffies; ++ setup_timer(t->t, timer_callback, (unsigned long)t); ++ ++ t->cb = cb; ++ t->data = data; ++ ++ return t; ++ ++ no_lock: ++ DWC_FREE(t->name); ++ no_name: ++ DWC_FREE(t->t); ++ no_timer: ++ DWC_FREE(t); ++ return NULL; ++} ++ ++void DWC_TIMER_FREE(dwc_timer_t *timer) ++{ ++ dwc_irqflags_t flags; ++ ++ DWC_SPINLOCK_IRQSAVE(timer->lock, &flags); ++ ++ if (timer->scheduled) { ++ del_timer(timer->t); ++ timer->scheduled = 0; ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags); ++ DWC_SPINLOCK_FREE(timer->lock); ++ DWC_FREE(timer->t); ++ DWC_FREE(timer->name); ++ DWC_FREE(timer); ++} ++ ++void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time) ++{ ++ dwc_irqflags_t flags; ++ ++ DWC_SPINLOCK_IRQSAVE(timer->lock, &flags); ++ ++ if (!timer->scheduled) { ++ timer->scheduled = 1; ++ DWC_DEBUGC("Scheduling timer %s to expire in +%d msec", timer->name, time); ++ timer->t->expires = jiffies + msecs_to_jiffies(time); ++ add_timer(timer->t); ++ } else { ++ DWC_DEBUGC("Modifying timer %s to expire in +%d msec", timer->name, time); ++ mod_timer(timer->t, jiffies + msecs_to_jiffies(time)); ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags); ++} ++ ++void DWC_TIMER_CANCEL(dwc_timer_t *timer) ++{ ++ del_timer(timer->t); ++} ++ ++ ++/* Wait Queues */ ++ ++struct dwc_waitq { ++ wait_queue_head_t queue; ++ int abort; ++}; ++ ++dwc_waitq_t *DWC_WAITQ_ALLOC(void) ++{ ++ dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq)); ++ ++ if (!wq) { ++ DWC_ERROR("Cannot allocate memory for waitqueue\n"); ++ return NULL; ++ } ++ ++ init_waitqueue_head(&wq->queue); ++ wq->abort = 0; ++ return wq; ++} ++ ++void DWC_WAITQ_FREE(dwc_waitq_t *wq) ++{ ++ DWC_FREE(wq); ++} ++ ++int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data) ++{ ++ int result = wait_event_interruptible(wq->queue, ++ cond(data) || wq->abort); ++ if (result == -ERESTARTSYS) { ++ wq->abort = 0; ++ return -DWC_E_RESTART; ++ } ++ ++ if (wq->abort == 1) { ++ wq->abort = 0; ++ return -DWC_E_ABORT; ++ } ++ ++ wq->abort = 0; ++ ++ if (result == 0) { ++ return 0; ++ } ++ ++ return -DWC_E_UNKNOWN; ++} ++ ++int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, ++ void *data, int32_t msecs) ++{ ++ int32_t tmsecs; ++ int result = wait_event_interruptible_timeout(wq->queue, ++ cond(data) || wq->abort, ++ msecs_to_jiffies(msecs)); ++ if (result == -ERESTARTSYS) { ++ wq->abort = 0; ++ return -DWC_E_RESTART; ++ } ++ ++ if (wq->abort == 1) { ++ wq->abort = 0; ++ return -DWC_E_ABORT; ++ } ++ ++ wq->abort = 0; ++ ++ if (result > 0) { ++ tmsecs = jiffies_to_msecs(result); ++ if (!tmsecs) { ++ return 1; ++ } ++ ++ return tmsecs; ++ } ++ ++ if (result == 0) { ++ return -DWC_E_TIMEOUT; ++ } ++ ++ return -DWC_E_UNKNOWN; ++} ++ ++void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq) ++{ ++ wq->abort = 0; ++ wake_up_interruptible(&wq->queue); ++} ++ ++void DWC_WAITQ_ABORT(dwc_waitq_t *wq) ++{ ++ wq->abort = 1; ++ wake_up_interruptible(&wq->queue); ++} ++ ++ ++/* Threading */ ++ ++dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data) ++{ ++ struct task_struct *thread = kthread_run(func, data, name); ++ ++ if (thread == ERR_PTR(-ENOMEM)) { ++ return NULL; ++ } ++ ++ return (dwc_thread_t *)thread; ++} ++ ++int DWC_THREAD_STOP(dwc_thread_t *thread) ++{ ++ return kthread_stop((struct task_struct *)thread); ++} ++ ++dwc_bool_t DWC_THREAD_SHOULD_STOP(void) ++{ ++ return kthread_should_stop(); ++} ++ ++ ++/* tasklets ++ - run in interrupt context (cannot sleep) ++ - each tasklet runs on a single CPU ++ - different tasklets can be running simultaneously on different CPUs ++ */ ++struct dwc_tasklet { ++ struct tasklet_struct t; ++ dwc_tasklet_callback_t cb; ++ void *data; ++}; ++ ++static void tasklet_callback(unsigned long data) ++{ ++ dwc_tasklet_t *t = (dwc_tasklet_t *)data; ++ t->cb(t->data); ++} ++ ++dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data) ++{ ++ dwc_tasklet_t *t = DWC_ALLOC(sizeof(*t)); ++ ++ if (t) { ++ t->cb = cb; ++ t->data = data; ++ tasklet_init(&t->t, tasklet_callback, (unsigned long)t); ++ } else { ++ DWC_ERROR("Cannot allocate memory for tasklet\n"); ++ } ++ ++ return t; ++} ++ ++void DWC_TASK_FREE(dwc_tasklet_t *task) ++{ ++ DWC_FREE(task); ++} ++ ++void DWC_TASK_SCHEDULE(dwc_tasklet_t *task) ++{ ++ tasklet_schedule(&task->t); ++} ++ ++ ++/* workqueues ++ - run in process context (can sleep) ++ */ ++typedef struct work_container { ++ dwc_work_callback_t cb; ++ void *data; ++ dwc_workq_t *wq; ++ char *name; ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_ENTRY(work_container) entry; ++#endif ++ struct delayed_work work; ++} work_container_t; ++ ++#ifdef DEBUG ++DWC_CIRCLEQ_HEAD(work_container_queue, work_container); ++#endif ++ ++struct dwc_workq { ++ struct workqueue_struct *wq; ++ dwc_spinlock_t *lock; ++ dwc_waitq_t *waitq; ++ int pending; ++ ++#ifdef DEBUG ++ struct work_container_queue entries; ++#endif ++}; ++ ++static void do_work(struct work_struct *work) ++{ ++ dwc_irqflags_t flags; ++ struct delayed_work *dw = container_of(work, struct delayed_work, work); ++ work_container_t *container = container_of(dw, struct work_container, work); ++ dwc_workq_t *wq = container->wq; ++ ++ container->cb(container->data); ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_REMOVE(&wq->entries, container, entry); ++#endif ++ DWC_DEBUGC("Work done: %s, container=%p", container->name, container); ++ if (container->name) { ++ DWC_FREE(container->name); ++ } ++ DWC_FREE(container); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ wq->pending--; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++} ++ ++static int work_done(void *data) ++{ ++ dwc_workq_t *workq = (dwc_workq_t *)data; ++ return workq->pending == 0; ++} ++ ++int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout) ++{ ++ return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout); ++} ++ ++dwc_workq_t *DWC_WORKQ_ALLOC(char *name) ++{ ++ dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq)); ++ ++ if (!wq) { ++ return NULL; ++ } ++ ++ wq->wq = create_singlethread_workqueue(name); ++ if (!wq->wq) { ++ goto no_wq; ++ } ++ ++ wq->pending = 0; ++ ++ wq->lock = DWC_SPINLOCK_ALLOC(); ++ if (!wq->lock) { ++ goto no_lock; ++ } ++ ++ wq->waitq = DWC_WAITQ_ALLOC(); ++ if (!wq->waitq) { ++ goto no_waitq; ++ } ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_INIT(&wq->entries); ++#endif ++ return wq; ++ ++ no_waitq: ++ DWC_SPINLOCK_FREE(wq->lock); ++ no_lock: ++ destroy_workqueue(wq->wq); ++ no_wq: ++ DWC_FREE(wq); ++ ++ return NULL; ++} ++ ++void DWC_WORKQ_FREE(dwc_workq_t *wq) ++{ ++#ifdef DEBUG ++ if (wq->pending != 0) { ++ struct work_container *wc; ++ DWC_ERROR("Destroying work queue with pending work"); ++ DWC_CIRCLEQ_FOREACH(wc, &wq->entries, entry) { ++ DWC_ERROR("Work %s still pending", wc->name); ++ } ++ } ++#endif ++ destroy_workqueue(wq->wq); ++ DWC_SPINLOCK_FREE(wq->lock); ++ DWC_WAITQ_FREE(wq->waitq); ++ DWC_FREE(wq); ++} ++ ++void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data, ++ char *format, ...) ++{ ++ dwc_irqflags_t flags; ++ work_container_t *container; ++ static char name[128]; ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VSNPRINTF(name, 128, format, args); ++ va_end(args); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ wq->pending++; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++ ++ container = DWC_ALLOC_ATOMIC(sizeof(*container)); ++ if (!container) { ++ DWC_ERROR("Cannot allocate memory for container\n"); ++ return; ++ } ++ ++ container->name = DWC_STRDUP(name); ++ if (!container->name) { ++ DWC_ERROR("Cannot allocate memory for container->name\n"); ++ DWC_FREE(container); ++ return; ++ } ++ ++ container->cb = cb; ++ container->data = data; ++ container->wq = wq; ++ DWC_DEBUGC("Queueing work: %s, container=%p", container->name, container); ++ INIT_WORK(&container->work.work, do_work); ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry); ++#endif ++ queue_work(wq->wq, &container->work.work); ++} ++ ++void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb, ++ void *data, uint32_t time, char *format, ...) ++{ ++ dwc_irqflags_t flags; ++ work_container_t *container; ++ static char name[128]; ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VSNPRINTF(name, 128, format, args); ++ va_end(args); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ wq->pending++; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++ ++ container = DWC_ALLOC_ATOMIC(sizeof(*container)); ++ if (!container) { ++ DWC_ERROR("Cannot allocate memory for container\n"); ++ return; ++ } ++ ++ container->name = DWC_STRDUP(name); ++ if (!container->name) { ++ DWC_ERROR("Cannot allocate memory for container->name\n"); ++ DWC_FREE(container); ++ return; ++ } ++ ++ container->cb = cb; ++ container->data = data; ++ container->wq = wq; ++ DWC_DEBUGC("Queueing work: %s, container=%p", container->name, container); ++ INIT_DELAYED_WORK(&container->work, do_work); ++ ++#ifdef DEBUG ++ DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry); ++#endif ++ queue_delayed_work(wq->wq, &container->work, msecs_to_jiffies(time)); ++} ++ ++int DWC_WORKQ_PENDING(dwc_workq_t *wq) ++{ ++ return wq->pending; ++} ++ ++ ++#ifdef DWC_LIBMODULE ++ ++#ifdef DWC_CCLIB ++/* CC */ ++EXPORT_SYMBOL(dwc_cc_if_alloc); ++EXPORT_SYMBOL(dwc_cc_if_free); ++EXPORT_SYMBOL(dwc_cc_clear); ++EXPORT_SYMBOL(dwc_cc_add); ++EXPORT_SYMBOL(dwc_cc_remove); ++EXPORT_SYMBOL(dwc_cc_change); ++EXPORT_SYMBOL(dwc_cc_data_for_save); ++EXPORT_SYMBOL(dwc_cc_restore_from_data); ++EXPORT_SYMBOL(dwc_cc_match_chid); ++EXPORT_SYMBOL(dwc_cc_match_cdid); ++EXPORT_SYMBOL(dwc_cc_ck); ++EXPORT_SYMBOL(dwc_cc_chid); ++EXPORT_SYMBOL(dwc_cc_cdid); ++EXPORT_SYMBOL(dwc_cc_name); ++#endif /* DWC_CCLIB */ ++ ++#ifdef DWC_CRYPTOLIB ++# ifndef CONFIG_MACH_IPMATE ++/* Modpow */ ++EXPORT_SYMBOL(dwc_modpow); ++ ++/* DH */ ++EXPORT_SYMBOL(dwc_dh_modpow); ++EXPORT_SYMBOL(dwc_dh_derive_keys); ++EXPORT_SYMBOL(dwc_dh_pk); ++# endif /* CONFIG_MACH_IPMATE */ ++ ++/* Crypto */ ++EXPORT_SYMBOL(dwc_wusb_aes_encrypt); ++EXPORT_SYMBOL(dwc_wusb_cmf); ++EXPORT_SYMBOL(dwc_wusb_prf); ++EXPORT_SYMBOL(dwc_wusb_fill_ccm_nonce); ++EXPORT_SYMBOL(dwc_wusb_gen_nonce); ++EXPORT_SYMBOL(dwc_wusb_gen_key); ++EXPORT_SYMBOL(dwc_wusb_gen_mic); ++#endif /* DWC_CRYPTOLIB */ ++ ++/* Notification */ ++#ifdef DWC_NOTIFYLIB ++EXPORT_SYMBOL(dwc_alloc_notification_manager); ++EXPORT_SYMBOL(dwc_free_notification_manager); ++EXPORT_SYMBOL(dwc_register_notifier); ++EXPORT_SYMBOL(dwc_unregister_notifier); ++EXPORT_SYMBOL(dwc_add_observer); ++EXPORT_SYMBOL(dwc_remove_observer); ++EXPORT_SYMBOL(dwc_notify); ++#endif ++ ++/* Memory Debugging Routines */ ++#ifdef DWC_DEBUG_MEMORY ++EXPORT_SYMBOL(dwc_alloc_debug); ++EXPORT_SYMBOL(dwc_alloc_atomic_debug); ++EXPORT_SYMBOL(dwc_free_debug); ++EXPORT_SYMBOL(dwc_dma_alloc_debug); ++EXPORT_SYMBOL(dwc_dma_free_debug); ++#endif ++ ++EXPORT_SYMBOL(DWC_MEMSET); ++EXPORT_SYMBOL(DWC_MEMCPY); ++EXPORT_SYMBOL(DWC_MEMMOVE); ++EXPORT_SYMBOL(DWC_MEMCMP); ++EXPORT_SYMBOL(DWC_STRNCMP); ++EXPORT_SYMBOL(DWC_STRCMP); ++EXPORT_SYMBOL(DWC_STRLEN); ++EXPORT_SYMBOL(DWC_STRCPY); ++EXPORT_SYMBOL(DWC_STRDUP); ++EXPORT_SYMBOL(DWC_ATOI); ++EXPORT_SYMBOL(DWC_ATOUI); ++ ++#ifdef DWC_UTFLIB ++EXPORT_SYMBOL(DWC_UTF8_TO_UTF16LE); ++#endif /* DWC_UTFLIB */ ++ ++EXPORT_SYMBOL(DWC_IN_IRQ); ++EXPORT_SYMBOL(DWC_IN_BH); ++EXPORT_SYMBOL(DWC_VPRINTF); ++EXPORT_SYMBOL(DWC_VSNPRINTF); ++EXPORT_SYMBOL(DWC_PRINTF); ++EXPORT_SYMBOL(DWC_SPRINTF); ++EXPORT_SYMBOL(DWC_SNPRINTF); ++EXPORT_SYMBOL(__DWC_WARN); ++EXPORT_SYMBOL(__DWC_ERROR); ++EXPORT_SYMBOL(DWC_EXCEPTION); ++ ++#ifdef DEBUG ++EXPORT_SYMBOL(__DWC_DEBUG); ++#endif ++ ++EXPORT_SYMBOL(__DWC_DMA_ALLOC); ++EXPORT_SYMBOL(__DWC_DMA_ALLOC_ATOMIC); ++EXPORT_SYMBOL(__DWC_DMA_FREE); ++EXPORT_SYMBOL(__DWC_ALLOC); ++EXPORT_SYMBOL(__DWC_ALLOC_ATOMIC); ++EXPORT_SYMBOL(__DWC_FREE); ++ ++#ifdef DWC_CRYPTOLIB ++EXPORT_SYMBOL(DWC_RANDOM_BYTES); ++EXPORT_SYMBOL(DWC_AES_CBC); ++EXPORT_SYMBOL(DWC_SHA256); ++EXPORT_SYMBOL(DWC_HMAC_SHA256); ++#endif ++ ++EXPORT_SYMBOL(DWC_CPU_TO_LE32); ++EXPORT_SYMBOL(DWC_CPU_TO_BE32); ++EXPORT_SYMBOL(DWC_LE32_TO_CPU); ++EXPORT_SYMBOL(DWC_BE32_TO_CPU); ++EXPORT_SYMBOL(DWC_CPU_TO_LE16); ++EXPORT_SYMBOL(DWC_CPU_TO_BE16); ++EXPORT_SYMBOL(DWC_LE16_TO_CPU); ++EXPORT_SYMBOL(DWC_BE16_TO_CPU); ++EXPORT_SYMBOL(DWC_READ_REG32); ++EXPORT_SYMBOL(DWC_WRITE_REG32); ++EXPORT_SYMBOL(DWC_MODIFY_REG32); ++ ++#if 0 ++EXPORT_SYMBOL(DWC_READ_REG64); ++EXPORT_SYMBOL(DWC_WRITE_REG64); ++EXPORT_SYMBOL(DWC_MODIFY_REG64); ++#endif ++ ++EXPORT_SYMBOL(DWC_SPINLOCK_ALLOC); ++EXPORT_SYMBOL(DWC_SPINLOCK_FREE); ++EXPORT_SYMBOL(DWC_SPINLOCK); ++EXPORT_SYMBOL(DWC_SPINUNLOCK); ++EXPORT_SYMBOL(DWC_SPINLOCK_IRQSAVE); ++EXPORT_SYMBOL(DWC_SPINUNLOCK_IRQRESTORE); ++EXPORT_SYMBOL(DWC_MUTEX_ALLOC); ++ ++#if (!defined(DWC_LINUX) || !defined(CONFIG_DEBUG_MUTEXES)) ++EXPORT_SYMBOL(DWC_MUTEX_FREE); ++#endif ++ ++EXPORT_SYMBOL(DWC_MUTEX_LOCK); ++EXPORT_SYMBOL(DWC_MUTEX_TRYLOCK); ++EXPORT_SYMBOL(DWC_MUTEX_UNLOCK); ++EXPORT_SYMBOL(DWC_UDELAY); ++EXPORT_SYMBOL(DWC_MDELAY); ++EXPORT_SYMBOL(DWC_MSLEEP); ++EXPORT_SYMBOL(DWC_TIME); ++EXPORT_SYMBOL(DWC_TIMER_ALLOC); ++EXPORT_SYMBOL(DWC_TIMER_FREE); ++EXPORT_SYMBOL(DWC_TIMER_SCHEDULE); ++EXPORT_SYMBOL(DWC_TIMER_CANCEL); ++EXPORT_SYMBOL(DWC_WAITQ_ALLOC); ++EXPORT_SYMBOL(DWC_WAITQ_FREE); ++EXPORT_SYMBOL(DWC_WAITQ_WAIT); ++EXPORT_SYMBOL(DWC_WAITQ_WAIT_TIMEOUT); ++EXPORT_SYMBOL(DWC_WAITQ_TRIGGER); ++EXPORT_SYMBOL(DWC_WAITQ_ABORT); ++EXPORT_SYMBOL(DWC_THREAD_RUN); ++EXPORT_SYMBOL(DWC_THREAD_STOP); ++EXPORT_SYMBOL(DWC_THREAD_SHOULD_STOP); ++EXPORT_SYMBOL(DWC_TASK_ALLOC); ++EXPORT_SYMBOL(DWC_TASK_FREE); ++EXPORT_SYMBOL(DWC_TASK_SCHEDULE); ++EXPORT_SYMBOL(DWC_WORKQ_WAIT_WORK_DONE); ++EXPORT_SYMBOL(DWC_WORKQ_ALLOC); ++EXPORT_SYMBOL(DWC_WORKQ_FREE); ++EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE); ++EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE_DELAYED); ++EXPORT_SYMBOL(DWC_WORKQ_PENDING); ++ ++static int dwc_common_port_init_module(void) ++{ ++ int result = 0; ++ ++ printk(KERN_DEBUG "Module dwc_common_port init\n" ); ++ ++#ifdef DWC_DEBUG_MEMORY ++ result = dwc_memory_debug_start(NULL); ++ if (result) { ++ printk(KERN_ERR ++ "dwc_memory_debug_start() failed with error %d\n", ++ result); ++ return result; ++ } ++#endif ++ ++#ifdef DWC_NOTIFYLIB ++ result = dwc_alloc_notification_manager(NULL, NULL); ++ if (result) { ++ printk(KERN_ERR ++ "dwc_alloc_notification_manager() failed with error %d\n", ++ result); ++ return result; ++ } ++#endif ++ return result; ++} ++ ++static void dwc_common_port_exit_module(void) ++{ ++ printk(KERN_DEBUG "Module dwc_common_port exit\n" ); ++ ++#ifdef DWC_NOTIFYLIB ++ dwc_free_notification_manager(); ++#endif ++ ++#ifdef DWC_DEBUG_MEMORY ++ dwc_memory_debug_stop(); ++#endif ++} ++ ++module_init(dwc_common_port_init_module); ++module_exit(dwc_common_port_exit_module); ++ ++MODULE_DESCRIPTION("DWC Common Library - Portable version"); ++MODULE_AUTHOR("Synopsys Inc."); ++MODULE_LICENSE ("GPL"); ++ ++#endif /* DWC_LIBMODULE */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_common_nbsd.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_common_nbsd.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1275 @@ ++#include "dwc_os.h" ++#include "dwc_list.h" ++ ++#ifdef DWC_CCLIB ++# include "dwc_cc.h" ++#endif ++ ++#ifdef DWC_CRYPTOLIB ++# include "dwc_modpow.h" ++# include "dwc_dh.h" ++# include "dwc_crypto.h" ++#endif ++ ++#ifdef DWC_NOTIFYLIB ++# include "dwc_notifier.h" ++#endif ++ ++/* OS-Level Implementations */ ++ ++/* This is the NetBSD 4.0.1 kernel implementation of the DWC platform library. */ ++ ++ ++/* MISC */ ++ ++void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size) ++{ ++ return memset(dest, byte, size); ++} ++ ++void *DWC_MEMCPY(void *dest, void const *src, uint32_t size) ++{ ++ return memcpy(dest, src, size); ++} ++ ++void *DWC_MEMMOVE(void *dest, void *src, uint32_t size) ++{ ++ bcopy(src, dest, size); ++ return dest; ++} ++ ++int DWC_MEMCMP(void *m1, void *m2, uint32_t size) ++{ ++ return memcmp(m1, m2, size); ++} ++ ++int DWC_STRNCMP(void *s1, void *s2, uint32_t size) ++{ ++ return strncmp(s1, s2, size); ++} ++ ++int DWC_STRCMP(void *s1, void *s2) ++{ ++ return strcmp(s1, s2); ++} ++ ++int DWC_STRLEN(char const *str) ++{ ++ return strlen(str); ++} ++ ++char *DWC_STRCPY(char *to, char const *from) ++{ ++ return strcpy(to, from); ++} ++ ++char *DWC_STRDUP(char const *str) ++{ ++ int len = DWC_STRLEN(str) + 1; ++ char *new = DWC_ALLOC_ATOMIC(len); ++ ++ if (!new) { ++ return NULL; ++ } ++ ++ DWC_MEMCPY(new, str, len); ++ return new; ++} ++ ++int DWC_ATOI(char *str, int32_t *value) ++{ ++ char *end = NULL; ++ ++ /* NetBSD doesn't have 'strtol' in the kernel, but 'strtoul' ++ * should be equivalent on 2's complement machines ++ */ ++ *value = strtoul(str, &end, 0); ++ if (*end == '\0') { ++ return 0; ++ } ++ ++ return -1; ++} ++ ++int DWC_ATOUI(char *str, uint32_t *value) ++{ ++ char *end = NULL; ++ ++ *value = strtoul(str, &end, 0); ++ if (*end == '\0') { ++ return 0; ++ } ++ ++ return -1; ++} ++ ++ ++#ifdef DWC_UTFLIB ++/* From usbstring.c */ ++ ++int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len) ++{ ++ int count = 0; ++ u8 c; ++ u16 uchar; ++ ++ /* this insists on correct encodings, though not minimal ones. ++ * BUT it currently rejects legit 4-byte UTF-8 code points, ++ * which need surrogate pairs. (Unicode 3.1 can use them.) ++ */ ++ while (len != 0 && (c = (u8) *s++) != 0) { ++ if (unlikely(c & 0x80)) { ++ // 2-byte sequence: ++ // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx ++ if ((c & 0xe0) == 0xc0) { ++ uchar = (c & 0x1f) << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ // 3-byte sequence (most CJKV characters): ++ // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx ++ } else if ((c & 0xf0) == 0xe0) { ++ uchar = (c & 0x0f) << 12; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ /* no bogus surrogates */ ++ if (0xd800 <= uchar && uchar <= 0xdfff) ++ goto fail; ++ ++ // 4-byte sequence (surrogate pairs, currently rare): ++ // 11101110wwwwzzzzyy + 110111yyyyxxxxxx ++ // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ++ // (uuuuu = wwww + 1) ++ // FIXME accept the surrogate code points (only) ++ } else ++ goto fail; ++ } else ++ uchar = c; ++ put_unaligned (cpu_to_le16 (uchar), cp++); ++ count++; ++ len--; ++ } ++ return count; ++fail: ++ return -1; ++} ++ ++#endif /* DWC_UTFLIB */ ++ ++ ++/* dwc_debug.h */ ++ ++dwc_bool_t DWC_IN_IRQ(void) ++{ ++// return in_irq(); ++ return 0; ++} ++ ++dwc_bool_t DWC_IN_BH(void) ++{ ++// return in_softirq(); ++ return 0; ++} ++ ++void DWC_VPRINTF(char *format, va_list args) ++{ ++ vprintf(format, args); ++} ++ ++int DWC_VSNPRINTF(char *str, int size, char *format, va_list args) ++{ ++ return vsnprintf(str, size, format, args); ++} ++ ++void DWC_PRINTF(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++int DWC_SPRINTF(char *buffer, char *format, ...) ++{ ++ int retval; ++ va_list args; ++ ++ va_start(args, format); ++ retval = vsprintf(buffer, format, args); ++ va_end(args); ++ return retval; ++} ++ ++int DWC_SNPRINTF(char *buffer, int size, char *format, ...) ++{ ++ int retval; ++ va_list args; ++ ++ va_start(args, format); ++ retval = vsnprintf(buffer, size, format, args); ++ va_end(args); ++ return retval; ++} ++ ++void __DWC_WARN(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++void __DWC_ERROR(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++ ++void DWC_EXCEPTION(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++// BUG_ON(1); ??? ++} ++ ++#ifdef DEBUG ++void __DWC_DEBUG(char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VPRINTF(format, args); ++ va_end(args); ++} ++#endif ++ ++ ++/* dwc_mem.h */ ++ ++#if 0 ++dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size, ++ uint32_t align, ++ uint32_t alloc) ++{ ++ struct dma_pool *pool = dma_pool_create("Pool", NULL, ++ size, align, alloc); ++ return (dwc_pool_t *)pool; ++} ++ ++void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool) ++{ ++ dma_pool_destroy((struct dma_pool *)pool); ++} ++ ++void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr) ++{ ++// return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr); ++ return dma_pool_alloc((struct dma_pool *)pool, M_WAITOK, dma_addr); ++} ++ ++void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr) ++{ ++ void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr); ++ memset(..); ++} ++ ++void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr) ++{ ++ dma_pool_free(pool, vaddr, daddr); ++} ++#endif ++ ++void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr) ++{ ++ dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx; ++ int error; ++ ++ error = bus_dmamem_alloc(dma->dma_tag, size, 1, size, dma->segs, ++ sizeof(dma->segs) / sizeof(dma->segs[0]), ++ &dma->nsegs, BUS_DMA_NOWAIT); ++ if (error) { ++ printf("%s: bus_dmamem_alloc(%ju) failed: %d\n", __func__, ++ (uintmax_t)size, error); ++ goto fail_0; ++ } ++ ++ error = bus_dmamem_map(dma->dma_tag, dma->segs, dma->nsegs, size, ++ (caddr_t *)&dma->dma_vaddr, ++ BUS_DMA_NOWAIT | BUS_DMA_COHERENT); ++ if (error) { ++ printf("%s: bus_dmamem_map failed: %d\n", __func__, error); ++ goto fail_1; ++ } ++ ++ error = bus_dmamap_create(dma->dma_tag, size, 1, size, 0, ++ BUS_DMA_NOWAIT, &dma->dma_map); ++ if (error) { ++ printf("%s: bus_dmamap_create failed: %d\n", __func__, error); ++ goto fail_2; ++ } ++ ++ error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr, ++ size, NULL, BUS_DMA_NOWAIT); ++ if (error) { ++ printf("%s: bus_dmamap_load failed: %d\n", __func__, error); ++ goto fail_3; ++ } ++ ++ dma->dma_paddr = (bus_addr_t)dma->segs[0].ds_addr; ++ *dma_addr = dma->dma_paddr; ++ return dma->dma_vaddr; ++ ++fail_3: ++ bus_dmamap_destroy(dma->dma_tag, dma->dma_map); ++fail_2: ++ bus_dmamem_unmap(dma->dma_tag, dma->dma_vaddr, size); ++fail_1: ++ bus_dmamem_free(dma->dma_tag, dma->segs, dma->nsegs); ++fail_0: ++ dma->dma_map = NULL; ++ dma->dma_vaddr = NULL; ++ dma->nsegs = 0; ++ ++ return NULL; ++} ++ ++void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr) ++{ ++ dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx; ++ ++ if (dma->dma_map != NULL) { ++ bus_dmamap_sync(dma->dma_tag, dma->dma_map, 0, size, ++ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); ++ bus_dmamap_unload(dma->dma_tag, dma->dma_map); ++ bus_dmamap_destroy(dma->dma_tag, dma->dma_map); ++ bus_dmamem_unmap(dma->dma_tag, dma->dma_vaddr, size); ++ bus_dmamem_free(dma->dma_tag, dma->segs, dma->nsegs); ++ dma->dma_paddr = 0; ++ dma->dma_map = NULL; ++ dma->dma_vaddr = NULL; ++ dma->nsegs = 0; ++ } ++} ++ ++void *__DWC_ALLOC(void *mem_ctx, uint32_t size) ++{ ++ return malloc(size, M_DEVBUF, M_WAITOK | M_ZERO); ++} ++ ++void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size) ++{ ++ return malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); ++} ++ ++void __DWC_FREE(void *mem_ctx, void *addr) ++{ ++ free(addr, M_DEVBUF); ++} ++ ++ ++#ifdef DWC_CRYPTOLIB ++/* dwc_crypto.h */ ++ ++void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length) ++{ ++ get_random_bytes(buffer, length); ++} ++ ++int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out) ++{ ++ struct crypto_blkcipher *tfm; ++ struct blkcipher_desc desc; ++ struct scatterlist sgd; ++ struct scatterlist sgs; ++ ++ tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); ++ if (tfm == NULL) { ++ printk("failed to load transform for aes CBC\n"); ++ return -1; ++ } ++ ++ crypto_blkcipher_setkey(tfm, key, keylen); ++ crypto_blkcipher_set_iv(tfm, iv, 16); ++ ++ sg_init_one(&sgd, out, messagelen); ++ sg_init_one(&sgs, message, messagelen); ++ ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) { ++ crypto_free_blkcipher(tfm); ++ DWC_ERROR("AES CBC encryption failed"); ++ return -1; ++ } ++ ++ crypto_free_blkcipher(tfm); ++ return 0; ++} ++ ++int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out) ++{ ++ struct crypto_hash *tfm; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) { ++ DWC_ERROR("Failed to load transform for sha256: %ld", PTR_ERR(tfm)); ++ return 0; ++ } ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ sg_init_one(&sg, message, len); ++ crypto_hash_digest(&desc, &sg, len, out); ++ crypto_free_hash(tfm); ++ ++ return 1; ++} ++ ++int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen, ++ uint8_t *key, uint32_t keylen, uint8_t *out) ++{ ++ struct crypto_hash *tfm; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ ++ tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) { ++ DWC_ERROR("Failed to load transform for hmac(sha256): %ld", PTR_ERR(tfm)); ++ return 0; ++ } ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ sg_init_one(&sg, message, messagelen); ++ crypto_hash_setkey(tfm, key, keylen); ++ crypto_hash_digest(&desc, &sg, messagelen, out); ++ crypto_free_hash(tfm); ++ ++ return 1; ++} ++ ++#endif /* DWC_CRYPTOLIB */ ++ ++ ++/* Byte Ordering Conversions */ ++ ++uint32_t DWC_CPU_TO_LE32(uint32_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_CPU_TO_BE32(uint32_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_LE32_TO_CPU(uint32_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint32_t DWC_BE32_TO_CPU(uint32_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ ++ return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24)); ++#endif ++} ++ ++uint16_t DWC_CPU_TO_LE16(uint16_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_CPU_TO_BE16(uint16_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_LE16_TO_CPU(uint16_t *p) ++{ ++#ifdef __LITTLE_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++uint16_t DWC_BE16_TO_CPU(uint16_t *p) ++{ ++#ifdef __BIG_ENDIAN ++ return *p; ++#else ++ uint8_t *u_p = (uint8_t *)p; ++ return (u_p[1] | (u_p[0] << 8)); ++#endif ++} ++ ++ ++/* Registers */ ++ ++uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ return bus_space_read_4(io->iot, io->ioh, ior); ++} ++ ++#if 0 ++uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ return bus_space_read_8(io->iot, io->ioh, ior); ++} ++#endif ++ ++void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_4(io->iot, io->ioh, ior, value); ++} ++ ++#if 0 ++void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_8(io->iot, io->ioh, ior, value); ++} ++#endif ++ ++void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask, ++ uint32_t set_mask) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_4(io->iot, io->ioh, ior, ++ (bus_space_read_4(io->iot, io->ioh, ior) & ++ ~clear_mask) | set_mask); ++} ++ ++#if 0 ++void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask, ++ uint64_t set_mask) ++{ ++ dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx; ++ bus_size_t ior = (bus_size_t)reg; ++ ++ bus_space_write_8(io->iot, io->ioh, ior, ++ (bus_space_read_8(io->iot, io->ioh, ior) & ++ ~clear_mask) | set_mask); ++} ++#endif ++ ++ ++/* Locking */ ++ ++dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void) ++{ ++ struct simplelock *sl = DWC_ALLOC(sizeof(*sl)); ++ ++ if (!sl) { ++ DWC_ERROR("Cannot allocate memory for spinlock"); ++ return NULL; ++ } ++ ++ simple_lock_init(sl); ++ return (dwc_spinlock_t *)sl; ++} ++ ++void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock) ++{ ++ struct simplelock *sl = (struct simplelock *)lock; ++ ++ DWC_FREE(sl); ++} ++ ++void DWC_SPINLOCK(dwc_spinlock_t *lock) ++{ ++ simple_lock((struct simplelock *)lock); ++} ++ ++void DWC_SPINUNLOCK(dwc_spinlock_t *lock) ++{ ++ simple_unlock((struct simplelock *)lock); ++} ++ ++void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags) ++{ ++ simple_lock((struct simplelock *)lock); ++ *flags = splbio(); ++} ++ ++void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags) ++{ ++ splx(flags); ++ simple_unlock((struct simplelock *)lock); ++} ++ ++dwc_mutex_t *DWC_MUTEX_ALLOC(void) ++{ ++ dwc_mutex_t *mutex = DWC_ALLOC(sizeof(struct lock)); ++ ++ if (!mutex) { ++ DWC_ERROR("Cannot allocate memory for mutex"); ++ return NULL; ++ } ++ ++ lockinit((struct lock *)mutex, 0, "dw3mtx", 0, 0); ++ return mutex; ++} ++ ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)) ++#else ++void DWC_MUTEX_FREE(dwc_mutex_t *mutex) ++{ ++ DWC_FREE(mutex); ++} ++#endif ++ ++void DWC_MUTEX_LOCK(dwc_mutex_t *mutex) ++{ ++ lockmgr((struct lock *)mutex, LK_EXCLUSIVE, NULL); ++} ++ ++int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex) ++{ ++ int status; ++ ++ status = lockmgr((struct lock *)mutex, LK_EXCLUSIVE | LK_NOWAIT, NULL); ++ return status == 0; ++} ++ ++void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex) ++{ ++ lockmgr((struct lock *)mutex, LK_RELEASE, NULL); ++} ++ ++ ++/* Timing */ ++ ++void DWC_UDELAY(uint32_t usecs) ++{ ++ DELAY(usecs); ++} ++ ++void DWC_MDELAY(uint32_t msecs) ++{ ++ do { ++ DELAY(1000); ++ } while (--msecs); ++} ++ ++void DWC_MSLEEP(uint32_t msecs) ++{ ++ struct timeval tv; ++ ++ tv.tv_sec = msecs / 1000; ++ tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000; ++ tsleep(&tv, 0, "dw3slp", tvtohz(&tv)); ++} ++ ++uint32_t DWC_TIME(void) ++{ ++ struct timeval tv; ++ ++ microuptime(&tv); // or getmicrouptime? (less precise, but faster) ++ return tv.tv_sec * 1000 + tv.tv_usec / 1000; ++} ++ ++ ++/* Timers */ ++ ++struct dwc_timer { ++ struct callout t; ++ char *name; ++ dwc_spinlock_t *lock; ++ dwc_timer_callback_t cb; ++ void *data; ++}; ++ ++dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data) ++{ ++ dwc_timer_t *t = DWC_ALLOC(sizeof(*t)); ++ ++ if (!t) { ++ DWC_ERROR("Cannot allocate memory for timer"); ++ return NULL; ++ } ++ ++ callout_init(&t->t); ++ ++ t->name = DWC_STRDUP(name); ++ if (!t->name) { ++ DWC_ERROR("Cannot allocate memory for timer->name"); ++ goto no_name; ++ } ++ ++ t->lock = DWC_SPINLOCK_ALLOC(); ++ if (!t->lock) { ++ DWC_ERROR("Cannot allocate memory for timer->lock"); ++ goto no_lock; ++ } ++ ++ t->cb = cb; ++ t->data = data; ++ ++ return t; ++ ++ no_lock: ++ DWC_FREE(t->name); ++ no_name: ++ DWC_FREE(t); ++ ++ return NULL; ++} ++ ++void DWC_TIMER_FREE(dwc_timer_t *timer) ++{ ++ callout_stop(&timer->t); ++ DWC_SPINLOCK_FREE(timer->lock); ++ DWC_FREE(timer->name); ++ DWC_FREE(timer); ++} ++ ++void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time) ++{ ++ struct timeval tv; ++ ++ tv.tv_sec = time / 1000; ++ tv.tv_usec = (time - tv.tv_sec * 1000) * 1000; ++ callout_reset(&timer->t, tvtohz(&tv), timer->cb, timer->data); ++} ++ ++void DWC_TIMER_CANCEL(dwc_timer_t *timer) ++{ ++ callout_stop(&timer->t); ++} ++ ++ ++/* Wait Queues */ ++ ++struct dwc_waitq { ++ struct simplelock lock; ++ int abort; ++}; ++ ++dwc_waitq_t *DWC_WAITQ_ALLOC(void) ++{ ++ dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq)); ++ ++ if (!wq) { ++ DWC_ERROR("Cannot allocate memory for waitqueue"); ++ return NULL; ++ } ++ ++ simple_lock_init(&wq->lock); ++ wq->abort = 0; ++ ++ return wq; ++} ++ ++void DWC_WAITQ_FREE(dwc_waitq_t *wq) ++{ ++ DWC_FREE(wq); ++} ++ ++int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data) ++{ ++ int ipl; ++ int result = 0; ++ ++ simple_lock(&wq->lock); ++ ipl = splbio(); ++ ++ /* Skip the sleep if already aborted or triggered */ ++ if (!wq->abort && !cond(data)) { ++ splx(ipl); ++ result = ltsleep(wq, PCATCH, "dw3wat", 0, &wq->lock); // infinite timeout ++ ipl = splbio(); ++ } ++ ++ if (result == 0) { // awoken ++ if (wq->abort) { ++ wq->abort = 0; ++ result = -DWC_E_ABORT; ++ } else { ++ result = 0; ++ } ++ ++ splx(ipl); ++ simple_unlock(&wq->lock); ++ } else { ++ wq->abort = 0; ++ splx(ipl); ++ simple_unlock(&wq->lock); ++ ++ if (result == ERESTART) { // signaled - restart ++ result = -DWC_E_RESTART; ++ } else { // signaled - must be EINTR ++ result = -DWC_E_ABORT; ++ } ++ } ++ ++ return result; ++} ++ ++int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, ++ void *data, int32_t msecs) ++{ ++ struct timeval tv, tv1, tv2; ++ int ipl; ++ int result = 0; ++ ++ tv.tv_sec = msecs / 1000; ++ tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000; ++ ++ simple_lock(&wq->lock); ++ ipl = splbio(); ++ ++ /* Skip the sleep if already aborted or triggered */ ++ if (!wq->abort && !cond(data)) { ++ splx(ipl); ++ getmicrouptime(&tv1); ++ result = ltsleep(wq, PCATCH, "dw3wto", tvtohz(&tv), &wq->lock); ++ getmicrouptime(&tv2); ++ ipl = splbio(); ++ } ++ ++ if (result == 0) { // awoken ++ if (wq->abort) { ++ wq->abort = 0; ++ splx(ipl); ++ simple_unlock(&wq->lock); ++ result = -DWC_E_ABORT; ++ } else { ++ splx(ipl); ++ simple_unlock(&wq->lock); ++ ++ tv2.tv_usec -= tv1.tv_usec; ++ if (tv2.tv_usec < 0) { ++ tv2.tv_usec += 1000000; ++ tv2.tv_sec--; ++ } ++ ++ tv2.tv_sec -= tv1.tv_sec; ++ result = tv2.tv_sec * 1000 + tv2.tv_usec / 1000; ++ result = msecs - result; ++ if (result <= 0) ++ result = 1; ++ } ++ } else { ++ wq->abort = 0; ++ splx(ipl); ++ simple_unlock(&wq->lock); ++ ++ if (result == ERESTART) { // signaled - restart ++ result = -DWC_E_RESTART; ++ ++ } else if (result == EINTR) { // signaled - interrupt ++ result = -DWC_E_ABORT; ++ ++ } else { // timed out ++ result = -DWC_E_TIMEOUT; ++ } ++ } ++ ++ return result; ++} ++ ++void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq) ++{ ++ wakeup(wq); ++} ++ ++void DWC_WAITQ_ABORT(dwc_waitq_t *wq) ++{ ++ int ipl; ++ ++ simple_lock(&wq->lock); ++ ipl = splbio(); ++ wq->abort = 1; ++ wakeup(wq); ++ splx(ipl); ++ simple_unlock(&wq->lock); ++} ++ ++ ++/* Threading */ ++ ++struct dwc_thread { ++ struct proc *proc; ++ int abort; ++}; ++ ++dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data) ++{ ++ int retval; ++ dwc_thread_t *thread = DWC_ALLOC(sizeof(*thread)); ++ ++ if (!thread) { ++ return NULL; ++ } ++ ++ thread->abort = 0; ++ retval = kthread_create1((void (*)(void *))func, data, &thread->proc, ++ "%s", name); ++ if (retval) { ++ DWC_FREE(thread); ++ return NULL; ++ } ++ ++ return thread; ++} ++ ++int DWC_THREAD_STOP(dwc_thread_t *thread) ++{ ++ int retval; ++ ++ thread->abort = 1; ++ retval = tsleep(&thread->abort, 0, "dw3stp", 60 * hz); ++ ++ if (retval == 0) { ++ /* DWC_THREAD_EXIT() will free the thread struct */ ++ return 0; ++ } ++ ++ /* NOTE: We leak the thread struct if thread doesn't die */ ++ ++ if (retval == EWOULDBLOCK) { ++ return -DWC_E_TIMEOUT; ++ } ++ ++ return -DWC_E_UNKNOWN; ++} ++ ++dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread) ++{ ++ return thread->abort; ++} ++ ++void DWC_THREAD_EXIT(dwc_thread_t *thread) ++{ ++ wakeup(&thread->abort); ++ DWC_FREE(thread); ++ kthread_exit(0); ++} ++ ++/* tasklets ++ - Runs in interrupt context (cannot sleep) ++ - Each tasklet runs on a single CPU ++ - Different tasklets can be running simultaneously on different CPUs ++ [ On NetBSD there is no corresponding mechanism, drivers don't have bottom- ++ halves. So we just call the callback directly from DWC_TASK_SCHEDULE() ] ++ */ ++struct dwc_tasklet { ++ dwc_tasklet_callback_t cb; ++ void *data; ++}; ++ ++static void tasklet_callback(void *data) ++{ ++ dwc_tasklet_t *task = (dwc_tasklet_t *)data; ++ ++ task->cb(task->data); ++} ++ ++dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data) ++{ ++ dwc_tasklet_t *task = DWC_ALLOC(sizeof(*task)); ++ ++ if (task) { ++ task->cb = cb; ++ task->data = data; ++ } else { ++ DWC_ERROR("Cannot allocate memory for tasklet"); ++ } ++ ++ return task; ++} ++ ++void DWC_TASK_FREE(dwc_tasklet_t *task) ++{ ++ DWC_FREE(task); ++} ++ ++void DWC_TASK_SCHEDULE(dwc_tasklet_t *task) ++{ ++ tasklet_callback(task); ++} ++ ++ ++/* workqueues ++ - Runs in process context (can sleep) ++ */ ++typedef struct work_container { ++ dwc_work_callback_t cb; ++ void *data; ++ dwc_workq_t *wq; ++ char *name; ++ int hz; ++ struct work task; ++} work_container_t; ++ ++struct dwc_workq { ++ struct workqueue *taskq; ++ dwc_spinlock_t *lock; ++ dwc_waitq_t *waitq; ++ int pending; ++ struct work_container *container; ++}; ++ ++static void do_work(struct work *task, void *data) ++{ ++ dwc_workq_t *wq = (dwc_workq_t *)data; ++ work_container_t *container = wq->container; ++ dwc_irqflags_t flags; ++ ++ if (container->hz) { ++ tsleep(container, 0, "dw3wrk", container->hz); ++ } ++ ++ container->cb(container->data); ++ DWC_DEBUG("Work done: %s, container=%p", container->name, container); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ if (container->name) ++ DWC_FREE(container->name); ++ DWC_FREE(container); ++ wq->pending--; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++} ++ ++static int work_done(void *data) ++{ ++ dwc_workq_t *workq = (dwc_workq_t *)data; ++ ++ return workq->pending == 0; ++} ++ ++int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout) ++{ ++ return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout); ++} ++ ++dwc_workq_t *DWC_WORKQ_ALLOC(char *name) ++{ ++ int result; ++ dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq)); ++ ++ if (!wq) { ++ DWC_ERROR("Cannot allocate memory for workqueue"); ++ return NULL; ++ } ++ ++ result = workqueue_create(&wq->taskq, name, do_work, wq, 0 /*PWAIT*/, ++ IPL_BIO, 0); ++ if (result) { ++ DWC_ERROR("Cannot create workqueue"); ++ goto no_taskq; ++ } ++ ++ wq->pending = 0; ++ ++ wq->lock = DWC_SPINLOCK_ALLOC(); ++ if (!wq->lock) { ++ DWC_ERROR("Cannot allocate memory for spinlock"); ++ goto no_lock; ++ } ++ ++ wq->waitq = DWC_WAITQ_ALLOC(); ++ if (!wq->waitq) { ++ DWC_ERROR("Cannot allocate memory for waitqueue"); ++ goto no_waitq; ++ } ++ ++ return wq; ++ ++ no_waitq: ++ DWC_SPINLOCK_FREE(wq->lock); ++ no_lock: ++ workqueue_destroy(wq->taskq); ++ no_taskq: ++ DWC_FREE(wq); ++ ++ return NULL; ++} ++ ++void DWC_WORKQ_FREE(dwc_workq_t *wq) ++{ ++#ifdef DEBUG ++ dwc_irqflags_t flags; ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ ++ if (wq->pending != 0) { ++ struct work_container *container = wq->container; ++ ++ DWC_ERROR("Destroying work queue with pending work"); ++ ++ if (container && container->name) { ++ DWC_ERROR("Work %s still pending", container->name); ++ } ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++#endif ++ DWC_WAITQ_FREE(wq->waitq); ++ DWC_SPINLOCK_FREE(wq->lock); ++ workqueue_destroy(wq->taskq); ++ DWC_FREE(wq); ++} ++ ++void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data, ++ char *format, ...) ++{ ++ dwc_irqflags_t flags; ++ work_container_t *container; ++ static char name[128]; ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VSNPRINTF(name, 128, format, args); ++ va_end(args); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ wq->pending++; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++ ++ container = DWC_ALLOC_ATOMIC(sizeof(*container)); ++ if (!container) { ++ DWC_ERROR("Cannot allocate memory for container"); ++ return; ++ } ++ ++ container->name = DWC_STRDUP(name); ++ if (!container->name) { ++ DWC_ERROR("Cannot allocate memory for container->name"); ++ DWC_FREE(container); ++ return; ++ } ++ ++ container->cb = cb; ++ container->data = data; ++ container->wq = wq; ++ container->hz = 0; ++ wq->container = container; ++ ++ DWC_DEBUG("Queueing work: %s, container=%p", container->name, container); ++ workqueue_enqueue(wq->taskq, &container->task); ++} ++ ++void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb, ++ void *data, uint32_t time, char *format, ...) ++{ ++ dwc_irqflags_t flags; ++ work_container_t *container; ++ static char name[128]; ++ struct timeval tv; ++ va_list args; ++ ++ va_start(args, format); ++ DWC_VSNPRINTF(name, 128, format, args); ++ va_end(args); ++ ++ DWC_SPINLOCK_IRQSAVE(wq->lock, &flags); ++ wq->pending++; ++ DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags); ++ DWC_WAITQ_TRIGGER(wq->waitq); ++ ++ container = DWC_ALLOC_ATOMIC(sizeof(*container)); ++ if (!container) { ++ DWC_ERROR("Cannot allocate memory for container"); ++ return; ++ } ++ ++ container->name = DWC_STRDUP(name); ++ if (!container->name) { ++ DWC_ERROR("Cannot allocate memory for container->name"); ++ DWC_FREE(container); ++ return; ++ } ++ ++ container->cb = cb; ++ container->data = data; ++ container->wq = wq; ++ tv.tv_sec = time / 1000; ++ tv.tv_usec = (time - tv.tv_sec * 1000) * 1000; ++ container->hz = tvtohz(&tv); ++ wq->container = container; ++ ++ DWC_DEBUG("Queueing work: %s, container=%p", container->name, container); ++ workqueue_enqueue(wq->taskq, &container->task); ++} ++ ++int DWC_WORKQ_PENDING(dwc_workq_t *wq) ++{ ++ return wq->pending; ++} +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_crypto.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_crypto.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,308 @@ ++/* ========================================================================= ++ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_crypto.c $ ++ * $Revision: #5 $ ++ * $Date: 2010/09/28 $ ++ * $Change: 1596182 $ ++ * ++ * Synopsys Portability Library Software and documentation ++ * (hereinafter, "Software") is an Unsupported proprietary work of ++ * Synopsys, Inc. unless otherwise expressly agreed to in writing ++ * between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product ++ * under any End User Software License Agreement or Agreement for ++ * Licensed Product with Synopsys or any supplement thereto. You are ++ * permitted to use and redistribute this Software in source and binary ++ * forms, with or without modification, provided that redistributions ++ * of source code must retain this notice. You may not view, use, ++ * disclose, copy or distribute this file or any information contained ++ * herein except pursuant to this license grant from Synopsys. If you ++ * do not agree with this notice, including the disclaimer below, then ++ * you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" ++ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL ++ * SYNOPSYS 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. ++ * ========================================================================= */ ++ ++/** @file ++ * This file contains the WUSB cryptographic routines. ++ */ ++ ++#ifdef DWC_CRYPTOLIB ++ ++#include "dwc_crypto.h" ++#include "usb.h" ++ ++#ifdef DEBUG ++static inline void dump_bytes(char *name, uint8_t *bytes, int len) ++{ ++ int i; ++ DWC_PRINTF("%s: ", name); ++ for (i=0; idst == src, then the bytes will be encrypted ++ * in-place. ++ * ++ * @return 0 on success, negative error code on error. ++ */ ++int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst) ++{ ++ u8 block_t[16]; ++ DWC_MEMSET(block_t, 0, 16); ++ ++ return DWC_AES_CBC(src, 16, key, 16, block_t, dst); ++} ++ ++/** ++ * The CCM-MAC-FUNCTION described in section 6.5 of the WUSB spec. ++ * This function takes a data string and returns the encrypted CBC ++ * Counter-mode MIC. ++ * ++ * @param key The 128-bit symmetric key. ++ * @param nonce The CCM nonce. ++ * @param label The unique 14-byte ASCII text label. ++ * @param bytes The byte array to be encrypted. ++ * @param len Length of the byte array. ++ * @param result Byte array to receive the 8-byte encrypted MIC. ++ */ ++void dwc_wusb_cmf(u8 *key, u8 *nonce, ++ char *label, u8 *bytes, int len, u8 *result) ++{ ++ u8 block_m[16]; ++ u8 block_x[16]; ++ u8 block_t[8]; ++ int idx, blkNum; ++ u16 la = (u16)(len + 14); ++ ++ /* Set the AES-128 key */ ++ //dwc_aes_setkey(tfm, key, 16); ++ ++ /* Fill block B0 from flags = 0x59, N, and l(m) = 0 */ ++ block_m[0] = 0x59; ++ for (idx = 0; idx < 13; idx++) ++ block_m[idx + 1] = nonce[idx]; ++ block_m[14] = 0; ++ block_m[15] = 0; ++ ++ /* Produce the CBC IV */ ++ dwc_wusb_aes_encrypt(block_m, key, block_x); ++ show_block(block_m, "CBC IV in: ", "\n", 0); ++ show_block(block_x, "CBC IV out:", "\n", 0); ++ ++ /* Fill block B1 from l(a) = Blen + 14, and A */ ++ block_x[0] ^= (u8)(la >> 8); ++ block_x[1] ^= (u8)la; ++ for (idx = 0; idx < 14; idx++) ++ block_x[idx + 2] ^= label[idx]; ++ show_block(block_x, "After xor: ", "b1\n", 16); ++ ++ dwc_wusb_aes_encrypt(block_x, key, block_x); ++ show_block(block_x, "After AES: ", "b1\n", 16); ++ ++ idx = 0; ++ blkNum = 0; ++ ++ /* Fill remaining blocks with B */ ++ while (len-- > 0) { ++ block_x[idx] ^= *bytes++; ++ if (++idx >= 16) { ++ idx = 0; ++ show_block(block_x, "After xor: ", "\n", blkNum); ++ dwc_wusb_aes_encrypt(block_x, key, block_x); ++ show_block(block_x, "After AES: ", "\n", blkNum); ++ blkNum++; ++ } ++ } ++ ++ /* Handle partial last block */ ++ if (idx > 0) { ++ show_block(block_x, "After xor: ", "\n", blkNum); ++ dwc_wusb_aes_encrypt(block_x, key, block_x); ++ show_block(block_x, "After AES: ", "\n", blkNum); ++ } ++ ++ /* Save the MIC tag */ ++ DWC_MEMCPY(block_t, block_x, 8); ++ show_block(block_t, "MIC tag : ", NULL, 8); ++ ++ /* Fill block A0 from flags = 0x01, N, and counter = 0 */ ++ block_m[0] = 0x01; ++ block_m[14] = 0; ++ block_m[15] = 0; ++ ++ /* Encrypt the counter */ ++ dwc_wusb_aes_encrypt(block_m, key, block_x); ++ show_block(block_x, "CTR[MIC] : ", NULL, 8); ++ ++ /* XOR with MIC tag */ ++ for (idx = 0; idx < 8; idx++) { ++ block_t[idx] ^= block_x[idx]; ++ } ++ ++ /* Return result to caller */ ++ DWC_MEMCPY(result, block_t, 8); ++ show_block(result, "CCM-MIC : ", NULL, 8); ++ ++} ++ ++/** ++ * The PRF function described in section 6.5 of the WUSB spec. This function ++ * concatenates MIC values returned from dwc_cmf() to create a value of ++ * the requested length. ++ * ++ * @param prf_len Length of the PRF function in bits (64, 128, or 256). ++ * @param key, nonce, label, bytes, len Same as for dwc_cmf(). ++ * @param result Byte array to receive the result. ++ */ ++void dwc_wusb_prf(int prf_len, u8 *key, ++ u8 *nonce, char *label, u8 *bytes, int len, u8 *result) ++{ ++ int i; ++ ++ nonce[0] = 0; ++ for (i = 0; i < prf_len >> 6; i++, nonce[0]++) { ++ dwc_wusb_cmf(key, nonce, label, bytes, len, result); ++ result += 8; ++ } ++} ++ ++/** ++ * Fills in CCM Nonce per the WUSB spec. ++ * ++ * @param[in] haddr Host address. ++ * @param[in] daddr Device address. ++ * @param[in] tkid Session Key(PTK) identifier. ++ * @param[out] nonce Pointer to where the CCM Nonce output is to be written. ++ */ ++void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid, ++ uint8_t *nonce) ++{ ++ ++ DWC_DEBUG("%s %x %x\n", __func__, daddr, haddr); ++ ++ DWC_MEMSET(&nonce[0], 0, 16); ++ ++ DWC_MEMCPY(&nonce[6], tkid, 3); ++ nonce[9] = daddr & 0xFF; ++ nonce[10] = (daddr >> 8) & 0xFF; ++ nonce[11] = haddr & 0xFF; ++ nonce[12] = (haddr >> 8) & 0xFF; ++ ++ dump_bytes("CCM nonce", nonce, 16); ++} ++ ++/** ++ * Generates a 16-byte cryptographic-grade random number for the Host/Device ++ * Nonce. ++ */ ++void dwc_wusb_gen_nonce(uint16_t addr, uint8_t *nonce) ++{ ++ uint8_t inonce[16]; ++ uint32_t temp[4]; ++ ++ /* Fill in the Nonce */ ++ DWC_MEMSET(&inonce[0], 0, sizeof(inonce)); ++ inonce[9] = addr & 0xFF; ++ inonce[10] = (addr >> 8) & 0xFF; ++ inonce[11] = inonce[9]; ++ inonce[12] = inonce[10]; ++ ++ /* Collect "randomness samples" */ ++ DWC_RANDOM_BYTES((uint8_t *)temp, 16); ++ ++ dwc_wusb_prf_128((uint8_t *)temp, nonce, ++ "Random Numbers", (uint8_t *)temp, sizeof(temp), ++ nonce); ++} ++ ++/** ++ * Generates the Session Key (PTK) and Key Confirmation Key (KCK) per the ++ * WUSB spec. ++ * ++ * @param[in] ccm_nonce Pointer to CCM Nonce. ++ * @param[in] mk Master Key to derive the session from ++ * @param[in] hnonce Pointer to Host Nonce. ++ * @param[in] dnonce Pointer to Device Nonce. ++ * @param[out] kck Pointer to where the KCK output is to be written. ++ * @param[out] ptk Pointer to where the PTK output is to be written. ++ */ ++void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk, uint8_t *hnonce, ++ uint8_t *dnonce, uint8_t *kck, uint8_t *ptk) ++{ ++ uint8_t idata[32]; ++ uint8_t odata[32]; ++ ++ dump_bytes("ck", mk, 16); ++ dump_bytes("hnonce", hnonce, 16); ++ dump_bytes("dnonce", dnonce, 16); ++ ++ /* The data is the HNonce and DNonce concatenated */ ++ DWC_MEMCPY(&idata[0], hnonce, 16); ++ DWC_MEMCPY(&idata[16], dnonce, 16); ++ ++ dwc_wusb_prf_256(mk, ccm_nonce, "Pair-wise keys", idata, 32, odata); ++ ++ /* Low 16 bytes of the result is the KCK, high 16 is the PTK */ ++ DWC_MEMCPY(kck, &odata[0], 16); ++ DWC_MEMCPY(ptk, &odata[16], 16); ++ ++ dump_bytes("kck", kck, 16); ++ dump_bytes("ptk", ptk, 16); ++} ++ ++/** ++ * Generates the Message Integrity Code over the Handshake data per the ++ * WUSB spec. ++ * ++ * @param ccm_nonce Pointer to CCM Nonce. ++ * @param kck Pointer to Key Confirmation Key. ++ * @param data Pointer to Handshake data to be checked. ++ * @param mic Pointer to where the MIC output is to be written. ++ */ ++void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t *kck, ++ uint8_t *data, uint8_t *mic) ++{ ++ ++ dwc_wusb_prf_64(kck, ccm_nonce, "out-of-bandMIC", ++ data, WUSB_HANDSHAKE_LEN_FOR_MIC, mic); ++} ++ ++#endif /* DWC_CRYPTOLIB */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_crypto.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_crypto.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,111 @@ ++/* ========================================================================= ++ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_crypto.h $ ++ * $Revision: #3 $ ++ * $Date: 2010/09/28 $ ++ * $Change: 1596182 $ ++ * ++ * Synopsys Portability Library Software and documentation ++ * (hereinafter, "Software") is an Unsupported proprietary work of ++ * Synopsys, Inc. unless otherwise expressly agreed to in writing ++ * between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product ++ * under any End User Software License Agreement or Agreement for ++ * Licensed Product with Synopsys or any supplement thereto. You are ++ * permitted to use and redistribute this Software in source and binary ++ * forms, with or without modification, provided that redistributions ++ * of source code must retain this notice. You may not view, use, ++ * disclose, copy or distribute this file or any information contained ++ * herein except pursuant to this license grant from Synopsys. If you ++ * do not agree with this notice, including the disclaimer below, then ++ * you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" ++ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL ++ * SYNOPSYS 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. ++ * ========================================================================= */ ++ ++#ifndef _DWC_CRYPTO_H_ ++#define _DWC_CRYPTO_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/** @file ++ * ++ * This file contains declarations for the WUSB Cryptographic routines as ++ * defined in the WUSB spec. They are only to be used internally by the DWC UWB ++ * modules. ++ */ ++ ++#include "dwc_os.h" ++ ++int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst); ++ ++void dwc_wusb_cmf(u8 *key, u8 *nonce, ++ char *label, u8 *bytes, int len, u8 *result); ++void dwc_wusb_prf(int prf_len, u8 *key, ++ u8 *nonce, char *label, u8 *bytes, int len, u8 *result); ++ ++/** ++ * The PRF-64 function described in section 6.5 of the WUSB spec. ++ * ++ * @param key, nonce, label, bytes, len, result Same as for dwc_prf(). ++ */ ++static inline void dwc_wusb_prf_64(u8 *key, u8 *nonce, ++ char *label, u8 *bytes, int len, u8 *result) ++{ ++ dwc_wusb_prf(64, key, nonce, label, bytes, len, result); ++} ++ ++/** ++ * The PRF-128 function described in section 6.5 of the WUSB spec. ++ * ++ * @param key, nonce, label, bytes, len, result Same as for dwc_prf(). ++ */ ++static inline void dwc_wusb_prf_128(u8 *key, u8 *nonce, ++ char *label, u8 *bytes, int len, u8 *result) ++{ ++ dwc_wusb_prf(128, key, nonce, label, bytes, len, result); ++} ++ ++/** ++ * The PRF-256 function described in section 6.5 of the WUSB spec. ++ * ++ * @param key, nonce, label, bytes, len, result Same as for dwc_prf(). ++ */ ++static inline void dwc_wusb_prf_256(u8 *key, u8 *nonce, ++ char *label, u8 *bytes, int len, u8 *result) ++{ ++ dwc_wusb_prf(256, key, nonce, label, bytes, len, result); ++} ++ ++ ++void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid, ++ uint8_t *nonce); ++void dwc_wusb_gen_nonce(uint16_t addr, ++ uint8_t *nonce); ++ ++void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk, ++ uint8_t *hnonce, uint8_t *dnonce, ++ uint8_t *kck, uint8_t *ptk); ++ ++ ++void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t ++ *kck, uint8_t *data, uint8_t *mic); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _DWC_CRYPTO_H_ */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_dh.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_dh.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,291 @@ ++/* ========================================================================= ++ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_dh.c $ ++ * $Revision: #3 $ ++ * $Date: 2010/09/28 $ ++ * $Change: 1596182 $ ++ * ++ * Synopsys Portability Library Software and documentation ++ * (hereinafter, "Software") is an Unsupported proprietary work of ++ * Synopsys, Inc. unless otherwise expressly agreed to in writing ++ * between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product ++ * under any End User Software License Agreement or Agreement for ++ * Licensed Product with Synopsys or any supplement thereto. You are ++ * permitted to use and redistribute this Software in source and binary ++ * forms, with or without modification, provided that redistributions ++ * of source code must retain this notice. You may not view, use, ++ * disclose, copy or distribute this file or any information contained ++ * herein except pursuant to this license grant from Synopsys. If you ++ * do not agree with this notice, including the disclaimer below, then ++ * you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" ++ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL ++ * SYNOPSYS 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. ++ * ========================================================================= */ ++#ifdef DWC_CRYPTOLIB ++ ++#ifndef CONFIG_MACH_IPMATE ++ ++#include "dwc_dh.h" ++#include "dwc_modpow.h" ++ ++#ifdef DEBUG ++/* This function prints out a buffer in the format described in the Association ++ * Model specification. */ ++static void dh_dump(char *str, void *_num, int len) ++{ ++ uint8_t *num = _num; ++ int i; ++ DWC_PRINTF("%s\n", str); ++ for (i = 0; i < len; i ++) { ++ DWC_PRINTF("%02x", num[i]); ++ if (((i + 1) % 2) == 0) DWC_PRINTF(" "); ++ if (((i + 1) % 26) == 0) DWC_PRINTF("\n"); ++ } ++ ++ DWC_PRINTF("\n"); ++} ++#else ++#define dh_dump(_x...) do {; } while(0) ++#endif ++ ++/* Constant g value */ ++static __u32 dh_g[] = { ++ 0x02000000, ++}; ++ ++/* Constant p value */ ++static __u32 dh_p[] = { ++ 0xFFFFFFFF, 0xFFFFFFFF, 0xA2DA0FC9, 0x34C26821, 0x8B62C6C4, 0xD11CDC80, 0x084E0229, 0x74CC678A, ++ 0xA6BE0B02, 0x229B133B, 0x79084A51, 0xDD04348E, 0xB31995EF, 0x1B433ACD, 0x6D0A2B30, 0x37145FF2, ++ 0x6D35E14F, 0x45C2516D, 0x76B585E4, 0xC67E5E62, 0xE9424CF4, 0x6BED37A6, 0xB65CFF0B, 0xEDB706F4, ++ 0xFB6B38EE, 0xA59F895A, 0x11249FAE, 0xE61F4B7C, 0x51662849, 0x3D5BE4EC, 0xB87C00C2, 0x05BF63A1, ++ 0x3648DA98, 0x9AD3551C, 0xA83F1669, 0x5FCF24FD, 0x235D6583, 0x96ADA3DC, 0x56F3621C, 0xBB528520, ++ 0x0729D59E, 0x6D969670, 0x4E350C67, 0x0498BC4A, 0x086C74F1, 0x7C2118CA, 0x465E9032, 0x3BCE362E, ++ 0x2C779EE3, 0x03860E18, 0xA283279B, 0x8FA207EC, 0xF05DC5B5, 0xC9524C6F, 0xF6CB2BDE, 0x18175895, ++ 0x7C499539, 0xE56A95EA, 0x1826D215, 0x1005FA98, 0x5A8E7215, 0x2DC4AA8A, 0x0D1733AD, 0x337A5004, ++ 0xAB2155A8, 0x64BA1CDF, 0x0485FBEC, 0x0AEFDB58, 0x5771EA8A, 0x7D0C065D, 0x850F97B3, 0xC7E4E1A6, ++ 0x8CAEF5AB, 0xD73309DB, 0xE0948C1E, 0x9D61254A, 0x26D2E3CE, 0x6BEED21A, 0x06FA2FF1, 0x64088AD9, ++ 0x730276D8, 0x646AC83E, 0x182B1F52, 0x0C207B17, 0x5717E1BB, 0x6C5D617A, 0xC0880977, 0xE246D9BA, ++ 0xA04FE208, 0x31ABE574, 0xFC5BDB43, 0x8E10FDE0, 0x20D1824B, 0xCAD23AA9, 0xFFFFFFFF, 0xFFFFFFFF, ++}; ++ ++static void dh_swap_bytes(void *_in, void *_out, uint32_t len) ++{ ++ uint8_t *in = _in; ++ uint8_t *out = _out; ++ int i; ++ for (i=0; inext = (link); \ ++ (link)->prev = (link); \ ++} while (0) ++ ++#define DWC_LIST_FIRST(link) ((link)->next) ++#define DWC_LIST_LAST(link) ((link)->prev) ++#define DWC_LIST_END(link) (link) ++#define DWC_LIST_NEXT(link) ((link)->next) ++#define DWC_LIST_PREV(link) ((link)->prev) ++#define DWC_LIST_EMPTY(link) \ ++ (DWC_LIST_FIRST(link) == DWC_LIST_END(link)) ++#define DWC_LIST_ENTRY(link, type, field) \ ++ (type *)((uint8_t *)(link) - (size_t)(&((type *)0)->field)) ++ ++#if 0 ++#define DWC_LIST_INSERT_HEAD(list, link) do { \ ++ (link)->next = (list)->next; \ ++ (link)->prev = (list); \ ++ (list)->next->prev = (link); \ ++ (list)->next = (link); \ ++} while (0) ++ ++#define DWC_LIST_INSERT_TAIL(list, link) do { \ ++ (link)->next = (list); \ ++ (link)->prev = (list)->prev; \ ++ (list)->prev->next = (link); \ ++ (list)->prev = (link); \ ++} while (0) ++#else ++#define DWC_LIST_INSERT_HEAD(list, link) do { \ ++ dwc_list_link_t *__next__ = (list)->next; \ ++ __next__->prev = (link); \ ++ (link)->next = __next__; \ ++ (link)->prev = (list); \ ++ (list)->next = (link); \ ++} while (0) ++ ++#define DWC_LIST_INSERT_TAIL(list, link) do { \ ++ dwc_list_link_t *__prev__ = (list)->prev; \ ++ (list)->prev = (link); \ ++ (link)->next = (list); \ ++ (link)->prev = __prev__; \ ++ __prev__->next = (link); \ ++} while (0) ++#endif ++ ++#if 0 ++static inline void __list_add(struct list_head *new, ++ struct list_head *prev, ++ struct list_head *next) ++{ ++ next->prev = new; ++ new->next = next; ++ new->prev = prev; ++ prev->next = new; ++} ++ ++static inline void list_add(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head, head->next); ++} ++ ++static inline void list_add_tail(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head->prev, head); ++} ++ ++static inline void __list_del(struct list_head * prev, struct list_head * next) ++{ ++ next->prev = prev; ++ prev->next = next; ++} ++ ++static inline void list_del(struct list_head *entry) ++{ ++ __list_del(entry->prev, entry->next); ++ entry->next = LIST_POISON1; ++ entry->prev = LIST_POISON2; ++} ++#endif ++ ++#define DWC_LIST_REMOVE(link) do { \ ++ (link)->next->prev = (link)->prev; \ ++ (link)->prev->next = (link)->next; \ ++} while (0) ++ ++#define DWC_LIST_REMOVE_INIT(link) do { \ ++ DWC_LIST_REMOVE(link); \ ++ DWC_LIST_INIT(link); \ ++} while (0) ++ ++#define DWC_LIST_MOVE_HEAD(list, link) do { \ ++ DWC_LIST_REMOVE(link); \ ++ DWC_LIST_INSERT_HEAD(list, link); \ ++} while (0) ++ ++#define DWC_LIST_MOVE_TAIL(list, link) do { \ ++ DWC_LIST_REMOVE(link); \ ++ DWC_LIST_INSERT_TAIL(list, link); \ ++} while (0) ++ ++#define DWC_LIST_FOREACH(var, list) \ ++ for((var) = DWC_LIST_FIRST(list); \ ++ (var) != DWC_LIST_END(list); \ ++ (var) = DWC_LIST_NEXT(var)) ++ ++#define DWC_LIST_FOREACH_SAFE(var, var2, list) \ ++ for((var) = DWC_LIST_FIRST(list), (var2) = DWC_LIST_NEXT(var); \ ++ (var) != DWC_LIST_END(list); \ ++ (var) = (var2), (var2) = DWC_LIST_NEXT(var2)) ++ ++#define DWC_LIST_FOREACH_REVERSE(var, list) \ ++ for((var) = DWC_LIST_LAST(list); \ ++ (var) != DWC_LIST_END(list); \ ++ (var) = DWC_LIST_PREV(var)) ++ ++/* ++ * Singly-linked List definitions. ++ */ ++#define DWC_SLIST_HEAD(name, type) \ ++struct name { \ ++ struct type *slh_first; /* first element */ \ ++} ++ ++#define DWC_SLIST_HEAD_INITIALIZER(head) \ ++ { NULL } ++ ++#define DWC_SLIST_ENTRY(type) \ ++struct { \ ++ struct type *sle_next; /* next element */ \ ++} ++ ++/* ++ * Singly-linked List access methods. ++ */ ++#define DWC_SLIST_FIRST(head) ((head)->slh_first) ++#define DWC_SLIST_END(head) NULL ++#define DWC_SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) ++#define DWC_SLIST_NEXT(elm, field) ((elm)->field.sle_next) ++ ++#define DWC_SLIST_FOREACH(var, head, field) \ ++ for((var) = SLIST_FIRST(head); \ ++ (var) != SLIST_END(head); \ ++ (var) = SLIST_NEXT(var, field)) ++ ++#define DWC_SLIST_FOREACH_PREVPTR(var, varp, head, field) \ ++ for((varp) = &SLIST_FIRST((head)); \ ++ ((var) = *(varp)) != SLIST_END(head); \ ++ (varp) = &SLIST_NEXT((var), field)) ++ ++/* ++ * Singly-linked List functions. ++ */ ++#define DWC_SLIST_INIT(head) { \ ++ SLIST_FIRST(head) = SLIST_END(head); \ ++} ++ ++#define DWC_SLIST_INSERT_AFTER(slistelm, elm, field) do { \ ++ (elm)->field.sle_next = (slistelm)->field.sle_next; \ ++ (slistelm)->field.sle_next = (elm); \ ++} while (0) ++ ++#define DWC_SLIST_INSERT_HEAD(head, elm, field) do { \ ++ (elm)->field.sle_next = (head)->slh_first; \ ++ (head)->slh_first = (elm); \ ++} while (0) ++ ++#define DWC_SLIST_REMOVE_NEXT(head, elm, field) do { \ ++ (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ ++} while (0) ++ ++#define DWC_SLIST_REMOVE_HEAD(head, field) do { \ ++ (head)->slh_first = (head)->slh_first->field.sle_next; \ ++} while (0) ++ ++#define DWC_SLIST_REMOVE(head, elm, type, field) do { \ ++ if ((head)->slh_first == (elm)) { \ ++ SLIST_REMOVE_HEAD((head), field); \ ++ } \ ++ else { \ ++ struct type *curelm = (head)->slh_first; \ ++ while( curelm->field.sle_next != (elm) ) \ ++ curelm = curelm->field.sle_next; \ ++ curelm->field.sle_next = \ ++ curelm->field.sle_next->field.sle_next; \ ++ } \ ++} while (0) ++ ++/* ++ * Simple queue definitions. ++ */ ++#define DWC_SIMPLEQ_HEAD(name, type) \ ++struct name { \ ++ struct type *sqh_first; /* first element */ \ ++ struct type **sqh_last; /* addr of last next element */ \ ++} ++ ++#define DWC_SIMPLEQ_HEAD_INITIALIZER(head) \ ++ { NULL, &(head).sqh_first } ++ ++#define DWC_SIMPLEQ_ENTRY(type) \ ++struct { \ ++ struct type *sqe_next; /* next element */ \ ++} ++ ++/* ++ * Simple queue access methods. ++ */ ++#define DWC_SIMPLEQ_FIRST(head) ((head)->sqh_first) ++#define DWC_SIMPLEQ_END(head) NULL ++#define DWC_SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) ++#define DWC_SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) ++ ++#define DWC_SIMPLEQ_FOREACH(var, head, field) \ ++ for((var) = SIMPLEQ_FIRST(head); \ ++ (var) != SIMPLEQ_END(head); \ ++ (var) = SIMPLEQ_NEXT(var, field)) ++ ++/* ++ * Simple queue functions. ++ */ ++#define DWC_SIMPLEQ_INIT(head) do { \ ++ (head)->sqh_first = NULL; \ ++ (head)->sqh_last = &(head)->sqh_first; \ ++} while (0) ++ ++#define DWC_SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ ++ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ ++ (head)->sqh_last = &(elm)->field.sqe_next; \ ++ (head)->sqh_first = (elm); \ ++} while (0) ++ ++#define DWC_SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ ++ (elm)->field.sqe_next = NULL; \ ++ *(head)->sqh_last = (elm); \ ++ (head)->sqh_last = &(elm)->field.sqe_next; \ ++} while (0) ++ ++#define DWC_SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ ++ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ ++ (head)->sqh_last = &(elm)->field.sqe_next; \ ++ (listelm)->field.sqe_next = (elm); \ ++} while (0) ++ ++#define DWC_SIMPLEQ_REMOVE_HEAD(head, field) do { \ ++ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ ++ (head)->sqh_last = &(head)->sqh_first; \ ++} while (0) ++ ++/* ++ * Tail queue definitions. ++ */ ++#define DWC_TAILQ_HEAD(name, type) \ ++struct name { \ ++ struct type *tqh_first; /* first element */ \ ++ struct type **tqh_last; /* addr of last next element */ \ ++} ++ ++#define DWC_TAILQ_HEAD_INITIALIZER(head) \ ++ { NULL, &(head).tqh_first } ++ ++#define DWC_TAILQ_ENTRY(type) \ ++struct { \ ++ struct type *tqe_next; /* next element */ \ ++ struct type **tqe_prev; /* address of previous next element */ \ ++} ++ ++/* ++ * tail queue access methods ++ */ ++#define DWC_TAILQ_FIRST(head) ((head)->tqh_first) ++#define DWC_TAILQ_END(head) NULL ++#define DWC_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) ++#define DWC_TAILQ_LAST(head, headname) \ ++ (*(((struct headname *)((head)->tqh_last))->tqh_last)) ++/* XXX */ ++#define DWC_TAILQ_PREV(elm, headname, field) \ ++ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) ++#define DWC_TAILQ_EMPTY(head) \ ++ (TAILQ_FIRST(head) == TAILQ_END(head)) ++ ++#define DWC_TAILQ_FOREACH(var, head, field) \ ++ for((var) = TAILQ_FIRST(head); \ ++ (var) != TAILQ_END(head); \ ++ (var) = TAILQ_NEXT(var, field)) ++ ++#define DWC_TAILQ_FOREACH_REVERSE(var, head, headname, field) \ ++ for((var) = TAILQ_LAST(head, headname); \ ++ (var) != TAILQ_END(head); \ ++ (var) = TAILQ_PREV(var, headname, field)) ++ ++/* ++ * Tail queue functions. ++ */ ++#define DWC_TAILQ_INIT(head) do { \ ++ (head)->tqh_first = NULL; \ ++ (head)->tqh_last = &(head)->tqh_first; \ ++} while (0) ++ ++#define DWC_TAILQ_INSERT_HEAD(head, elm, field) do { \ ++ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ ++ (head)->tqh_first->field.tqe_prev = \ ++ &(elm)->field.tqe_next; \ ++ else \ ++ (head)->tqh_last = &(elm)->field.tqe_next; \ ++ (head)->tqh_first = (elm); \ ++ (elm)->field.tqe_prev = &(head)->tqh_first; \ ++} while (0) ++ ++#define DWC_TAILQ_INSERT_TAIL(head, elm, field) do { \ ++ (elm)->field.tqe_next = NULL; \ ++ (elm)->field.tqe_prev = (head)->tqh_last; \ ++ *(head)->tqh_last = (elm); \ ++ (head)->tqh_last = &(elm)->field.tqe_next; \ ++} while (0) ++ ++#define DWC_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ ++ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ ++ (elm)->field.tqe_next->field.tqe_prev = \ ++ &(elm)->field.tqe_next; \ ++ else \ ++ (head)->tqh_last = &(elm)->field.tqe_next; \ ++ (listelm)->field.tqe_next = (elm); \ ++ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ ++} while (0) ++ ++#define DWC_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ ++ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ ++ (elm)->field.tqe_next = (listelm); \ ++ *(listelm)->field.tqe_prev = (elm); \ ++ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ ++} while (0) ++ ++#define DWC_TAILQ_REMOVE(head, elm, field) do { \ ++ if (((elm)->field.tqe_next) != NULL) \ ++ (elm)->field.tqe_next->field.tqe_prev = \ ++ (elm)->field.tqe_prev; \ ++ else \ ++ (head)->tqh_last = (elm)->field.tqe_prev; \ ++ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ ++} while (0) ++ ++#define DWC_TAILQ_REPLACE(head, elm, elm2, field) do { \ ++ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ ++ (elm2)->field.tqe_next->field.tqe_prev = \ ++ &(elm2)->field.tqe_next; \ ++ else \ ++ (head)->tqh_last = &(elm2)->field.tqe_next; \ ++ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ ++ *(elm2)->field.tqe_prev = (elm2); \ ++} while (0) ++ ++/* ++ * Circular queue definitions. ++ */ ++#define DWC_CIRCLEQ_HEAD(name, type) \ ++struct name { \ ++ struct type *cqh_first; /* first element */ \ ++ struct type *cqh_last; /* last element */ \ ++} ++ ++#define DWC_CIRCLEQ_HEAD_INITIALIZER(head) \ ++ { DWC_CIRCLEQ_END(&head), DWC_CIRCLEQ_END(&head) } ++ ++#define DWC_CIRCLEQ_ENTRY(type) \ ++struct { \ ++ struct type *cqe_next; /* next element */ \ ++ struct type *cqe_prev; /* previous element */ \ ++} ++ ++/* ++ * Circular queue access methods ++ */ ++#define DWC_CIRCLEQ_FIRST(head) ((head)->cqh_first) ++#define DWC_CIRCLEQ_LAST(head) ((head)->cqh_last) ++#define DWC_CIRCLEQ_END(head) ((void *)(head)) ++#define DWC_CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) ++#define DWC_CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) ++#define DWC_CIRCLEQ_EMPTY(head) \ ++ (DWC_CIRCLEQ_FIRST(head) == DWC_CIRCLEQ_END(head)) ++ ++#define DWC_CIRCLEQ_EMPTY_ENTRY(elm, field) (((elm)->field.cqe_next == NULL) && ((elm)->field.cqe_prev == NULL)) ++ ++#define DWC_CIRCLEQ_FOREACH(var, head, field) \ ++ for((var) = DWC_CIRCLEQ_FIRST(head); \ ++ (var) != DWC_CIRCLEQ_END(head); \ ++ (var) = DWC_CIRCLEQ_NEXT(var, field)) ++ ++#define DWC_CIRCLEQ_FOREACH_SAFE(var, var2, head, field) \ ++ for((var) = DWC_CIRCLEQ_FIRST(head), var2 = DWC_CIRCLEQ_NEXT(var, field); \ ++ (var) != DWC_CIRCLEQ_END(head); \ ++ (var) = var2, var2 = DWC_CIRCLEQ_NEXT(var, field)) ++ ++#define DWC_CIRCLEQ_FOREACH_REVERSE(var, head, field) \ ++ for((var) = DWC_CIRCLEQ_LAST(head); \ ++ (var) != DWC_CIRCLEQ_END(head); \ ++ (var) = DWC_CIRCLEQ_PREV(var, field)) ++ ++/* ++ * Circular queue functions. ++ */ ++#define DWC_CIRCLEQ_INIT(head) do { \ ++ (head)->cqh_first = DWC_CIRCLEQ_END(head); \ ++ (head)->cqh_last = DWC_CIRCLEQ_END(head); \ ++} while (0) ++ ++#define DWC_CIRCLEQ_INIT_ENTRY(elm, field) do { \ ++ (elm)->field.cqe_next = NULL; \ ++ (elm)->field.cqe_prev = NULL; \ ++} while (0) ++ ++#define DWC_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ ++ (elm)->field.cqe_next = (listelm)->field.cqe_next; \ ++ (elm)->field.cqe_prev = (listelm); \ ++ if ((listelm)->field.cqe_next == DWC_CIRCLEQ_END(head)) \ ++ (head)->cqh_last = (elm); \ ++ else \ ++ (listelm)->field.cqe_next->field.cqe_prev = (elm); \ ++ (listelm)->field.cqe_next = (elm); \ ++} while (0) ++ ++#define DWC_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ ++ (elm)->field.cqe_next = (listelm); \ ++ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ ++ if ((listelm)->field.cqe_prev == DWC_CIRCLEQ_END(head)) \ ++ (head)->cqh_first = (elm); \ ++ else \ ++ (listelm)->field.cqe_prev->field.cqe_next = (elm); \ ++ (listelm)->field.cqe_prev = (elm); \ ++} while (0) ++ ++#define DWC_CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ ++ (elm)->field.cqe_next = (head)->cqh_first; \ ++ (elm)->field.cqe_prev = DWC_CIRCLEQ_END(head); \ ++ if ((head)->cqh_last == DWC_CIRCLEQ_END(head)) \ ++ (head)->cqh_last = (elm); \ ++ else \ ++ (head)->cqh_first->field.cqe_prev = (elm); \ ++ (head)->cqh_first = (elm); \ ++} while (0) ++ ++#define DWC_CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ ++ (elm)->field.cqe_next = DWC_CIRCLEQ_END(head); \ ++ (elm)->field.cqe_prev = (head)->cqh_last; \ ++ if ((head)->cqh_first == DWC_CIRCLEQ_END(head)) \ ++ (head)->cqh_first = (elm); \ ++ else \ ++ (head)->cqh_last->field.cqe_next = (elm); \ ++ (head)->cqh_last = (elm); \ ++} while (0) ++ ++#define DWC_CIRCLEQ_REMOVE(head, elm, field) do { \ ++ if ((elm)->field.cqe_next == DWC_CIRCLEQ_END(head)) \ ++ (head)->cqh_last = (elm)->field.cqe_prev; \ ++ else \ ++ (elm)->field.cqe_next->field.cqe_prev = \ ++ (elm)->field.cqe_prev; \ ++ if ((elm)->field.cqe_prev == DWC_CIRCLEQ_END(head)) \ ++ (head)->cqh_first = (elm)->field.cqe_next; \ ++ else \ ++ (elm)->field.cqe_prev->field.cqe_next = \ ++ (elm)->field.cqe_next; \ ++} while (0) ++ ++#define DWC_CIRCLEQ_REMOVE_INIT(head, elm, field) do { \ ++ DWC_CIRCLEQ_REMOVE(head, elm, field); \ ++ DWC_CIRCLEQ_INIT_ENTRY(elm, field); \ ++} while (0) ++ ++#define DWC_CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ ++ if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ ++ DWC_CIRCLEQ_END(head)) \ ++ (head).cqh_last = (elm2); \ ++ else \ ++ (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ ++ if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ ++ DWC_CIRCLEQ_END(head)) \ ++ (head).cqh_first = (elm2); \ ++ else \ ++ (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ ++} while (0) ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _DWC_LIST_H_ */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_mem.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_mem.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,245 @@ ++/* Memory Debugging */ ++#ifdef DWC_DEBUG_MEMORY ++ ++#include "dwc_os.h" ++#include "dwc_list.h" ++ ++struct allocation { ++ void *addr; ++ void *ctx; ++ char *func; ++ int line; ++ uint32_t size; ++ int dma; ++ DWC_CIRCLEQ_ENTRY(allocation) entry; ++}; ++ ++DWC_CIRCLEQ_HEAD(allocation_queue, allocation); ++ ++struct allocation_manager { ++ void *mem_ctx; ++ struct allocation_queue allocations; ++ ++ /* statistics */ ++ int num; ++ int num_freed; ++ int num_active; ++ uint32_t total; ++ uint32_t cur; ++ uint32_t max; ++}; ++ ++static struct allocation_manager *manager = NULL; ++ ++static int add_allocation(void *ctx, uint32_t size, char const *func, int line, void *addr, ++ int dma) ++{ ++ struct allocation *a; ++ ++ DWC_ASSERT(manager != NULL, "manager not allocated"); ++ ++ a = __DWC_ALLOC_ATOMIC(manager->mem_ctx, sizeof(*a)); ++ if (!a) { ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ a->func = __DWC_ALLOC_ATOMIC(manager->mem_ctx, DWC_STRLEN(func) + 1); ++ if (!a->func) { ++ __DWC_FREE(manager->mem_ctx, a); ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ DWC_MEMCPY(a->func, func, DWC_STRLEN(func) + 1); ++ a->addr = addr; ++ a->ctx = ctx; ++ a->line = line; ++ a->size = size; ++ a->dma = dma; ++ DWC_CIRCLEQ_INSERT_TAIL(&manager->allocations, a, entry); ++ ++ /* Update stats */ ++ manager->num++; ++ manager->num_active++; ++ manager->total += size; ++ manager->cur += size; ++ ++ if (manager->max < manager->cur) { ++ manager->max = manager->cur; ++ } ++ ++ return 0; ++} ++ ++static struct allocation *find_allocation(void *ctx, void *addr) ++{ ++ struct allocation *a; ++ ++ DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) { ++ if (a->ctx == ctx && a->addr == addr) { ++ return a; ++ } ++ } ++ ++ return NULL; ++} ++ ++static void free_allocation(void *ctx, void *addr, char const *func, int line) ++{ ++ struct allocation *a = find_allocation(ctx, addr); ++ ++ if (!a) { ++ DWC_ASSERT(0, ++ "Free of address %p that was never allocated or already freed %s:%d", ++ addr, func, line); ++ return; ++ } ++ ++ DWC_CIRCLEQ_REMOVE(&manager->allocations, a, entry); ++ ++ manager->num_active--; ++ manager->num_freed++; ++ manager->cur -= a->size; ++ __DWC_FREE(manager->mem_ctx, a->func); ++ __DWC_FREE(manager->mem_ctx, a); ++} ++ ++int dwc_memory_debug_start(void *mem_ctx) ++{ ++ DWC_ASSERT(manager == NULL, "Memory debugging has already started\n"); ++ ++ if (manager) { ++ return -DWC_E_BUSY; ++ } ++ ++ manager = __DWC_ALLOC(mem_ctx, sizeof(*manager)); ++ if (!manager) { ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ DWC_CIRCLEQ_INIT(&manager->allocations); ++ manager->mem_ctx = mem_ctx; ++ manager->num = 0; ++ manager->num_freed = 0; ++ manager->num_active = 0; ++ manager->total = 0; ++ manager->cur = 0; ++ manager->max = 0; ++ ++ return 0; ++} ++ ++void dwc_memory_debug_stop(void) ++{ ++ struct allocation *a; ++ ++ dwc_memory_debug_report(); ++ ++ DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) { ++ DWC_ERROR("Memory leaked from %s:%d\n", a->func, a->line); ++ free_allocation(a->ctx, a->addr, NULL, -1); ++ } ++ ++ __DWC_FREE(manager->mem_ctx, manager); ++} ++ ++void dwc_memory_debug_report(void) ++{ ++ struct allocation *a; ++ ++ DWC_PRINTF("\n\n\n----------------- Memory Debugging Report -----------------\n\n"); ++ DWC_PRINTF("Num Allocations = %d\n", manager->num); ++ DWC_PRINTF("Freed = %d\n", manager->num_freed); ++ DWC_PRINTF("Active = %d\n", manager->num_active); ++ DWC_PRINTF("Current Memory Used = %d\n", manager->cur); ++ DWC_PRINTF("Total Memory Used = %d\n", manager->total); ++ DWC_PRINTF("Maximum Memory Used at Once = %d\n", manager->max); ++ DWC_PRINTF("Unfreed allocations:\n"); ++ ++ DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) { ++ DWC_PRINTF(" addr=%p, size=%d from %s:%d, DMA=%d\n", ++ a->addr, a->size, a->func, a->line, a->dma); ++ } ++} ++ ++/* The replacement functions */ ++void *dwc_alloc_debug(void *mem_ctx, uint32_t size, char const *func, int line) ++{ ++ void *addr = __DWC_ALLOC(mem_ctx, size); ++ ++ if (!addr) { ++ return NULL; ++ } ++ ++ if (add_allocation(mem_ctx, size, func, line, addr, 0)) { ++ __DWC_FREE(mem_ctx, addr); ++ return NULL; ++ } ++ ++ return addr; ++} ++ ++void *dwc_alloc_atomic_debug(void *mem_ctx, uint32_t size, char const *func, ++ int line) ++{ ++ void *addr = __DWC_ALLOC_ATOMIC(mem_ctx, size); ++ ++ if (!addr) { ++ return NULL; ++ } ++ ++ if (add_allocation(mem_ctx, size, func, line, addr, 0)) { ++ __DWC_FREE(mem_ctx, addr); ++ return NULL; ++ } ++ ++ return addr; ++} ++ ++void dwc_free_debug(void *mem_ctx, void *addr, char const *func, int line) ++{ ++ free_allocation(mem_ctx, addr, func, line); ++ __DWC_FREE(mem_ctx, addr); ++} ++ ++void *dwc_dma_alloc_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr, ++ char const *func, int line) ++{ ++ void *addr = __DWC_DMA_ALLOC(dma_ctx, size, dma_addr); ++ ++ if (!addr) { ++ return NULL; ++ } ++ ++ if (add_allocation(dma_ctx, size, func, line, addr, 1)) { ++ __DWC_DMA_FREE(dma_ctx, size, addr, *dma_addr); ++ return NULL; ++ } ++ ++ return addr; ++} ++ ++void *dwc_dma_alloc_atomic_debug(void *dma_ctx, uint32_t size, ++ dwc_dma_t *dma_addr, char const *func, int line) ++{ ++ void *addr = __DWC_DMA_ALLOC_ATOMIC(dma_ctx, size, dma_addr); ++ ++ if (!addr) { ++ return NULL; ++ } ++ ++ if (add_allocation(dma_ctx, size, func, line, addr, 1)) { ++ __DWC_DMA_FREE(dma_ctx, size, addr, *dma_addr); ++ return NULL; ++ } ++ ++ return addr; ++} ++ ++void dwc_dma_free_debug(void *dma_ctx, uint32_t size, void *virt_addr, ++ dwc_dma_t dma_addr, char const *func, int line) ++{ ++ free_allocation(dma_ctx, virt_addr, func, line); ++ __DWC_DMA_FREE(dma_ctx, size, virt_addr, dma_addr); ++} ++ ++#endif /* DWC_DEBUG_MEMORY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_modpow.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_modpow.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,636 @@ ++/* Bignum routines adapted from PUTTY sources. PuTTY copyright notice follows. ++ * ++ * PuTTY is copyright 1997-2007 Simon Tatham. ++ * ++ * Portions copyright Robert de Bath, Joris van Rantwijk, Delian ++ * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, ++ * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus ++ * Kuhn, and CORE SDI S.A. ++ * ++ * Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation files ++ * (the "Software"), to deal in the Software without restriction, ++ * including without limitation the rights to use, copy, modify, merge, ++ * publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, ++ * subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE ++ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF ++ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++#ifdef DWC_CRYPTOLIB ++ ++#ifndef CONFIG_MACH_IPMATE ++ ++#include "dwc_modpow.h" ++ ++#define BIGNUM_INT_MASK 0xFFFFFFFFUL ++#define BIGNUM_TOP_BIT 0x80000000UL ++#define BIGNUM_INT_BITS 32 ++ ++ ++static void *snmalloc(void *mem_ctx, size_t n, size_t size) ++{ ++ void *p; ++ size *= n; ++ if (size == 0) size = 1; ++ p = dwc_alloc(mem_ctx, size); ++ return p; ++} ++ ++#define snewn(ctx, n, type) ((type *)snmalloc((ctx), (n), sizeof(type))) ++#define sfree dwc_free ++ ++/* ++ * Usage notes: ++ * * Do not call the DIVMOD_WORD macro with expressions such as array ++ * subscripts, as some implementations object to this (see below). ++ * * Note that none of the division methods below will cope if the ++ * quotient won't fit into BIGNUM_INT_BITS. Callers should be careful ++ * to avoid this case. ++ * If this condition occurs, in the case of the x86 DIV instruction, ++ * an overflow exception will occur, which (according to a correspondent) ++ * will manifest on Windows as something like ++ * 0xC0000095: Integer overflow ++ * The C variant won't give the right answer, either. ++ */ ++ ++#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2) ++ ++#if defined __GNUC__ && defined __i386__ ++#define DIVMOD_WORD(q, r, hi, lo, w) \ ++ __asm__("div %2" : \ ++ "=d" (r), "=a" (q) : \ ++ "r" (w), "d" (hi), "a" (lo)) ++#else ++#define DIVMOD_WORD(q, r, hi, lo, w) do { \ ++ BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \ ++ q = n / w; \ ++ r = n % w; \ ++} while (0) ++#endif ++ ++// q = n / w; ++// r = n % w; ++ ++#define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8) ++ ++#define BIGNUM_INTERNAL ++ ++static Bignum newbn(void *mem_ctx, int length) ++{ ++ Bignum b = snewn(mem_ctx, length + 1, BignumInt); ++ //if (!b) ++ //abort(); /* FIXME */ ++ DWC_MEMSET(b, 0, (length + 1) * sizeof(*b)); ++ b[0] = length; ++ return b; ++} ++ ++void freebn(void *mem_ctx, Bignum b) ++{ ++ /* ++ * Burn the evidence, just in case. ++ */ ++ DWC_MEMSET(b, 0, sizeof(b[0]) * (b[0] + 1)); ++ sfree(mem_ctx, b); ++} ++ ++/* ++ * Compute c = a * b. ++ * Input is in the first len words of a and b. ++ * Result is returned in the first 2*len words of c. ++ */ ++static void internal_mul(BignumInt *a, BignumInt *b, ++ BignumInt *c, int len) ++{ ++ int i, j; ++ BignumDblInt t; ++ ++ for (j = 0; j < 2 * len; j++) ++ c[j] = 0; ++ ++ for (i = len - 1; i >= 0; i--) { ++ t = 0; ++ for (j = len - 1; j >= 0; j--) { ++ t += MUL_WORD(a[i], (BignumDblInt) b[j]); ++ t += (BignumDblInt) c[i + j + 1]; ++ c[i + j + 1] = (BignumInt) t; ++ t = t >> BIGNUM_INT_BITS; ++ } ++ c[i] = (BignumInt) t; ++ } ++} ++ ++static void internal_add_shifted(BignumInt *number, ++ unsigned n, int shift) ++{ ++ int word = 1 + (shift / BIGNUM_INT_BITS); ++ int bshift = shift % BIGNUM_INT_BITS; ++ BignumDblInt addend; ++ ++ addend = (BignumDblInt)n << bshift; ++ ++ while (addend) { ++ addend += number[word]; ++ number[word] = (BignumInt) addend & BIGNUM_INT_MASK; ++ addend >>= BIGNUM_INT_BITS; ++ word++; ++ } ++} ++ ++/* ++ * Compute a = a % m. ++ * Input in first alen words of a and first mlen words of m. ++ * Output in first alen words of a ++ * (of which first alen-mlen words will be zero). ++ * The MSW of m MUST have its high bit set. ++ * Quotient is accumulated in the `quotient' array, which is a Bignum ++ * rather than the internal bigendian format. Quotient parts are shifted ++ * left by `qshift' before adding into quot. ++ */ ++static void internal_mod(BignumInt *a, int alen, ++ BignumInt *m, int mlen, ++ BignumInt *quot, int qshift) ++{ ++ BignumInt m0, m1; ++ unsigned int h; ++ int i, k; ++ ++ m0 = m[0]; ++ if (mlen > 1) ++ m1 = m[1]; ++ else ++ m1 = 0; ++ ++ for (i = 0; i <= alen - mlen; i++) { ++ BignumDblInt t; ++ unsigned int q, r, c, ai1; ++ ++ if (i == 0) { ++ h = 0; ++ } else { ++ h = a[i - 1]; ++ a[i - 1] = 0; ++ } ++ ++ if (i == alen - 1) ++ ai1 = 0; ++ else ++ ai1 = a[i + 1]; ++ ++ /* Find q = h:a[i] / m0 */ ++ if (h >= m0) { ++ /* ++ * Special case. ++ * ++ * To illustrate it, suppose a BignumInt is 8 bits, and ++ * we are dividing (say) A1:23:45:67 by A1:B2:C3. Then ++ * our initial division will be 0xA123 / 0xA1, which ++ * will give a quotient of 0x100 and a divide overflow. ++ * However, the invariants in this division algorithm ++ * are not violated, since the full number A1:23:... is ++ * _less_ than the quotient prefix A1:B2:... and so the ++ * following correction loop would have sorted it out. ++ * ++ * In this situation we set q to be the largest ++ * quotient we _can_ stomach (0xFF, of course). ++ */ ++ q = BIGNUM_INT_MASK; ++ } else { ++ /* Macro doesn't want an array subscript expression passed ++ * into it (see definition), so use a temporary. */ ++ BignumInt tmplo = a[i]; ++ DIVMOD_WORD(q, r, h, tmplo, m0); ++ ++ /* Refine our estimate of q by looking at ++ h:a[i]:a[i+1] / m0:m1 */ ++ t = MUL_WORD(m1, q); ++ if (t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) { ++ q--; ++ t -= m1; ++ r = (r + m0) & BIGNUM_INT_MASK; /* overflow? */ ++ if (r >= (BignumDblInt) m0 && ++ t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) q--; ++ } ++ } ++ ++ /* Subtract q * m from a[i...] */ ++ c = 0; ++ for (k = mlen - 1; k >= 0; k--) { ++ t = MUL_WORD(q, m[k]); ++ t += c; ++ c = (unsigned)(t >> BIGNUM_INT_BITS); ++ if ((BignumInt) t > a[i + k]) ++ c++; ++ a[i + k] -= (BignumInt) t; ++ } ++ ++ /* Add back m in case of borrow */ ++ if (c != h) { ++ t = 0; ++ for (k = mlen - 1; k >= 0; k--) { ++ t += m[k]; ++ t += a[i + k]; ++ a[i + k] = (BignumInt) t; ++ t = t >> BIGNUM_INT_BITS; ++ } ++ q--; ++ } ++ if (quot) ++ internal_add_shifted(quot, q, qshift + BIGNUM_INT_BITS * (alen - mlen - i)); ++ } ++} ++ ++/* ++ * Compute p % mod. ++ * The most significant word of mod MUST be non-zero. ++ * We assume that the result array is the same size as the mod array. ++ * We optionally write out a quotient if `quotient' is non-NULL. ++ * We can avoid writing out the result if `result' is NULL. ++ */ ++void bigdivmod(void *mem_ctx, Bignum p, Bignum mod, Bignum result, Bignum quotient) ++{ ++ BignumInt *n, *m; ++ int mshift; ++ int plen, mlen, i, j; ++ ++ /* Allocate m of size mlen, copy mod to m */ ++ /* We use big endian internally */ ++ mlen = mod[0]; ++ m = snewn(mem_ctx, mlen, BignumInt); ++ //if (!m) ++ //abort(); /* FIXME */ ++ for (j = 0; j < mlen; j++) ++ m[j] = mod[mod[0] - j]; ++ ++ /* Shift m left to make msb bit set */ ++ for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++) ++ if ((m[0] << mshift) & BIGNUM_TOP_BIT) ++ break; ++ if (mshift) { ++ for (i = 0; i < mlen - 1; i++) ++ m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift)); ++ m[mlen - 1] = m[mlen - 1] << mshift; ++ } ++ ++ plen = p[0]; ++ /* Ensure plen > mlen */ ++ if (plen <= mlen) ++ plen = mlen + 1; ++ ++ /* Allocate n of size plen, copy p to n */ ++ n = snewn(mem_ctx, plen, BignumInt); ++ //if (!n) ++ //abort(); /* FIXME */ ++ for (j = 0; j < plen; j++) ++ n[j] = 0; ++ for (j = 1; j <= (int)p[0]; j++) ++ n[plen - j] = p[j]; ++ ++ /* Main computation */ ++ internal_mod(n, plen, m, mlen, quotient, mshift); ++ ++ /* Fixup result in case the modulus was shifted */ ++ if (mshift) { ++ for (i = plen - mlen - 1; i < plen - 1; i++) ++ n[i] = (n[i] << mshift) | (n[i + 1] >> (BIGNUM_INT_BITS - mshift)); ++ n[plen - 1] = n[plen - 1] << mshift; ++ internal_mod(n, plen, m, mlen, quotient, 0); ++ for (i = plen - 1; i >= plen - mlen; i--) ++ n[i] = (n[i] >> mshift) | (n[i - 1] << (BIGNUM_INT_BITS - mshift)); ++ } ++ ++ /* Copy result to buffer */ ++ if (result) { ++ for (i = 1; i <= (int)result[0]; i++) { ++ int j = plen - i; ++ result[i] = j >= 0 ? n[j] : 0; ++ } ++ } ++ ++ /* Free temporary arrays */ ++ for (i = 0; i < mlen; i++) ++ m[i] = 0; ++ sfree(mem_ctx, m); ++ for (i = 0; i < plen; i++) ++ n[i] = 0; ++ sfree(mem_ctx, n); ++} ++ ++/* ++ * Simple remainder. ++ */ ++Bignum bigmod(void *mem_ctx, Bignum a, Bignum b) ++{ ++ Bignum r = newbn(mem_ctx, b[0]); ++ bigdivmod(mem_ctx, a, b, r, NULL); ++ return r; ++} ++ ++/* ++ * Compute (base ^ exp) % mod. ++ */ ++Bignum dwc_modpow(void *mem_ctx, Bignum base_in, Bignum exp, Bignum mod) ++{ ++ BignumInt *a, *b, *n, *m; ++ int mshift; ++ int mlen, i, j; ++ Bignum base, result; ++ ++ /* ++ * The most significant word of mod needs to be non-zero. It ++ * should already be, but let's make sure. ++ */ ++ //assert(mod[mod[0]] != 0); ++ ++ /* ++ * Make sure the base is smaller than the modulus, by reducing ++ * it modulo the modulus if not. ++ */ ++ base = bigmod(mem_ctx, base_in, mod); ++ ++ /* Allocate m of size mlen, copy mod to m */ ++ /* We use big endian internally */ ++ mlen = mod[0]; ++ m = snewn(mem_ctx, mlen, BignumInt); ++ //if (!m) ++ //abort(); /* FIXME */ ++ for (j = 0; j < mlen; j++) ++ m[j] = mod[mod[0] - j]; ++ ++ /* Shift m left to make msb bit set */ ++ for (mshift = 0; mshift < BIGNUM_INT_BITS - 1; mshift++) ++ if ((m[0] << mshift) & BIGNUM_TOP_BIT) ++ break; ++ if (mshift) { ++ for (i = 0; i < mlen - 1; i++) ++ m[i] = ++ (m[i] << mshift) | (m[i + 1] >> ++ (BIGNUM_INT_BITS - mshift)); ++ m[mlen - 1] = m[mlen - 1] << mshift; ++ } ++ ++ /* Allocate n of size mlen, copy base to n */ ++ n = snewn(mem_ctx, mlen, BignumInt); ++ //if (!n) ++ //abort(); /* FIXME */ ++ i = mlen - base[0]; ++ for (j = 0; j < i; j++) ++ n[j] = 0; ++ for (j = 0; j < base[0]; j++) ++ n[i + j] = base[base[0] - j]; ++ ++ /* Allocate a and b of size 2*mlen. Set a = 1 */ ++ a = snewn(mem_ctx, 2 * mlen, BignumInt); ++ //if (!a) ++ //abort(); /* FIXME */ ++ b = snewn(mem_ctx, 2 * mlen, BignumInt); ++ //if (!b) ++ //abort(); /* FIXME */ ++ for (i = 0; i < 2 * mlen; i++) ++ a[i] = 0; ++ a[2 * mlen - 1] = 1; ++ ++ /* Skip leading zero bits of exp. */ ++ i = 0; ++ j = BIGNUM_INT_BITS - 1; ++ while (i < exp[0] && (exp[exp[0] - i] & (1 << j)) == 0) { ++ j--; ++ if (j < 0) { ++ i++; ++ j = BIGNUM_INT_BITS - 1; ++ } ++ } ++ ++ /* Main computation */ ++ while (i < exp[0]) { ++ while (j >= 0) { ++ internal_mul(a + mlen, a + mlen, b, mlen); ++ internal_mod(b, mlen * 2, m, mlen, NULL, 0); ++ if ((exp[exp[0] - i] & (1 << j)) != 0) { ++ internal_mul(b + mlen, n, a, mlen); ++ internal_mod(a, mlen * 2, m, mlen, NULL, 0); ++ } else { ++ BignumInt *t; ++ t = a; ++ a = b; ++ b = t; ++ } ++ j--; ++ } ++ i++; ++ j = BIGNUM_INT_BITS - 1; ++ } ++ ++ /* Fixup result in case the modulus was shifted */ ++ if (mshift) { ++ for (i = mlen - 1; i < 2 * mlen - 1; i++) ++ a[i] = ++ (a[i] << mshift) | (a[i + 1] >> ++ (BIGNUM_INT_BITS - mshift)); ++ a[2 * mlen - 1] = a[2 * mlen - 1] << mshift; ++ internal_mod(a, mlen * 2, m, mlen, NULL, 0); ++ for (i = 2 * mlen - 1; i >= mlen; i--) ++ a[i] = ++ (a[i] >> mshift) | (a[i - 1] << ++ (BIGNUM_INT_BITS - mshift)); ++ } ++ ++ /* Copy result to buffer */ ++ result = newbn(mem_ctx, mod[0]); ++ for (i = 0; i < mlen; i++) ++ result[result[0] - i] = a[i + mlen]; ++ while (result[0] > 1 && result[result[0]] == 0) ++ result[0]--; ++ ++ /* Free temporary arrays */ ++ for (i = 0; i < 2 * mlen; i++) ++ a[i] = 0; ++ sfree(mem_ctx, a); ++ for (i = 0; i < 2 * mlen; i++) ++ b[i] = 0; ++ sfree(mem_ctx, b); ++ for (i = 0; i < mlen; i++) ++ m[i] = 0; ++ sfree(mem_ctx, m); ++ for (i = 0; i < mlen; i++) ++ n[i] = 0; ++ sfree(mem_ctx, n); ++ ++ freebn(mem_ctx, base); ++ ++ return result; ++} ++ ++ ++#ifdef UNITTEST ++ ++static __u32 dh_p[] = { ++ 96, ++ 0xFFFFFFFF, ++ 0xFFFFFFFF, ++ 0xA93AD2CA, ++ 0x4B82D120, ++ 0xE0FD108E, ++ 0x43DB5BFC, ++ 0x74E5AB31, ++ 0x08E24FA0, ++ 0xBAD946E2, ++ 0x770988C0, ++ 0x7A615D6C, ++ 0xBBE11757, ++ 0x177B200C, ++ 0x521F2B18, ++ 0x3EC86A64, ++ 0xD8760273, ++ 0xD98A0864, ++ 0xF12FFA06, ++ 0x1AD2EE6B, ++ 0xCEE3D226, ++ 0x4A25619D, ++ 0x1E8C94E0, ++ 0xDB0933D7, ++ 0xABF5AE8C, ++ 0xA6E1E4C7, ++ 0xB3970F85, ++ 0x5D060C7D, ++ 0x8AEA7157, ++ 0x58DBEF0A, ++ 0xECFB8504, ++ 0xDF1CBA64, ++ 0xA85521AB, ++ 0x04507A33, ++ 0xAD33170D, ++ 0x8AAAC42D, ++ 0x15728E5A, ++ 0x98FA0510, ++ 0x15D22618, ++ 0xEA956AE5, ++ 0x3995497C, ++ 0x95581718, ++ 0xDE2BCBF6, ++ 0x6F4C52C9, ++ 0xB5C55DF0, ++ 0xEC07A28F, ++ 0x9B2783A2, ++ 0x180E8603, ++ 0xE39E772C, ++ 0x2E36CE3B, ++ 0x32905E46, ++ 0xCA18217C, ++ 0xF1746C08, ++ 0x4ABC9804, ++ 0x670C354E, ++ 0x7096966D, ++ 0x9ED52907, ++ 0x208552BB, ++ 0x1C62F356, ++ 0xDCA3AD96, ++ 0x83655D23, ++ 0xFD24CF5F, ++ 0x69163FA8, ++ 0x1C55D39A, ++ 0x98DA4836, ++ 0xA163BF05, ++ 0xC2007CB8, ++ 0xECE45B3D, ++ 0x49286651, ++ 0x7C4B1FE6, ++ 0xAE9F2411, ++ 0x5A899FA5, ++ 0xEE386BFB, ++ 0xF406B7ED, ++ 0x0BFF5CB6, ++ 0xA637ED6B, ++ 0xF44C42E9, ++ 0x625E7EC6, ++ 0xE485B576, ++ 0x6D51C245, ++ 0x4FE1356D, ++ 0xF25F1437, ++ 0x302B0A6D, ++ 0xCD3A431B, ++ 0xEF9519B3, ++ 0x8E3404DD, ++ 0x514A0879, ++ 0x3B139B22, ++ 0x020BBEA6, ++ 0x8A67CC74, ++ 0x29024E08, ++ 0x80DC1CD1, ++ 0xC4C6628B, ++ 0x2168C234, ++ 0xC90FDAA2, ++ 0xFFFFFFFF, ++ 0xFFFFFFFF, ++}; ++ ++static __u32 dh_a[] = { ++ 8, ++ 0xdf367516, ++ 0x86459caa, ++ 0xe2d459a4, ++ 0xd910dae0, ++ 0x8a8b5e37, ++ 0x67ab31c6, ++ 0xf0b55ea9, ++ 0x440051d6, ++}; ++ ++static __u32 dh_b[] = { ++ 8, ++ 0xded92656, ++ 0xe07a048a, ++ 0x6fa452cd, ++ 0x2df89d30, ++ 0xc75f1b0f, ++ 0x8ce3578f, ++ 0x7980a324, ++ 0x5daec786, ++}; ++ ++static __u32 dh_g[] = { ++ 1, ++ 2, ++}; ++ ++int main(void) ++{ ++ int i; ++ __u32 *k; ++ k = dwc_modpow(NULL, dh_g, dh_a, dh_p); ++ ++ printf("\n\n"); ++ for (i=0; i> 16; ++ printf("%04x %04x ", m, l); ++ if (!((i + 1)%13)) printf("\n"); ++ } ++ printf("\n\n"); ++ ++ if ((k[0] == 0x60) && (k[1] == 0x28e490e5) && (k[0x60] == 0x5a0d3d4e)) { ++ printf("PASS\n\n"); ++ } ++ else { ++ printf("FAIL\n\n"); ++ } ++ ++} ++ ++#endif /* UNITTEST */ ++ ++#endif /* CONFIG_MACH_IPMATE */ ++ ++#endif /*DWC_CRYPTOLIB */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_modpow.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_modpow.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,34 @@ ++/* ++ * dwc_modpow.h ++ * See dwc_modpow.c for license and changes ++ */ ++#ifndef _DWC_MODPOW_H ++#define _DWC_MODPOW_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include "dwc_os.h" ++ ++/** @file ++ * ++ * This file defines the module exponentiation function which is only used ++ * internally by the DWC UWB modules for calculation of PKs during numeric ++ * association. The routine is taken from the PUTTY, an open source terminal ++ * emulator. The PUTTY License is preserved in the dwc_modpow.c file. ++ * ++ */ ++ ++typedef uint32_t BignumInt; ++typedef uint64_t BignumDblInt; ++typedef BignumInt *Bignum; ++ ++/* Compute modular exponentiaion */ ++extern Bignum dwc_modpow(void *mem_ctx, Bignum base_in, Bignum exp, Bignum mod); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _LINUX_BIGNUM_H */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_notifier.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_notifier.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,319 @@ ++#ifdef DWC_NOTIFYLIB ++ ++#include "dwc_notifier.h" ++#include "dwc_list.h" ++ ++typedef struct dwc_observer { ++ void *observer; ++ dwc_notifier_callback_t callback; ++ void *data; ++ char *notification; ++ DWC_CIRCLEQ_ENTRY(dwc_observer) list_entry; ++} observer_t; ++ ++DWC_CIRCLEQ_HEAD(observer_queue, dwc_observer); ++ ++typedef struct dwc_notifier { ++ void *mem_ctx; ++ void *object; ++ struct observer_queue observers; ++ DWC_CIRCLEQ_ENTRY(dwc_notifier) list_entry; ++} notifier_t; ++ ++DWC_CIRCLEQ_HEAD(notifier_queue, dwc_notifier); ++ ++typedef struct manager { ++ void *mem_ctx; ++ void *wkq_ctx; ++ dwc_workq_t *wq; ++// dwc_mutex_t *mutex; ++ struct notifier_queue notifiers; ++} manager_t; ++ ++static manager_t *manager = NULL; ++ ++static int create_manager(void *mem_ctx, void *wkq_ctx) ++{ ++ manager = dwc_alloc(mem_ctx, sizeof(manager_t)); ++ if (!manager) { ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ DWC_CIRCLEQ_INIT(&manager->notifiers); ++ ++ manager->wq = dwc_workq_alloc(wkq_ctx, "DWC Notification WorkQ"); ++ if (!manager->wq) { ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ return 0; ++} ++ ++static void free_manager(void) ++{ ++ dwc_workq_free(manager->wq); ++ ++ /* All notifiers must have unregistered themselves before this module ++ * can be removed. Hitting this assertion indicates a programmer ++ * error. */ ++ DWC_ASSERT(DWC_CIRCLEQ_EMPTY(&manager->notifiers), ++ "Notification manager being freed before all notifiers have been removed"); ++ dwc_free(manager->mem_ctx, manager); ++} ++ ++#ifdef DEBUG ++static void dump_manager(void) ++{ ++ notifier_t *n; ++ observer_t *o; ++ ++ DWC_ASSERT(manager, "Notification manager not found"); ++ ++ DWC_DEBUG("List of all notifiers and observers:\n"); ++ DWC_CIRCLEQ_FOREACH(n, &manager->notifiers, list_entry) { ++ DWC_DEBUG("Notifier %p has observers:\n", n->object); ++ DWC_CIRCLEQ_FOREACH(o, &n->observers, list_entry) { ++ DWC_DEBUG(" %p watching %s\n", o->observer, o->notification); ++ } ++ } ++} ++#else ++#define dump_manager(...) ++#endif ++ ++static observer_t *alloc_observer(void *mem_ctx, void *observer, char *notification, ++ dwc_notifier_callback_t callback, void *data) ++{ ++ observer_t *new_observer = dwc_alloc(mem_ctx, sizeof(observer_t)); ++ ++ if (!new_observer) { ++ return NULL; ++ } ++ ++ DWC_CIRCLEQ_INIT_ENTRY(new_observer, list_entry); ++ new_observer->observer = observer; ++ new_observer->notification = notification; ++ new_observer->callback = callback; ++ new_observer->data = data; ++ return new_observer; ++} ++ ++static void free_observer(void *mem_ctx, observer_t *observer) ++{ ++ dwc_free(mem_ctx, observer); ++} ++ ++static notifier_t *alloc_notifier(void *mem_ctx, void *object) ++{ ++ notifier_t *notifier; ++ ++ if (!object) { ++ return NULL; ++ } ++ ++ notifier = dwc_alloc(mem_ctx, sizeof(notifier_t)); ++ if (!notifier) { ++ return NULL; ++ } ++ ++ DWC_CIRCLEQ_INIT(¬ifier->observers); ++ DWC_CIRCLEQ_INIT_ENTRY(notifier, list_entry); ++ ++ notifier->mem_ctx = mem_ctx; ++ notifier->object = object; ++ return notifier; ++} ++ ++static void free_notifier(notifier_t *notifier) ++{ ++ observer_t *observer; ++ ++ DWC_CIRCLEQ_FOREACH(observer, ¬ifier->observers, list_entry) { ++ free_observer(notifier->mem_ctx, observer); ++ } ++ ++ dwc_free(notifier->mem_ctx, notifier); ++} ++ ++static notifier_t *find_notifier(void *object) ++{ ++ notifier_t *notifier; ++ ++ DWC_ASSERT(manager, "Notification manager not found"); ++ ++ if (!object) { ++ return NULL; ++ } ++ ++ DWC_CIRCLEQ_FOREACH(notifier, &manager->notifiers, list_entry) { ++ if (notifier->object == object) { ++ return notifier; ++ } ++ } ++ ++ return NULL; ++} ++ ++int dwc_alloc_notification_manager(void *mem_ctx, void *wkq_ctx) ++{ ++ return create_manager(mem_ctx, wkq_ctx); ++} ++ ++void dwc_free_notification_manager(void) ++{ ++ free_manager(); ++} ++ ++dwc_notifier_t *dwc_register_notifier(void *mem_ctx, void *object) ++{ ++ notifier_t *notifier; ++ ++ DWC_ASSERT(manager, "Notification manager not found"); ++ ++ notifier = find_notifier(object); ++ if (notifier) { ++ DWC_ERROR("Notifier %p is already registered\n", object); ++ return NULL; ++ } ++ ++ notifier = alloc_notifier(mem_ctx, object); ++ if (!notifier) { ++ return NULL; ++ } ++ ++ DWC_CIRCLEQ_INSERT_TAIL(&manager->notifiers, notifier, list_entry); ++ ++ DWC_INFO("Notifier %p registered", object); ++ dump_manager(); ++ ++ return notifier; ++} ++ ++void dwc_unregister_notifier(dwc_notifier_t *notifier) ++{ ++ DWC_ASSERT(manager, "Notification manager not found"); ++ ++ if (!DWC_CIRCLEQ_EMPTY(¬ifier->observers)) { ++ observer_t *o; ++ ++ DWC_ERROR("Notifier %p has active observers when removing\n", notifier->object); ++ DWC_CIRCLEQ_FOREACH(o, ¬ifier->observers, list_entry) { ++ DWC_DEBUGC(" %p watching %s\n", o->observer, o->notification); ++ } ++ ++ DWC_ASSERT(DWC_CIRCLEQ_EMPTY(¬ifier->observers), ++ "Notifier %p has active observers when removing", notifier); ++ } ++ ++ DWC_CIRCLEQ_REMOVE_INIT(&manager->notifiers, notifier, list_entry); ++ free_notifier(notifier); ++ ++ DWC_INFO("Notifier unregistered"); ++ dump_manager(); ++} ++ ++/* Add an observer to observe the notifier for a particular state, event, or notification. */ ++int dwc_add_observer(void *observer, void *object, char *notification, ++ dwc_notifier_callback_t callback, void *data) ++{ ++ notifier_t *notifier = find_notifier(object); ++ observer_t *new_observer; ++ ++ if (!notifier) { ++ DWC_ERROR("Notifier %p is not found when adding observer\n", object); ++ return -DWC_E_INVALID; ++ } ++ ++ new_observer = alloc_observer(notifier->mem_ctx, observer, notification, callback, data); ++ if (!new_observer) { ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ DWC_CIRCLEQ_INSERT_TAIL(¬ifier->observers, new_observer, list_entry); ++ ++ DWC_INFO("Added observer %p to notifier %p observing notification %s, callback=%p, data=%p", ++ observer, object, notification, callback, data); ++ ++ dump_manager(); ++ return 0; ++} ++ ++int dwc_remove_observer(void *observer) ++{ ++ notifier_t *n; ++ ++ DWC_ASSERT(manager, "Notification manager not found"); ++ ++ DWC_CIRCLEQ_FOREACH(n, &manager->notifiers, list_entry) { ++ observer_t *o; ++ observer_t *o2; ++ ++ DWC_CIRCLEQ_FOREACH_SAFE(o, o2, &n->observers, list_entry) { ++ if (o->observer == observer) { ++ DWC_CIRCLEQ_REMOVE_INIT(&n->observers, o, list_entry); ++ DWC_INFO("Removing observer %p from notifier %p watching notification %s:", ++ o->observer, n->object, o->notification); ++ free_observer(n->mem_ctx, o); ++ } ++ } ++ } ++ ++ dump_manager(); ++ return 0; ++} ++ ++typedef struct callback_data { ++ void *mem_ctx; ++ dwc_notifier_callback_t cb; ++ void *observer; ++ void *data; ++ void *object; ++ char *notification; ++ void *notification_data; ++} cb_data_t; ++ ++static void cb_task(void *data) ++{ ++ cb_data_t *cb = (cb_data_t *)data; ++ ++ cb->cb(cb->object, cb->notification, cb->observer, cb->notification_data, cb->data); ++ dwc_free(cb->mem_ctx, cb); ++} ++ ++void dwc_notify(dwc_notifier_t *notifier, char *notification, void *notification_data) ++{ ++ observer_t *o; ++ ++ DWC_ASSERT(manager, "Notification manager not found"); ++ ++ DWC_CIRCLEQ_FOREACH(o, ¬ifier->observers, list_entry) { ++ int len = DWC_STRLEN(notification); ++ ++ if (DWC_STRLEN(o->notification) != len) { ++ continue; ++ } ++ ++ if (DWC_STRNCMP(o->notification, notification, len) == 0) { ++ cb_data_t *cb_data = dwc_alloc(notifier->mem_ctx, sizeof(cb_data_t)); ++ ++ if (!cb_data) { ++ DWC_ERROR("Failed to allocate callback data\n"); ++ return; ++ } ++ ++ cb_data->mem_ctx = notifier->mem_ctx; ++ cb_data->cb = o->callback; ++ cb_data->observer = o->observer; ++ cb_data->data = o->data; ++ cb_data->object = notifier->object; ++ cb_data->notification = notification; ++ cb_data->notification_data = notification_data; ++ DWC_DEBUGC("Observer found %p for notification %s\n", o->observer, notification); ++ DWC_WORKQ_SCHEDULE(manager->wq, cb_task, cb_data, ++ "Notify callback from %p for Notification %s, to observer %p", ++ cb_data->object, notification, cb_data->observer); ++ } ++ } ++} ++ ++#endif /* DWC_NOTIFYLIB */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_notifier.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_notifier.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,122 @@ ++ ++#ifndef __DWC_NOTIFIER_H__ ++#define __DWC_NOTIFIER_H__ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include "dwc_os.h" ++ ++/** @file ++ * ++ * A simple implementation of the Observer pattern. Any "module" can ++ * register as an observer or notifier. The notion of "module" is abstract and ++ * can mean anything used to identify either an observer or notifier. Usually ++ * it will be a pointer to a data structure which contains some state, ie an ++ * object. ++ * ++ * Before any notifiers can be added, the global notification manager must be ++ * brought up with dwc_alloc_notification_manager(). ++ * dwc_free_notification_manager() will bring it down and free all resources. ++ * These would typically be called upon module load and unload. The ++ * notification manager is a single global instance that handles all registered ++ * observable modules and observers so this should be done only once. ++ * ++ * A module can be observable by using Notifications to publicize some general ++ * information about it's state or operation. It does not care who listens, or ++ * even if anyone listens, or what they do with the information. The observable ++ * modules do not need to know any information about it's observers or their ++ * interface, or their state or data. ++ * ++ * Any module can register to emit Notifications. It should publish a list of ++ * notifications that it can emit and their behavior, such as when they will get ++ * triggered, and what information will be provided to the observer. Then it ++ * should register itself as an observable module. See dwc_register_notifier(). ++ * ++ * Any module can observe any observable, registered module, provided it has a ++ * handle to the other module and knows what notifications to observe. See ++ * dwc_add_observer(). ++ * ++ * A function of type dwc_notifier_callback_t is called whenever a notification ++ * is triggered with one or more observers observing it. This function is ++ * called in it's own process so it may sleep or block if needed. It is ++ * guaranteed to be called sometime after the notification has occurred and will ++ * be called once per each time the notification is triggered. It will NOT be ++ * called in the same process context used to trigger the notification. ++ * ++ * @section Limitiations ++ * ++ * Keep in mind that Notifications that can be triggered in rapid sucession may ++ * schedule too many processes too handle. Be aware of this limitation when ++ * designing to use notifications, and only add notifications for appropriate ++ * observable information. ++ * ++ * Also Notification callbacks are not synchronous. If you need to synchronize ++ * the behavior between module/observer you must use other means. And perhaps ++ * that will mean Notifications are not the proper solution. ++ */ ++ ++struct dwc_notifier; ++typedef struct dwc_notifier dwc_notifier_t; ++ ++/** The callback function must be of this type. ++ * ++ * @param object This is the object that is being observed. ++ * @param notification This is the notification that was triggered. ++ * @param observer This is the observer ++ * @param notification_data This is notification-specific data that the notifier ++ * has included in this notification. The value of this should be published in ++ * the documentation of the observable module with the notifications. ++ * @param user_data This is any custom data that the observer provided when ++ * adding itself as an observer to the notification. */ ++typedef void (*dwc_notifier_callback_t)(void *object, char *notification, void *observer, ++ void *notification_data, void *user_data); ++ ++/** Brings up the notification manager. */ ++extern int dwc_alloc_notification_manager(void *mem_ctx, void *wkq_ctx); ++/** Brings down the notification manager. */ ++extern void dwc_free_notification_manager(void); ++ ++/** This function registers an observable module. A dwc_notifier_t object is ++ * returned to the observable module. This is an opaque object that is used by ++ * the observable module to trigger notifications. This object should only be ++ * accessible to functions that are authorized to trigger notifications for this ++ * module. Observers do not need this object. */ ++extern dwc_notifier_t *dwc_register_notifier(void *mem_ctx, void *object); ++ ++/** This function unregisters an observable module. All observers have to be ++ * removed prior to unregistration. */ ++extern void dwc_unregister_notifier(dwc_notifier_t *notifier); ++ ++/** Add a module as an observer to the observable module. The observable module ++ * needs to have previously registered with the notification manager. ++ * ++ * @param observer The observer module ++ * @param object The module to observe ++ * @param notification The notification to observe ++ * @param callback The callback function to call ++ * @param user_data Any additional user data to pass into the callback function */ ++extern int dwc_add_observer(void *observer, void *object, char *notification, ++ dwc_notifier_callback_t callback, void *user_data); ++ ++/** Removes the specified observer from all notifications that it is currently ++ * observing. */ ++extern int dwc_remove_observer(void *observer); ++ ++/** This function triggers a Notification. It should be called by the ++ * observable module, or any module or library which the observable module ++ * allows to trigger notification on it's behalf. Such as the dwc_cc_t. ++ * ++ * dwc_notify is a non-blocking function. Callbacks are scheduled called in ++ * their own process context for each trigger. Callbacks can be blocking. ++ * dwc_notify can be called from interrupt context if needed. ++ * ++ */ ++void dwc_notify(dwc_notifier_t *notifier, char *notification, void *notification_data); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* __DWC_NOTIFIER_H__ */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_os.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/dwc_os.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1260 @@ ++/* ========================================================================= ++ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_os.h $ ++ * $Revision: #14 $ ++ * $Date: 2010/11/04 $ ++ * $Change: 1621695 $ ++ * ++ * Synopsys Portability Library Software and documentation ++ * (hereinafter, "Software") is an Unsupported proprietary work of ++ * Synopsys, Inc. unless otherwise expressly agreed to in writing ++ * between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product ++ * under any End User Software License Agreement or Agreement for ++ * Licensed Product with Synopsys or any supplement thereto. You are ++ * permitted to use and redistribute this Software in source and binary ++ * forms, with or without modification, provided that redistributions ++ * of source code must retain this notice. You may not view, use, ++ * disclose, copy or distribute this file or any information contained ++ * herein except pursuant to this license grant from Synopsys. If you ++ * do not agree with this notice, including the disclaimer below, then ++ * you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" ++ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL ++ * SYNOPSYS 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. ++ * ========================================================================= */ ++#ifndef _DWC_OS_H_ ++#define _DWC_OS_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/** @file ++ * ++ * DWC portability library, low level os-wrapper functions ++ * ++ */ ++ ++/* These basic types need to be defined by some OS header file or custom header ++ * file for your specific target architecture. ++ * ++ * uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t ++ * ++ * Any custom or alternate header file must be added and enabled here. ++ */ ++ ++#ifdef DWC_LINUX ++# include ++# ifdef CONFIG_DEBUG_MUTEXES ++# include ++# endif ++# include ++# include ++#endif ++ ++#if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++# include ++#endif ++ ++ ++/** @name Primitive Types and Values */ ++ ++/** We define a boolean type for consistency. Can be either YES or NO */ ++typedef uint8_t dwc_bool_t; ++#define YES 1 ++#define NO 0 ++ ++#ifdef DWC_LINUX ++ ++/** @name Error Codes */ ++#define DWC_E_INVALID EINVAL ++#define DWC_E_NO_MEMORY ENOMEM ++#define DWC_E_NO_DEVICE ENODEV ++#define DWC_E_NOT_SUPPORTED EOPNOTSUPP ++#define DWC_E_TIMEOUT ETIMEDOUT ++#define DWC_E_BUSY EBUSY ++#define DWC_E_AGAIN EAGAIN ++#define DWC_E_RESTART ERESTART ++#define DWC_E_ABORT ECONNABORTED ++#define DWC_E_SHUTDOWN ESHUTDOWN ++#define DWC_E_NO_DATA ENODATA ++#define DWC_E_DISCONNECT ECONNRESET ++#define DWC_E_UNKNOWN EINVAL ++#define DWC_E_NO_STREAM_RES ENOSR ++#define DWC_E_COMMUNICATION ECOMM ++#define DWC_E_OVERFLOW EOVERFLOW ++#define DWC_E_PROTOCOL EPROTO ++#define DWC_E_IN_PROGRESS EINPROGRESS ++#define DWC_E_PIPE EPIPE ++#define DWC_E_IO EIO ++#define DWC_E_NO_SPACE ENOSPC ++ ++#else ++ ++/** @name Error Codes */ ++#define DWC_E_INVALID 1001 ++#define DWC_E_NO_MEMORY 1002 ++#define DWC_E_NO_DEVICE 1003 ++#define DWC_E_NOT_SUPPORTED 1004 ++#define DWC_E_TIMEOUT 1005 ++#define DWC_E_BUSY 1006 ++#define DWC_E_AGAIN 1007 ++#define DWC_E_RESTART 1008 ++#define DWC_E_ABORT 1009 ++#define DWC_E_SHUTDOWN 1010 ++#define DWC_E_NO_DATA 1011 ++#define DWC_E_DISCONNECT 2000 ++#define DWC_E_UNKNOWN 3000 ++#define DWC_E_NO_STREAM_RES 4001 ++#define DWC_E_COMMUNICATION 4002 ++#define DWC_E_OVERFLOW 4003 ++#define DWC_E_PROTOCOL 4004 ++#define DWC_E_IN_PROGRESS 4005 ++#define DWC_E_PIPE 4006 ++#define DWC_E_IO 4007 ++#define DWC_E_NO_SPACE 4008 ++ ++#endif ++ ++ ++/** @name Tracing/Logging Functions ++ * ++ * These function provide the capability to add tracing, debugging, and error ++ * messages, as well exceptions as assertions. The WUDEV uses these ++ * extensively. These could be logged to the main console, the serial port, an ++ * internal buffer, etc. These functions could also be no-op if they are too ++ * expensive on your system. By default undefining the DEBUG macro already ++ * no-ops some of these functions. */ ++ ++/** Returns non-zero if in interrupt context. */ ++extern dwc_bool_t DWC_IN_IRQ(void); ++#define dwc_in_irq DWC_IN_IRQ ++ ++/** Returns "IRQ" if DWC_IN_IRQ is true. */ ++static inline char *dwc_irq(void) { ++ return DWC_IN_IRQ() ? "IRQ" : ""; ++} ++ ++/** Returns non-zero if in bottom-half context. */ ++extern dwc_bool_t DWC_IN_BH(void); ++#define dwc_in_bh DWC_IN_BH ++ ++/** Returns "BH" if DWC_IN_BH is true. */ ++static inline char *dwc_bh(void) { ++ return DWC_IN_BH() ? "BH" : ""; ++} ++ ++/** ++ * A vprintf() clone. Just call vprintf if you've got it. ++ */ ++extern void DWC_VPRINTF(char *format, va_list args); ++#define dwc_vprintf DWC_VPRINTF ++ ++/** ++ * A vsnprintf() clone. Just call vprintf if you've got it. ++ */ ++extern int DWC_VSNPRINTF(char *str, int size, char *format, va_list args); ++#define dwc_vsnprintf DWC_VSNPRINTF ++ ++/** ++ * printf() clone. Just call printf if you've go it. ++ */ ++extern void DWC_PRINTF(char *format, ...) ++/* This provides compiler level static checking of the parameters if you're ++ * using GCC. */ ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 1, 2))); ++#else ++ ; ++#endif ++#define dwc_printf DWC_PRINTF ++ ++/** ++ * sprintf() clone. Just call sprintf if you've got it. ++ */ ++extern int DWC_SPRINTF(char *string, char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 2, 3))); ++#else ++ ; ++#endif ++#define dwc_sprintf DWC_SPRINTF ++ ++/** ++ * snprintf() clone. Just call snprintf if you've got it. ++ */ ++extern int DWC_SNPRINTF(char *string, int size, char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 3, 4))); ++#else ++ ; ++#endif ++#define dwc_snprintf DWC_SNPRINTF ++ ++/** ++ * Prints a WARNING message. On systems that don't differentiate between ++ * warnings and regular log messages, just print it. Indicates that something ++ * may be wrong with the driver. Works like printf(). ++ * ++ * Use the DWC_WARN macro to call this function. ++ */ ++extern void __DWC_WARN(char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 1, 2))); ++#else ++ ; ++#endif ++ ++/** ++ * Prints an error message. On systems that don't differentiate between errors ++ * and regular log messages, just print it. Indicates that something went wrong ++ * with the driver. Works like printf(). ++ * ++ * Use the DWC_ERROR macro to call this function. ++ */ ++extern void __DWC_ERROR(char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 1, 2))); ++#else ++ ; ++#endif ++ ++/** ++ * Prints an exception error message and takes some user-defined action such as ++ * print out a backtrace or trigger a breakpoint. Indicates that something went ++ * abnormally wrong with the driver such as programmer error, or other ++ * exceptional condition. It should not be ignored so even on systems without ++ * printing capability, some action should be taken to notify the developer of ++ * it. Works like printf(). ++ */ ++extern void DWC_EXCEPTION(char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 1, 2))); ++#else ++ ; ++#endif ++#define dwc_exception DWC_EXCEPTION ++ ++#ifndef DWC_OTG_DEBUG_LEV ++#define DWC_OTG_DEBUG_LEV 0 ++#endif ++ ++#ifdef DEBUG ++/** ++ * Prints out a debug message. Used for logging/trace messages. ++ * ++ * Use the DWC_DEBUG macro to call this function ++ */ ++extern void __DWC_DEBUG(char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 1, 2))); ++#else ++ ; ++#endif ++#else ++#define __DWC_DEBUG printk ++#endif ++ ++/** ++ * Prints out a Debug message. ++ */ ++#define DWC_DEBUG(_format, _args...) __DWC_DEBUG("DEBUG:%s:%s: " _format "\n", \ ++ __func__, dwc_irq(), ## _args) ++#define dwc_debug DWC_DEBUG ++/** ++ * Prints out a Debug message if enabled at compile time. ++ */ ++#if DWC_OTG_DEBUG_LEV > 0 ++#define DWC_DEBUGC(_format, _args...) DWC_DEBUG(_format, ##_args ) ++#else ++#define DWC_DEBUGC(_format, _args...) ++#endif ++#define dwc_debugc DWC_DEBUGC ++/** ++ * Prints out an informative message. ++ */ ++#define DWC_INFO(_format, _args...) DWC_PRINTF("INFO:%s: " _format "\n", \ ++ dwc_irq(), ## _args) ++#define dwc_info DWC_INFO ++/** ++ * Prints out an informative message if enabled at compile time. ++ */ ++#if DWC_OTG_DEBUG_LEV > 1 ++#define DWC_INFOC(_format, _args...) DWC_INFO(_format, ##_args ) ++#else ++#define DWC_INFOC(_format, _args...) ++#endif ++#define dwc_infoc DWC_INFOC ++/** ++ * Prints out a warning message. ++ */ ++#define DWC_WARN(_format, _args...) __DWC_WARN("WARN:%s:%s:%d: " _format "\n", \ ++ dwc_irq(), __func__, __LINE__, ## _args) ++#define dwc_warn DWC_WARN ++/** ++ * Prints out an error message. ++ */ ++#define DWC_ERROR(_format, _args...) __DWC_ERROR("ERROR:%s:%s:%d: " _format "\n", \ ++ dwc_irq(), __func__, __LINE__, ## _args) ++#define dwc_error DWC_ERROR ++ ++#define DWC_PROTO_ERROR(_format, _args...) __DWC_WARN("ERROR:%s:%s:%d: " _format "\n", \ ++ dwc_irq(), __func__, __LINE__, ## _args) ++#define dwc_proto_error DWC_PROTO_ERROR ++ ++#ifdef DEBUG ++/** Prints out a exception error message if the _expr expression fails. Disabled ++ * if DEBUG is not enabled. */ ++#define DWC_ASSERT(_expr, _format, _args...) do { \ ++ if (!(_expr)) { DWC_EXCEPTION("%s:%s:%d: " _format "\n", dwc_irq(), \ ++ __FILE__, __LINE__, ## _args); } \ ++ } while (0) ++#else ++#define DWC_ASSERT(_x...) ++#endif ++#define dwc_assert DWC_ASSERT ++ ++ ++/** @name Byte Ordering ++ * The following functions are for conversions between processor's byte ordering ++ * and specific ordering you want. ++ */ ++ ++/** Converts 32 bit data in CPU byte ordering to little endian. */ ++extern uint32_t DWC_CPU_TO_LE32(uint32_t *p); ++#define dwc_cpu_to_le32 DWC_CPU_TO_LE32 ++ ++/** Converts 32 bit data in CPU byte orderint to big endian. */ ++extern uint32_t DWC_CPU_TO_BE32(uint32_t *p); ++#define dwc_cpu_to_be32 DWC_CPU_TO_BE32 ++ ++/** Converts 32 bit little endian data to CPU byte ordering. */ ++extern uint32_t DWC_LE32_TO_CPU(uint32_t *p); ++#define dwc_le32_to_cpu DWC_LE32_TO_CPU ++ ++/** Converts 32 bit big endian data to CPU byte ordering. */ ++extern uint32_t DWC_BE32_TO_CPU(uint32_t *p); ++#define dwc_be32_to_cpu DWC_BE32_TO_CPU ++ ++/** Converts 16 bit data in CPU byte ordering to little endian. */ ++extern uint16_t DWC_CPU_TO_LE16(uint16_t *p); ++#define dwc_cpu_to_le16 DWC_CPU_TO_LE16 ++ ++/** Converts 16 bit data in CPU byte orderint to big endian. */ ++extern uint16_t DWC_CPU_TO_BE16(uint16_t *p); ++#define dwc_cpu_to_be16 DWC_CPU_TO_BE16 ++ ++/** Converts 16 bit little endian data to CPU byte ordering. */ ++extern uint16_t DWC_LE16_TO_CPU(uint16_t *p); ++#define dwc_le16_to_cpu DWC_LE16_TO_CPU ++ ++/** Converts 16 bit bi endian data to CPU byte ordering. */ ++extern uint16_t DWC_BE16_TO_CPU(uint16_t *p); ++#define dwc_be16_to_cpu DWC_BE16_TO_CPU ++ ++ ++/** @name Register Read/Write ++ * ++ * The following six functions should be implemented to read/write registers of ++ * 32-bit and 64-bit sizes. All modules use this to read/write register values. ++ * The reg value is a pointer to the register calculated from the void *base ++ * variable passed into the driver when it is started. */ ++ ++#ifdef DWC_LINUX ++/* Linux doesn't need any extra parameters for register read/write, so we ++ * just throw away the IO context parameter. ++ */ ++/** Reads the content of a 32-bit register. */ ++extern uint32_t DWC_READ_REG32(uint32_t volatile *reg); ++#define dwc_read_reg32(_ctx_,_reg_) DWC_READ_REG32(_reg_) ++ ++/** Reads the content of a 64-bit register. */ ++extern uint64_t DWC_READ_REG64(uint64_t volatile *reg); ++#define dwc_read_reg64(_ctx_,_reg_) DWC_READ_REG64(_reg_) ++ ++/** Writes to a 32-bit register. */ ++extern void DWC_WRITE_REG32(uint32_t volatile *reg, uint32_t value); ++#define dwc_write_reg32(_ctx_,_reg_,_val_) DWC_WRITE_REG32(_reg_, _val_) ++ ++/** Writes to a 64-bit register. */ ++extern void DWC_WRITE_REG64(uint64_t volatile *reg, uint64_t value); ++#define dwc_write_reg64(_ctx_,_reg_,_val_) DWC_WRITE_REG64(_reg_, _val_) ++ ++/** ++ * Modify bit values in a register. Using the ++ * algorithm: (reg_contents & ~clear_mask) | set_mask. ++ */ ++extern void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask); ++#define dwc_modify_reg32(_ctx_,_reg_,_cmsk_,_smsk_) DWC_MODIFY_REG32(_reg_,_cmsk_,_smsk_) ++extern void DWC_MODIFY_REG64(uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask); ++#define dwc_modify_reg64(_ctx_,_reg_,_cmsk_,_smsk_) DWC_MODIFY_REG64(_reg_,_cmsk_,_smsk_) ++ ++#endif /* DWC_LINUX */ ++ ++#if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++typedef struct dwc_ioctx { ++ struct device *dev; ++ bus_space_tag_t iot; ++ bus_space_handle_t ioh; ++} dwc_ioctx_t; ++ ++/** BSD needs two extra parameters for register read/write, so we pass ++ * them in using the IO context parameter. ++ */ ++/** Reads the content of a 32-bit register. */ ++extern uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg); ++#define dwc_read_reg32 DWC_READ_REG32 ++ ++/** Reads the content of a 64-bit register. */ ++extern uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg); ++#define dwc_read_reg64 DWC_READ_REG64 ++ ++/** Writes to a 32-bit register. */ ++extern void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value); ++#define dwc_write_reg32 DWC_WRITE_REG32 ++ ++/** Writes to a 64-bit register. */ ++extern void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value); ++#define dwc_write_reg64 DWC_WRITE_REG64 ++ ++/** ++ * Modify bit values in a register. Using the ++ * algorithm: (reg_contents & ~clear_mask) | set_mask. ++ */ ++extern void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask); ++#define dwc_modify_reg32 DWC_MODIFY_REG32 ++extern void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask); ++#define dwc_modify_reg64 DWC_MODIFY_REG64 ++ ++#endif /* DWC_FREEBSD || DWC_NETBSD */ ++ ++/** @cond */ ++ ++/** @name Some convenience MACROS used internally. Define DWC_DEBUG_REGS to log the ++ * register writes. */ ++ ++#ifdef DWC_LINUX ++ ++# ifdef DWC_DEBUG_REGS ++ ++#define dwc_define_read_write_reg_n(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \ ++ return DWC_READ_REG32(&container->regs->_reg[num]); \ ++} \ ++static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \ ++ DWC_DEBUG("WRITING %8s[%d]: %p: %08x", #_reg, num, \ ++ &(((uint32_t*)container->regs->_reg)[num]), data); \ ++ DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \ ++} ++ ++#define dwc_define_read_write_reg(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg(_container_type *container) { \ ++ return DWC_READ_REG32(&container->regs->_reg); \ ++} \ ++static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \ ++ DWC_DEBUG("WRITING %11s: %p: %08x", #_reg, &container->regs->_reg, data); \ ++ DWC_WRITE_REG32(&container->regs->_reg, data); \ ++} ++ ++# else /* DWC_DEBUG_REGS */ ++ ++#define dwc_define_read_write_reg_n(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \ ++ return DWC_READ_REG32(&container->regs->_reg[num]); \ ++} \ ++static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \ ++ DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \ ++} ++ ++#define dwc_define_read_write_reg(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg(_container_type *container) { \ ++ return DWC_READ_REG32(&container->regs->_reg); \ ++} \ ++static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \ ++ DWC_WRITE_REG32(&container->regs->_reg, data); \ ++} ++ ++# endif /* DWC_DEBUG_REGS */ ++ ++#endif /* DWC_LINUX */ ++ ++#if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++ ++# ifdef DWC_DEBUG_REGS ++ ++#define dwc_define_read_write_reg_n(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg##_n(void *io_ctx, _container_type *container, int num) { \ ++ return DWC_READ_REG32(io_ctx, &container->regs->_reg[num]); \ ++} \ ++static inline void dwc_write_##_reg##_n(void *io_ctx, _container_type *container, int num, uint32_t data) { \ ++ DWC_DEBUG("WRITING %8s[%d]: %p: %08x", #_reg, num, \ ++ &(((uint32_t*)container->regs->_reg)[num]), data); \ ++ DWC_WRITE_REG32(io_ctx, &(((uint32_t*)container->regs->_reg)[num]), data); \ ++} ++ ++#define dwc_define_read_write_reg(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg(void *io_ctx, _container_type *container) { \ ++ return DWC_READ_REG32(io_ctx, &container->regs->_reg); \ ++} \ ++static inline void dwc_write_##_reg(void *io_ctx, _container_type *container, uint32_t data) { \ ++ DWC_DEBUG("WRITING %11s: %p: %08x", #_reg, &container->regs->_reg, data); \ ++ DWC_WRITE_REG32(io_ctx, &container->regs->_reg, data); \ ++} ++ ++# else /* DWC_DEBUG_REGS */ ++ ++#define dwc_define_read_write_reg_n(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg##_n(void *io_ctx, _container_type *container, int num) { \ ++ return DWC_READ_REG32(io_ctx, &container->regs->_reg[num]); \ ++} \ ++static inline void dwc_write_##_reg##_n(void *io_ctx, _container_type *container, int num, uint32_t data) { \ ++ DWC_WRITE_REG32(io_ctx, &(((uint32_t*)container->regs->_reg)[num]), data); \ ++} ++ ++#define dwc_define_read_write_reg(_reg,_container_type) \ ++static inline uint32_t dwc_read_##_reg(void *io_ctx, _container_type *container) { \ ++ return DWC_READ_REG32(io_ctx, &container->regs->_reg); \ ++} \ ++static inline void dwc_write_##_reg(void *io_ctx, _container_type *container, uint32_t data) { \ ++ DWC_WRITE_REG32(io_ctx, &container->regs->_reg, data); \ ++} ++ ++# endif /* DWC_DEBUG_REGS */ ++ ++#endif /* DWC_FREEBSD || DWC_NETBSD */ ++ ++/** @endcond */ ++ ++ ++#ifdef DWC_CRYPTOLIB ++/** @name Crypto Functions ++ * ++ * These are the low-level cryptographic functions used by the driver. */ ++ ++/** Perform AES CBC */ ++extern int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out); ++#define dwc_aes_cbc DWC_AES_CBC ++ ++/** Fill the provided buffer with random bytes. These should be cryptographic grade random numbers. */ ++extern void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length); ++#define dwc_random_bytes DWC_RANDOM_BYTES ++ ++/** Perform the SHA-256 hash function */ ++extern int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out); ++#define dwc_sha256 DWC_SHA256 ++ ++/** Calculated the HMAC-SHA256 */ ++extern int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t *out); ++#define dwc_hmac_sha256 DWC_HMAC_SHA256 ++ ++#endif /* DWC_CRYPTOLIB */ ++ ++ ++/** @name Memory Allocation ++ * ++ * These function provide access to memory allocation. There are only 2 DMA ++ * functions and 3 Regular memory functions that need to be implemented. None ++ * of the memory debugging routines need to be implemented. The allocation ++ * routines all ZERO the contents of the memory. ++ * ++ * Defining DWC_DEBUG_MEMORY turns on memory debugging and statistic gathering. ++ * This checks for memory leaks, keeping track of alloc/free pairs. It also ++ * keeps track of how much memory the driver is using at any given time. */ ++ ++#define DWC_PAGE_SIZE 4096 ++#define DWC_PAGE_OFFSET(addr) (((uint32_t)addr) & 0xfff) ++#define DWC_PAGE_ALIGNED(addr) ((((uint32_t)addr) & 0xfff) == 0) ++ ++#define DWC_INVALID_DMA_ADDR 0x0 ++ ++#ifdef DWC_LINUX ++/** Type for a DMA address */ ++typedef dma_addr_t dwc_dma_t; ++#endif ++ ++#if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++typedef bus_addr_t dwc_dma_t; ++#endif ++ ++#ifdef DWC_FREEBSD ++typedef struct dwc_dmactx { ++ struct device *dev; ++ bus_dma_tag_t dma_tag; ++ bus_dmamap_t dma_map; ++ bus_addr_t dma_paddr; ++ void *dma_vaddr; ++} dwc_dmactx_t; ++#endif ++ ++#ifdef DWC_NETBSD ++typedef struct dwc_dmactx { ++ struct device *dev; ++ bus_dma_tag_t dma_tag; ++ bus_dmamap_t dma_map; ++ bus_dma_segment_t segs[1]; ++ int nsegs; ++ bus_addr_t dma_paddr; ++ void *dma_vaddr; ++} dwc_dmactx_t; ++#endif ++ ++/* @todo these functions will be added in the future */ ++#if 0 ++/** ++ * Creates a DMA pool from which you can allocate DMA buffers. Buffers ++ * allocated from this pool will be guaranteed to meet the size, alignment, and ++ * boundary requirements specified. ++ * ++ * @param[in] size Specifies the size of the buffers that will be allocated from ++ * this pool. ++ * @param[in] align Specifies the byte alignment requirements of the buffers ++ * allocated from this pool. Must be a power of 2. ++ * @param[in] boundary Specifies the N-byte boundary that buffers allocated from ++ * this pool must not cross. ++ * ++ * @returns A pointer to an internal opaque structure which is not to be ++ * accessed outside of these library functions. Use this handle to specify ++ * which pools to allocate/free DMA buffers from and also to destroy the pool, ++ * when you are done with it. ++ */ ++extern dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size, uint32_t align, uint32_t boundary); ++ ++/** ++ * Destroy a DMA pool. All buffers allocated from that pool must be freed first. ++ */ ++extern void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool); ++ ++/** ++ * Allocate a buffer from the specified DMA pool and zeros its contents. ++ */ ++extern void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr); ++ ++/** ++ * Free a previously allocated buffer from the DMA pool. ++ */ ++extern void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr); ++#endif ++ ++/** Allocates a DMA capable buffer and zeroes its contents. */ ++extern void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr); ++ ++/** Allocates a DMA capable buffer and zeroes its contents in atomic contest */ ++extern void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr); ++ ++/** Frees a previously allocated buffer. */ ++extern void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr); ++ ++/** Allocates a block of memory and zeroes its contents. */ ++extern void *__DWC_ALLOC(void *mem_ctx, uint32_t size); ++ ++/** Allocates a block of memory and zeroes its contents, in an atomic manner ++ * which can be used inside interrupt context. The size should be sufficiently ++ * small, a few KB at most, such that failures are not likely to occur. Can just call ++ * __DWC_ALLOC if it is atomic. */ ++extern void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size); ++ ++/** Frees a previously allocated buffer. */ ++extern void __DWC_FREE(void *mem_ctx, void *addr); ++ ++#ifndef DWC_DEBUG_MEMORY ++ ++#define DWC_ALLOC(_size_) __DWC_ALLOC(NULL, _size_) ++#define DWC_ALLOC_ATOMIC(_size_) __DWC_ALLOC_ATOMIC(NULL, _size_) ++#define DWC_FREE(_addr_) __DWC_FREE(NULL, _addr_) ++ ++# ifdef DWC_LINUX ++#define DWC_DMA_ALLOC(_size_,_dma_) __DWC_DMA_ALLOC(NULL, _size_, _dma_) ++#define DWC_DMA_ALLOC_ATOMIC(_size_,_dma_) __DWC_DMA_ALLOC_ATOMIC(NULL, _size_,_dma_) ++#define DWC_DMA_FREE(_size_,_virt_,_dma_) __DWC_DMA_FREE(NULL, _size_, _virt_, _dma_) ++# endif ++ ++# if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++#define DWC_DMA_ALLOC __DWC_DMA_ALLOC ++#define DWC_DMA_FREE __DWC_DMA_FREE ++# endif ++extern void *dwc_dma_alloc_atomic_debug(uint32_t size, dwc_dma_t *dma_addr, char const *func, int line); ++ ++#else /* DWC_DEBUG_MEMORY */ ++ ++extern void *dwc_alloc_debug(void *mem_ctx, uint32_t size, char const *func, int line); ++extern void *dwc_alloc_atomic_debug(void *mem_ctx, uint32_t size, char const *func, int line); ++extern void dwc_free_debug(void *mem_ctx, void *addr, char const *func, int line); ++extern void *dwc_dma_alloc_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr, ++ char const *func, int line); ++extern void *dwc_dma_alloc_atomic_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr, ++ char const *func, int line); ++extern void dwc_dma_free_debug(void *dma_ctx, uint32_t size, void *virt_addr, ++ dwc_dma_t dma_addr, char const *func, int line); ++ ++extern int dwc_memory_debug_start(void *mem_ctx); ++extern void dwc_memory_debug_stop(void); ++extern void dwc_memory_debug_report(void); ++ ++#define DWC_ALLOC(_size_) dwc_alloc_debug(NULL, _size_, __func__, __LINE__) ++#define DWC_ALLOC_ATOMIC(_size_) dwc_alloc_atomic_debug(NULL, _size_, \ ++ __func__, __LINE__) ++#define DWC_FREE(_addr_) dwc_free_debug(NULL, _addr_, __func__, __LINE__) ++ ++# ifdef DWC_LINUX ++#define DWC_DMA_ALLOC(_size_,_dma_) dwc_dma_alloc_debug(NULL, _size_, \ ++ _dma_, __func__, __LINE__) ++#define DWC_DMA_ALLOC_ATOMIC(_size_,_dma_) dwc_dma_alloc_atomic_debug(NULL, _size_, \ ++ _dma_, __func__, __LINE__) ++#define DWC_DMA_FREE(_size_,_virt_,_dma_) dwc_dma_free_debug(NULL, _size_, \ ++ _virt_, _dma_, __func__, __LINE__) ++# endif ++ ++# if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++#define DWC_DMA_ALLOC(_ctx_,_size_,_dma_) dwc_dma_alloc_debug(_ctx_, _size_, \ ++ _dma_, __func__, __LINE__) ++#define DWC_DMA_FREE(_ctx_,_size_,_virt_,_dma_) dwc_dma_free_debug(_ctx_, _size_, \ ++ _virt_, _dma_, __func__, __LINE__) ++# endif ++ ++#endif /* DWC_DEBUG_MEMORY */ ++ ++#define dwc_alloc(_ctx_,_size_) DWC_ALLOC(_size_) ++#define dwc_alloc_atomic(_ctx_,_size_) DWC_ALLOC_ATOMIC(_size_) ++#define dwc_free(_ctx_,_addr_) DWC_FREE(_addr_) ++ ++#ifdef DWC_LINUX ++/* Linux doesn't need any extra parameters for DMA buffer allocation, so we ++ * just throw away the DMA context parameter. ++ */ ++#define dwc_dma_alloc(_ctx_,_size_,_dma_) DWC_DMA_ALLOC(_size_, _dma_) ++#define dwc_dma_alloc_atomic(_ctx_,_size_,_dma_) DWC_DMA_ALLOC_ATOMIC(_size_, _dma_) ++#define dwc_dma_free(_ctx_,_size_,_virt_,_dma_) DWC_DMA_FREE(_size_, _virt_, _dma_) ++#endif ++ ++#if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++/** BSD needs several extra parameters for DMA buffer allocation, so we pass ++ * them in using the DMA context parameter. ++ */ ++#define dwc_dma_alloc DWC_DMA_ALLOC ++#define dwc_dma_free DWC_DMA_FREE ++#endif ++ ++ ++/** @name Memory and String Processing */ ++ ++/** memset() clone */ ++extern void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size); ++#define dwc_memset DWC_MEMSET ++ ++/** memcpy() clone */ ++extern void *DWC_MEMCPY(void *dest, void const *src, uint32_t size); ++#define dwc_memcpy DWC_MEMCPY ++ ++/** memmove() clone */ ++extern void *DWC_MEMMOVE(void *dest, void *src, uint32_t size); ++#define dwc_memmove DWC_MEMMOVE ++ ++/** memcmp() clone */ ++extern int DWC_MEMCMP(void *m1, void *m2, uint32_t size); ++#define dwc_memcmp DWC_MEMCMP ++ ++/** strcmp() clone */ ++extern int DWC_STRCMP(void *s1, void *s2); ++#define dwc_strcmp DWC_STRCMP ++ ++/** strncmp() clone */ ++extern int DWC_STRNCMP(void *s1, void *s2, uint32_t size); ++#define dwc_strncmp DWC_STRNCMP ++ ++/** strlen() clone, for NULL terminated ASCII strings */ ++extern int DWC_STRLEN(char const *str); ++#define dwc_strlen DWC_STRLEN ++ ++/** strcpy() clone, for NULL terminated ASCII strings */ ++extern char *DWC_STRCPY(char *to, const char *from); ++#define dwc_strcpy DWC_STRCPY ++ ++/** strdup() clone. If you wish to use memory allocation debugging, this ++ * implementation of strdup should use the DWC_* memory routines instead of ++ * calling a predefined strdup. Otherwise the memory allocated by this routine ++ * will not be seen by the debugging routines. */ ++extern char *DWC_STRDUP(char const *str); ++#define dwc_strdup(_ctx_,_str_) DWC_STRDUP(_str_) ++ ++/** NOT an atoi() clone. Read the description carefully. Returns an integer ++ * converted from the string str in base 10 unless the string begins with a "0x" ++ * in which case it is base 16. String must be a NULL terminated sequence of ++ * ASCII characters and may optionally begin with whitespace, a + or -, and a ++ * "0x" prefix if base 16. The remaining characters must be valid digits for ++ * the number and end with a NULL character. If any invalid characters are ++ * encountered or it returns with a negative error code and the results of the ++ * conversion are undefined. On sucess it returns 0. Overflow conditions are ++ * undefined. An example implementation using atoi() can be referenced from the ++ * Linux implementation. */ ++extern int DWC_ATOI(const char *str, int32_t *value); ++#define dwc_atoi DWC_ATOI ++ ++/** Same as above but for unsigned. */ ++extern int DWC_ATOUI(const char *str, uint32_t *value); ++#define dwc_atoui DWC_ATOUI ++ ++#ifdef DWC_UTFLIB ++/** This routine returns a UTF16LE unicode encoded string from a UTF8 string. */ ++extern int DWC_UTF8_TO_UTF16LE(uint8_t const *utf8string, uint16_t *utf16string, unsigned len); ++#define dwc_utf8_to_utf16le DWC_UTF8_TO_UTF16LE ++#endif ++ ++ ++/** @name Wait queues ++ * ++ * Wait queues provide a means of synchronizing between threads or processes. A ++ * process can block on a waitq if some condition is not true, waiting for it to ++ * become true. When the waitq is triggered all waiting process will get ++ * unblocked and the condition will be check again. Waitqs should be triggered ++ * every time a condition can potentially change.*/ ++struct dwc_waitq; ++ ++/** Type for a waitq */ ++typedef struct dwc_waitq dwc_waitq_t; ++ ++/** The type of waitq condition callback function. This is called every time ++ * condition is evaluated. */ ++typedef int (*dwc_waitq_condition_t)(void *data); ++ ++/** Allocate a waitq */ ++extern dwc_waitq_t *DWC_WAITQ_ALLOC(void); ++#define dwc_waitq_alloc(_ctx_) DWC_WAITQ_ALLOC() ++ ++/** Free a waitq */ ++extern void DWC_WAITQ_FREE(dwc_waitq_t *wq); ++#define dwc_waitq_free DWC_WAITQ_FREE ++ ++/** Check the condition and if it is false, block on the waitq. When unblocked, check the ++ * condition again. The function returns when the condition becomes true. The return value ++ * is 0 on condition true, DWC_WAITQ_ABORTED on abort or killed, or DWC_WAITQ_UNKNOWN on error. */ ++extern int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data); ++#define dwc_waitq_wait DWC_WAITQ_WAIT ++ ++/** Check the condition and if it is false, block on the waitq. When unblocked, ++ * check the condition again. The function returns when the condition become ++ * true or the timeout has passed. The return value is 0 on condition true or ++ * DWC_TIMED_OUT on timeout, or DWC_WAITQ_ABORTED, or DWC_WAITQ_UNKNOWN on ++ * error. */ ++extern int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, ++ void *data, int32_t msecs); ++#define dwc_waitq_wait_timeout DWC_WAITQ_WAIT_TIMEOUT ++ ++/** Trigger a waitq, unblocking all processes. This should be called whenever a condition ++ * has potentially changed. */ ++extern void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq); ++#define dwc_waitq_trigger DWC_WAITQ_TRIGGER ++ ++/** Unblock all processes waiting on the waitq with an ABORTED result. */ ++extern void DWC_WAITQ_ABORT(dwc_waitq_t *wq); ++#define dwc_waitq_abort DWC_WAITQ_ABORT ++ ++ ++/** @name Threads ++ * ++ * A thread must be explicitly stopped. It must check DWC_THREAD_SHOULD_STOP ++ * whenever it is woken up, and then return. The DWC_THREAD_STOP function ++ * returns the value from the thread. ++ */ ++ ++struct dwc_thread; ++ ++/** Type for a thread */ ++typedef struct dwc_thread dwc_thread_t; ++ ++/** The thread function */ ++typedef int (*dwc_thread_function_t)(void *data); ++ ++/** Create a thread and start it running the thread_function. Returns a handle ++ * to the thread */ ++extern dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data); ++#define dwc_thread_run(_ctx_,_func_,_name_,_data_) DWC_THREAD_RUN(_func_, _name_, _data_) ++ ++/** Stops a thread. Return the value returned by the thread. Or will return ++ * DWC_ABORT if the thread never started. */ ++extern int DWC_THREAD_STOP(dwc_thread_t *thread); ++#define dwc_thread_stop DWC_THREAD_STOP ++ ++/** Signifies to the thread that it must stop. */ ++#ifdef DWC_LINUX ++/* Linux doesn't need any parameters for kthread_should_stop() */ ++extern dwc_bool_t DWC_THREAD_SHOULD_STOP(void); ++#define dwc_thread_should_stop(_thrd_) DWC_THREAD_SHOULD_STOP() ++ ++/* No thread_exit function in Linux */ ++#define dwc_thread_exit(_thrd_) ++#endif ++ ++#if defined(DWC_FREEBSD) || defined(DWC_NETBSD) ++/** BSD needs the thread pointer for kthread_suspend_check() */ ++extern dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread); ++#define dwc_thread_should_stop DWC_THREAD_SHOULD_STOP ++ ++/** The thread must call this to exit. */ ++extern void DWC_THREAD_EXIT(dwc_thread_t *thread); ++#define dwc_thread_exit DWC_THREAD_EXIT ++#endif ++ ++ ++/** @name Work queues ++ * ++ * Workqs are used to queue a callback function to be called at some later time, ++ * in another thread. */ ++struct dwc_workq; ++ ++/** Type for a workq */ ++typedef struct dwc_workq dwc_workq_t; ++ ++/** The type of the callback function to be called. */ ++typedef void (*dwc_work_callback_t)(void *data); ++ ++/** Allocate a workq */ ++extern dwc_workq_t *DWC_WORKQ_ALLOC(char *name); ++#define dwc_workq_alloc(_ctx_,_name_) DWC_WORKQ_ALLOC(_name_) ++ ++/** Free a workq. All work must be completed before being freed. */ ++extern void DWC_WORKQ_FREE(dwc_workq_t *workq); ++#define dwc_workq_free DWC_WORKQ_FREE ++ ++/** Schedule a callback on the workq, passing in data. The function will be ++ * scheduled at some later time. */ ++extern void DWC_WORKQ_SCHEDULE(dwc_workq_t *workq, dwc_work_callback_t cb, ++ void *data, char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 4, 5))); ++#else ++ ; ++#endif ++#define dwc_workq_schedule DWC_WORKQ_SCHEDULE ++ ++/** Schedule a callback on the workq, that will be called until at least ++ * given number miliseconds have passed. */ ++extern void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *workq, dwc_work_callback_t cb, ++ void *data, uint32_t time, char *format, ...) ++#ifdef __GNUC__ ++ __attribute__ ((format(printf, 5, 6))); ++#else ++ ; ++#endif ++#define dwc_workq_schedule_delayed DWC_WORKQ_SCHEDULE_DELAYED ++ ++/** The number of processes in the workq */ ++extern int DWC_WORKQ_PENDING(dwc_workq_t *workq); ++#define dwc_workq_pending DWC_WORKQ_PENDING ++ ++/** Blocks until all the work in the workq is complete or timed out. Returns < ++ * 0 on timeout. */ ++extern int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout); ++#define dwc_workq_wait_work_done DWC_WORKQ_WAIT_WORK_DONE ++ ++ ++/** @name Tasklets ++ * ++ */ ++struct dwc_tasklet; ++ ++/** Type for a tasklet */ ++typedef struct dwc_tasklet dwc_tasklet_t; ++ ++/** The type of the callback function to be called */ ++typedef void (*dwc_tasklet_callback_t)(void *data); ++ ++/** Allocates a tasklet */ ++extern dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data); ++#define dwc_task_alloc(_ctx_,_name_,_cb_,_data_) DWC_TASK_ALLOC(_name_, _cb_, _data_) ++ ++/** Frees a tasklet */ ++extern void DWC_TASK_FREE(dwc_tasklet_t *task); ++#define dwc_task_free DWC_TASK_FREE ++ ++/** Schedules a tasklet to run */ ++extern void DWC_TASK_SCHEDULE(dwc_tasklet_t *task); ++#define dwc_task_schedule DWC_TASK_SCHEDULE ++ ++ ++/** @name Timer ++ * ++ * Callbacks must be small and atomic. ++ */ ++struct dwc_timer; ++ ++/** Type for a timer */ ++typedef struct dwc_timer dwc_timer_t; ++ ++/** The type of the callback function to be called */ ++typedef void (*dwc_timer_callback_t)(void *data); ++ ++/** Allocates a timer */ ++extern dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data); ++#define dwc_timer_alloc(_ctx_,_name_,_cb_,_data_) DWC_TIMER_ALLOC(_name_,_cb_,_data_) ++ ++/** Frees a timer */ ++extern void DWC_TIMER_FREE(dwc_timer_t *timer); ++#define dwc_timer_free DWC_TIMER_FREE ++ ++/** Schedules the timer to run at time ms from now. And will repeat at every ++ * repeat_interval msec therafter ++ * ++ * Modifies a timer that is still awaiting execution to a new expiration time. ++ * The mod_time is added to the old time. */ ++extern void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time); ++#define dwc_timer_schedule DWC_TIMER_SCHEDULE ++ ++/** Disables the timer from execution. */ ++extern void DWC_TIMER_CANCEL(dwc_timer_t *timer); ++#define dwc_timer_cancel DWC_TIMER_CANCEL ++ ++ ++/** @name Spinlocks ++ * ++ * These locks are used when the work between the lock/unlock is atomic and ++ * short. Interrupts are also disabled during the lock/unlock and thus they are ++ * suitable to lock between interrupt/non-interrupt context. They also lock ++ * between processes if you have multiple CPUs or Preemption. If you don't have ++ * multiple CPUS or Preemption, then the you can simply implement the ++ * DWC_SPINLOCK and DWC_SPINUNLOCK to disable and enable interrupts. Because ++ * the work between the lock/unlock is atomic, the process context will never ++ * change, and so you never have to lock between processes. */ ++ ++struct dwc_spinlock; ++ ++/** Type for a spinlock */ ++typedef struct dwc_spinlock dwc_spinlock_t; ++ ++/** Type for the 'flags' argument to spinlock funtions */ ++typedef unsigned long dwc_irqflags_t; ++ ++/** Returns an initialized lock variable. This function should allocate and ++ * initialize the OS-specific data structure used for locking. This data ++ * structure is to be used for the DWC_LOCK and DWC_UNLOCK functions and should ++ * be freed by the DWC_FREE_LOCK when it is no longer used. */ ++extern dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void); ++#define dwc_spinlock_alloc(_ctx_) DWC_SPINLOCK_ALLOC() ++ ++/** Frees an initialized lock variable. */ ++extern void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock); ++#define dwc_spinlock_free(_ctx_,_lock_) DWC_SPINLOCK_FREE(_lock_) ++ ++/** Disables interrupts and blocks until it acquires the lock. ++ * ++ * @param lock Pointer to the spinlock. ++ * @param flags Unsigned long for irq flags storage. ++ */ ++extern void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags); ++#define dwc_spinlock_irqsave DWC_SPINLOCK_IRQSAVE ++ ++/** Re-enables the interrupt and releases the lock. ++ * ++ * @param lock Pointer to the spinlock. ++ * @param flags Unsigned long for irq flags storage. Must be the same as was ++ * passed into DWC_LOCK. ++ */ ++extern void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags); ++#define dwc_spinunlock_irqrestore DWC_SPINUNLOCK_IRQRESTORE ++ ++/** Blocks until it acquires the lock. ++ * ++ * @param lock Pointer to the spinlock. ++ */ ++extern void DWC_SPINLOCK(dwc_spinlock_t *lock); ++#define dwc_spinlock DWC_SPINLOCK ++ ++/** Releases the lock. ++ * ++ * @param lock Pointer to the spinlock. ++ */ ++extern void DWC_SPINUNLOCK(dwc_spinlock_t *lock); ++#define dwc_spinunlock DWC_SPINUNLOCK ++ ++ ++/** @name Mutexes ++ * ++ * Unlike spinlocks Mutexes lock only between processes and the work between the ++ * lock/unlock CAN block, therefore it CANNOT be called from interrupt context. ++ */ ++ ++struct dwc_mutex; ++ ++/** Type for a mutex */ ++typedef struct dwc_mutex dwc_mutex_t; ++ ++/* For Linux Mutex Debugging make it inline because the debugging routines use ++ * the symbol to determine recursive locking. This makes it falsely think ++ * recursive locking occurs. */ ++#if defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES) ++#define DWC_MUTEX_ALLOC_LINUX_DEBUG(__mutexp) ({ \ ++ __mutexp = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex)); \ ++ mutex_init((struct mutex *)__mutexp); \ ++}) ++#endif ++ ++/** Allocate a mutex */ ++extern dwc_mutex_t *DWC_MUTEX_ALLOC(void); ++#define dwc_mutex_alloc(_ctx_) DWC_MUTEX_ALLOC() ++ ++/* For memory leak debugging when using Linux Mutex Debugging */ ++#if defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES) ++#define DWC_MUTEX_FREE(__mutexp) do { \ ++ mutex_destroy((struct mutex *)__mutexp); \ ++ DWC_FREE(__mutexp); \ ++} while(0) ++#else ++/** Free a mutex */ ++extern void DWC_MUTEX_FREE(dwc_mutex_t *mutex); ++#define dwc_mutex_free(_ctx_,_mutex_) DWC_MUTEX_FREE(_mutex_) ++#endif ++ ++/** Lock a mutex */ ++extern void DWC_MUTEX_LOCK(dwc_mutex_t *mutex); ++#define dwc_mutex_lock DWC_MUTEX_LOCK ++ ++/** Non-blocking lock returns 1 on successful lock. */ ++extern int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex); ++#define dwc_mutex_trylock DWC_MUTEX_TRYLOCK ++ ++/** Unlock a mutex */ ++extern void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex); ++#define dwc_mutex_unlock DWC_MUTEX_UNLOCK ++ ++ ++/** @name Time */ ++ ++/** Microsecond delay. ++ * ++ * @param usecs Microseconds to delay. ++ */ ++extern void DWC_UDELAY(uint32_t usecs); ++#define dwc_udelay DWC_UDELAY ++ ++/** Millisecond delay. ++ * ++ * @param msecs Milliseconds to delay. ++ */ ++extern void DWC_MDELAY(uint32_t msecs); ++#define dwc_mdelay DWC_MDELAY ++ ++/** Non-busy waiting. ++ * Sleeps for specified number of milliseconds. ++ * ++ * @param msecs Milliseconds to sleep. ++ */ ++extern void DWC_MSLEEP(uint32_t msecs); ++#define dwc_msleep DWC_MSLEEP ++ ++/** ++ * Returns number of milliseconds since boot. ++ */ ++extern uint32_t DWC_TIME(void); ++#define dwc_time DWC_TIME ++ ++ ++ ++ ++/* @mainpage DWC Portability and Common Library ++ * ++ * This is the documentation for the DWC Portability and Common Library. ++ * ++ * @section intro Introduction ++ * ++ * The DWC Portability library consists of wrapper calls and data structures to ++ * all low-level functions which are typically provided by the OS. The WUDEV ++ * driver uses only these functions. In order to port the WUDEV driver, only ++ * the functions in this library need to be re-implemented, with the same ++ * behavior as documented here. ++ * ++ * The Common library consists of higher level functions, which rely only on ++ * calling the functions from the DWC Portability library. These common ++ * routines are shared across modules. Some of the common libraries need to be ++ * used directly by the driver programmer when porting WUDEV. Such as the ++ * parameter and notification libraries. ++ * ++ * @section low Portability Library OS Wrapper Functions ++ * ++ * Any function starting with DWC and in all CAPS is a low-level OS-wrapper that ++ * needs to be implemented when porting, for example DWC_MUTEX_ALLOC(). All of ++ * these functions are included in the dwc_os.h file. ++ * ++ * There are many functions here covering a wide array of OS services. Please ++ * see dwc_os.h for details, and implementation notes for each function. ++ * ++ * @section common Common Library Functions ++ * ++ * Any function starting with dwc and in all lowercase is a common library ++ * routine. These functions have a portable implementation and do not need to ++ * be reimplemented when porting. The common routines can be used by any ++ * driver, and some must be used by the end user to control the drivers. For ++ * example, you must use the Parameter common library in order to set the ++ * parameters in the WUDEV module. ++ * ++ * The common libraries consist of the following: ++ * ++ * - Connection Contexts - Used internally and can be used by end-user. See dwc_cc.h ++ * - Parameters - Used internally and can be used by end-user. See dwc_params.h ++ * - Notifications - Used internally and can be used by end-user. See dwc_notifier.h ++ * - Lists - Used internally and can be used by end-user. See dwc_list.h ++ * - Memory Debugging - Used internally and can be used by end-user. See dwc_os.h ++ * - Modpow - Used internally only. See dwc_modpow.h ++ * - DH - Used internally only. See dwc_dh.h ++ * - Crypto - Used internally only. See dwc_crypto.h ++ * ++ * ++ * @section prereq Prerequistes For dwc_os.h ++ * @subsection types Data Types ++ * ++ * The dwc_os.h file assumes that several low-level data types are pre defined for the ++ * compilation environment. These data types are: ++ * ++ * - uint8_t - unsigned 8-bit data type ++ * - int8_t - signed 8-bit data type ++ * - uint16_t - unsigned 16-bit data type ++ * - int16_t - signed 16-bit data type ++ * - uint32_t - unsigned 32-bit data type ++ * - int32_t - signed 32-bit data type ++ * - uint64_t - unsigned 64-bit data type ++ * - int64_t - signed 64-bit data type ++ * ++ * Ensure that these are defined before using dwc_os.h. The easiest way to do ++ * that is to modify the top of the file to include the appropriate header. ++ * This is already done for the Linux environment. If the DWC_LINUX macro is ++ * defined, the correct header will be added. A standard header is ++ * also used for environments where standard C headers are available. ++ * ++ * @subsection stdarg Variable Arguments ++ * ++ * Variable arguments are provided by a standard C header . it is ++ * available in Both the Linux and ANSI C enviornment. An equivalent must be ++ * provided in your enviornment in order to use dwc_os.h with the debug and ++ * tracing message functionality. ++ * ++ * @subsection thread Threading ++ * ++ * WUDEV Core must be run on an operating system that provides for multiple ++ * threads/processes. Threading can be implemented in many ways, even in ++ * embedded systems without an operating system. At the bare minimum, the ++ * system should be able to start any number of processes at any time to handle ++ * special work. It need not be a pre-emptive system. Process context can ++ * change upon a call to a blocking function. The hardware interrupt context ++ * that calls the module's ISR() function must be differentiable from process ++ * context, even if your processes are impemented via a hardware interrupt. ++ * Further locking mechanism between process must exist (or be implemented), and ++ * process context must have a way to disable interrupts for a period of time to ++ * lock them out. If all of this exists, the functions in dwc_os.h related to ++ * threading should be able to be implemented with the defined behavior. ++ * ++ */ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _DWC_OS_H_ */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/usb.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_common_port/usb.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,946 @@ ++/* ++ * Copyright (c) 1998 The NetBSD Foundation, Inc. ++ * All rights reserved. ++ * ++ * This code is derived from software contributed to The NetBSD Foundation ++ * by Lennart Augustsson (lennart@augustsson.net) at ++ * Carlstedt Research & Technology. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * This product includes software developed by the NetBSD ++ * Foundation, Inc. and its contributors. ++ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. ++ */ ++ ++/* Modified by Synopsys, Inc, 12/12/2007 */ ++ ++ ++#ifndef _USB_H_ ++#define _USB_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* ++ * The USB records contain some unaligned little-endian word ++ * components. The U[SG]ETW macros take care of both the alignment ++ * and endian problem and should always be used to access non-byte ++ * values. ++ */ ++typedef u_int8_t uByte; ++typedef u_int8_t uWord[2]; ++typedef u_int8_t uDWord[4]; ++ ++#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h)) ++#define UCONSTW(x) { (x) & 0xff, ((x) >> 8) & 0xff } ++#define UCONSTDW(x) { (x) & 0xff, ((x) >> 8) & 0xff, \ ++ ((x) >> 16) & 0xff, ((x) >> 24) & 0xff } ++ ++#if 1 ++#define UGETW(w) ((w)[0] | ((w)[1] << 8)) ++#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8)) ++#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) ++#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \ ++ (w)[1] = (u_int8_t)((v) >> 8), \ ++ (w)[2] = (u_int8_t)((v) >> 16), \ ++ (w)[3] = (u_int8_t)((v) >> 24)) ++#else ++/* ++ * On little-endian machines that can handle unanliged accesses ++ * (e.g. i386) these macros can be replaced by the following. ++ */ ++#define UGETW(w) (*(u_int16_t *)(w)) ++#define USETW(w,v) (*(u_int16_t *)(w) = (v)) ++#define UGETDW(w) (*(u_int32_t *)(w)) ++#define USETDW(w,v) (*(u_int32_t *)(w) = (v)) ++#endif ++ ++/* ++ * Macros for accessing UAS IU fields, which are big-endian ++ */ ++#define IUSETW2(w,h,l) ((w)[0] = (u_int8_t)(h), (w)[1] = (u_int8_t)(l)) ++#define IUCONSTW(x) { ((x) >> 8) & 0xff, (x) & 0xff } ++#define IUCONSTDW(x) { ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \ ++ ((x) >> 8) & 0xff, (x) & 0xff } ++#define IUGETW(w) (((w)[0] << 8) | (w)[1]) ++#define IUSETW(w,v) ((w)[0] = (u_int8_t)((v) >> 8), (w)[1] = (u_int8_t)(v)) ++#define IUGETDW(w) (((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) ++#define IUSETDW(w,v) ((w)[0] = (u_int8_t)((v) >> 24), \ ++ (w)[1] = (u_int8_t)((v) >> 16), \ ++ (w)[2] = (u_int8_t)((v) >> 8), \ ++ (w)[3] = (u_int8_t)(v)) ++ ++#define UPACKED __attribute__((__packed__)) ++ ++typedef struct { ++ uByte bmRequestType; ++ uByte bRequest; ++ uWord wValue; ++ uWord wIndex; ++ uWord wLength; ++} UPACKED usb_device_request_t; ++ ++#define UT_GET_DIR(a) ((a) & 0x80) ++#define UT_WRITE 0x00 ++#define UT_READ 0x80 ++ ++#define UT_GET_TYPE(a) ((a) & 0x60) ++#define UT_STANDARD 0x00 ++#define UT_CLASS 0x20 ++#define UT_VENDOR 0x40 ++ ++#define UT_GET_RECIPIENT(a) ((a) & 0x1f) ++#define UT_DEVICE 0x00 ++#define UT_INTERFACE 0x01 ++#define UT_ENDPOINT 0x02 ++#define UT_OTHER 0x03 ++ ++#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE) ++#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE) ++#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT) ++#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE) ++#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE) ++#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT) ++#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE) ++#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE) ++#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER) ++#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT) ++#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE) ++#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE) ++#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER) ++#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT) ++#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE) ++#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE) ++#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER) ++#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT) ++#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE) ++#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE) ++#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER) ++#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT) ++ ++/* Requests */ ++#define UR_GET_STATUS 0x00 ++#define USTAT_STANDARD_STATUS 0x00 ++#define WUSTAT_WUSB_FEATURE 0x01 ++#define WUSTAT_CHANNEL_INFO 0x02 ++#define WUSTAT_RECEIVED_DATA 0x03 ++#define WUSTAT_MAS_AVAILABILITY 0x04 ++#define WUSTAT_CURRENT_TRANSMIT_POWER 0x05 ++#define UR_CLEAR_FEATURE 0x01 ++#define UR_SET_FEATURE 0x03 ++#define UR_SET_AND_TEST_FEATURE 0x0c ++#define UR_SET_ADDRESS 0x05 ++#define UR_GET_DESCRIPTOR 0x06 ++#define UDESC_DEVICE 0x01 ++#define UDESC_CONFIG 0x02 ++#define UDESC_STRING 0x03 ++#define UDESC_INTERFACE 0x04 ++#define UDESC_ENDPOINT 0x05 ++#define UDESC_SS_USB_COMPANION 0x30 ++#define UDESC_DEVICE_QUALIFIER 0x06 ++#define UDESC_OTHER_SPEED_CONFIGURATION 0x07 ++#define UDESC_INTERFACE_POWER 0x08 ++#define UDESC_OTG 0x09 ++#define WUDESC_SECURITY 0x0c ++#define WUDESC_KEY 0x0d ++#define WUD_GET_KEY_INDEX(_wValue_) ((_wValue_) & 0xf) ++#define WUD_GET_KEY_TYPE(_wValue_) (((_wValue_) & 0x30) >> 4) ++#define WUD_KEY_TYPE_ASSOC 0x01 ++#define WUD_KEY_TYPE_GTK 0x02 ++#define WUD_GET_KEY_ORIGIN(_wValue_) (((_wValue_) & 0x40) >> 6) ++#define WUD_KEY_ORIGIN_HOST 0x00 ++#define WUD_KEY_ORIGIN_DEVICE 0x01 ++#define WUDESC_ENCRYPTION_TYPE 0x0e ++#define WUDESC_BOS 0x0f ++#define WUDESC_DEVICE_CAPABILITY 0x10 ++#define WUDESC_WIRELESS_ENDPOINT_COMPANION 0x11 ++#define UDESC_BOS 0x0f ++#define UDESC_DEVICE_CAPABILITY 0x10 ++#define UDESC_CS_DEVICE 0x21 /* class specific */ ++#define UDESC_CS_CONFIG 0x22 ++#define UDESC_CS_STRING 0x23 ++#define UDESC_CS_INTERFACE 0x24 ++#define UDESC_CS_ENDPOINT 0x25 ++#define UDESC_HUB 0x29 ++#define UR_SET_DESCRIPTOR 0x07 ++#define UR_GET_CONFIG 0x08 ++#define UR_SET_CONFIG 0x09 ++#define UR_GET_INTERFACE 0x0a ++#define UR_SET_INTERFACE 0x0b ++#define UR_SYNCH_FRAME 0x0c ++#define WUR_SET_ENCRYPTION 0x0d ++#define WUR_GET_ENCRYPTION 0x0e ++#define WUR_SET_HANDSHAKE 0x0f ++#define WUR_GET_HANDSHAKE 0x10 ++#define WUR_SET_CONNECTION 0x11 ++#define WUR_SET_SECURITY_DATA 0x12 ++#define WUR_GET_SECURITY_DATA 0x13 ++#define WUR_SET_WUSB_DATA 0x14 ++#define WUDATA_DRPIE_INFO 0x01 ++#define WUDATA_TRANSMIT_DATA 0x02 ++#define WUDATA_TRANSMIT_PARAMS 0x03 ++#define WUDATA_RECEIVE_PARAMS 0x04 ++#define WUDATA_TRANSMIT_POWER 0x05 ++#define WUR_LOOPBACK_DATA_WRITE 0x15 ++#define WUR_LOOPBACK_DATA_READ 0x16 ++#define WUR_SET_INTERFACE_DS 0x17 ++ ++/* Feature numbers */ ++#define UF_ENDPOINT_HALT 0 ++#define UF_DEVICE_REMOTE_WAKEUP 1 ++#define UF_TEST_MODE 2 ++#define UF_DEVICE_B_HNP_ENABLE 3 ++#define UF_DEVICE_A_HNP_SUPPORT 4 ++#define UF_DEVICE_A_ALT_HNP_SUPPORT 5 ++#define WUF_WUSB 3 ++#define WUF_TX_DRPIE 0x0 ++#define WUF_DEV_XMIT_PACKET 0x1 ++#define WUF_COUNT_PACKETS 0x2 ++#define WUF_CAPTURE_PACKETS 0x3 ++#define UF_FUNCTION_SUSPEND 0 ++#define UF_U1_ENABLE 48 ++#define UF_U2_ENABLE 49 ++#define UF_LTM_ENABLE 50 ++ ++/* Class requests from the USB 2.0 hub spec, table 11-15 */ ++#define UCR_CLEAR_HUB_FEATURE (0x2000 | UR_CLEAR_FEATURE) ++#define UCR_CLEAR_PORT_FEATURE (0x2300 | UR_CLEAR_FEATURE) ++#define UCR_GET_HUB_DESCRIPTOR (0xa000 | UR_GET_DESCRIPTOR) ++#define UCR_GET_HUB_STATUS (0xa000 | UR_GET_STATUS) ++#define UCR_GET_PORT_STATUS (0xa300 | UR_GET_STATUS) ++#define UCR_SET_HUB_FEATURE (0x2000 | UR_SET_FEATURE) ++#define UCR_SET_PORT_FEATURE (0x2300 | UR_SET_FEATURE) ++#define UCR_SET_AND_TEST_PORT_FEATURE (0xa300 | UR_SET_AND_TEST_FEATURE) ++ ++#ifdef _MSC_VER ++#include ++#endif ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bDescriptorSubtype; ++} UPACKED usb_descriptor_t; ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++} UPACKED usb_descriptor_header_t; ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uWord bcdUSB; ++#define UD_USB_2_0 0x0200 ++#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0) ++ uByte bDeviceClass; ++ uByte bDeviceSubClass; ++ uByte bDeviceProtocol; ++ uByte bMaxPacketSize; ++ /* The fields below are not part of the initial descriptor. */ ++ uWord idVendor; ++ uWord idProduct; ++ uWord bcdDevice; ++ uByte iManufacturer; ++ uByte iProduct; ++ uByte iSerialNumber; ++ uByte bNumConfigurations; ++} UPACKED usb_device_descriptor_t; ++#define USB_DEVICE_DESCRIPTOR_SIZE 18 ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uWord wTotalLength; ++ uByte bNumInterface; ++ uByte bConfigurationValue; ++ uByte iConfiguration; ++#define UC_ATT_ONE (1 << 7) /* must be set */ ++#define UC_ATT_SELFPOWER (1 << 6) /* self powered */ ++#define UC_ATT_WAKEUP (1 << 5) /* can wakeup */ ++#define UC_ATT_BATTERY (1 << 4) /* battery powered */ ++ uByte bmAttributes; ++#define UC_BUS_POWERED 0x80 ++#define UC_SELF_POWERED 0x40 ++#define UC_REMOTE_WAKEUP 0x20 ++ uByte bMaxPower; /* max current in 2 mA units */ ++#define UC_POWER_FACTOR 2 ++} UPACKED usb_config_descriptor_t; ++#define USB_CONFIG_DESCRIPTOR_SIZE 9 ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bInterfaceNumber; ++ uByte bAlternateSetting; ++ uByte bNumEndpoints; ++ uByte bInterfaceClass; ++ uByte bInterfaceSubClass; ++ uByte bInterfaceProtocol; ++ uByte iInterface; ++} UPACKED usb_interface_descriptor_t; ++#define USB_INTERFACE_DESCRIPTOR_SIZE 9 ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bEndpointAddress; ++#define UE_GET_DIR(a) ((a) & 0x80) ++#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7)) ++#define UE_DIR_IN 0x80 ++#define UE_DIR_OUT 0x00 ++#define UE_ADDR 0x0f ++#define UE_GET_ADDR(a) ((a) & UE_ADDR) ++ uByte bmAttributes; ++#define UE_XFERTYPE 0x03 ++#define UE_CONTROL 0x00 ++#define UE_ISOCHRONOUS 0x01 ++#define UE_BULK 0x02 ++#define UE_INTERRUPT 0x03 ++#define UE_GET_XFERTYPE(a) ((a) & UE_XFERTYPE) ++#define UE_ISO_TYPE 0x0c ++#define UE_ISO_ASYNC 0x04 ++#define UE_ISO_ADAPT 0x08 ++#define UE_ISO_SYNC 0x0c ++#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE) ++ uWord wMaxPacketSize; ++ uByte bInterval; ++} UPACKED usb_endpoint_descriptor_t; ++#define USB_ENDPOINT_DESCRIPTOR_SIZE 7 ++ ++typedef struct ss_endpoint_companion_descriptor { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bMaxBurst; ++#define USSE_GET_MAX_STREAMS(a) ((a) & 0x1f) ++#define USSE_SET_MAX_STREAMS(a, b) ((a) | ((b) & 0x1f)) ++#define USSE_GET_MAX_PACKET_NUM(a) ((a) & 0x03) ++#define USSE_SET_MAX_PACKET_NUM(a, b) ((a) | ((b) & 0x03)) ++ uByte bmAttributes; ++ uWord wBytesPerInterval; ++} UPACKED ss_endpoint_companion_descriptor_t; ++#define USB_SS_ENDPOINT_COMPANION_DESCRIPTOR_SIZE 6 ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uWord bString[127]; ++} UPACKED usb_string_descriptor_t; ++#define USB_MAX_STRING_LEN 128 ++#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */ ++ ++/* Hub specific request */ ++#define UR_GET_BUS_STATE 0x02 ++#define UR_CLEAR_TT_BUFFER 0x08 ++#define UR_RESET_TT 0x09 ++#define UR_GET_TT_STATE 0x0a ++#define UR_STOP_TT 0x0b ++ ++/* Hub features */ ++#define UHF_C_HUB_LOCAL_POWER 0 ++#define UHF_C_HUB_OVER_CURRENT 1 ++#define UHF_PORT_CONNECTION 0 ++#define UHF_PORT_ENABLE 1 ++#define UHF_PORT_SUSPEND 2 ++#define UHF_PORT_OVER_CURRENT 3 ++#define UHF_PORT_RESET 4 ++#define UHF_PORT_L1 5 ++#define UHF_PORT_POWER 8 ++#define UHF_PORT_LOW_SPEED 9 ++#define UHF_PORT_HIGH_SPEED 10 ++#define UHF_C_PORT_CONNECTION 16 ++#define UHF_C_PORT_ENABLE 17 ++#define UHF_C_PORT_SUSPEND 18 ++#define UHF_C_PORT_OVER_CURRENT 19 ++#define UHF_C_PORT_RESET 20 ++#define UHF_C_PORT_L1 23 ++#define UHF_PORT_TEST 21 ++#define UHF_PORT_INDICATOR 22 ++ ++typedef struct { ++ uByte bDescLength; ++ uByte bDescriptorType; ++ uByte bNbrPorts; ++ uWord wHubCharacteristics; ++#define UHD_PWR 0x0003 ++#define UHD_PWR_GANGED 0x0000 ++#define UHD_PWR_INDIVIDUAL 0x0001 ++#define UHD_PWR_NO_SWITCH 0x0002 ++#define UHD_COMPOUND 0x0004 ++#define UHD_OC 0x0018 ++#define UHD_OC_GLOBAL 0x0000 ++#define UHD_OC_INDIVIDUAL 0x0008 ++#define UHD_OC_NONE 0x0010 ++#define UHD_TT_THINK 0x0060 ++#define UHD_TT_THINK_8 0x0000 ++#define UHD_TT_THINK_16 0x0020 ++#define UHD_TT_THINK_24 0x0040 ++#define UHD_TT_THINK_32 0x0060 ++#define UHD_PORT_IND 0x0080 ++ uByte bPwrOn2PwrGood; /* delay in 2 ms units */ ++#define UHD_PWRON_FACTOR 2 ++ uByte bHubContrCurrent; ++ uByte DeviceRemovable[32]; /* max 255 ports */ ++#define UHD_NOT_REMOV(desc, i) \ ++ (((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1) ++ /* deprecated */ uByte PortPowerCtrlMask[1]; ++} UPACKED usb_hub_descriptor_t; ++#define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */ ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uWord bcdUSB; ++ uByte bDeviceClass; ++ uByte bDeviceSubClass; ++ uByte bDeviceProtocol; ++ uByte bMaxPacketSize0; ++ uByte bNumConfigurations; ++ uByte bReserved; ++} UPACKED usb_device_qualifier_t; ++#define USB_DEVICE_QUALIFIER_SIZE 10 ++ ++typedef struct { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bmAttributes; ++#define UOTG_SRP 0x01 ++#define UOTG_HNP 0x02 ++} UPACKED usb_otg_descriptor_t; ++ ++/* OTG feature selectors */ ++#define UOTG_B_HNP_ENABLE 3 ++#define UOTG_A_HNP_SUPPORT 4 ++#define UOTG_A_ALT_HNP_SUPPORT 5 ++ ++typedef struct { ++ uWord wStatus; ++/* Device status flags */ ++#define UDS_SELF_POWERED 0x0001 ++#define UDS_REMOTE_WAKEUP 0x0002 ++/* Endpoint status flags */ ++#define UES_HALT 0x0001 ++} UPACKED usb_status_t; ++ ++typedef struct { ++ uWord wHubStatus; ++#define UHS_LOCAL_POWER 0x0001 ++#define UHS_OVER_CURRENT 0x0002 ++ uWord wHubChange; ++} UPACKED usb_hub_status_t; ++ ++typedef struct { ++ uWord wPortStatus; ++#define UPS_CURRENT_CONNECT_STATUS 0x0001 ++#define UPS_PORT_ENABLED 0x0002 ++#define UPS_SUSPEND 0x0004 ++#define UPS_OVERCURRENT_INDICATOR 0x0008 ++#define UPS_RESET 0x0010 ++#define UPS_PORT_POWER 0x0100 ++#define UPS_LOW_SPEED 0x0200 ++#define UPS_HIGH_SPEED 0x0400 ++#define UPS_PORT_TEST 0x0800 ++#define UPS_PORT_INDICATOR 0x1000 ++ uWord wPortChange; ++#define UPS_C_CONNECT_STATUS 0x0001 ++#define UPS_C_PORT_ENABLED 0x0002 ++#define UPS_C_SUSPEND 0x0004 ++#define UPS_C_OVERCURRENT_INDICATOR 0x0008 ++#define UPS_C_PORT_RESET 0x0010 ++} UPACKED usb_port_status_t; ++ ++#ifdef _MSC_VER ++#include ++#endif ++ ++/* Device class codes */ ++#define UDCLASS_IN_INTERFACE 0x00 ++#define UDCLASS_COMM 0x02 ++#define UDCLASS_HUB 0x09 ++#define UDSUBCLASS_HUB 0x00 ++#define UDPROTO_FSHUB 0x00 ++#define UDPROTO_HSHUBSTT 0x01 ++#define UDPROTO_HSHUBMTT 0x02 ++#define UDCLASS_DIAGNOSTIC 0xdc ++#define UDCLASS_WIRELESS 0xe0 ++#define UDSUBCLASS_RF 0x01 ++#define UDPROTO_BLUETOOTH 0x01 ++#define UDCLASS_VENDOR 0xff ++ ++/* Interface class codes */ ++#define UICLASS_UNSPEC 0x00 ++ ++#define UICLASS_AUDIO 0x01 ++#define UISUBCLASS_AUDIOCONTROL 1 ++#define UISUBCLASS_AUDIOSTREAM 2 ++#define UISUBCLASS_MIDISTREAM 3 ++ ++#define UICLASS_CDC 0x02 /* communication */ ++#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1 ++#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2 ++#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3 ++#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4 ++#define UISUBCLASS_CAPI_CONTROLMODEL 5 ++#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6 ++#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7 ++#define UIPROTO_CDC_AT 1 ++ ++#define UICLASS_HID 0x03 ++#define UISUBCLASS_BOOT 1 ++#define UIPROTO_BOOT_KEYBOARD 1 ++ ++#define UICLASS_PHYSICAL 0x05 ++ ++#define UICLASS_IMAGE 0x06 ++ ++#define UICLASS_PRINTER 0x07 ++#define UISUBCLASS_PRINTER 1 ++#define UIPROTO_PRINTER_UNI 1 ++#define UIPROTO_PRINTER_BI 2 ++#define UIPROTO_PRINTER_1284 3 ++ ++#define UICLASS_MASS 0x08 ++#define UISUBCLASS_RBC 1 ++#define UISUBCLASS_SFF8020I 2 ++#define UISUBCLASS_QIC157 3 ++#define UISUBCLASS_UFI 4 ++#define UISUBCLASS_SFF8070I 5 ++#define UISUBCLASS_SCSI 6 ++#define UIPROTO_MASS_CBI_I 0 ++#define UIPROTO_MASS_CBI 1 ++#define UIPROTO_MASS_BBB_OLD 2 /* Not in the spec anymore */ ++#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */ ++ ++#define UICLASS_HUB 0x09 ++#define UISUBCLASS_HUB 0 ++#define UIPROTO_FSHUB 0 ++#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */ ++#define UIPROTO_HSHUBMTT 1 ++ ++#define UICLASS_CDC_DATA 0x0a ++#define UISUBCLASS_DATA 0 ++#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */ ++#define UIPROTO_DATA_HDLC 0x31 /* HDLC */ ++#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */ ++#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */ ++#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */ ++#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */ ++#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */ ++#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */ ++#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */ ++#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */ ++#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */ ++#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/ ++#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */ ++ ++#define UICLASS_SMARTCARD 0x0b ++ ++/*#define UICLASS_FIRM_UPD 0x0c*/ ++ ++#define UICLASS_SECURITY 0x0d ++ ++#define UICLASS_DIAGNOSTIC 0xdc ++ ++#define UICLASS_WIRELESS 0xe0 ++#define UISUBCLASS_RF 0x01 ++#define UIPROTO_BLUETOOTH 0x01 ++ ++#define UICLASS_APPL_SPEC 0xfe ++#define UISUBCLASS_FIRMWARE_DOWNLOAD 1 ++#define UISUBCLASS_IRDA 2 ++#define UIPROTO_IRDA 0 ++ ++#define UICLASS_VENDOR 0xff ++ ++#define USB_HUB_MAX_DEPTH 5 ++ ++/* ++ * Minimum time a device needs to be powered down to go through ++ * a power cycle. XXX Are these time in the spec? ++ */ ++#define USB_POWER_DOWN_TIME 200 /* ms */ ++#define USB_PORT_POWER_DOWN_TIME 100 /* ms */ ++ ++#if 0 ++/* These are the values from the spec. */ ++#define USB_PORT_RESET_DELAY 10 /* ms */ ++#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */ ++#define USB_PORT_RESET_RECOVERY 10 /* ms */ ++#define USB_PORT_POWERUP_DELAY 100 /* ms */ ++#define USB_SET_ADDRESS_SETTLE 2 /* ms */ ++#define USB_RESUME_DELAY (20*5) /* ms */ ++#define USB_RESUME_WAIT 10 /* ms */ ++#define USB_RESUME_RECOVERY 10 /* ms */ ++#define USB_EXTRA_POWER_UP_TIME 0 /* ms */ ++#else ++/* Allow for marginal (i.e. non-conforming) devices. */ ++#define USB_PORT_RESET_DELAY 50 /* ms */ ++#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */ ++#define USB_PORT_RESET_RECOVERY 250 /* ms */ ++#define USB_PORT_POWERUP_DELAY 300 /* ms */ ++#define USB_SET_ADDRESS_SETTLE 10 /* ms */ ++#define USB_RESUME_DELAY (50*5) /* ms */ ++#define USB_RESUME_WAIT 50 /* ms */ ++#define USB_RESUME_RECOVERY 50 /* ms */ ++#define USB_EXTRA_POWER_UP_TIME 20 /* ms */ ++#endif ++ ++#define USB_MIN_POWER 100 /* mA */ ++#define USB_MAX_POWER 500 /* mA */ ++ ++#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/ ++ ++#define USB_UNCONFIG_NO 0 ++#define USB_UNCONFIG_INDEX (-1) ++ ++/*** ioctl() related stuff ***/ ++ ++struct usb_ctl_request { ++ int ucr_addr; ++ usb_device_request_t ucr_request; ++ void *ucr_data; ++ int ucr_flags; ++#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */ ++ int ucr_actlen; /* actual length transferred */ ++}; ++ ++struct usb_alt_interface { ++ int uai_config_index; ++ int uai_interface_index; ++ int uai_alt_no; ++}; ++ ++#define USB_CURRENT_CONFIG_INDEX (-1) ++#define USB_CURRENT_ALT_INDEX (-1) ++ ++struct usb_config_desc { ++ int ucd_config_index; ++ usb_config_descriptor_t ucd_desc; ++}; ++ ++struct usb_interface_desc { ++ int uid_config_index; ++ int uid_interface_index; ++ int uid_alt_index; ++ usb_interface_descriptor_t uid_desc; ++}; ++ ++struct usb_endpoint_desc { ++ int ued_config_index; ++ int ued_interface_index; ++ int ued_alt_index; ++ int ued_endpoint_index; ++ usb_endpoint_descriptor_t ued_desc; ++}; ++ ++struct usb_full_desc { ++ int ufd_config_index; ++ u_int ufd_size; ++ u_char *ufd_data; ++}; ++ ++struct usb_string_desc { ++ int usd_string_index; ++ int usd_language_id; ++ usb_string_descriptor_t usd_desc; ++}; ++ ++struct usb_ctl_report_desc { ++ int ucrd_size; ++ u_char ucrd_data[1024]; /* filled data size will vary */ ++}; ++ ++typedef struct { u_int32_t cookie; } usb_event_cookie_t; ++ ++#define USB_MAX_DEVNAMES 4 ++#define USB_MAX_DEVNAMELEN 16 ++struct usb_device_info { ++ u_int8_t udi_bus; ++ u_int8_t udi_addr; /* device address */ ++ usb_event_cookie_t udi_cookie; ++ char udi_product[USB_MAX_STRING_LEN]; ++ char udi_vendor[USB_MAX_STRING_LEN]; ++ char udi_release[8]; ++ u_int16_t udi_productNo; ++ u_int16_t udi_vendorNo; ++ u_int16_t udi_releaseNo; ++ u_int8_t udi_class; ++ u_int8_t udi_subclass; ++ u_int8_t udi_protocol; ++ u_int8_t udi_config; ++ u_int8_t udi_speed; ++#define USB_SPEED_UNKNOWN 0 ++#define USB_SPEED_LOW 1 ++#define USB_SPEED_FULL 2 ++#define USB_SPEED_HIGH 3 ++#define USB_SPEED_VARIABLE 4 ++#define USB_SPEED_SUPER 5 ++ int udi_power; /* power consumption in mA, 0 if selfpowered */ ++ int udi_nports; ++ char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; ++ u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */ ++#define USB_PORT_ENABLED 0xff ++#define USB_PORT_SUSPENDED 0xfe ++#define USB_PORT_POWERED 0xfd ++#define USB_PORT_DISABLED 0xfc ++}; ++ ++struct usb_ctl_report { ++ int ucr_report; ++ u_char ucr_data[1024]; /* filled data size will vary */ ++}; ++ ++struct usb_device_stats { ++ u_long uds_requests[4]; /* indexed by transfer type UE_* */ ++}; ++ ++#define WUSB_MIN_IE 0x80 ++#define WUSB_WCTA_IE 0x80 ++#define WUSB_WCONNECTACK_IE 0x81 ++#define WUSB_WHOSTINFO_IE 0x82 ++#define WUHI_GET_CA(_bmAttributes_) ((_bmAttributes_) & 0x3) ++#define WUHI_CA_RECONN 0x00 ++#define WUHI_CA_LIMITED 0x01 ++#define WUHI_CA_ALL 0x03 ++#define WUHI_GET_MLSI(_bmAttributes_) (((_bmAttributes_) & 0x38) >> 3) ++#define WUSB_WCHCHANGEANNOUNCE_IE 0x83 ++#define WUSB_WDEV_DISCONNECT_IE 0x84 ++#define WUSB_WHOST_DISCONNECT_IE 0x85 ++#define WUSB_WRELEASE_CHANNEL_IE 0x86 ++#define WUSB_WWORK_IE 0x87 ++#define WUSB_WCHANNEL_STOP_IE 0x88 ++#define WUSB_WDEV_KEEPALIVE_IE 0x89 ++#define WUSB_WISOCH_DISCARD_IE 0x8A ++#define WUSB_WRESETDEVICE_IE 0x8B ++#define WUSB_WXMIT_PACKET_ADJUST_IE 0x8C ++#define WUSB_MAX_IE 0x8C ++ ++/* Device Notification Types */ ++ ++#define WUSB_DN_MIN 0x01 ++#define WUSB_DN_CONNECT 0x01 ++# define WUSB_DA_OLDCONN 0x00 ++# define WUSB_DA_NEWCONN 0x01 ++# define WUSB_DA_SELF_BEACON 0x02 ++# define WUSB_DA_DIR_BEACON 0x04 ++# define WUSB_DA_NO_BEACON 0x06 ++#define WUSB_DN_DISCONNECT 0x02 ++#define WUSB_DN_EPRDY 0x03 ++#define WUSB_DN_MASAVAILCHANGED 0x04 ++#define WUSB_DN_REMOTEWAKEUP 0x05 ++#define WUSB_DN_SLEEP 0x06 ++#define WUSB_DN_ALIVE 0x07 ++#define WUSB_DN_MAX 0x07 ++ ++#ifdef _MSC_VER ++#include ++#endif ++ ++/* WUSB Handshake Data. Used during the SET/GET HANDSHAKE requests */ ++typedef struct wusb_hndshk_data { ++ uByte bMessageNumber; ++ uByte bStatus; ++ uByte tTKID[3]; ++ uByte bReserved; ++ uByte CDID[16]; ++ uByte Nonce[16]; ++ uByte MIC[8]; ++} UPACKED wusb_hndshk_data_t; ++#define WUSB_HANDSHAKE_LEN_FOR_MIC 38 ++ ++/* WUSB Connection Context */ ++typedef struct wusb_conn_context { ++ uByte CHID [16]; ++ uByte CDID [16]; ++ uByte CK [16]; ++} UPACKED wusb_conn_context_t; ++ ++/* WUSB Security Descriptor */ ++typedef struct wusb_security_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ uWord wTotalLength; ++ uByte bNumEncryptionTypes; ++} UPACKED wusb_security_desc_t; ++ ++/* WUSB Encryption Type Descriptor */ ++typedef struct wusb_encrypt_type_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ ++ uByte bEncryptionType; ++#define WUETD_UNSECURE 0 ++#define WUETD_WIRED 1 ++#define WUETD_CCM_1 2 ++#define WUETD_RSA_1 3 ++ ++ uByte bEncryptionValue; ++ uByte bAuthKeyIndex; ++} UPACKED wusb_encrypt_type_desc_t; ++ ++/* WUSB Key Descriptor */ ++typedef struct wusb_key_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte tTKID[3]; ++ uByte bReserved; ++ uByte KeyData[1]; /* variable length */ ++} UPACKED wusb_key_desc_t; ++ ++/* WUSB BOS Descriptor (Binary device Object Store) */ ++typedef struct wusb_bos_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ uWord wTotalLength; ++ uByte bNumDeviceCaps; ++} UPACKED wusb_bos_desc_t; ++ ++#define USB_DEVICE_CAPABILITY_20_EXTENSION 0x02 ++typedef struct usb_dev_cap_20_ext_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bDevCapabilityType; ++#define USB_20_EXT_LPM 0x02 ++ uDWord bmAttributes; ++} UPACKED usb_dev_cap_20_ext_desc_t; ++ ++#define USB_DEVICE_CAPABILITY_SS_USB 0x03 ++typedef struct usb_dev_cap_ss_usb { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bDevCapabilityType; ++#define USB_DC_SS_USB_LTM_CAPABLE 0x02 ++ uByte bmAttributes; ++#define USB_DC_SS_USB_SPEED_SUPPORT_LOW 0x01 ++#define USB_DC_SS_USB_SPEED_SUPPORT_FULL 0x02 ++#define USB_DC_SS_USB_SPEED_SUPPORT_HIGH 0x04 ++#define USB_DC_SS_USB_SPEED_SUPPORT_SS 0x08 ++ uWord wSpeedsSupported; ++ uByte bFunctionalitySupport; ++ uByte bU1DevExitLat; ++ uWord wU2DevExitLat; ++} UPACKED usb_dev_cap_ss_usb_t; ++ ++#define USB_DEVICE_CAPABILITY_CONTAINER_ID 0x04 ++typedef struct usb_dev_cap_container_id { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bDevCapabilityType; ++ uByte bReserved; ++ uByte containerID[16]; ++} UPACKED usb_dev_cap_container_id_t; ++ ++/* Device Capability Type Codes */ ++#define WUSB_DEVICE_CAPABILITY_WIRELESS_USB 0x01 ++ ++/* Device Capability Descriptor */ ++typedef struct wusb_dev_cap_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bDevCapabilityType; ++ uByte caps[1]; /* Variable length */ ++} UPACKED wusb_dev_cap_desc_t; ++ ++/* Device Capability Descriptor */ ++typedef struct wusb_dev_cap_uwb_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bDevCapabilityType; ++ uByte bmAttributes; ++ uWord wPHYRates; /* Bitmap */ ++ uByte bmTFITXPowerInfo; ++ uByte bmFFITXPowerInfo; ++ uWord bmBandGroup; ++ uByte bReserved; ++} UPACKED wusb_dev_cap_uwb_desc_t; ++ ++/* Wireless USB Endpoint Companion Descriptor */ ++typedef struct wusb_endpoint_companion_desc { ++ uByte bLength; ++ uByte bDescriptorType; ++ uByte bMaxBurst; ++ uByte bMaxSequence; ++ uWord wMaxStreamDelay; ++ uWord wOverTheAirPacketSize; ++ uByte bOverTheAirInterval; ++ uByte bmCompAttributes; ++} UPACKED wusb_endpoint_companion_desc_t; ++ ++/* Wireless USB Numeric Association M1 Data Structure */ ++typedef struct wusb_m1_data { ++ uByte version; ++ uWord langId; ++ uByte deviceFriendlyNameLength; ++ uByte sha_256_m3[32]; ++ uByte deviceFriendlyName[256]; ++} UPACKED wusb_m1_data_t; ++ ++typedef struct wusb_m2_data { ++ uByte version; ++ uWord langId; ++ uByte hostFriendlyNameLength; ++ uByte pkh[384]; ++ uByte hostFriendlyName[256]; ++} UPACKED wusb_m2_data_t; ++ ++typedef struct wusb_m3_data { ++ uByte pkd[384]; ++ uByte nd; ++} UPACKED wusb_m3_data_t; ++ ++typedef struct wusb_m4_data { ++ uDWord _attributeTypeIdAndLength_1; ++ uWord associationTypeId; ++ ++ uDWord _attributeTypeIdAndLength_2; ++ uWord associationSubTypeId; ++ ++ uDWord _attributeTypeIdAndLength_3; ++ uDWord length; ++ ++ uDWord _attributeTypeIdAndLength_4; ++ uDWord associationStatus; ++ ++ uDWord _attributeTypeIdAndLength_5; ++ uByte chid[16]; ++ ++ uDWord _attributeTypeIdAndLength_6; ++ uByte cdid[16]; ++ ++ uDWord _attributeTypeIdAndLength_7; ++ uByte bandGroups[2]; ++} UPACKED wusb_m4_data_t; ++ ++#ifdef _MSC_VER ++#include ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _USB_H_ */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/Makefile 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,80 @@ ++# ++# Makefile for DWC_otg Highspeed USB controller driver ++# ++ ++ifneq ($(KERNELRELEASE),) ++ ++# Use the BUS_INTERFACE variable to compile the software for either ++# PCI(PCI_INTERFACE) or LM(LM_INTERFACE) bus. ++ifeq ($(BUS_INTERFACE),) ++# BUS_INTERFACE = -DPCI_INTERFACE ++# BUS_INTERFACE = -DLM_INTERFACE ++ BUS_INTERFACE = -DPLATFORM_INTERFACE ++endif ++ ++#EXTRA_CFLAGS += -DDEBUG ++#EXTRA_CFLAGS += -DDWC_OTG_DEBUGLEV=1 # reduce common debug msgs ++ ++# Use one of the following flags to compile the software in host-only or ++# device-only mode. ++#EXTRA_CFLAGS += -DDWC_HOST_ONLY ++#EXTRA_CFLAGS += -DDWC_DEVICE_ONLY ++ ++EXTRA_CFLAGS += -Dlinux -DDWC_HS_ELECT_TST ++#EXTRA_CFLAGS += -DDWC_EN_ISOC ++EXTRA_CFLAGS += -I$(obj)/../dwc_common_port ++#EXTRA_CFLAGS += -I$(PORTLIB) ++EXTRA_CFLAGS += -DDWC_LINUX ++EXTRA_CFLAGS += $(CFI) ++EXTRA_CFLAGS += $(BUS_INTERFACE) ++#EXTRA_CFLAGS += -DDWC_DEV_SRPCAP ++ ++obj-$(CONFIG_USB_DWCOTG) += dwc_otg.o ++ ++dwc_otg-objs := dwc_otg_driver.o dwc_otg_attr.o ++dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o ++dwc_otg-objs += dwc_otg_pcd_linux.o dwc_otg_pcd.o dwc_otg_pcd_intr.o ++dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_linux.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o dwc_otg_hcd_ddma.o ++dwc_otg-objs += dwc_otg_adp.o ++ifneq ($(CFI),) ++dwc_otg-objs += dwc_otg_cfi.o ++endif ++ ++kernrelwd := $(subst ., ,$(KERNELRELEASE)) ++kernrel3 := $(word 1,$(kernrelwd)).$(word 2,$(kernrelwd)).$(word 3,$(kernrelwd)) ++ ++ifneq ($(kernrel3),2.6.20) ++EXTRA_CFLAGS += $(CPPFLAGS) ++endif ++ ++else ++ ++PWD := $(shell pwd) ++PORTLIB := $(PWD)/../dwc_common_port ++ ++# Command paths ++CTAGS := $(CTAGS) ++DOXYGEN := $(DOXYGEN) ++ ++default: portlib ++ $(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules ++ ++install: default ++ $(MAKE) -C$(KDIR) M=$(PORTLIB) modules_install ++ $(MAKE) -C$(KDIR) M=$(PWD) modules_install ++ ++portlib: ++ $(MAKE) -C$(KDIR) M=$(PORTLIB) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules ++ cp $(PORTLIB)/Module.symvers $(PWD)/ ++ ++docs: $(wildcard *.[hc]) doc/doxygen.cfg ++ $(DOXYGEN) doc/doxygen.cfg ++ ++tags: $(wildcard *.[hc]) ++ $(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h) ++ ++ ++clean: ++ rm -rf *.o *.ko .*cmd *.mod.c .tmp_versions Module.symvers ++ ++endif +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/doc/doxygen.cfg +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/doc/doxygen.cfg 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,224 @@ ++# Doxyfile 1.3.9.1 ++ ++#--------------------------------------------------------------------------- ++# Project related configuration options ++#--------------------------------------------------------------------------- ++PROJECT_NAME = "DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver" ++PROJECT_NUMBER = v3.00a ++OUTPUT_DIRECTORY = ./doc/ ++CREATE_SUBDIRS = NO ++OUTPUT_LANGUAGE = English ++BRIEF_MEMBER_DESC = YES ++REPEAT_BRIEF = YES ++ABBREVIATE_BRIEF = "The $name class" \ ++ "The $name widget" \ ++ "The $name file" \ ++ is \ ++ provides \ ++ specifies \ ++ contains \ ++ represents \ ++ a \ ++ an \ ++ the ++ALWAYS_DETAILED_SEC = NO ++INLINE_INHERITED_MEMB = NO ++FULL_PATH_NAMES = NO ++STRIP_FROM_PATH = ++STRIP_FROM_INC_PATH = ++SHORT_NAMES = NO ++JAVADOC_AUTOBRIEF = YES ++MULTILINE_CPP_IS_BRIEF = NO ++INHERIT_DOCS = YES ++DISTRIBUTE_GROUP_DOC = NO ++TAB_SIZE = 8 ++ALIASES = ++OPTIMIZE_OUTPUT_FOR_C = YES ++OPTIMIZE_OUTPUT_JAVA = NO ++SUBGROUPING = YES ++#--------------------------------------------------------------------------- ++# Build related configuration options ++#--------------------------------------------------------------------------- ++EXTRACT_ALL = NO ++EXTRACT_PRIVATE = YES ++EXTRACT_STATIC = YES ++EXTRACT_LOCAL_CLASSES = YES ++EXTRACT_LOCAL_METHODS = NO ++HIDE_UNDOC_MEMBERS = NO ++HIDE_UNDOC_CLASSES = NO ++HIDE_FRIEND_COMPOUNDS = NO ++HIDE_IN_BODY_DOCS = NO ++INTERNAL_DOCS = NO ++CASE_SENSE_NAMES = NO ++HIDE_SCOPE_NAMES = NO ++SHOW_INCLUDE_FILES = YES ++INLINE_INFO = YES ++SORT_MEMBER_DOCS = NO ++SORT_BRIEF_DOCS = NO ++SORT_BY_SCOPE_NAME = NO ++GENERATE_TODOLIST = YES ++GENERATE_TESTLIST = YES ++GENERATE_BUGLIST = YES ++GENERATE_DEPRECATEDLIST= YES ++ENABLED_SECTIONS = ++MAX_INITIALIZER_LINES = 30 ++SHOW_USED_FILES = YES ++SHOW_DIRECTORIES = YES ++#--------------------------------------------------------------------------- ++# configuration options related to warning and progress messages ++#--------------------------------------------------------------------------- ++QUIET = YES ++WARNINGS = YES ++WARN_IF_UNDOCUMENTED = NO ++WARN_IF_DOC_ERROR = YES ++WARN_FORMAT = "$file:$line: $text" ++WARN_LOGFILE = ++#--------------------------------------------------------------------------- ++# configuration options related to the input files ++#--------------------------------------------------------------------------- ++INPUT = . ++FILE_PATTERNS = *.c \ ++ *.h \ ++ ./linux/*.c \ ++ ./linux/*.h ++RECURSIVE = NO ++EXCLUDE = ./test/ \ ++ ./dwc_otg/.AppleDouble/ ++EXCLUDE_SYMLINKS = YES ++EXCLUDE_PATTERNS = *.mod.* ++EXAMPLE_PATH = ++EXAMPLE_PATTERNS = * ++EXAMPLE_RECURSIVE = NO ++IMAGE_PATH = ++INPUT_FILTER = ++FILTER_PATTERNS = ++FILTER_SOURCE_FILES = NO ++#--------------------------------------------------------------------------- ++# configuration options related to source browsing ++#--------------------------------------------------------------------------- ++SOURCE_BROWSER = YES ++INLINE_SOURCES = NO ++STRIP_CODE_COMMENTS = YES ++REFERENCED_BY_RELATION = NO ++REFERENCES_RELATION = NO ++VERBATIM_HEADERS = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the alphabetical class index ++#--------------------------------------------------------------------------- ++ALPHABETICAL_INDEX = NO ++COLS_IN_ALPHA_INDEX = 5 ++IGNORE_PREFIX = ++#--------------------------------------------------------------------------- ++# configuration options related to the HTML output ++#--------------------------------------------------------------------------- ++GENERATE_HTML = YES ++HTML_OUTPUT = html ++HTML_FILE_EXTENSION = .html ++HTML_HEADER = ++HTML_FOOTER = ++HTML_STYLESHEET = ++HTML_ALIGN_MEMBERS = YES ++GENERATE_HTMLHELP = NO ++CHM_FILE = ++HHC_LOCATION = ++GENERATE_CHI = NO ++BINARY_TOC = NO ++TOC_EXPAND = NO ++DISABLE_INDEX = NO ++ENUM_VALUES_PER_LINE = 4 ++GENERATE_TREEVIEW = YES ++TREEVIEW_WIDTH = 250 ++#--------------------------------------------------------------------------- ++# configuration options related to the LaTeX output ++#--------------------------------------------------------------------------- ++GENERATE_LATEX = NO ++LATEX_OUTPUT = latex ++LATEX_CMD_NAME = latex ++MAKEINDEX_CMD_NAME = makeindex ++COMPACT_LATEX = NO ++PAPER_TYPE = a4wide ++EXTRA_PACKAGES = ++LATEX_HEADER = ++PDF_HYPERLINKS = NO ++USE_PDFLATEX = NO ++LATEX_BATCHMODE = NO ++LATEX_HIDE_INDICES = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the RTF output ++#--------------------------------------------------------------------------- ++GENERATE_RTF = NO ++RTF_OUTPUT = rtf ++COMPACT_RTF = NO ++RTF_HYPERLINKS = NO ++RTF_STYLESHEET_FILE = ++RTF_EXTENSIONS_FILE = ++#--------------------------------------------------------------------------- ++# configuration options related to the man page output ++#--------------------------------------------------------------------------- ++GENERATE_MAN = NO ++MAN_OUTPUT = man ++MAN_EXTENSION = .3 ++MAN_LINKS = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the XML output ++#--------------------------------------------------------------------------- ++GENERATE_XML = NO ++XML_OUTPUT = xml ++XML_SCHEMA = ++XML_DTD = ++XML_PROGRAMLISTING = YES ++#--------------------------------------------------------------------------- ++# configuration options for the AutoGen Definitions output ++#--------------------------------------------------------------------------- ++GENERATE_AUTOGEN_DEF = NO ++#--------------------------------------------------------------------------- ++# configuration options related to the Perl module output ++#--------------------------------------------------------------------------- ++GENERATE_PERLMOD = NO ++PERLMOD_LATEX = NO ++PERLMOD_PRETTY = YES ++PERLMOD_MAKEVAR_PREFIX = ++#--------------------------------------------------------------------------- ++# Configuration options related to the preprocessor ++#--------------------------------------------------------------------------- ++ENABLE_PREPROCESSING = YES ++MACRO_EXPANSION = YES ++EXPAND_ONLY_PREDEF = YES ++SEARCH_INCLUDES = YES ++INCLUDE_PATH = ++INCLUDE_FILE_PATTERNS = ++PREDEFINED = DEVICE_ATTR DWC_EN_ISOC ++EXPAND_AS_DEFINED = DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW DWC_OTG_DEVICE_ATTR_BITFIELD_STORE DWC_OTG_DEVICE_ATTR_BITFIELD_RW DWC_OTG_DEVICE_ATTR_BITFIELD_RO DWC_OTG_DEVICE_ATTR_REG_SHOW DWC_OTG_DEVICE_ATTR_REG_STORE DWC_OTG_DEVICE_ATTR_REG32_RW DWC_OTG_DEVICE_ATTR_REG32_RO DWC_EN_ISOC ++SKIP_FUNCTION_MACROS = NO ++#--------------------------------------------------------------------------- ++# Configuration::additions related to external references ++#--------------------------------------------------------------------------- ++TAGFILES = ++GENERATE_TAGFILE = ++ALLEXTERNALS = NO ++EXTERNAL_GROUPS = YES ++PERL_PATH = /usr/bin/perl ++#--------------------------------------------------------------------------- ++# Configuration options related to the dot tool ++#--------------------------------------------------------------------------- ++CLASS_DIAGRAMS = YES ++HIDE_UNDOC_RELATIONS = YES ++HAVE_DOT = NO ++CLASS_GRAPH = YES ++COLLABORATION_GRAPH = YES ++UML_LOOK = NO ++TEMPLATE_RELATIONS = NO ++INCLUDE_GRAPH = YES ++INCLUDED_BY_GRAPH = YES ++CALL_GRAPH = NO ++GRAPHICAL_HIERARCHY = YES ++DOT_IMAGE_FORMAT = png ++DOT_PATH = ++DOTFILE_DIRS = ++MAX_DOT_GRAPH_DEPTH = 1000 ++GENERATE_LEGEND = YES ++DOT_CLEANUP = YES ++#--------------------------------------------------------------------------- ++# Configuration::additions related to the search engine ++#--------------------------------------------------------------------------- ++SEARCHENGINE = NO +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dummy_audio.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dummy_audio.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1575 @@ ++/* ++ * zero.c -- Gadget Zero, for USB development ++ * ++ * Copyright (C) 2003-2004 David Brownell ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") as published by the Free Software ++ * Foundation, either version 2 of that License or (at your option) any ++ * later version. ++ * ++ * 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. ++ */ ++ ++ ++/* ++ * Gadget Zero only needs two bulk endpoints, and is an example of how you ++ * can write a hardware-agnostic gadget driver running inside a USB device. ++ * ++ * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't ++ * affect most of the driver. ++ * ++ * Use it with the Linux host/master side "usbtest" driver to get a basic ++ * functional test of your device-side usb stack, or with "usb-skeleton". ++ * ++ * It supports two similar configurations. One sinks whatever the usb host ++ * writes, and in return sources zeroes. The other loops whatever the host ++ * writes back, so the host can read it. Module options include: ++ * ++ * buflen=N default N=4096, buffer size used ++ * qlen=N default N=32, how many buffers in the loopback queue ++ * loopdefault default false, list loopback config first ++ * ++ * Many drivers will only have one configuration, letting them be much ++ * simpler if they also don't support high speed operation (like this ++ * driver does). ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++# include ++#else ++# include ++#endif ++ ++#include ++ ++ ++/*-------------------------------------------------------------------------*/ ++/*-------------------------------------------------------------------------*/ ++ ++ ++static int utf8_to_utf16le(const char *s, u16 *cp, unsigned len) ++{ ++ int count = 0; ++ u8 c; ++ u16 uchar; ++ ++ /* this insists on correct encodings, though not minimal ones. ++ * BUT it currently rejects legit 4-byte UTF-8 code points, ++ * which need surrogate pairs. (Unicode 3.1 can use them.) ++ */ ++ while (len != 0 && (c = (u8) *s++) != 0) { ++ if (unlikely(c & 0x80)) { ++ // 2-byte sequence: ++ // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx ++ if ((c & 0xe0) == 0xc0) { ++ uchar = (c & 0x1f) << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ // 3-byte sequence (most CJKV characters): ++ // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx ++ } else if ((c & 0xf0) == 0xe0) { ++ uchar = (c & 0x0f) << 12; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c << 6; ++ ++ c = (u8) *s++; ++ if ((c & 0xc0) != 0xc0) ++ goto fail; ++ c &= 0x3f; ++ uchar |= c; ++ ++ /* no bogus surrogates */ ++ if (0xd800 <= uchar && uchar <= 0xdfff) ++ goto fail; ++ ++ // 4-byte sequence (surrogate pairs, currently rare): ++ // 11101110wwwwzzzzyy + 110111yyyyxxxxxx ++ // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ++ // (uuuuu = wwww + 1) ++ // FIXME accept the surrogate code points (only) ++ ++ } else ++ goto fail; ++ } else ++ uchar = c; ++ put_unaligned (cpu_to_le16 (uchar), cp++); ++ count++; ++ len--; ++ } ++ return count; ++fail: ++ return -1; ++} ++ ++ ++/** ++ * usb_gadget_get_string - fill out a string descriptor ++ * @table: of c strings encoded using UTF-8 ++ * @id: string id, from low byte of wValue in get string descriptor ++ * @buf: at least 256 bytes ++ * ++ * Finds the UTF-8 string matching the ID, and converts it into a ++ * string descriptor in utf16-le. ++ * Returns length of descriptor (always even) or negative errno ++ * ++ * If your driver needs stings in multiple languages, you'll probably ++ * "switch (wIndex) { ... }" in your ep0 string descriptor logic, ++ * using this routine after choosing which set of UTF-8 strings to use. ++ * Note that US-ASCII is a strict subset of UTF-8; any string bytes with ++ * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1 ++ * characters (which are also widely used in C strings). ++ */ ++int ++usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) ++{ ++ struct usb_string *s; ++ int len; ++ ++ /* descriptor 0 has the language id */ ++ if (id == 0) { ++ buf [0] = 4; ++ buf [1] = USB_DT_STRING; ++ buf [2] = (u8) table->language; ++ buf [3] = (u8) (table->language >> 8); ++ return 4; ++ } ++ for (s = table->strings; s && s->s; s++) ++ if (s->id == id) ++ break; ++ ++ /* unrecognized: stall. */ ++ if (!s || !s->s) ++ return -EINVAL; ++ ++ /* string descriptors have length, tag, then UTF16-LE text */ ++ len = min ((size_t) 126, strlen (s->s)); ++ memset (buf + 2, 0, 2 * len); /* zero all the bytes */ ++ len = utf8_to_utf16le(s->s, (u16 *)&buf[2], len); ++ if (len < 0) ++ return -EINVAL; ++ buf [0] = (len + 1) * 2; ++ buf [1] = USB_DT_STRING; ++ return buf [0]; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++/*-------------------------------------------------------------------------*/ ++ ++ ++/** ++ * usb_descriptor_fillbuf - fill buffer with descriptors ++ * @buf: Buffer to be filled ++ * @buflen: Size of buf ++ * @src: Array of descriptor pointers, terminated by null pointer. ++ * ++ * Copies descriptors into the buffer, returning the length or a ++ * negative error code if they can't all be copied. Useful when ++ * assembling descriptors for an associated set of interfaces used ++ * as part of configuring a composite device; or in other cases where ++ * sets of descriptors need to be marshaled. ++ */ ++int ++usb_descriptor_fillbuf(void *buf, unsigned buflen, ++ const struct usb_descriptor_header **src) ++{ ++ u8 *dest = buf; ++ ++ if (!src) ++ return -EINVAL; ++ ++ /* fill buffer from src[] until null descriptor ptr */ ++ for (; 0 != *src; src++) { ++ unsigned len = (*src)->bLength; ++ ++ if (len > buflen) ++ return -EINVAL; ++ memcpy(dest, *src, len); ++ buflen -= len; ++ dest += len; ++ } ++ return dest - (u8 *)buf; ++} ++ ++ ++/** ++ * usb_gadget_config_buf - builts a complete configuration descriptor ++ * @config: Header for the descriptor, including characteristics such ++ * as power requirements and number of interfaces. ++ * @desc: Null-terminated vector of pointers to the descriptors (interface, ++ * endpoint, etc) defining all functions in this device configuration. ++ * @buf: Buffer for the resulting configuration descriptor. ++ * @length: Length of buffer. If this is not big enough to hold the ++ * entire configuration descriptor, an error code will be returned. ++ * ++ * This copies descriptors into the response buffer, building a descriptor ++ * for that configuration. It returns the buffer length or a negative ++ * status code. The config.wTotalLength field is set to match the length ++ * of the result, but other descriptor fields (including power usage and ++ * interface count) must be set by the caller. ++ * ++ * Gadget drivers could use this when constructing a config descriptor ++ * in response to USB_REQ_GET_DESCRIPTOR. They will need to patch the ++ * resulting bDescriptorType value if USB_DT_OTHER_SPEED_CONFIG is needed. ++ */ ++int usb_gadget_config_buf( ++ const struct usb_config_descriptor *config, ++ void *buf, ++ unsigned length, ++ const struct usb_descriptor_header **desc ++) ++{ ++ struct usb_config_descriptor *cp = buf; ++ int len; ++ ++ /* config descriptor first */ ++ if (length < USB_DT_CONFIG_SIZE || !desc) ++ return -EINVAL; ++ *cp = *config; ++ ++ /* then interface/endpoint/class/vendor/... */ ++ len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf, ++ length - USB_DT_CONFIG_SIZE, desc); ++ if (len < 0) ++ return len; ++ len += USB_DT_CONFIG_SIZE; ++ if (len > 0xffff) ++ return -EINVAL; ++ ++ /* patch up the config descriptor */ ++ cp->bLength = USB_DT_CONFIG_SIZE; ++ cp->bDescriptorType = USB_DT_CONFIG; ++ cp->wTotalLength = cpu_to_le16(len); ++ cp->bmAttributes |= USB_CONFIG_ATT_ONE; ++ return len; ++} ++ ++/*-------------------------------------------------------------------------*/ ++/*-------------------------------------------------------------------------*/ ++ ++ ++#define RBUF_LEN (1024*1024) ++static int rbuf_start; ++static int rbuf_len; ++static __u8 rbuf[RBUF_LEN]; ++ ++/*-------------------------------------------------------------------------*/ ++ ++#define DRIVER_VERSION "St Patrick's Day 2004" ++ ++static const char shortname [] = "zero"; ++static const char longname [] = "YAMAHA YST-MS35D USB Speaker "; ++ ++static const char source_sink [] = "source and sink data"; ++static const char loopback [] = "loop input to output"; ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * driver assumes self-powered hardware, and ++ * has no way for users to trigger remote wakeup. ++ * ++ * this version autoconfigures as much as possible, ++ * which is reasonable for most "bulk-only" drivers. ++ */ ++static const char *EP_IN_NAME; /* source */ ++static const char *EP_OUT_NAME; /* sink */ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* big enough to hold our biggest descriptor */ ++#define USB_BUFSIZ 512 ++ ++struct zero_dev { ++ spinlock_t lock; ++ struct usb_gadget *gadget; ++ struct usb_request *req; /* for control responses */ ++ ++ /* when configured, we have one of two configs: ++ * - source data (in to host) and sink it (out from host) ++ * - or loop it back (out from host back in to host) ++ */ ++ u8 config; ++ struct usb_ep *in_ep, *out_ep; ++ ++ /* autoresume timer */ ++ struct timer_list resume; ++}; ++ ++#define xprintk(d,level,fmt,args...) \ ++ dev_printk(level , &(d)->gadget->dev , fmt , ## args) ++ ++#ifdef DEBUG ++#define DBG(dev,fmt,args...) \ ++ xprintk(dev , KERN_DEBUG , fmt , ## args) ++#else ++#define DBG(dev,fmt,args...) \ ++ do { } while (0) ++#endif /* DEBUG */ ++ ++#ifdef VERBOSE ++#define VDBG DBG ++#else ++#define VDBG(dev,fmt,args...) \ ++ do { } while (0) ++#endif /* VERBOSE */ ++ ++#define ERROR(dev,fmt,args...) \ ++ xprintk(dev , KERN_ERR , fmt , ## args) ++#define WARN(dev,fmt,args...) \ ++ xprintk(dev , KERN_WARNING , fmt , ## args) ++#define INFO(dev,fmt,args...) \ ++ xprintk(dev , KERN_INFO , fmt , ## args) ++ ++/*-------------------------------------------------------------------------*/ ++ ++static unsigned buflen = 4096; ++static unsigned qlen = 32; ++static unsigned pattern = 0; ++ ++module_param (buflen, uint, S_IRUGO|S_IWUSR); ++module_param (qlen, uint, S_IRUGO|S_IWUSR); ++module_param (pattern, uint, S_IRUGO|S_IWUSR); ++ ++/* ++ * if it's nonzero, autoresume says how many seconds to wait ++ * before trying to wake up the host after suspend. ++ */ ++static unsigned autoresume = 0; ++module_param (autoresume, uint, 0); ++ ++/* ++ * Normally the "loopback" configuration is second (index 1) so ++ * it's not the default. Here's where to change that order, to ++ * work better with hosts where config changes are problematic. ++ * Or controllers (like superh) that only support one config. ++ */ ++static int loopdefault = 0; ++ ++module_param (loopdefault, bool, S_IRUGO|S_IWUSR); ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Thanks to NetChip Technologies for donating this product ID. ++ * ++ * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! ++ * Instead: allocate your own, using normal USB-IF procedures. ++ */ ++#ifndef CONFIG_USB_ZERO_HNPTEST ++#define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ ++#define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ ++#else ++#define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ ++#define DRIVER_PRODUCT_NUM 0xbadd ++#endif ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * DESCRIPTORS ... most are static, but strings and (full) ++ * configuration descriptors are built on demand. ++ */ ++ ++/* ++#define STRING_MANUFACTURER 25 ++#define STRING_PRODUCT 42 ++#define STRING_SERIAL 101 ++*/ ++#define STRING_MANUFACTURER 1 ++#define STRING_PRODUCT 2 ++#define STRING_SERIAL 3 ++ ++#define STRING_SOURCE_SINK 250 ++#define STRING_LOOPBACK 251 ++ ++/* ++ * This device advertises two configurations; these numbers work ++ * on a pxa250 as well as more flexible hardware. ++ */ ++#define CONFIG_SOURCE_SINK 3 ++#define CONFIG_LOOPBACK 2 ++ ++/* ++static struct usb_device_descriptor ++device_desc = { ++ .bLength = sizeof device_desc, ++ .bDescriptorType = USB_DT_DEVICE, ++ ++ .bcdUSB = __constant_cpu_to_le16 (0x0200), ++ .bDeviceClass = USB_CLASS_VENDOR_SPEC, ++ ++ .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), ++ .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), ++ .iManufacturer = STRING_MANUFACTURER, ++ .iProduct = STRING_PRODUCT, ++ .iSerialNumber = STRING_SERIAL, ++ .bNumConfigurations = 2, ++}; ++*/ ++static struct usb_device_descriptor ++device_desc = { ++ .bLength = sizeof device_desc, ++ .bDescriptorType = USB_DT_DEVICE, ++ .bcdUSB = __constant_cpu_to_le16 (0x0100), ++ .bDeviceClass = USB_CLASS_PER_INTERFACE, ++ .bDeviceSubClass = 0, ++ .bDeviceProtocol = 0, ++ .bMaxPacketSize0 = 64, ++ .bcdDevice = __constant_cpu_to_le16 (0x0100), ++ .idVendor = __constant_cpu_to_le16 (0x0499), ++ .idProduct = __constant_cpu_to_le16 (0x3002), ++ .iManufacturer = STRING_MANUFACTURER, ++ .iProduct = STRING_PRODUCT, ++ .iSerialNumber = STRING_SERIAL, ++ .bNumConfigurations = 1, ++}; ++ ++static struct usb_config_descriptor ++z_config = { ++ .bLength = sizeof z_config, ++ .bDescriptorType = USB_DT_CONFIG, ++ ++ /* compute wTotalLength on the fly */ ++ .bNumInterfaces = 2, ++ .bConfigurationValue = 1, ++ .iConfiguration = 0, ++ .bmAttributes = 0x40, ++ .bMaxPower = 0, /* self-powered */ ++}; ++ ++ ++static struct usb_otg_descriptor ++otg_descriptor = { ++ .bLength = sizeof otg_descriptor, ++ .bDescriptorType = USB_DT_OTG, ++ ++ .bmAttributes = USB_OTG_SRP, ++}; ++ ++/* one interface in each configuration */ ++#ifdef CONFIG_USB_GADGET_DUALSPEED ++ ++/* ++ * usb 2.0 devices need to expose both high speed and full speed ++ * descriptors, unless they only run at full speed. ++ * ++ * that means alternate endpoint descriptors (bigger packets) ++ * and a "device qualifier" ... plus more construction options ++ * for the config descriptor. ++ */ ++ ++static struct usb_qualifier_descriptor ++dev_qualifier = { ++ .bLength = sizeof dev_qualifier, ++ .bDescriptorType = USB_DT_DEVICE_QUALIFIER, ++ ++ .bcdUSB = __constant_cpu_to_le16 (0x0200), ++ .bDeviceClass = USB_CLASS_VENDOR_SPEC, ++ ++ .bNumConfigurations = 2, ++}; ++ ++ ++struct usb_cs_as_general_descriptor { ++ __u8 bLength; ++ __u8 bDescriptorType; ++ ++ __u8 bDescriptorSubType; ++ __u8 bTerminalLink; ++ __u8 bDelay; ++ __u16 wFormatTag; ++} __attribute__ ((packed)); ++ ++struct usb_cs_as_format_descriptor { ++ __u8 bLength; ++ __u8 bDescriptorType; ++ ++ __u8 bDescriptorSubType; ++ __u8 bFormatType; ++ __u8 bNrChannels; ++ __u8 bSubframeSize; ++ __u8 bBitResolution; ++ __u8 bSamfreqType; ++ __u8 tLowerSamFreq[3]; ++ __u8 tUpperSamFreq[3]; ++} __attribute__ ((packed)); ++ ++static const struct usb_interface_descriptor ++z_audio_control_if_desc = { ++ .bLength = sizeof z_audio_control_if_desc, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bInterfaceNumber = 0, ++ .bAlternateSetting = 0, ++ .bNumEndpoints = 0, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = 0x1, ++ .bInterfaceProtocol = 0, ++ .iInterface = 0, ++}; ++ ++static const struct usb_interface_descriptor ++z_audio_if_desc = { ++ .bLength = sizeof z_audio_if_desc, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bInterfaceNumber = 1, ++ .bAlternateSetting = 0, ++ .bNumEndpoints = 0, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = 0x2, ++ .bInterfaceProtocol = 0, ++ .iInterface = 0, ++}; ++ ++static const struct usb_interface_descriptor ++z_audio_if_desc2 = { ++ .bLength = sizeof z_audio_if_desc, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bInterfaceNumber = 1, ++ .bAlternateSetting = 1, ++ .bNumEndpoints = 1, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = 0x2, ++ .bInterfaceProtocol = 0, ++ .iInterface = 0, ++}; ++ ++static const struct usb_cs_as_general_descriptor ++z_audio_cs_as_if_desc = { ++ .bLength = 7, ++ .bDescriptorType = 0x24, ++ ++ .bDescriptorSubType = 0x01, ++ .bTerminalLink = 0x01, ++ .bDelay = 0x0, ++ .wFormatTag = __constant_cpu_to_le16 (0x0001) ++}; ++ ++ ++static const struct usb_cs_as_format_descriptor ++z_audio_cs_as_format_desc = { ++ .bLength = 0xe, ++ .bDescriptorType = 0x24, ++ ++ .bDescriptorSubType = 2, ++ .bFormatType = 1, ++ .bNrChannels = 1, ++ .bSubframeSize = 1, ++ .bBitResolution = 8, ++ .bSamfreqType = 0, ++ .tLowerSamFreq = {0x7e, 0x13, 0x00}, ++ .tUpperSamFreq = {0xe2, 0xd6, 0x00}, ++}; ++ ++static const struct usb_endpoint_descriptor ++z_iso_ep = { ++ .bLength = 0x09, ++ .bDescriptorType = 0x05, ++ .bEndpointAddress = 0x04, ++ .bmAttributes = 0x09, ++ .wMaxPacketSize = 0x0038, ++ .bInterval = 0x01, ++ .bRefresh = 0x00, ++ .bSynchAddress = 0x00, ++}; ++ ++static char z_iso_ep2[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02}; ++ ++// 9 bytes ++static char z_ac_interface_header_desc[] = ++{ 0x09, 0x24, 0x01, 0x00, 0x01, 0x2b, 0x00, 0x01, 0x01 }; ++ ++// 12 bytes ++static char z_0[] = {0x0c, 0x24, 0x02, 0x01, 0x01, 0x01, 0x00, 0x02, ++ 0x03, 0x00, 0x00, 0x00}; ++// 13 bytes ++static char z_1[] = {0x0d, 0x24, 0x06, 0x02, 0x01, 0x02, 0x15, 0x00, ++ 0x02, 0x00, 0x02, 0x00, 0x00}; ++// 9 bytes ++static char z_2[] = {0x09, 0x24, 0x03, 0x03, 0x01, 0x03, 0x00, 0x02, ++ 0x00}; ++ ++static char za_0[] = {0x09, 0x04, 0x01, 0x02, 0x01, 0x01, 0x02, 0x00, ++ 0x00}; ++ ++static char za_1[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00}; ++ ++static char za_2[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x01, 0x08, 0x00, ++ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00}; ++ ++static char za_3[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00, ++ 0x00}; ++ ++static char za_4[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02}; ++ ++static char za_5[] = {0x09, 0x04, 0x01, 0x03, 0x01, 0x01, 0x02, 0x00, ++ 0x00}; ++ ++static char za_6[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00}; ++ ++static char za_7[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x00, ++ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00}; ++ ++static char za_8[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00, ++ 0x00}; ++ ++static char za_9[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02}; ++ ++static char za_10[] = {0x09, 0x04, 0x01, 0x04, 0x01, 0x01, 0x02, 0x00, ++ 0x00}; ++ ++static char za_11[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00}; ++ ++static char za_12[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x00, ++ 0x73, 0x13, 0x00, 0xe2, 0xd6, 0x00}; ++ ++static char za_13[] = {0x09, 0x05, 0x04, 0x09, 0xe0, 0x00, 0x01, 0x00, ++ 0x00}; ++ ++static char za_14[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02}; ++ ++static char za_15[] = {0x09, 0x04, 0x01, 0x05, 0x01, 0x01, 0x02, 0x00, ++ 0x00}; ++ ++static char za_16[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00}; ++ ++static char za_17[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x03, 0x14, 0x00, ++ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00}; ++ ++static char za_18[] = {0x09, 0x05, 0x04, 0x09, 0xa8, 0x00, 0x01, 0x00, ++ 0x00}; ++ ++static char za_19[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02}; ++ ++static char za_20[] = {0x09, 0x04, 0x01, 0x06, 0x01, 0x01, 0x02, 0x00, ++ 0x00}; ++ ++static char za_21[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00}; ++ ++static char za_22[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x03, 0x14, 0x00, ++ 0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00}; ++ ++static char za_23[] = {0x09, 0x05, 0x04, 0x09, 0x50, 0x01, 0x01, 0x00, ++ 0x00}; ++ ++static char za_24[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02}; ++ ++ ++ ++static const struct usb_descriptor_header *z_function [] = { ++ (struct usb_descriptor_header *) &z_audio_control_if_desc, ++ (struct usb_descriptor_header *) &z_ac_interface_header_desc, ++ (struct usb_descriptor_header *) &z_0, ++ (struct usb_descriptor_header *) &z_1, ++ (struct usb_descriptor_header *) &z_2, ++ (struct usb_descriptor_header *) &z_audio_if_desc, ++ (struct usb_descriptor_header *) &z_audio_if_desc2, ++ (struct usb_descriptor_header *) &z_audio_cs_as_if_desc, ++ (struct usb_descriptor_header *) &z_audio_cs_as_format_desc, ++ (struct usb_descriptor_header *) &z_iso_ep, ++ (struct usb_descriptor_header *) &z_iso_ep2, ++ (struct usb_descriptor_header *) &za_0, ++ (struct usb_descriptor_header *) &za_1, ++ (struct usb_descriptor_header *) &za_2, ++ (struct usb_descriptor_header *) &za_3, ++ (struct usb_descriptor_header *) &za_4, ++ (struct usb_descriptor_header *) &za_5, ++ (struct usb_descriptor_header *) &za_6, ++ (struct usb_descriptor_header *) &za_7, ++ (struct usb_descriptor_header *) &za_8, ++ (struct usb_descriptor_header *) &za_9, ++ (struct usb_descriptor_header *) &za_10, ++ (struct usb_descriptor_header *) &za_11, ++ (struct usb_descriptor_header *) &za_12, ++ (struct usb_descriptor_header *) &za_13, ++ (struct usb_descriptor_header *) &za_14, ++ (struct usb_descriptor_header *) &za_15, ++ (struct usb_descriptor_header *) &za_16, ++ (struct usb_descriptor_header *) &za_17, ++ (struct usb_descriptor_header *) &za_18, ++ (struct usb_descriptor_header *) &za_19, ++ (struct usb_descriptor_header *) &za_20, ++ (struct usb_descriptor_header *) &za_21, ++ (struct usb_descriptor_header *) &za_22, ++ (struct usb_descriptor_header *) &za_23, ++ (struct usb_descriptor_header *) &za_24, ++ NULL, ++}; ++ ++/* maxpacket and other transfer characteristics vary by speed. */ ++#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) ++ ++#else ++ ++/* if there's no high speed support, maxpacket doesn't change. */ ++#define ep_desc(g,hs,fs) fs ++ ++#endif /* !CONFIG_USB_GADGET_DUALSPEED */ ++ ++static char manufacturer [40]; ++//static char serial [40]; ++static char serial [] = "Ser 00 em"; ++ ++/* static strings, in UTF-8 */ ++static struct usb_string strings [] = { ++ { STRING_MANUFACTURER, manufacturer, }, ++ { STRING_PRODUCT, longname, }, ++ { STRING_SERIAL, serial, }, ++ { STRING_LOOPBACK, loopback, }, ++ { STRING_SOURCE_SINK, source_sink, }, ++ { } /* end of list */ ++}; ++ ++static struct usb_gadget_strings stringtab = { ++ .language = 0x0409, /* en-us */ ++ .strings = strings, ++}; ++ ++/* ++ * config descriptors are also handcrafted. these must agree with code ++ * that sets configurations, and with code managing interfaces and their ++ * altsettings. other complexity may come from: ++ * ++ * - high speed support, including "other speed config" rules ++ * - multiple configurations ++ * - interfaces with alternate settings ++ * - embedded class or vendor-specific descriptors ++ * ++ * this handles high speed, and has a second config that could as easily ++ * have been an alternate interface setting (on most hardware). ++ * ++ * NOTE: to demonstrate (and test) more USB capabilities, this driver ++ * should include an altsetting to test interrupt transfers, including ++ * high bandwidth modes at high speed. (Maybe work like Intel's test ++ * device?) ++ */ ++static int ++config_buf (struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index) ++{ ++ int len; ++ const struct usb_descriptor_header **function; ++ ++ function = z_function; ++ len = usb_gadget_config_buf (&z_config, buf, USB_BUFSIZ, function); ++ if (len < 0) ++ return len; ++ ((struct usb_config_descriptor *) buf)->bDescriptorType = type; ++ return len; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static struct usb_request * ++alloc_ep_req (struct usb_ep *ep, unsigned length) ++{ ++ struct usb_request *req; ++ ++ req = usb_ep_alloc_request (ep, GFP_ATOMIC); ++ if (req) { ++ req->length = length; ++ req->buf = usb_ep_alloc_buffer (ep, length, ++ &req->dma, GFP_ATOMIC); ++ if (!req->buf) { ++ usb_ep_free_request (ep, req); ++ req = NULL; ++ } ++ } ++ return req; ++} ++ ++static void free_ep_req (struct usb_ep *ep, struct usb_request *req) ++{ ++ if (req->buf) ++ usb_ep_free_buffer (ep, req->buf, req->dma, req->length); ++ usb_ep_free_request (ep, req); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* optionally require specific source/sink data patterns */ ++ ++static int ++check_read_data ( ++ struct zero_dev *dev, ++ struct usb_ep *ep, ++ struct usb_request *req ++) ++{ ++ unsigned i; ++ u8 *buf = req->buf; ++ ++ for (i = 0; i < req->actual; i++, buf++) { ++ switch (pattern) { ++ /* all-zeroes has no synchronization issues */ ++ case 0: ++ if (*buf == 0) ++ continue; ++ break; ++ /* mod63 stays in sync with short-terminated transfers, ++ * or otherwise when host and gadget agree on how large ++ * each usb transfer request should be. resync is done ++ * with set_interface or set_config. ++ */ ++ case 1: ++ if (*buf == (u8)(i % 63)) ++ continue; ++ break; ++ } ++ ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf); ++ usb_ep_set_halt (ep); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void zero_reset_config (struct zero_dev *dev) ++{ ++ if (dev->config == 0) ++ return; ++ ++ DBG (dev, "reset config\n"); ++ ++ /* just disable endpoints, forcing completion of pending i/o. ++ * all our completion handlers free their requests in this case. ++ */ ++ if (dev->in_ep) { ++ usb_ep_disable (dev->in_ep); ++ dev->in_ep = NULL; ++ } ++ if (dev->out_ep) { ++ usb_ep_disable (dev->out_ep); ++ dev->out_ep = NULL; ++ } ++ dev->config = 0; ++ del_timer (&dev->resume); ++} ++ ++#define _write(f, buf, sz) (f->f_op->write(f, buf, sz, &f->f_pos)) ++ ++static void ++zero_isoc_complete (struct usb_ep *ep, struct usb_request *req) ++{ ++ struct zero_dev *dev = ep->driver_data; ++ int status = req->status; ++ int i, j; ++ ++ switch (status) { ++ ++ case 0: /* normal completion? */ ++ //printk ("\nzero ---------------> isoc normal completion %d bytes\n", req->actual); ++ for (i=0, j=rbuf_start; iactual; i++) { ++ //printk ("%02x ", ((__u8*)req->buf)[i]); ++ rbuf[j] = ((__u8*)req->buf)[i]; ++ j++; ++ if (j >= RBUF_LEN) j=0; ++ } ++ rbuf_start = j; ++ //printk ("\n\n"); ++ ++ if (rbuf_len < RBUF_LEN) { ++ rbuf_len += req->actual; ++ if (rbuf_len > RBUF_LEN) { ++ rbuf_len = RBUF_LEN; ++ } ++ } ++ ++ break; ++ ++ /* this endpoint is normally active while we're configured */ ++ case -ECONNABORTED: /* hardware forced ep reset */ ++ case -ECONNRESET: /* request dequeued */ ++ case -ESHUTDOWN: /* disconnect from host */ ++ VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, ++ req->actual, req->length); ++ if (ep == dev->out_ep) ++ check_read_data (dev, ep, req); ++ free_ep_req (ep, req); ++ return; ++ ++ case -EOVERFLOW: /* buffer overrun on read means that ++ * we didn't provide a big enough ++ * buffer. ++ */ ++ default: ++#if 1 ++ DBG (dev, "%s complete --> %d, %d/%d\n", ep->name, ++ status, req->actual, req->length); ++#endif ++ case -EREMOTEIO: /* short read */ ++ break; ++ } ++ ++ status = usb_ep_queue (ep, req, GFP_ATOMIC); ++ if (status) { ++ ERROR (dev, "kill %s: resubmit %d bytes --> %d\n", ++ ep->name, req->length, status); ++ usb_ep_set_halt (ep); ++ /* FIXME recover later ... somehow */ ++ } ++} ++ ++static struct usb_request * ++zero_start_isoc_ep (struct usb_ep *ep, int gfp_flags) ++{ ++ struct usb_request *req; ++ int status; ++ ++ req = alloc_ep_req (ep, 512); ++ if (!req) ++ return NULL; ++ ++ req->complete = zero_isoc_complete; ++ ++ status = usb_ep_queue (ep, req, gfp_flags); ++ if (status) { ++ struct zero_dev *dev = ep->driver_data; ++ ++ ERROR (dev, "start %s --> %d\n", ep->name, status); ++ free_ep_req (ep, req); ++ req = NULL; ++ } ++ ++ return req; ++} ++ ++/* change our operational config. this code must agree with the code ++ * that returns config descriptors, and altsetting code. ++ * ++ * it's also responsible for power management interactions. some ++ * configurations might not work with our current power sources. ++ * ++ * note that some device controller hardware will constrain what this ++ * code can do, perhaps by disallowing more than one configuration or ++ * by limiting configuration choices (like the pxa2xx). ++ */ ++static int ++zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags) ++{ ++ int result = 0; ++ struct usb_gadget *gadget = dev->gadget; ++ const struct usb_endpoint_descriptor *d; ++ struct usb_ep *ep; ++ ++ if (number == dev->config) ++ return 0; ++ ++ zero_reset_config (dev); ++ ++ gadget_for_each_ep (ep, gadget) { ++ ++ if (strcmp (ep->name, "ep4") == 0) { ++ ++ d = (struct usb_endpoint_descripter *)&za_23; // isoc ep desc for audio i/f alt setting 6 ++ result = usb_ep_enable (ep, d); ++ ++ if (result == 0) { ++ ep->driver_data = dev; ++ dev->in_ep = ep; ++ ++ if (zero_start_isoc_ep (ep, gfp_flags) != 0) { ++ ++ dev->in_ep = ep; ++ continue; ++ } ++ ++ usb_ep_disable (ep); ++ result = -EIO; ++ } ++ } ++ ++ } ++ ++ dev->config = number; ++ return result; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req) ++{ ++ if (req->status || req->actual != req->length) ++ DBG ((struct zero_dev *) ep->driver_data, ++ "setup complete --> %d, %d/%d\n", ++ req->status, req->actual, req->length); ++} ++ ++/* ++ * The setup() callback implements all the ep0 functionality that's ++ * not handled lower down, in hardware or the hardware driver (like ++ * device and endpoint feature flags, and their status). It's all ++ * housekeeping for the gadget function we're implementing. Most of ++ * the work is in config-specific setup. ++ */ ++static int ++zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ++{ ++ struct zero_dev *dev = get_gadget_data (gadget); ++ struct usb_request *req = dev->req; ++ int value = -EOPNOTSUPP; ++ ++ /* usually this stores reply data in the pre-allocated ep0 buffer, ++ * but config change events will reconfigure hardware. ++ */ ++ req->zero = 0; ++ switch (ctrl->bRequest) { ++ ++ case USB_REQ_GET_DESCRIPTOR: ++ ++ switch (ctrl->wValue >> 8) { ++ ++ case USB_DT_DEVICE: ++ value = min (ctrl->wLength, (u16) sizeof device_desc); ++ memcpy (req->buf, &device_desc, value); ++ break; ++#ifdef CONFIG_USB_GADGET_DUALSPEED ++ case USB_DT_DEVICE_QUALIFIER: ++ if (!gadget->is_dualspeed) ++ break; ++ value = min (ctrl->wLength, (u16) sizeof dev_qualifier); ++ memcpy (req->buf, &dev_qualifier, value); ++ break; ++ ++ case USB_DT_OTHER_SPEED_CONFIG: ++ if (!gadget->is_dualspeed) ++ break; ++ // FALLTHROUGH ++#endif /* CONFIG_USB_GADGET_DUALSPEED */ ++ case USB_DT_CONFIG: ++ value = config_buf (gadget, req->buf, ++ ctrl->wValue >> 8, ++ ctrl->wValue & 0xff); ++ if (value >= 0) ++ value = min (ctrl->wLength, (u16) value); ++ break; ++ ++ case USB_DT_STRING: ++ /* wIndex == language code. ++ * this driver only handles one language, you can ++ * add string tables for other languages, using ++ * any UTF-8 characters ++ */ ++ value = usb_gadget_get_string (&stringtab, ++ ctrl->wValue & 0xff, req->buf); ++ if (value >= 0) { ++ value = min (ctrl->wLength, (u16) value); ++ } ++ break; ++ } ++ break; ++ ++ /* currently two configs, two speeds */ ++ case USB_REQ_SET_CONFIGURATION: ++ if (ctrl->bRequestType != 0) ++ goto unknown; ++ ++ spin_lock (&dev->lock); ++ value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC); ++ spin_unlock (&dev->lock); ++ break; ++ case USB_REQ_GET_CONFIGURATION: ++ if (ctrl->bRequestType != USB_DIR_IN) ++ goto unknown; ++ *(u8 *)req->buf = dev->config; ++ value = min (ctrl->wLength, (u16) 1); ++ break; ++ ++ /* until we add altsetting support, or other interfaces, ++ * only 0/0 are possible. pxa2xx only supports 0/0 (poorly) ++ * and already killed pending endpoint I/O. ++ */ ++ case USB_REQ_SET_INTERFACE: ++ ++ if (ctrl->bRequestType != USB_RECIP_INTERFACE) ++ goto unknown; ++ spin_lock (&dev->lock); ++ if (dev->config) { ++ u8 config = dev->config; ++ ++ /* resets interface configuration, forgets about ++ * previous transaction state (queued bufs, etc) ++ * and re-inits endpoint state (toggle etc) ++ * no response queued, just zero status == success. ++ * if we had more than one interface we couldn't ++ * use this "reset the config" shortcut. ++ */ ++ zero_reset_config (dev); ++ zero_set_config (dev, config, GFP_ATOMIC); ++ value = 0; ++ } ++ spin_unlock (&dev->lock); ++ break; ++ case USB_REQ_GET_INTERFACE: ++ if ((ctrl->bRequestType == 0x21) && (ctrl->wIndex == 0x02)) { ++ value = ctrl->wLength; ++ break; ++ } ++ else { ++ if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) ++ goto unknown; ++ if (!dev->config) ++ break; ++ if (ctrl->wIndex != 0) { ++ value = -EDOM; ++ break; ++ } ++ *(u8 *)req->buf = 0; ++ value = min (ctrl->wLength, (u16) 1); ++ } ++ break; ++ ++ /* ++ * These are the same vendor-specific requests supported by ++ * Intel's USB 2.0 compliance test devices. We exceed that ++ * device spec by allowing multiple-packet requests. ++ */ ++ case 0x5b: /* control WRITE test -- fill the buffer */ ++ if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR)) ++ goto unknown; ++ if (ctrl->wValue || ctrl->wIndex) ++ break; ++ /* just read that many bytes into the buffer */ ++ if (ctrl->wLength > USB_BUFSIZ) ++ break; ++ value = ctrl->wLength; ++ break; ++ case 0x5c: /* control READ test -- return the buffer */ ++ if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR)) ++ goto unknown; ++ if (ctrl->wValue || ctrl->wIndex) ++ break; ++ /* expect those bytes are still in the buffer; send back */ ++ if (ctrl->wLength > USB_BUFSIZ ++ || ctrl->wLength != req->length) ++ break; ++ value = ctrl->wLength; ++ break; ++ ++ case 0x01: // SET_CUR ++ case 0x02: ++ case 0x03: ++ case 0x04: ++ case 0x05: ++ value = ctrl->wLength; ++ break; ++ case 0x81: ++ switch (ctrl->wValue) { ++ case 0x0201: ++ case 0x0202: ++ ((u8*)req->buf)[0] = 0x00; ++ ((u8*)req->buf)[1] = 0xe3; ++ break; ++ case 0x0300: ++ case 0x0500: ++ ((u8*)req->buf)[0] = 0x00; ++ break; ++ } ++ //((u8*)req->buf)[0] = 0x81; ++ //((u8*)req->buf)[1] = 0x81; ++ value = ctrl->wLength; ++ break; ++ case 0x82: ++ switch (ctrl->wValue) { ++ case 0x0201: ++ case 0x0202: ++ ((u8*)req->buf)[0] = 0x00; ++ ((u8*)req->buf)[1] = 0xc3; ++ break; ++ case 0x0300: ++ case 0x0500: ++ ((u8*)req->buf)[0] = 0x00; ++ break; ++ } ++ //((u8*)req->buf)[0] = 0x82; ++ //((u8*)req->buf)[1] = 0x82; ++ value = ctrl->wLength; ++ break; ++ case 0x83: ++ switch (ctrl->wValue) { ++ case 0x0201: ++ case 0x0202: ++ ((u8*)req->buf)[0] = 0x00; ++ ((u8*)req->buf)[1] = 0x00; ++ break; ++ case 0x0300: ++ ((u8*)req->buf)[0] = 0x60; ++ break; ++ case 0x0500: ++ ((u8*)req->buf)[0] = 0x18; ++ break; ++ } ++ //((u8*)req->buf)[0] = 0x83; ++ //((u8*)req->buf)[1] = 0x83; ++ value = ctrl->wLength; ++ break; ++ case 0x84: ++ switch (ctrl->wValue) { ++ case 0x0201: ++ case 0x0202: ++ ((u8*)req->buf)[0] = 0x00; ++ ((u8*)req->buf)[1] = 0x01; ++ break; ++ case 0x0300: ++ case 0x0500: ++ ((u8*)req->buf)[0] = 0x08; ++ break; ++ } ++ //((u8*)req->buf)[0] = 0x84; ++ //((u8*)req->buf)[1] = 0x84; ++ value = ctrl->wLength; ++ break; ++ case 0x85: ++ ((u8*)req->buf)[0] = 0x85; ++ ((u8*)req->buf)[1] = 0x85; ++ value = ctrl->wLength; ++ break; ++ ++ ++ default: ++unknown: ++ printk("unknown control req%02x.%02x v%04x i%04x l%d\n", ++ ctrl->bRequestType, ctrl->bRequest, ++ ctrl->wValue, ctrl->wIndex, ctrl->wLength); ++ } ++ ++ /* respond with data transfer before status phase? */ ++ if (value >= 0) { ++ req->length = value; ++ req->zero = value < ctrl->wLength ++ && (value % gadget->ep0->maxpacket) == 0; ++ value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); ++ if (value < 0) { ++ DBG (dev, "ep_queue < 0 --> %d\n", value); ++ req->status = 0; ++ zero_setup_complete (gadget->ep0, req); ++ } ++ } ++ ++ /* device either stalls (value < 0) or reports success */ ++ return value; ++} ++ ++static void ++zero_disconnect (struct usb_gadget *gadget) ++{ ++ struct zero_dev *dev = get_gadget_data (gadget); ++ unsigned long flags; ++ ++ spin_lock_irqsave (&dev->lock, flags); ++ zero_reset_config (dev); ++ ++ /* a more significant application might have some non-usb ++ * activities to quiesce here, saving resources like power ++ * or pushing the notification up a network stack. ++ */ ++ spin_unlock_irqrestore (&dev->lock, flags); ++ ++ /* next we may get setup() calls to enumerate new connections; ++ * or an unbind() during shutdown (including removing module). ++ */ ++} ++ ++static void ++zero_autoresume (unsigned long _dev) ++{ ++ struct zero_dev *dev = (struct zero_dev *) _dev; ++ int status; ++ ++ /* normally the host would be woken up for something ++ * more significant than just a timer firing... ++ */ ++ if (dev->gadget->speed != USB_SPEED_UNKNOWN) { ++ status = usb_gadget_wakeup (dev->gadget); ++ DBG (dev, "wakeup --> %d\n", status); ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void ++zero_unbind (struct usb_gadget *gadget) ++{ ++ struct zero_dev *dev = get_gadget_data (gadget); ++ ++ DBG (dev, "unbind\n"); ++ ++ /* we've already been disconnected ... no i/o is active */ ++ if (dev->req) ++ free_ep_req (gadget->ep0, dev->req); ++ del_timer_sync (&dev->resume); ++ kfree (dev); ++ set_gadget_data (gadget, NULL); ++} ++ ++static int ++zero_bind (struct usb_gadget *gadget) ++{ ++ struct zero_dev *dev; ++ //struct usb_ep *ep; ++ ++ printk("binding\n"); ++ /* ++ * DRIVER POLICY CHOICE: you may want to do this differently. ++ * One thing to avoid is reusing a bcdDevice revision code ++ * with different host-visible configurations or behavior ++ * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc ++ */ ++ //device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201); ++ ++ ++ /* ok, we made sense of the hardware ... */ ++ dev = kmalloc (sizeof *dev, SLAB_KERNEL); ++ if (!dev) ++ return -ENOMEM; ++ memset (dev, 0, sizeof *dev); ++ spin_lock_init (&dev->lock); ++ dev->gadget = gadget; ++ set_gadget_data (gadget, dev); ++ ++ /* preallocate control response and buffer */ ++ dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); ++ if (!dev->req) ++ goto enomem; ++ dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ, ++ &dev->req->dma, GFP_KERNEL); ++ if (!dev->req->buf) ++ goto enomem; ++ ++ dev->req->complete = zero_setup_complete; ++ ++ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; ++ ++#ifdef CONFIG_USB_GADGET_DUALSPEED ++ /* assume ep0 uses the same value for both speeds ... */ ++ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; ++ ++ /* and that all endpoints are dual-speed */ ++ //hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; ++ //hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; ++#endif ++ ++ usb_gadget_set_selfpowered (gadget); ++ ++ init_timer (&dev->resume); ++ dev->resume.function = zero_autoresume; ++ dev->resume.data = (unsigned long) dev; ++ ++ gadget->ep0->driver_data = dev; ++ ++ INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname); ++ INFO (dev, "using %s, OUT %s IN %s\n", gadget->name, ++ EP_OUT_NAME, EP_IN_NAME); ++ ++ snprintf (manufacturer, sizeof manufacturer, ++ UTS_SYSNAME " " UTS_RELEASE " with %s", ++ gadget->name); ++ ++ return 0; ++ ++enomem: ++ zero_unbind (gadget); ++ return -ENOMEM; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void ++zero_suspend (struct usb_gadget *gadget) ++{ ++ struct zero_dev *dev = get_gadget_data (gadget); ++ ++ if (gadget->speed == USB_SPEED_UNKNOWN) ++ return; ++ ++ if (autoresume) { ++ mod_timer (&dev->resume, jiffies + (HZ * autoresume)); ++ DBG (dev, "suspend, wakeup in %d seconds\n", autoresume); ++ } else ++ DBG (dev, "suspend\n"); ++} ++ ++static void ++zero_resume (struct usb_gadget *gadget) ++{ ++ struct zero_dev *dev = get_gadget_data (gadget); ++ ++ DBG (dev, "resume\n"); ++ del_timer (&dev->resume); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static struct usb_gadget_driver zero_driver = { ++#ifdef CONFIG_USB_GADGET_DUALSPEED ++ .speed = USB_SPEED_HIGH, ++#else ++ .speed = USB_SPEED_FULL, ++#endif ++ .function = (char *) longname, ++ .bind = zero_bind, ++ .unbind = zero_unbind, ++ ++ .setup = zero_setup, ++ .disconnect = zero_disconnect, ++ ++ .suspend = zero_suspend, ++ .resume = zero_resume, ++ ++ .driver = { ++ .name = (char *) shortname, ++ // .shutdown = ... ++ // .suspend = ... ++ // .resume = ... ++ }, ++}; ++ ++MODULE_AUTHOR ("David Brownell"); ++MODULE_LICENSE ("Dual BSD/GPL"); ++ ++static struct proc_dir_entry *pdir, *pfile; ++ ++static int isoc_read_data (char *page, char **start, ++ off_t off, int count, ++ int *eof, void *data) ++{ ++ int i; ++ static int c = 0; ++ static int done = 0; ++ static int s = 0; ++ ++/* ++ printk ("\ncount: %d\n", count); ++ printk ("rbuf_start: %d\n", rbuf_start); ++ printk ("rbuf_len: %d\n", rbuf_len); ++ printk ("off: %d\n", off); ++ printk ("start: %p\n\n", *start); ++*/ ++ if (done) { ++ c = 0; ++ done = 0; ++ *eof = 1; ++ return 0; ++ } ++ ++ if (c == 0) { ++ if (rbuf_len == RBUF_LEN) ++ s = rbuf_start; ++ else s = 0; ++ } ++ ++ for (i=0; i= rbuf_len) { ++ *eof = 1; ++ done = 1; ++ } ++ ++ ++ return i; ++} ++ ++static int __init init (void) ++{ ++ ++ int retval = 0; ++ ++ pdir = proc_mkdir("isoc_test", NULL); ++ if(pdir == NULL) { ++ retval = -ENOMEM; ++ printk("Error creating dir\n"); ++ goto done; ++ } ++ pdir->owner = THIS_MODULE; ++ ++ pfile = create_proc_read_entry("isoc_data", ++ 0444, pdir, ++ isoc_read_data, ++ NULL); ++ if (pfile == NULL) { ++ retval = -ENOMEM; ++ printk("Error creating file\n"); ++ goto no_file; ++ } ++ pfile->owner = THIS_MODULE; ++ ++ return usb_gadget_register_driver (&zero_driver); ++ ++ no_file: ++ remove_proc_entry("isoc_data", NULL); ++ done: ++ return retval; ++} ++module_init (init); ++ ++static void __exit cleanup (void) ++{ ++ ++ usb_gadget_unregister_driver (&zero_driver); ++ ++ remove_proc_entry("isoc_data", pdir); ++ remove_proc_entry("isoc_test", NULL); ++} ++module_exit (cleanup); +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_cfi_common.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_cfi_common.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,142 @@ ++/* ========================================================================== ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#if !defined(__DWC_CFI_COMMON_H__) ++#define __DWC_CFI_COMMON_H__ ++ ++//#include ++ ++/** ++ * @file ++ * ++ * This file contains the CFI specific common constants, interfaces ++ * (functions and macros) and structures for Linux. No PCD specific ++ * data structure or definition is to be included in this file. ++ * ++ */ ++ ++/** This is a request for all Core Features */ ++#define VEN_CORE_GET_FEATURES 0xB1 ++ ++/** This is a request to get the value of a specific Core Feature */ ++#define VEN_CORE_GET_FEATURE 0xB2 ++ ++/** This command allows the host to set the value of a specific Core Feature */ ++#define VEN_CORE_SET_FEATURE 0xB3 ++ ++/** This command allows the host to set the default values of ++ * either all or any specific Core Feature ++ */ ++#define VEN_CORE_RESET_FEATURES 0xB4 ++ ++/** This command forces the PCD to write the deferred values of a Core Features */ ++#define VEN_CORE_ACTIVATE_FEATURES 0xB5 ++ ++/** This request reads a DWORD value from a register at the specified offset */ ++#define VEN_CORE_READ_REGISTER 0xB6 ++ ++/** This request writes a DWORD value into a register at the specified offset */ ++#define VEN_CORE_WRITE_REGISTER 0xB7 ++ ++/** This structure is the header of the Core Features dataset returned to ++ * the Host ++ */ ++struct cfi_all_features_header { ++/** The features header structure length is */ ++#define CFI_ALL_FEATURES_HDR_LEN 8 ++ /** ++ * The total length of the features dataset returned to the Host ++ */ ++ uint16_t wTotalLen; ++ ++ /** ++ * CFI version number inBinary-Coded Decimal (i.e., 1.00 is 100H). ++ * This field identifies the version of the CFI Specification with which ++ * the device is compliant. ++ */ ++ uint16_t wVersion; ++ ++ /** The ID of the Core */ ++ uint16_t wCoreID; ++#define CFI_CORE_ID_UDC 1 ++#define CFI_CORE_ID_OTG 2 ++#define CFI_CORE_ID_WUDEV 3 ++ ++ /** Number of features returned by VEN_CORE_GET_FEATURES request */ ++ uint16_t wNumFeatures; ++} UPACKED; ++ ++typedef struct cfi_all_features_header cfi_all_features_header_t; ++ ++/** This structure is a header of the Core Feature descriptor dataset returned to ++ * the Host after the VEN_CORE_GET_FEATURES request ++ */ ++struct cfi_feature_desc_header { ++#define CFI_FEATURE_DESC_HDR_LEN 8 ++ ++ /** The feature ID */ ++ uint16_t wFeatureID; ++ ++ /** Length of this feature descriptor in bytes - including the ++ * length of the feature name string ++ */ ++ uint16_t wLength; ++ ++ /** The data length of this feature in bytes */ ++ uint16_t wDataLength; ++ ++ /** ++ * Attributes of this features ++ * D0: Access rights ++ * 0 - Read/Write ++ * 1 - Read only ++ */ ++ uint8_t bmAttributes; ++#define CFI_FEATURE_ATTR_RO 1 ++#define CFI_FEATURE_ATTR_RW 0 ++ ++ /** Length of the feature name in bytes */ ++ uint8_t bNameLen; ++ ++ /** The feature name buffer */ ++ //uint8_t *name; ++} UPACKED; ++ ++typedef struct cfi_feature_desc_header cfi_feature_desc_header_t; ++ ++/** ++ * This structure describes a NULL terminated string referenced by its id field. ++ * It is very similar to usb_string structure but has the id field type set to 16-bit. ++ */ ++struct cfi_string { ++ uint16_t id; ++ const uint8_t *s; ++}; ++typedef struct cfi_string cfi_string_t; ++ ++#endif +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_adp.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_adp.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,854 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_adp.c $ ++ * $Revision: #12 $ ++ * $Date: 2011/10/26 $ ++ * $Change: 1873028 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ++ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH ++ * DAMAGE. ++ * ========================================================================== */ ++ ++#include "dwc_os.h" ++#include "dwc_otg_regs.h" ++#include "dwc_otg_cil.h" ++#include "dwc_otg_adp.h" ++ ++/** @file ++ * ++ * This file contains the most of the Attach Detect Protocol implementation for ++ * the driver to support OTG Rev2.0. ++ * ++ */ ++ ++void dwc_otg_adp_write_reg(dwc_otg_core_if_t * core_if, uint32_t value) ++{ ++ adpctl_data_t adpctl; ++ ++ adpctl.d32 = value; ++ adpctl.b.ar = 0x2; ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->adpctl, adpctl.d32); ++ ++ while (adpctl.b.ar) { ++ adpctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->adpctl); ++ } ++ ++} ++ ++/** ++ * Function is called to read ADP registers ++ */ ++uint32_t dwc_otg_adp_read_reg(dwc_otg_core_if_t * core_if) ++{ ++ adpctl_data_t adpctl; ++ ++ adpctl.d32 = 0; ++ adpctl.b.ar = 0x1; ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->adpctl, adpctl.d32); ++ ++ while (adpctl.b.ar) { ++ adpctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->adpctl); ++ } ++ ++ return adpctl.d32; ++} ++ ++/** ++ * Function is called to read ADPCTL register and filter Write-clear bits ++ */ ++uint32_t dwc_otg_adp_read_reg_filter(dwc_otg_core_if_t * core_if) ++{ ++ adpctl_data_t adpctl; ++ ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ adpctl.b.adp_tmout_int = 0; ++ adpctl.b.adp_prb_int = 0; ++ adpctl.b.adp_tmout_int = 0; ++ ++ return adpctl.d32; ++} ++ ++/** ++ * Function is called to write ADP registers ++ */ ++void dwc_otg_adp_modify_reg(dwc_otg_core_if_t * core_if, uint32_t clr, ++ uint32_t set) ++{ ++ dwc_otg_adp_write_reg(core_if, ++ (dwc_otg_adp_read_reg(core_if) & (~clr)) | set); ++} ++ ++static void adp_sense_timeout(void *ptr) ++{ ++ dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr; ++ core_if->adp.sense_timer_started = 0; ++ DWC_PRINTF("ADP SENSE TIMEOUT\n"); ++ if (core_if->adp_enable) { ++ dwc_otg_adp_sense_stop(core_if); ++ dwc_otg_adp_probe_start(core_if); ++ } ++} ++ ++/** ++ * This function is called when the ADP vbus timer expires. Timeout is 1.1s. ++ */ ++static void adp_vbuson_timeout(void *ptr) ++{ ++ gpwrdn_data_t gpwrdn; ++ dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr; ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ DWC_PRINTF("%s: 1.1 seconds expire after turning on VBUS\n",__FUNCTION__); ++ if (core_if) { ++ core_if->adp.vbuson_timer_started = 0; ++ /* Turn off vbus */ ++ hprt0.b.prtpwr = 1; ++ DWC_MODIFY_REG32(core_if->host_if->hprt0, hprt0.d32, 0); ++ gpwrdn.d32 = 0; ++ ++ /* Power off the core */ ++ if (core_if->power_down == 2) { ++ /* Enable Wakeup Logic */ ++// gpwrdn.b.wkupactiv = 1; ++ gpwrdn.b.pmuactv = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, ++ gpwrdn.d32); ++ ++ /* Suspend the Phy Clock */ ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32); ++ ++ /* Switch on VDD */ ++// gpwrdn.b.wkupactiv = 1; ++ gpwrdn.b.pmuactv = 1; ++ gpwrdn.b.pwrdnrstn = 1; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, ++ gpwrdn.d32); ++ } else { ++ /* Enable Power Down Logic */ ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ } ++ ++ /* Power off the core */ ++ if (core_if->power_down == 2) { ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, ++ gpwrdn.d32, 0); ++ } ++ ++ /* Unmask SRP detected interrupt from Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.srp_det_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ ++ dwc_otg_adp_probe_start(core_if); ++ dwc_otg_dump_global_registers(core_if); ++ dwc_otg_dump_host_registers(core_if); ++ } ++ ++} ++ ++/** ++ * Start the ADP Initial Probe timer to detect if Port Connected interrupt is ++ * not asserted within 1.1 seconds. ++ * ++ * @param core_if the pointer to core_if strucure. ++ */ ++void dwc_otg_adp_vbuson_timer_start(dwc_otg_core_if_t * core_if) ++{ ++ core_if->adp.vbuson_timer_started = 1; ++ if (core_if->adp.vbuson_timer) ++ { ++ DWC_PRINTF("SCHEDULING VBUSON TIMER\n"); ++ /* 1.1 secs + 60ms necessary for cil_hcd_start*/ ++ DWC_TIMER_SCHEDULE(core_if->adp.vbuson_timer, 1160); ++ } else { ++ DWC_WARN("VBUSON_TIMER = %p\n",core_if->adp.vbuson_timer); ++ } ++} ++ ++#if 0 ++/** ++ * Masks all DWC OTG core interrupts ++ * ++ */ ++static void mask_all_interrupts(dwc_otg_core_if_t * core_if) ++{ ++ int i; ++ gahbcfg_data_t ahbcfg = {.d32 = 0 }; ++ ++ /* Mask Host Interrupts */ ++ ++ /* Clear and disable HCINTs */ ++ for (i = 0; i < core_if->core_params->host_channels; i++) { ++ DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk, 0); ++ DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcint, 0xFFFFFFFF); ++ ++ } ++ ++ /* Clear and disable HAINT */ ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk, 0x0000); ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haint, 0xFFFFFFFF); ++ ++ /* Mask Device Interrupts */ ++ if (!core_if->multiproc_int_enable) { ++ /* Clear and disable IN Endpoint interrupts */ ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, 0); ++ for (i = 0; i <= core_if->dev_if->num_in_eps; i++) { ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]-> ++ diepint, 0xFFFFFFFF); ++ } ++ ++ /* Clear and disable OUT Endpoint interrupts */ ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, 0); ++ for (i = 0; i <= core_if->dev_if->num_out_eps; i++) { ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]-> ++ doepint, 0xFFFFFFFF); ++ } ++ ++ /* Clear and disable DAINT */ ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daint, ++ 0xFFFFFFFF); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, 0); ++ } else { ++ for (i = 0; i < core_if->dev_if->num_in_eps; ++i) { ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs-> ++ diepeachintmsk[i], 0); ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]-> ++ diepint, 0xFFFFFFFF); ++ } ++ ++ for (i = 0; i < core_if->dev_if->num_out_eps; ++i) { ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs-> ++ doepeachintmsk[i], 0); ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]-> ++ doepint, 0xFFFFFFFF); ++ } ++ ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->deachintmsk, ++ 0); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->deachint, ++ 0xFFFFFFFF); ++ ++ } ++ ++ /* Disable interrupts */ ++ ahbcfg.b.glblintrmsk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0); ++ ++ /* Disable all interrupts. */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0); ++ ++ /* Clear any pending interrupts */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* Clear any pending OTG Interrupts */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gotgint, 0xFFFFFFFF); ++} ++ ++/** ++ * Unmask Port Connection Detected interrupt ++ * ++ */ ++static void unmask_conn_det_intr(dwc_otg_core_if_t * core_if) ++{ ++ gintmsk_data_t gintmsk = {.d32 = 0,.b.portintr = 1 }; ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32); ++} ++#endif ++ ++/** ++ * Starts the ADP Probing ++ * ++ * @param core_if the pointer to core_if structure. ++ */ ++uint32_t dwc_otg_adp_probe_start(dwc_otg_core_if_t * core_if) ++{ ++ ++ adpctl_data_t adpctl = {.d32 = 0}; ++ gpwrdn_data_t gpwrdn; ++#if 0 ++ adpctl_data_t adpctl_int = {.d32 = 0, .b.adp_prb_int = 1, ++ .b.adp_sns_int = 1, b.adp_tmout_int}; ++#endif ++ dwc_otg_disable_global_interrupts(core_if); ++ DWC_PRINTF("ADP Probe Start\n"); ++ core_if->adp.probe_enabled = 1; ++ ++ adpctl.b.adpres = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ while (adpctl.b.adpres) { ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ } ++ ++ adpctl.d32 = 0; ++ gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ ++ /* In Host mode unmask SRP detected interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.sts_chngint_msk = 1; ++ if (!gpwrdn.b.idsts) { ++ gpwrdn.b.srp_det_msk = 1; ++ } ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ ++ adpctl.b.adp_tmout_int_msk = 1; ++ adpctl.b.adp_prb_int_msk = 1; ++ adpctl.b.prb_dschg = 1; ++ adpctl.b.prb_delta = 1; ++ adpctl.b.prb_per = 1; ++ adpctl.b.adpen = 1; ++ adpctl.b.enaprb = 1; ++ ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ DWC_PRINTF("ADP Probe Finish\n"); ++ return 0; ++} ++ ++/** ++ * Starts the ADP Sense timer to detect if ADP Sense interrupt is not asserted ++ * within 3 seconds. ++ * ++ * @param core_if the pointer to core_if strucure. ++ */ ++void dwc_otg_adp_sense_timer_start(dwc_otg_core_if_t * core_if) ++{ ++ core_if->adp.sense_timer_started = 1; ++ DWC_TIMER_SCHEDULE(core_if->adp.sense_timer, 3000 /* 3 secs */ ); ++} ++ ++/** ++ * Starts the ADP Sense ++ * ++ * @param core_if the pointer to core_if strucure. ++ */ ++uint32_t dwc_otg_adp_sense_start(dwc_otg_core_if_t * core_if) ++{ ++ adpctl_data_t adpctl; ++ ++ DWC_PRINTF("ADP Sense Start\n"); ++ ++ /* Unmask ADP sense interrupt and mask all other from the core */ ++ adpctl.d32 = dwc_otg_adp_read_reg_filter(core_if); ++ adpctl.b.adp_sns_int_msk = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ dwc_otg_disable_global_interrupts(core_if); // vahrama ++ ++ /* Set ADP reset bit*/ ++ adpctl.d32 = dwc_otg_adp_read_reg_filter(core_if); ++ adpctl.b.adpres = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ while (adpctl.b.adpres) { ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ } ++ ++ adpctl.b.adpres = 0; ++ adpctl.b.adpen = 1; ++ adpctl.b.enasns = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ dwc_otg_adp_sense_timer_start(core_if); ++ ++ return 0; ++} ++ ++/** ++ * Stops the ADP Probing ++ * ++ * @param core_if the pointer to core_if strucure. ++ */ ++uint32_t dwc_otg_adp_probe_stop(dwc_otg_core_if_t * core_if) ++{ ++ ++ adpctl_data_t adpctl; ++ DWC_PRINTF("Stop ADP probe\n"); ++ core_if->adp.probe_enabled = 0; ++ core_if->adp.probe_counter = 0; ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ ++ adpctl.b.adpen = 0; ++ adpctl.b.adp_prb_int = 1; ++ adpctl.b.adp_tmout_int = 1; ++ adpctl.b.adp_sns_int = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ return 0; ++} ++ ++/** ++ * Stops the ADP Sensing ++ * ++ * @param core_if the pointer to core_if strucure. ++ */ ++uint32_t dwc_otg_adp_sense_stop(dwc_otg_core_if_t * core_if) ++{ ++ adpctl_data_t adpctl; ++ ++ core_if->adp.sense_enabled = 0; ++ ++ adpctl.d32 = dwc_otg_adp_read_reg_filter(core_if); ++ adpctl.b.enasns = 0; ++ adpctl.b.adp_sns_int = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ return 0; ++} ++ ++/** ++ * Called to turn on the VBUS after initial ADP probe in host mode. ++ * If port power was already enabled in cil_hcd_start function then ++ * only schedule a timer. ++ * ++ * @param core_if the pointer to core_if structure. ++ */ ++void dwc_otg_adp_turnon_vbus(dwc_otg_core_if_t * core_if) ++{ ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ DWC_PRINTF("Turn on VBUS for 1.1s, port power is %d\n", hprt0.b.prtpwr); ++ ++ if (hprt0.b.prtpwr == 0) { ++ hprt0.b.prtpwr = 1; ++ //DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ } ++ ++ dwc_otg_adp_vbuson_timer_start(core_if); ++} ++ ++/** ++ * Called right after driver is loaded ++ * to perform initial actions for ADP ++ * ++ * @param core_if the pointer to core_if structure. ++ * @param is_host - flag for current mode of operation either from GINTSTS or GPWRDN ++ */ ++void dwc_otg_adp_start(dwc_otg_core_if_t * core_if, uint8_t is_host) ++{ ++ gpwrdn_data_t gpwrdn; ++ ++ DWC_PRINTF("ADP Initial Start\n"); ++ core_if->adp.adp_started = 1; ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ dwc_otg_disable_global_interrupts(core_if); ++ if (is_host) { ++ DWC_PRINTF("HOST MODE\n"); ++ /* Enable Power Down Logic Interrupt*/ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ /* Initialize first ADP probe to obtain Ramp Time value */ ++ core_if->adp.initial_probe = 1; ++ dwc_otg_adp_probe_start(core_if); ++ } else { ++ gotgctl_data_t gotgctl; ++ gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ DWC_PRINTF("DEVICE MODE\n"); ++ if (gotgctl.b.bsesvld == 0) { ++ /* Enable Power Down Logic Interrupt*/ ++ gpwrdn.d32 = 0; ++ DWC_PRINTF("VBUS is not valid - start ADP probe\n"); ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ core_if->adp.initial_probe = 1; ++ dwc_otg_adp_probe_start(core_if); ++ } else { ++ DWC_PRINTF("VBUS is valid - initialize core as a Device\n"); ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ dwc_otg_dump_global_registers(core_if); ++ dwc_otg_dump_dev_registers(core_if); ++ } ++ } ++} ++ ++void dwc_otg_adp_init(dwc_otg_core_if_t * core_if) ++{ ++ core_if->adp.adp_started = 0; ++ core_if->adp.initial_probe = 0; ++ core_if->adp.probe_timer_values[0] = -1; ++ core_if->adp.probe_timer_values[1] = -1; ++ core_if->adp.probe_enabled = 0; ++ core_if->adp.sense_enabled = 0; ++ core_if->adp.sense_timer_started = 0; ++ core_if->adp.vbuson_timer_started = 0; ++ core_if->adp.probe_counter = 0; ++ core_if->adp.gpwrdn = 0; ++ core_if->adp.attached = DWC_OTG_ADP_UNKOWN; ++ /* Initialize timers */ ++ core_if->adp.sense_timer = ++ DWC_TIMER_ALLOC("ADP SENSE TIMER", adp_sense_timeout, core_if); ++ core_if->adp.vbuson_timer = ++ DWC_TIMER_ALLOC("ADP VBUS ON TIMER", adp_vbuson_timeout, core_if); ++ if (!core_if->adp.sense_timer || !core_if->adp.vbuson_timer) ++ { ++ DWC_ERROR("Could not allocate memory for ADP timers\n"); ++ } ++} ++ ++void dwc_otg_adp_remove(dwc_otg_core_if_t * core_if) ++{ ++ gpwrdn_data_t gpwrdn = { .d32 = 0 }; ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ if (core_if->adp.probe_enabled) ++ dwc_otg_adp_probe_stop(core_if); ++ if (core_if->adp.sense_enabled) ++ dwc_otg_adp_sense_stop(core_if); ++ if (core_if->adp.sense_timer_started) ++ DWC_TIMER_CANCEL(core_if->adp.sense_timer); ++ if (core_if->adp.vbuson_timer_started) ++ DWC_TIMER_CANCEL(core_if->adp.vbuson_timer); ++ DWC_TIMER_FREE(core_if->adp.sense_timer); ++ DWC_TIMER_FREE(core_if->adp.vbuson_timer); ++} ++ ++///////////////////////////////////////////////////////////////////// ++////////////// ADP Interrupt Handlers /////////////////////////////// ++///////////////////////////////////////////////////////////////////// ++/** ++ * This function sets Ramp Timer values ++ */ ++static uint32_t set_timer_value(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ if (core_if->adp.probe_timer_values[0] == -1) { ++ core_if->adp.probe_timer_values[0] = val; ++ core_if->adp.probe_timer_values[1] = -1; ++ return 1; ++ } else { ++ core_if->adp.probe_timer_values[1] = ++ core_if->adp.probe_timer_values[0]; ++ core_if->adp.probe_timer_values[0] = val; ++ return 0; ++ } ++} ++ ++/** ++ * This function compares Ramp Timer values ++ */ ++static uint32_t compare_timer_values(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t diff; ++ if (core_if->adp.probe_timer_values[0]>=core_if->adp.probe_timer_values[1]) ++ diff = core_if->adp.probe_timer_values[0]-core_if->adp.probe_timer_values[1]; ++ else ++ diff = core_if->adp.probe_timer_values[1]-core_if->adp.probe_timer_values[0]; ++ if(diff < 2) { ++ return 0; ++ } else { ++ return 1; ++ } ++} ++ ++/** ++ * This function handles ADP Probe Interrupts ++ */ ++static int32_t dwc_otg_adp_handle_prb_intr(dwc_otg_core_if_t * core_if, ++ uint32_t val) ++{ ++ adpctl_data_t adpctl = {.d32 = 0 }; ++ gpwrdn_data_t gpwrdn, temp; ++ adpctl.d32 = val; ++ ++ temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ core_if->adp.probe_counter++; ++ core_if->adp.gpwrdn = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ if (adpctl.b.rtim == 0 && !temp.b.idsts){ ++ DWC_PRINTF("RTIM value is 0\n"); ++ goto exit; ++ } ++ if (set_timer_value(core_if, adpctl.b.rtim) && ++ core_if->adp.initial_probe) { ++ core_if->adp.initial_probe = 0; ++ dwc_otg_adp_probe_stop(core_if); ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* check which value is for device mode and which for Host mode */ ++ if (!temp.b.idsts) { /* considered host mode value is 0 */ ++ /* ++ * Turn on VBUS after initial ADP probe. ++ */ ++ core_if->op_state = A_HOST; ++ dwc_otg_enable_global_interrupts(core_if); ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_hcd_start(core_if); ++ dwc_otg_adp_turnon_vbus(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ } else { ++ /* ++ * Initiate SRP after initial ADP probe. ++ */ ++ dwc_otg_enable_global_interrupts(core_if); ++ dwc_otg_initiate_srp(core_if); ++ } ++ } else if (core_if->adp.probe_counter > 2){ ++ gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ if (compare_timer_values(core_if)) { ++ DWC_PRINTF("Difference in timer values !!! \n"); ++// core_if->adp.attached = DWC_OTG_ADP_ATTACHED; ++ dwc_otg_adp_probe_stop(core_if); ++ ++ /* Power on the core */ ++ if (core_if->power_down == 2) { ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ } ++ ++ /* check which value is for device mode and which for Host mode */ ++ if (!temp.b.idsts) { /* considered host mode value is 0 */ ++ /* Disable Interrupt from Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, gpwrdn.d32, 0); ++ ++ /* ++ * Initialize the Core for Host mode. ++ */ ++ core_if->op_state = A_HOST; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_hcd_start(core_if); ++ } else { ++ gotgctl_data_t gotgctl; ++ /* Mask SRP detected interrupt from Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.srp_det_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, gpwrdn.d32, 0); ++ ++ /* Disable Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, gpwrdn.d32, 0); ++ ++ /* ++ * Initialize the Core for Device mode. ++ */ ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ ++ gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ if (!gotgctl.b.bsesvld) { ++ dwc_otg_initiate_srp(core_if); ++ } ++ } ++ } ++ if (core_if->power_down == 2) { ++ if (gpwrdn.b.bsessvld) { ++ /* Mask SRP detected interrupt from Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.srp_det_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Disable Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* ++ * Initialize the Core for Device mode. ++ */ ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ } ++ } ++ } ++exit: ++ /* Clear interrupt */ ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ adpctl.b.adp_prb_int = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ return 0; ++} ++ ++/** ++ * This function hadles ADP Sense Interrupt ++ */ ++static int32_t dwc_otg_adp_handle_sns_intr(dwc_otg_core_if_t * core_if) ++{ ++ adpctl_data_t adpctl; ++ /* Stop ADP Sense timer */ ++ DWC_TIMER_CANCEL(core_if->adp.sense_timer); ++ ++ /* Restart ADP Sense timer */ ++ dwc_otg_adp_sense_timer_start(core_if); ++ ++ /* Clear interrupt */ ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ adpctl.b.adp_sns_int = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ return 0; ++} ++ ++/** ++ * This function handles ADP Probe Interrupts ++ */ ++static int32_t dwc_otg_adp_handle_prb_tmout_intr(dwc_otg_core_if_t * core_if, ++ uint32_t val) ++{ ++ adpctl_data_t adpctl = {.d32 = 0 }; ++ adpctl.d32 = val; ++ set_timer_value(core_if, adpctl.b.rtim); ++ ++ /* Clear interrupt */ ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ adpctl.b.adp_tmout_int = 1; ++ dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ ++ return 0; ++} ++ ++/** ++ * ADP Interrupt handler. ++ * ++ */ ++int32_t dwc_otg_adp_handle_intr(dwc_otg_core_if_t * core_if) ++{ ++ int retval = 0; ++ adpctl_data_t adpctl = {.d32 = 0}; ++ ++ adpctl.d32 = dwc_otg_adp_read_reg(core_if); ++ DWC_PRINTF("ADPCTL = %08x\n",adpctl.d32); ++ ++ if (adpctl.b.adp_sns_int & adpctl.b.adp_sns_int_msk) { ++ DWC_PRINTF("ADP Sense interrupt\n"); ++ retval |= dwc_otg_adp_handle_sns_intr(core_if); ++ } ++ if (adpctl.b.adp_tmout_int & adpctl.b.adp_tmout_int_msk) { ++ DWC_PRINTF("ADP timeout interrupt\n"); ++ retval |= dwc_otg_adp_handle_prb_tmout_intr(core_if, adpctl.d32); ++ } ++ if (adpctl.b.adp_prb_int & adpctl.b.adp_prb_int_msk) { ++ DWC_PRINTF("ADP Probe interrupt\n"); ++ adpctl.b.adp_prb_int = 1; ++ retval |= dwc_otg_adp_handle_prb_intr(core_if, adpctl.d32); ++ } ++ ++// dwc_otg_adp_modify_reg(core_if, adpctl.d32, 0); ++ //dwc_otg_adp_write_reg(core_if, adpctl.d32); ++ DWC_PRINTF("RETURN FROM ADP ISR\n"); ++ ++ return retval; ++} ++ ++/** ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++int32_t dwc_otg_adp_handle_srp_intr(dwc_otg_core_if_t * core_if) ++{ ++ ++#ifndef DWC_HOST_ONLY ++ hprt0_data_t hprt0; ++ gpwrdn_data_t gpwrdn; ++ DWC_DEBUGPL(DBG_ANY, "++ Power Down Logic Session Request Interrupt++\n"); ++ ++ gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ /* check which value is for device mode and which for Host mode */ ++ if (!gpwrdn.b.idsts) { /* considered host mode value is 0 */ ++ DWC_PRINTF("SRP: Host mode\n"); ++ ++ if (core_if->adp_enable) { ++ dwc_otg_adp_probe_stop(core_if); ++ ++ /* Power on the core */ ++ if (core_if->power_down == 2) { ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ } ++ ++ core_if->op_state = A_HOST; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_hcd_start(core_if); ++ } ++ ++ /* Turn on the port power bit. */ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtpwr = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ /* Start the Connection timer. So a message can be displayed ++ * if connect does not occur within 10 seconds. */ ++ cil_hcd_session_start(core_if); ++ } else { ++ DWC_PRINTF("SRP: Device mode %s\n", __FUNCTION__); ++ if (core_if->adp_enable) { ++ dwc_otg_adp_probe_stop(core_if); ++ ++ /* Power on the core */ ++ if (core_if->power_down == 2) { ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ } ++ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 0; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, ++ gpwrdn.d32); ++ ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ } ++ } ++#endif ++ return 1; ++} +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_adp.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_adp.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,80 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_adp.h $ ++ * $Revision: #7 $ ++ * $Date: 2011/10/24 $ ++ * $Change: 1871159 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#ifndef __DWC_OTG_ADP_H__ ++#define __DWC_OTG_ADP_H__ ++ ++/** ++ * @file ++ * ++ * This file contains the Attach Detect Protocol interfaces and defines ++ * (functions) and structures for Linux. ++ * ++ */ ++ ++#define DWC_OTG_ADP_UNATTACHED 0 ++#define DWC_OTG_ADP_ATTACHED 1 ++#define DWC_OTG_ADP_UNKOWN 2 ++ ++typedef struct dwc_otg_adp { ++ uint32_t adp_started; ++ uint32_t initial_probe; ++ int32_t probe_timer_values[2]; ++ uint32_t probe_enabled; ++ uint32_t sense_enabled; ++ dwc_timer_t *sense_timer; ++ uint32_t sense_timer_started; ++ dwc_timer_t *vbuson_timer; ++ uint32_t vbuson_timer_started; ++ uint32_t attached; ++ uint32_t probe_counter; ++ uint32_t gpwrdn; ++} dwc_otg_adp_t; ++ ++/** ++ * Attach Detect Protocol functions ++ */ ++ ++extern void dwc_otg_adp_write_reg(dwc_otg_core_if_t * core_if, uint32_t value); ++extern uint32_t dwc_otg_adp_read_reg(dwc_otg_core_if_t * core_if); ++extern uint32_t dwc_otg_adp_probe_start(dwc_otg_core_if_t * core_if); ++extern uint32_t dwc_otg_adp_sense_start(dwc_otg_core_if_t * core_if); ++extern uint32_t dwc_otg_adp_probe_stop(dwc_otg_core_if_t * core_if); ++extern uint32_t dwc_otg_adp_sense_stop(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_adp_start(dwc_otg_core_if_t * core_if, uint8_t is_host); ++extern void dwc_otg_adp_init(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_adp_remove(dwc_otg_core_if_t * core_if); ++extern int32_t dwc_otg_adp_handle_intr(dwc_otg_core_if_t * core_if); ++extern int32_t dwc_otg_adp_handle_srp_intr(dwc_otg_core_if_t * core_if); ++ ++#endif //__DWC_OTG_ADP_H__ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_attr.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_attr.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1210 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $ ++ * $Revision: #44 $ ++ * $Date: 2010/11/29 $ ++ * $Change: 1636033 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++/** @file ++ * ++ * The diagnostic interface will provide access to the controller for ++ * bringing up the hardware and testing. The Linux driver attributes ++ * feature will be used to provide the Linux Diagnostic ++ * Interface. These attributes are accessed through sysfs. ++ */ ++ ++/** @page "Linux Module Attributes" ++ * ++ * The Linux module attributes feature is used to provide the Linux ++ * Diagnostic Interface. These attributes are accessed through sysfs. ++ * The diagnostic interface will provide access to the controller for ++ * bringing up the hardware and testing. ++ ++ The following table shows the attributes. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
Name Description Access
mode Returns the current mode: 0 for device mode, 1 for host mode Read
hnpcapable Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register. ++ Read returns the current value. Read/Write
srpcapable Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register. ++ Read returns the current value. Read/Write
hsic_connect Gets or sets the "HSIC-Connect" bit in the GLPMCFG Register. ++ Read returns the current value. Read/Write
inv_sel_hsic Gets or sets the "Invert Select HSIC" bit in the GLPMFG Register. ++ Read returns the current value. Read/Write
hnp Initiates the Host Negotiation Protocol. Read returns the status. Read/Write
srp Initiates the Session Request Protocol. Read returns the status. Read/Write
buspower Gets or sets the Power State of the bus (0 - Off or 1 - On) Read/Write
bussuspend Suspends the USB bus. Read/Write
busconnected Gets the connection status of the bus Read
gotgctl Gets or sets the Core Control Status Register. Read/Write
gusbcfg Gets or sets the Core USB Configuration Register Read/Write
grxfsiz Gets or sets the Receive FIFO Size Register Read/Write
gnptxfsiz Gets or sets the non-periodic Transmit Size Register Read/Write
gpvndctl Gets or sets the PHY Vendor Control Register Read/Write
ggpio Gets the value in the lower 16-bits of the General Purpose IO Register ++ or sets the upper 16 bits. Read/Write
guid Gets or sets the value of the User ID Register Read/Write
gsnpsid Gets the value of the Synopsys ID Regester Read
devspeed Gets or sets the device speed setting in the DCFG register Read/Write
enumspeed Gets the device enumeration Speed. Read
hptxfsiz Gets the value of the Host Periodic Transmit FIFO Read
hprt0 Gets or sets the value in the Host Port Control and Status Register Read/Write
regoffset Sets the register offset for the next Register Access Read/Write
regvalue Gets or sets the value of the register at the offset in the regoffset attribute. Read/Write
remote_wakeup On read, shows the status of Remote Wakeup. On write, initiates a remote ++ wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote ++ Wakeup signalling bit in the Device Control Register is set for 1 ++ milli-second. Read/Write
rem_wakeup_pwrdn On read, shows the status core - hibernated or not. On write, initiates ++ a remote wakeup of the device from Hibernation. Read/Write
mode_ch_tim_en This bit is used to enable or disable the host core to wait for 200 PHY ++ clock cycles at the end of Resume to change the opmode signal to the PHY to 00 ++ after Suspend or LPM. Read/Write
fr_interval On read, shows the value of HFIR Frame Interval. On write, dynamically ++ reload HFIR register during runtime. The application can write a value to this ++ register only after the Port Enable bit of the Host Port Control and Status ++ register (HPRT.PrtEnaPort) has been set Read/Write
disconnect_us On read, shows the status of disconnect_device_us. On write, sets disconnect_us ++ which causes soft disconnect for 100us. Applicable only for device mode of operation. Read/Write
regdump Dumps the contents of core registers. Read
spramdump Dumps the contents of core registers. Read
hcddump Dumps the current HCD state. Read
hcd_frrem Shows the average value of the Frame Remaining ++ field in the Host Frame Number/Frame Remaining register when an SOF interrupt ++ occurs. This can be used to determine the average interrupt latency. Also ++ shows the average Frame Remaining value for start_transfer and the "a" and ++ "b" sample points. The "a" and "b" sample points may be used during debugging ++ bto determine how long it takes to execute a section of the HCD code. Read
rd_reg_test Displays the time required to read the GNPTXFSIZ register many times ++ (the output shows the number of times the register is read). ++ Read
wr_reg_test Displays the time required to write the GNPTXFSIZ register many times ++ (the output shows the number of times the register is written). ++ Read
lpm_response Gets or sets lpm_response mode. Applicable only in device mode. ++ Write
sleep_status Shows sleep status of device. ++ Read
++ ++ Example usage: ++ To get the current mode: ++ cat /sys/devices/lm0/mode ++ ++ To power down the USB: ++ echo 0 > /sys/devices/lm0/buspower ++ */ ++ ++#include "dwc_otg_os_dep.h" ++#include "dwc_os.h" ++#include "dwc_otg_driver.h" ++#include "dwc_otg_attr.h" ++#include "dwc_otg_core_if.h" ++#include "dwc_otg_pcd_if.h" ++#include "dwc_otg_hcd_if.h" ++ ++/* ++ * MACROs for defining sysfs attribute ++ */ ++#ifdef LM_INTERFACE ++ ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \ ++ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \ ++ uint32_t val; \ ++ val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \ ++ return sprintf (buf, "%s = 0x%x\n", _string_, val); \ ++} ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \ ++ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \ ++ uint32_t set = simple_strtoul(buf, NULL, 16); \ ++ dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\ ++ return count; \ ++} ++ ++#elif defined(PCI_INTERFACE) ++ ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \ ++ uint32_t val; \ ++ val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \ ++ return sprintf (buf, "%s = 0x%x\n", _string_, val); \ ++} ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \ ++ uint32_t set = simple_strtoul(buf, NULL, 16); \ ++ dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\ ++ return count; \ ++} ++ ++#elif defined(PLATFORM_INTERFACE) ++ ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ struct platform_device *platform_dev = \ ++ container_of(_dev, struct platform_device, dev); \ ++ dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \ ++ uint32_t val; \ ++ DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \ ++ __func__, _dev, platform_dev, otg_dev); \ ++ val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \ ++ return sprintf (buf, "%s = 0x%x\n", _string_, val); \ ++} ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \ ++ dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \ ++ uint32_t set = simple_strtoul(buf, NULL, 16); \ ++ dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\ ++ return count; \ ++} ++#endif ++ ++/* ++ * MACROs for defining sysfs attribute for 32-bit registers ++ */ ++#ifdef LM_INTERFACE ++#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \ ++ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \ ++ uint32_t val; \ ++ val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \ ++ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \ ++} ++#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \ ++ dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \ ++ uint32_t val = simple_strtoul(buf, NULL, 16); \ ++ dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \ ++ return count; \ ++} ++#elif defined(PCI_INTERFACE) ++#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \ ++ uint32_t val; \ ++ val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \ ++ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \ ++} ++#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \ ++ uint32_t val = simple_strtoul(buf, NULL, 16); \ ++ dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \ ++ return count; \ ++} ++ ++#elif defined(PLATFORM_INTERFACE) ++#include "dwc_otg_dbg.h" ++#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \ ++ dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \ ++ uint32_t val; \ ++ DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \ ++ __func__, _dev, platform_dev, otg_dev); \ ++ val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \ ++ return sprintf (buf, "%s = 0x%08x\n", _string_, val); \ ++} ++#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \ ++static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \ ++ const char *buf, size_t count) \ ++{ \ ++ struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \ ++ dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \ ++ uint32_t val = simple_strtoul(buf, NULL, 16); \ ++ dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \ ++ return count; \ ++} ++ ++#endif ++ ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_string_) \ ++DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \ ++DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \ ++DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store); ++ ++#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_string_) \ ++DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \ ++DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); ++ ++#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \ ++DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \ ++DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \ ++DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store); ++ ++#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \ ++DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \ ++DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL); ++ ++/** @name Functions for Show/Store of Attributes */ ++/**@{*/ ++ ++/** ++ * Helper function returning the otg_device structure of the given device ++ */ ++static dwc_otg_device_t *dwc_otg_drvdev(struct device *_dev) ++{ ++ dwc_otg_device_t *otg_dev; ++ DWC_OTG_GETDRVDEV(otg_dev, _dev); ++ return otg_dev; ++} ++ ++/** ++ * Show the register offset of the Register Access. ++ */ ++static ssize_t regoffset_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n", ++ otg_dev->os_dep.reg_offset); ++} ++ ++/** ++ * Set the register offset for the next Register Access Read/Write ++ */ ++static ssize_t regoffset_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t offset = simple_strtoul(buf, NULL, 16); ++#if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE) ++ if (offset < SZ_256K) { ++#elif defined(PCI_INTERFACE) ++ if (offset < 0x00040000) { ++#endif ++ otg_dev->os_dep.reg_offset = offset; ++ } else { ++ dev_err(_dev, "invalid offset\n"); ++ } ++ ++ return count; ++} ++ ++DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store); ++ ++/** ++ * Show the value of the register at the offset in the reg_offset ++ * attribute. ++ */ ++static ssize_t regvalue_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t val; ++ volatile uint32_t *addr; ++ ++ if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) { ++ /* Calculate the address */ ++ addr = (uint32_t *) (otg_dev->os_dep.reg_offset + ++ (uint8_t *) otg_dev->os_dep.base); ++ val = DWC_READ_REG32(addr); ++ return snprintf(buf, ++ sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n") + 1, ++ "Reg@0x%06x = 0x%08x\n", otg_dev->os_dep.reg_offset, ++ val); ++ } else { ++ dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->os_dep.reg_offset); ++ return sprintf(buf, "invalid offset\n"); ++ } ++} ++ ++/** ++ * Store the value in the register at the offset in the reg_offset ++ * attribute. ++ * ++ */ ++static ssize_t regvalue_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ volatile uint32_t *addr; ++ uint32_t val = simple_strtoul(buf, NULL, 16); ++ //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val); ++ if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) { ++ /* Calculate the address */ ++ addr = (uint32_t *) (otg_dev->os_dep.reg_offset + ++ (uint8_t *) otg_dev->os_dep.base); ++ DWC_WRITE_REG32(addr, val); ++ } else { ++ dev_err(_dev, "Invalid Register Offset (0x%08x)\n", ++ otg_dev->os_dep.reg_offset); ++ } ++ return count; ++} ++ ++DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store); ++ ++/* ++ * Attributes ++ */ ++DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode, "Mode"); ++DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable, "HNPCapable"); ++DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable, "SRPCapable"); ++DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hsic_connect, "HSIC Connect"); ++DWC_OTG_DEVICE_ATTR_BITFIELD_RW(inv_sel_hsic, "Invert Select HSIC"); ++ ++//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode"); ++//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode"); ++DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, "Bus Connected"); ++ ++DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl, 0, "GOTGCTL"); ++DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg, ++ &(otg_dev->core_if->core_global_regs->gusbcfg), ++ "GUSBCFG"); ++DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz, ++ &(otg_dev->core_if->core_global_regs->grxfsiz), ++ "GRXFSIZ"); ++DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz, ++ &(otg_dev->core_if->core_global_regs->gnptxfsiz), ++ "GNPTXFSIZ"); ++DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl, ++ &(otg_dev->core_if->core_global_regs->gpvndctl), ++ "GPVNDCTL"); ++DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio, ++ &(otg_dev->core_if->core_global_regs->ggpio), ++ "GGPIO"); ++DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid), ++ "GUID"); ++DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid, ++ &(otg_dev->core_if->core_global_regs->gsnpsid), ++ "GSNPSID"); ++DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed, "Device Speed"); ++DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed, "Device Enumeration Speed"); ++ ++DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz, ++ &(otg_dev->core_if->core_global_regs->hptxfsiz), ++ "HPTXFSIZ"); ++DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0"); ++ ++/** ++ * @todo Add code to initiate the HNP. ++ */ ++/** ++ * Show the HNP status bit ++ */ ++static ssize_t hnp_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return sprintf(buf, "HstNegScs = 0x%x\n", ++ dwc_otg_get_hnpstatus(otg_dev->core_if)); ++} ++ ++/** ++ * Set the HNP Request bit ++ */ ++static ssize_t hnp_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t in = simple_strtoul(buf, NULL, 16); ++ dwc_otg_set_hnpreq(otg_dev->core_if, in); ++ return count; ++} ++ ++DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store); ++ ++/** ++ * @todo Add code to initiate the SRP. ++ */ ++/** ++ * Show the SRP status bit ++ */ ++static ssize_t srp_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++#ifndef DWC_HOST_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return sprintf(buf, "SesReqScs = 0x%x\n", ++ dwc_otg_get_srpstatus(otg_dev->core_if)); ++#else ++ return sprintf(buf, "Host Only Mode!\n"); ++#endif ++} ++ ++/** ++ * Set the SRP Request bit ++ */ ++static ssize_t srp_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++#ifndef DWC_HOST_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ dwc_otg_pcd_initiate_srp(otg_dev->pcd); ++#endif ++ return count; ++} ++ ++DEVICE_ATTR(srp, 0644, srp_show, srp_store); ++ ++/** ++ * @todo Need to do more for power on/off? ++ */ ++/** ++ * Show the Bus Power status ++ */ ++static ssize_t buspower_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return sprintf(buf, "Bus Power = 0x%x\n", ++ dwc_otg_get_prtpower(otg_dev->core_if)); ++} ++ ++/** ++ * Set the Bus Power status ++ */ ++static ssize_t buspower_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t on = simple_strtoul(buf, NULL, 16); ++ dwc_otg_set_prtpower(otg_dev->core_if, on); ++ return count; ++} ++ ++DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store); ++ ++/** ++ * @todo Need to do more for suspend? ++ */ ++/** ++ * Show the Bus Suspend status ++ */ ++static ssize_t bussuspend_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return sprintf(buf, "Bus Suspend = 0x%x\n", ++ dwc_otg_get_prtsuspend(otg_dev->core_if)); ++} ++ ++/** ++ * Set the Bus Suspend status ++ */ ++static ssize_t bussuspend_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t in = simple_strtoul(buf, NULL, 16); ++ dwc_otg_set_prtsuspend(otg_dev->core_if, in); ++ return count; ++} ++ ++DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store); ++ ++/** ++ * Show the Mode Change Ready Timer status ++ */ ++static ssize_t mode_ch_tim_en_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return sprintf(buf, "Mode Change Ready Timer Enable = 0x%x\n", ++ dwc_otg_get_mode_ch_tim(otg_dev->core_if)); ++} ++ ++/** ++ * Set the Mode Change Ready Timer status ++ */ ++static ssize_t mode_ch_tim_en_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t in = simple_strtoul(buf, NULL, 16); ++ dwc_otg_set_mode_ch_tim(otg_dev->core_if, in); ++ return count; ++} ++ ++DEVICE_ATTR(mode_ch_tim_en, 0644, mode_ch_tim_en_show, mode_ch_tim_en_store); ++ ++/** ++ * Show the value of HFIR Frame Interval bitfield ++ */ ++static ssize_t fr_interval_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return sprintf(buf, "Frame Interval = 0x%x\n", ++ dwc_otg_get_fr_interval(otg_dev->core_if)); ++} ++ ++/** ++ * Set the HFIR Frame Interval value ++ */ ++static ssize_t fr_interval_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t in = simple_strtoul(buf, NULL, 10); ++ dwc_otg_set_fr_interval(otg_dev->core_if, in); ++ return count; ++} ++ ++DEVICE_ATTR(fr_interval, 0644, fr_interval_show, fr_interval_store); ++ ++/** ++ * Show the status of Remote Wakeup. ++ */ ++static ssize_t remote_wakeup_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++#ifndef DWC_HOST_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ ++ return sprintf(buf, ++ "Remote Wakeup Sig = %d Enabled = %d LPM Remote Wakeup = %d\n", ++ dwc_otg_get_remotewakesig(otg_dev->core_if), ++ dwc_otg_pcd_get_rmwkup_enable(otg_dev->pcd), ++ dwc_otg_get_lpm_remotewakeenabled(otg_dev->core_if)); ++#else ++ return sprintf(buf, "Host Only Mode!\n"); ++#endif /* DWC_HOST_ONLY */ ++} ++ ++/** ++ * Initiate a remote wakeup of the host. The Device control register ++ * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable ++ * flag is set. ++ * ++ */ ++static ssize_t remote_wakeup_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++#ifndef DWC_HOST_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t val = simple_strtoul(buf, NULL, 16); ++ ++ if (val & 1) { ++ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1); ++ } else { ++ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0); ++ } ++#endif /* DWC_HOST_ONLY */ ++ return count; ++} ++ ++DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show, ++ remote_wakeup_store); ++ ++/** ++ * Show the whether core is hibernated or not. ++ */ ++static ssize_t rem_wakeup_pwrdn_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++#ifndef DWC_HOST_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ ++ if (dwc_otg_get_core_state(otg_dev->core_if)) { ++ DWC_PRINTF("Core is in hibernation\n"); ++ } else { ++ DWC_PRINTF("Core is not in hibernation\n"); ++ } ++#endif /* DWC_HOST_ONLY */ ++ return 0; ++} ++ ++extern int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if, ++ int rem_wakeup, int reset); ++ ++/** ++ * Initiate a remote wakeup of the device to exit from hibernation. ++ */ ++static ssize_t rem_wakeup_pwrdn_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++#ifndef DWC_HOST_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ dwc_otg_device_hibernation_restore(otg_dev->core_if, 1, 0); ++#endif ++ return count; ++} ++ ++DEVICE_ATTR(rem_wakeup_pwrdn, S_IRUGO | S_IWUSR, rem_wakeup_pwrdn_show, ++ rem_wakeup_pwrdn_store); ++ ++static ssize_t disconnect_us(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ ++#ifndef DWC_HOST_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t val = simple_strtoul(buf, NULL, 16); ++ DWC_PRINTF("The Passed value is %04x\n", val); ++ ++ dwc_otg_pcd_disconnect_us(otg_dev->pcd, 50); ++ ++#endif /* DWC_HOST_ONLY */ ++ return count; ++} ++ ++DEVICE_ATTR(disconnect_us, S_IWUSR, 0, disconnect_us); ++ ++/** ++ * Dump global registers and either host or device registers (depending on the ++ * current mode of the core). ++ */ ++static ssize_t regdump_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ ++ dwc_otg_dump_global_registers(otg_dev->core_if); ++ if (dwc_otg_is_host_mode(otg_dev->core_if)) { ++ dwc_otg_dump_host_registers(otg_dev->core_if); ++ } else { ++ dwc_otg_dump_dev_registers(otg_dev->core_if); ++ ++ } ++ return sprintf(buf, "Register Dump\n"); ++} ++ ++DEVICE_ATTR(regdump, S_IRUGO | S_IWUSR, regdump_show, 0); ++ ++/** ++ * Dump global registers and either host or device registers (depending on the ++ * current mode of the core). ++ */ ++static ssize_t spramdump_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ ++ dwc_otg_dump_spram(otg_dev->core_if); ++ ++ return sprintf(buf, "SPRAM Dump\n"); ++} ++ ++DEVICE_ATTR(spramdump, S_IRUGO | S_IWUSR, spramdump_show, 0); ++ ++/** ++ * Dump the current hcd state. ++ */ ++static ssize_t hcddump_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++#ifndef DWC_DEVICE_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ dwc_otg_hcd_dump_state(otg_dev->hcd); ++#endif /* DWC_DEVICE_ONLY */ ++ return sprintf(buf, "HCD Dump\n"); ++} ++ ++DEVICE_ATTR(hcddump, S_IRUGO | S_IWUSR, hcddump_show, 0); ++ ++/** ++ * Dump the average frame remaining at SOF. This can be used to ++ * determine average interrupt latency. Frame remaining is also shown for ++ * start transfer and two additional sample points. ++ */ ++static ssize_t hcd_frrem_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++#ifndef DWC_DEVICE_ONLY ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ ++ dwc_otg_hcd_dump_frrem(otg_dev->hcd); ++#endif /* DWC_DEVICE_ONLY */ ++ return sprintf(buf, "HCD Dump Frame Remaining\n"); ++} ++ ++DEVICE_ATTR(hcd_frrem, S_IRUGO | S_IWUSR, hcd_frrem_show, 0); ++ ++/** ++ * Displays the time required to read the GNPTXFSIZ register many times (the ++ * output shows the number of times the register is read). ++ */ ++#define RW_REG_COUNT 10000000 ++#define MSEC_PER_JIFFIE 1000/HZ ++static ssize_t rd_reg_test_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ int i; ++ int time; ++ int start_jiffies; ++ ++ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", ++ HZ, MSEC_PER_JIFFIE, loops_per_jiffy); ++ start_jiffies = jiffies; ++ for (i = 0; i < RW_REG_COUNT; i++) { ++ dwc_otg_get_gnptxfsiz(otg_dev->core_if); ++ } ++ time = jiffies - start_jiffies; ++ return sprintf(buf, ++ "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n", ++ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time); ++} ++ ++DEVICE_ATTR(rd_reg_test, S_IRUGO | S_IWUSR, rd_reg_test_show, 0); ++ ++/** ++ * Displays the time required to write the GNPTXFSIZ register many times (the ++ * output shows the number of times the register is written). ++ */ ++static ssize_t wr_reg_test_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t reg_val; ++ int i; ++ int time; ++ int start_jiffies; ++ ++ printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", ++ HZ, MSEC_PER_JIFFIE, loops_per_jiffy); ++ reg_val = dwc_otg_get_gnptxfsiz(otg_dev->core_if); ++ start_jiffies = jiffies; ++ for (i = 0; i < RW_REG_COUNT; i++) { ++ dwc_otg_set_gnptxfsiz(otg_dev->core_if, reg_val); ++ } ++ time = jiffies - start_jiffies; ++ return sprintf(buf, ++ "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n", ++ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time); ++} ++ ++DEVICE_ATTR(wr_reg_test, S_IRUGO | S_IWUSR, wr_reg_test_show, 0); ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ ++/** ++* Show the lpm_response attribute. ++*/ ++static ssize_t lpmresp_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ ++ if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if)) ++ return sprintf(buf, "** LPM is DISABLED **\n"); ++ ++ if (!dwc_otg_is_device_mode(otg_dev->core_if)) { ++ return sprintf(buf, "** Current mode is not device mode\n"); ++ } ++ return sprintf(buf, "lpm_response = %d\n", ++ dwc_otg_get_lpmresponse(otg_dev->core_if)); ++} ++ ++/** ++* Store the lpm_response attribute. ++*/ ++static ssize_t lpmresp_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ uint32_t val = simple_strtoul(buf, NULL, 16); ++ ++ if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if)) { ++ return 0; ++ } ++ ++ if (!dwc_otg_is_device_mode(otg_dev->core_if)) { ++ return 0; ++ } ++ ++ dwc_otg_set_lpmresponse(otg_dev->core_if, val); ++ return count; ++} ++ ++DEVICE_ATTR(lpm_response, S_IRUGO | S_IWUSR, lpmresp_show, lpmresp_store); ++ ++/** ++* Show the sleep_status attribute. ++*/ ++static ssize_t sleepstatus_show(struct device *_dev, ++ struct device_attribute *attr, char *buf) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ return sprintf(buf, "Sleep Status = %d\n", ++ dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if)); ++} ++ ++/** ++ * Store the sleep_status attribure. ++ */ ++static ssize_t sleepstatus_store(struct device *_dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev); ++ dwc_otg_core_if_t *core_if = otg_dev->core_if; ++ ++ if (dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if)) { ++ if (dwc_otg_is_host_mode(core_if)) { ++ ++ DWC_PRINTF("Host initiated resume\n"); ++ dwc_otg_set_prtresume(otg_dev->core_if, 1); ++ } ++ } ++ ++ return count; ++} ++ ++DEVICE_ATTR(sleep_status, S_IRUGO | S_IWUSR, sleepstatus_show, ++ sleepstatus_store); ++ ++#endif /* CONFIG_USB_DWC_OTG_LPM_ENABLE */ ++ ++/**@}*/ ++ ++/** ++ * Create the device files ++ */ ++void dwc_otg_attr_create( ++#ifdef LM_INTERFACE ++ struct lm_device *dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *dev ++#endif ++ ) ++{ ++ int error; ++ ++ error = device_create_file(&dev->dev, &dev_attr_regoffset); ++ error = device_create_file(&dev->dev, &dev_attr_regvalue); ++ error = device_create_file(&dev->dev, &dev_attr_mode); ++ error = device_create_file(&dev->dev, &dev_attr_hnpcapable); ++ error = device_create_file(&dev->dev, &dev_attr_srpcapable); ++ error = device_create_file(&dev->dev, &dev_attr_hsic_connect); ++ error = device_create_file(&dev->dev, &dev_attr_inv_sel_hsic); ++ error = device_create_file(&dev->dev, &dev_attr_hnp); ++ error = device_create_file(&dev->dev, &dev_attr_srp); ++ error = device_create_file(&dev->dev, &dev_attr_buspower); ++ error = device_create_file(&dev->dev, &dev_attr_bussuspend); ++ error = device_create_file(&dev->dev, &dev_attr_mode_ch_tim_en); ++ error = device_create_file(&dev->dev, &dev_attr_fr_interval); ++ error = device_create_file(&dev->dev, &dev_attr_busconnected); ++ error = device_create_file(&dev->dev, &dev_attr_gotgctl); ++ error = device_create_file(&dev->dev, &dev_attr_gusbcfg); ++ error = device_create_file(&dev->dev, &dev_attr_grxfsiz); ++ error = device_create_file(&dev->dev, &dev_attr_gnptxfsiz); ++ error = device_create_file(&dev->dev, &dev_attr_gpvndctl); ++ error = device_create_file(&dev->dev, &dev_attr_ggpio); ++ error = device_create_file(&dev->dev, &dev_attr_guid); ++ error = device_create_file(&dev->dev, &dev_attr_gsnpsid); ++ error = device_create_file(&dev->dev, &dev_attr_devspeed); ++ error = device_create_file(&dev->dev, &dev_attr_enumspeed); ++ error = device_create_file(&dev->dev, &dev_attr_hptxfsiz); ++ error = device_create_file(&dev->dev, &dev_attr_hprt0); ++ error = device_create_file(&dev->dev, &dev_attr_remote_wakeup); ++ error = device_create_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn); ++ error = device_create_file(&dev->dev, &dev_attr_disconnect_us); ++ error = device_create_file(&dev->dev, &dev_attr_regdump); ++ error = device_create_file(&dev->dev, &dev_attr_spramdump); ++ error = device_create_file(&dev->dev, &dev_attr_hcddump); ++ error = device_create_file(&dev->dev, &dev_attr_hcd_frrem); ++ error = device_create_file(&dev->dev, &dev_attr_rd_reg_test); ++ error = device_create_file(&dev->dev, &dev_attr_wr_reg_test); ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ error = device_create_file(&dev->dev, &dev_attr_lpm_response); ++ error = device_create_file(&dev->dev, &dev_attr_sleep_status); ++#endif ++} ++ ++/** ++ * Remove the device files ++ */ ++void dwc_otg_attr_remove( ++#ifdef LM_INTERFACE ++ struct lm_device *dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *dev ++#endif ++ ) ++{ ++ device_remove_file(&dev->dev, &dev_attr_regoffset); ++ device_remove_file(&dev->dev, &dev_attr_regvalue); ++ device_remove_file(&dev->dev, &dev_attr_mode); ++ device_remove_file(&dev->dev, &dev_attr_hnpcapable); ++ device_remove_file(&dev->dev, &dev_attr_srpcapable); ++ device_remove_file(&dev->dev, &dev_attr_hsic_connect); ++ device_remove_file(&dev->dev, &dev_attr_inv_sel_hsic); ++ device_remove_file(&dev->dev, &dev_attr_hnp); ++ device_remove_file(&dev->dev, &dev_attr_srp); ++ device_remove_file(&dev->dev, &dev_attr_buspower); ++ device_remove_file(&dev->dev, &dev_attr_bussuspend); ++ device_remove_file(&dev->dev, &dev_attr_mode_ch_tim_en); ++ device_remove_file(&dev->dev, &dev_attr_fr_interval); ++ device_remove_file(&dev->dev, &dev_attr_busconnected); ++ device_remove_file(&dev->dev, &dev_attr_gotgctl); ++ device_remove_file(&dev->dev, &dev_attr_gusbcfg); ++ device_remove_file(&dev->dev, &dev_attr_grxfsiz); ++ device_remove_file(&dev->dev, &dev_attr_gnptxfsiz); ++ device_remove_file(&dev->dev, &dev_attr_gpvndctl); ++ device_remove_file(&dev->dev, &dev_attr_ggpio); ++ device_remove_file(&dev->dev, &dev_attr_guid); ++ device_remove_file(&dev->dev, &dev_attr_gsnpsid); ++ device_remove_file(&dev->dev, &dev_attr_devspeed); ++ device_remove_file(&dev->dev, &dev_attr_enumspeed); ++ device_remove_file(&dev->dev, &dev_attr_hptxfsiz); ++ device_remove_file(&dev->dev, &dev_attr_hprt0); ++ device_remove_file(&dev->dev, &dev_attr_remote_wakeup); ++ device_remove_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn); ++ device_remove_file(&dev->dev, &dev_attr_disconnect_us); ++ device_remove_file(&dev->dev, &dev_attr_regdump); ++ device_remove_file(&dev->dev, &dev_attr_spramdump); ++ device_remove_file(&dev->dev, &dev_attr_hcddump); ++ device_remove_file(&dev->dev, &dev_attr_hcd_frrem); ++ device_remove_file(&dev->dev, &dev_attr_rd_reg_test); ++ device_remove_file(&dev->dev, &dev_attr_wr_reg_test); ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ device_remove_file(&dev->dev, &dev_attr_lpm_response); ++ device_remove_file(&dev->dev, &dev_attr_sleep_status); ++#endif ++} +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_attr.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_attr.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,89 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.h $ ++ * $Revision: #13 $ ++ * $Date: 2010/06/21 $ ++ * $Change: 1532021 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#if !defined(__DWC_OTG_ATTR_H__) ++#define __DWC_OTG_ATTR_H__ ++ ++/** @file ++ * This file contains the interface to the Linux device attributes. ++ */ ++extern struct device_attribute dev_attr_regoffset; ++extern struct device_attribute dev_attr_regvalue; ++ ++extern struct device_attribute dev_attr_mode; ++extern struct device_attribute dev_attr_hnpcapable; ++extern struct device_attribute dev_attr_srpcapable; ++extern struct device_attribute dev_attr_hnp; ++extern struct device_attribute dev_attr_srp; ++extern struct device_attribute dev_attr_buspower; ++extern struct device_attribute dev_attr_bussuspend; ++extern struct device_attribute dev_attr_mode_ch_tim_en; ++extern struct device_attribute dev_attr_fr_interval; ++extern struct device_attribute dev_attr_busconnected; ++extern struct device_attribute dev_attr_gotgctl; ++extern struct device_attribute dev_attr_gusbcfg; ++extern struct device_attribute dev_attr_grxfsiz; ++extern struct device_attribute dev_attr_gnptxfsiz; ++extern struct device_attribute dev_attr_gpvndctl; ++extern struct device_attribute dev_attr_ggpio; ++extern struct device_attribute dev_attr_guid; ++extern struct device_attribute dev_attr_gsnpsid; ++extern struct device_attribute dev_attr_devspeed; ++extern struct device_attribute dev_attr_enumspeed; ++extern struct device_attribute dev_attr_hptxfsiz; ++extern struct device_attribute dev_attr_hprt0; ++#ifdef CONFIG_USB_DWC_OTG_LPM ++extern struct device_attribute dev_attr_lpm_response; ++extern struct device_attribute devi_attr_sleep_status; ++#endif ++ ++void dwc_otg_attr_create( ++#ifdef LM_INTERFACE ++ struct lm_device *dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *dev ++#endif ++ ); ++ ++void dwc_otg_attr_remove( ++#ifdef LM_INTERFACE ++ struct lm_device *dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *dev ++#endif ++ ); ++#endif +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cfi.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cfi.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1876 @@ ++/* ========================================================================== ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++/** @file ++ * ++ * This file contains the most of the CFI(Core Feature Interface) ++ * implementation for the OTG. ++ */ ++ ++#ifdef DWC_UTE_CFI ++ ++#include "dwc_otg_pcd.h" ++#include "dwc_otg_cfi.h" ++ ++/** This definition should actually migrate to the Portability Library */ ++#define DWC_CONSTANT_CPU_TO_LE16(x) (x) ++ ++extern dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex); ++ ++static int cfi_core_features_buf(uint8_t * buf, uint16_t buflen); ++static int cfi_get_feature_value(uint8_t * buf, uint16_t buflen, ++ struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *ctrl_req); ++static int cfi_set_feature_value(struct dwc_otg_pcd *pcd); ++static int cfi_ep_get_sg_val(uint8_t * buf, struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req); ++static int cfi_ep_get_concat_val(uint8_t * buf, struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req); ++static int cfi_ep_get_align_val(uint8_t * buf, struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req); ++static int cfi_preproc_reset(struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req); ++static void cfi_free_ep_bs_dyn_data(cfi_ep_t * cfiep); ++ ++static uint16_t get_dfifo_size(dwc_otg_core_if_t * core_if); ++static int32_t get_rxfifo_size(dwc_otg_core_if_t * core_if, uint16_t wValue); ++static int32_t get_txfifo_size(struct dwc_otg_pcd *pcd, uint16_t wValue); ++ ++static uint8_t resize_fifos(dwc_otg_core_if_t * core_if); ++ ++/** This is the header of the all features descriptor */ ++static cfi_all_features_header_t all_props_desc_header = { ++ .wVersion = DWC_CONSTANT_CPU_TO_LE16(0x100), ++ .wCoreID = DWC_CONSTANT_CPU_TO_LE16(CFI_CORE_ID_OTG), ++ .wNumFeatures = DWC_CONSTANT_CPU_TO_LE16(9), ++}; ++ ++/** This is an array of statically allocated feature descriptors */ ++static cfi_feature_desc_header_t prop_descs[] = { ++ ++ /* FT_ID_DMA_MODE */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_MODE), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(1), ++ }, ++ ++ /* FT_ID_DMA_BUFFER_SETUP */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_BUFFER_SETUP), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(6), ++ }, ++ ++ /* FT_ID_DMA_BUFF_ALIGN */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_BUFF_ALIGN), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2), ++ }, ++ ++ /* FT_ID_DMA_CONCAT_SETUP */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_CONCAT_SETUP), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ //.wDataLength = DWC_CONSTANT_CPU_TO_LE16(6), ++ }, ++ ++ /* FT_ID_DMA_CIRCULAR */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_CIRCULAR), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(6), ++ }, ++ ++ /* FT_ID_THRESHOLD_SETUP */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_THRESHOLD_SETUP), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(6), ++ }, ++ ++ /* FT_ID_DFIFO_DEPTH */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DFIFO_DEPTH), ++ .bmAttributes = CFI_FEATURE_ATTR_RO, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2), ++ }, ++ ++ /* FT_ID_TX_FIFO_DEPTH */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_TX_FIFO_DEPTH), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2), ++ }, ++ ++ /* FT_ID_RX_FIFO_DEPTH */ ++ { ++ .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_RX_FIFO_DEPTH), ++ .bmAttributes = CFI_FEATURE_ATTR_RW, ++ .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2), ++ } ++}; ++ ++/** The table of feature names */ ++cfi_string_t prop_name_table[] = { ++ {FT_ID_DMA_MODE, "dma_mode"}, ++ {FT_ID_DMA_BUFFER_SETUP, "buffer_setup"}, ++ {FT_ID_DMA_BUFF_ALIGN, "buffer_align"}, ++ {FT_ID_DMA_CONCAT_SETUP, "concat_setup"}, ++ {FT_ID_DMA_CIRCULAR, "buffer_circular"}, ++ {FT_ID_THRESHOLD_SETUP, "threshold_setup"}, ++ {FT_ID_DFIFO_DEPTH, "dfifo_depth"}, ++ {FT_ID_TX_FIFO_DEPTH, "txfifo_depth"}, ++ {FT_ID_RX_FIFO_DEPTH, "rxfifo_depth"}, ++ {} ++}; ++ ++/************************************************************************/ ++ ++/** ++ * Returns the name of the feature by its ID ++ * or NULL if no featute ID matches. ++ * ++ */ ++const uint8_t *get_prop_name(uint16_t prop_id, int *len) ++{ ++ cfi_string_t *pstr; ++ *len = 0; ++ ++ for (pstr = prop_name_table; pstr && pstr->s; pstr++) { ++ if (pstr->id == prop_id) { ++ *len = DWC_STRLEN(pstr->s); ++ return pstr->s; ++ } ++ } ++ return NULL; ++} ++ ++/** ++ * This function handles all CFI specific control requests. ++ * ++ * Return a negative value to stall the DCE. ++ */ ++int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl) ++{ ++ int retval = 0; ++ dwc_otg_pcd_ep_t *ep = NULL; ++ cfiobject_t *cfi = pcd->cfi; ++ struct dwc_otg_core_if *coreif = GET_CORE_IF(pcd); ++ uint16_t wLen = DWC_LE16_TO_CPU(&ctrl->wLength); ++ uint16_t wValue = DWC_LE16_TO_CPU(&ctrl->wValue); ++ uint16_t wIndex = DWC_LE16_TO_CPU(&ctrl->wIndex); ++ uint32_t regaddr = 0; ++ uint32_t regval = 0; ++ ++ /* Save this Control Request in the CFI object. ++ * The data field will be assigned in the data stage completion CB function. ++ */ ++ cfi->ctrl_req = *ctrl; ++ cfi->ctrl_req.data = NULL; ++ ++ cfi->need_gadget_att = 0; ++ cfi->need_status_in_complete = 0; ++ ++ switch (ctrl->bRequest) { ++ case VEN_CORE_GET_FEATURES: ++ retval = cfi_core_features_buf(cfi->buf_in.buf, CFI_IN_BUF_LEN); ++ if (retval >= 0) { ++ //dump_msg(cfi->buf_in.buf, retval); ++ ep = &pcd->ep0; ++ ++ retval = min((uint16_t) retval, wLen); ++ /* Transfer this buffer to the host through the EP0-IN EP */ ++ ep->dwc_ep.dma_addr = cfi->buf_in.addr; ++ ep->dwc_ep.start_xfer_buff = cfi->buf_in.buf; ++ ep->dwc_ep.xfer_buff = cfi->buf_in.buf; ++ ep->dwc_ep.xfer_len = retval; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len; ++ ++ pcd->ep0_pending = 1; ++ dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep); ++ } ++ retval = 0; ++ break; ++ ++ case VEN_CORE_GET_FEATURE: ++ CFI_INFO("VEN_CORE_GET_FEATURE\n"); ++ retval = cfi_get_feature_value(cfi->buf_in.buf, CFI_IN_BUF_LEN, ++ pcd, ctrl); ++ if (retval >= 0) { ++ ep = &pcd->ep0; ++ ++ retval = min((uint16_t) retval, wLen); ++ /* Transfer this buffer to the host through the EP0-IN EP */ ++ ep->dwc_ep.dma_addr = cfi->buf_in.addr; ++ ep->dwc_ep.start_xfer_buff = cfi->buf_in.buf; ++ ep->dwc_ep.xfer_buff = cfi->buf_in.buf; ++ ep->dwc_ep.xfer_len = retval; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len; ++ ++ pcd->ep0_pending = 1; ++ dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep); ++ } ++ CFI_INFO("VEN_CORE_GET_FEATURE=%d\n", retval); ++ dump_msg(cfi->buf_in.buf, retval); ++ break; ++ ++ case VEN_CORE_SET_FEATURE: ++ CFI_INFO("VEN_CORE_SET_FEATURE\n"); ++ /* Set up an XFER to get the data stage of the control request, ++ * which is the new value of the feature to be modified. ++ */ ++ ep = &pcd->ep0; ++ ep->dwc_ep.is_in = 0; ++ ep->dwc_ep.dma_addr = cfi->buf_out.addr; ++ ep->dwc_ep.start_xfer_buff = cfi->buf_out.buf; ++ ep->dwc_ep.xfer_buff = cfi->buf_out.buf; ++ ep->dwc_ep.xfer_len = wLen; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len; ++ ++ pcd->ep0_pending = 1; ++ /* Read the control write's data stage */ ++ dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep); ++ retval = 0; ++ break; ++ ++ case VEN_CORE_RESET_FEATURES: ++ CFI_INFO("VEN_CORE_RESET_FEATURES\n"); ++ cfi->need_gadget_att = 1; ++ cfi->need_status_in_complete = 1; ++ retval = cfi_preproc_reset(pcd, ctrl); ++ CFI_INFO("VEN_CORE_RESET_FEATURES = (%d)\n", retval); ++ break; ++ ++ case VEN_CORE_ACTIVATE_FEATURES: ++ CFI_INFO("VEN_CORE_ACTIVATE_FEATURES\n"); ++ break; ++ ++ case VEN_CORE_READ_REGISTER: ++ CFI_INFO("VEN_CORE_READ_REGISTER\n"); ++ /* wValue optionally contains the HI WORD of the register offset and ++ * wIndex contains the LOW WORD of the register offset ++ */ ++ if (wValue == 0) { ++ /* @TODO - MAS - fix the access to the base field */ ++ regaddr = 0; ++ //regaddr = (uint32_t) pcd->otg_dev->os_dep.base; ++ //GET_CORE_IF(pcd)->co ++ regaddr |= wIndex; ++ } else { ++ regaddr = (wValue << 16) | wIndex; ++ } ++ ++ /* Read a 32-bit value of the memory at the regaddr */ ++ regval = DWC_READ_REG32((uint32_t *) regaddr); ++ ++ ep = &pcd->ep0; ++ dwc_memcpy(cfi->buf_in.buf, ®val, sizeof(uint32_t)); ++ ep->dwc_ep.is_in = 1; ++ ep->dwc_ep.dma_addr = cfi->buf_in.addr; ++ ep->dwc_ep.start_xfer_buff = cfi->buf_in.buf; ++ ep->dwc_ep.xfer_buff = cfi->buf_in.buf; ++ ep->dwc_ep.xfer_len = wLen; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len; ++ ++ pcd->ep0_pending = 1; ++ dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep); ++ cfi->need_gadget_att = 0; ++ retval = 0; ++ break; ++ ++ case VEN_CORE_WRITE_REGISTER: ++ CFI_INFO("VEN_CORE_WRITE_REGISTER\n"); ++ /* Set up an XFER to get the data stage of the control request, ++ * which is the new value of the register to be modified. ++ */ ++ ep = &pcd->ep0; ++ ep->dwc_ep.is_in = 0; ++ ep->dwc_ep.dma_addr = cfi->buf_out.addr; ++ ep->dwc_ep.start_xfer_buff = cfi->buf_out.buf; ++ ep->dwc_ep.xfer_buff = cfi->buf_out.buf; ++ ep->dwc_ep.xfer_len = wLen; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len; ++ ++ pcd->ep0_pending = 1; ++ /* Read the control write's data stage */ ++ dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep); ++ retval = 0; ++ break; ++ ++ default: ++ retval = -DWC_E_NOT_SUPPORTED; ++ break; ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function prepares the core features descriptors and copies its ++ * raw representation into the buffer . ++ * ++ * The buffer structure is as follows: ++ * all_features_header (8 bytes) ++ * features_#1 (8 bytes + feature name string length) ++ * features_#2 (8 bytes + feature name string length) ++ * ..... ++ * features_#n - where n=the total count of feature descriptors ++ */ ++static int cfi_core_features_buf(uint8_t * buf, uint16_t buflen) ++{ ++ cfi_feature_desc_header_t *prop_hdr = prop_descs; ++ cfi_feature_desc_header_t *prop; ++ cfi_all_features_header_t *all_props_hdr = &all_props_desc_header; ++ cfi_all_features_header_t *tmp; ++ uint8_t *tmpbuf = buf; ++ const uint8_t *pname = NULL; ++ int i, j, namelen = 0, totlen; ++ ++ /* Prepare and copy the core features into the buffer */ ++ CFI_INFO("%s:\n", __func__); ++ ++ tmp = (cfi_all_features_header_t *) tmpbuf; ++ *tmp = *all_props_hdr; ++ tmpbuf += CFI_ALL_FEATURES_HDR_LEN; ++ ++ j = sizeof(prop_descs) / sizeof(cfi_all_features_header_t); ++ for (i = 0; i < j; i++, prop_hdr++) { ++ pname = get_prop_name(prop_hdr->wFeatureID, &namelen); ++ prop = (cfi_feature_desc_header_t *) tmpbuf; ++ *prop = *prop_hdr; ++ ++ prop->bNameLen = namelen; ++ prop->wLength = ++ DWC_CONSTANT_CPU_TO_LE16(CFI_FEATURE_DESC_HDR_LEN + ++ namelen); ++ ++ tmpbuf += CFI_FEATURE_DESC_HDR_LEN; ++ dwc_memcpy(tmpbuf, pname, namelen); ++ tmpbuf += namelen; ++ } ++ ++ totlen = tmpbuf - buf; ++ ++ if (totlen > 0) { ++ tmp = (cfi_all_features_header_t *) buf; ++ tmp->wTotalLen = DWC_CONSTANT_CPU_TO_LE16(totlen); ++ } ++ ++ return totlen; ++} ++ ++/** ++ * This function releases all the dynamic memory in the CFI object. ++ */ ++static void cfi_release(cfiobject_t * cfiobj) ++{ ++ cfi_ep_t *cfiep; ++ dwc_list_link_t *tmp; ++ ++ CFI_INFO("%s\n", __func__); ++ ++ if (cfiobj->buf_in.buf) { ++ DWC_DMA_FREE(CFI_IN_BUF_LEN, cfiobj->buf_in.buf, ++ cfiobj->buf_in.addr); ++ cfiobj->buf_in.buf = NULL; ++ } ++ ++ if (cfiobj->buf_out.buf) { ++ DWC_DMA_FREE(CFI_OUT_BUF_LEN, cfiobj->buf_out.buf, ++ cfiobj->buf_out.addr); ++ cfiobj->buf_out.buf = NULL; ++ } ++ ++ /* Free the Buffer Setup values for each EP */ ++ //list_for_each_entry(cfiep, &cfiobj->active_eps, lh) { ++ DWC_LIST_FOREACH(tmp, &cfiobj->active_eps) { ++ cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh); ++ cfi_free_ep_bs_dyn_data(cfiep); ++ } ++} ++ ++/** ++ * This function frees the dynamically allocated EP buffer setup data. ++ */ ++static void cfi_free_ep_bs_dyn_data(cfi_ep_t * cfiep) ++{ ++ if (cfiep->bm_sg) { ++ DWC_FREE(cfiep->bm_sg); ++ cfiep->bm_sg = NULL; ++ } ++ ++ if (cfiep->bm_align) { ++ DWC_FREE(cfiep->bm_align); ++ cfiep->bm_align = NULL; ++ } ++ ++ if (cfiep->bm_concat) { ++ if (NULL != cfiep->bm_concat->wTxBytes) { ++ DWC_FREE(cfiep->bm_concat->wTxBytes); ++ cfiep->bm_concat->wTxBytes = NULL; ++ } ++ DWC_FREE(cfiep->bm_concat); ++ cfiep->bm_concat = NULL; ++ } ++} ++ ++/** ++ * This function initializes the default values of the features ++ * for a specific endpoint and should be called only once when ++ * the EP is enabled first time. ++ */ ++static int cfi_ep_init_defaults(struct dwc_otg_pcd *pcd, cfi_ep_t * cfiep) ++{ ++ int retval = 0; ++ ++ cfiep->bm_sg = DWC_ALLOC(sizeof(ddma_sg_buffer_setup_t)); ++ if (NULL == cfiep->bm_sg) { ++ CFI_INFO("Failed to allocate memory for SG feature value\n"); ++ return -DWC_E_NO_MEMORY; ++ } ++ dwc_memset(cfiep->bm_sg, 0, sizeof(ddma_sg_buffer_setup_t)); ++ ++ /* For the Concatenation feature's default value we do not allocate ++ * memory for the wTxBytes field - it will be done in the set_feature_value ++ * request handler. ++ */ ++ cfiep->bm_concat = DWC_ALLOC(sizeof(ddma_concat_buffer_setup_t)); ++ if (NULL == cfiep->bm_concat) { ++ CFI_INFO ++ ("Failed to allocate memory for CONCATENATION feature value\n"); ++ DWC_FREE(cfiep->bm_sg); ++ return -DWC_E_NO_MEMORY; ++ } ++ dwc_memset(cfiep->bm_concat, 0, sizeof(ddma_concat_buffer_setup_t)); ++ ++ cfiep->bm_align = DWC_ALLOC(sizeof(ddma_align_buffer_setup_t)); ++ if (NULL == cfiep->bm_align) { ++ CFI_INFO ++ ("Failed to allocate memory for Alignment feature value\n"); ++ DWC_FREE(cfiep->bm_sg); ++ DWC_FREE(cfiep->bm_concat); ++ return -DWC_E_NO_MEMORY; ++ } ++ dwc_memset(cfiep->bm_align, 0, sizeof(ddma_align_buffer_setup_t)); ++ ++ return retval; ++} ++ ++/** ++ * The callback function that notifies the CFI on the activation of ++ * an endpoint in the PCD. The following steps are done in this function: ++ * ++ * Create a dynamically allocated cfi_ep_t object (a CFI wrapper to the PCD's ++ * active endpoint) ++ * Create MAX_DMA_DESCS_PER_EP count DMA Descriptors for the EP ++ * Set the Buffer Mode to standard ++ * Initialize the default values for all EP modes (SG, Circular, Concat, Align) ++ * Add the cfi_ep_t object to the list of active endpoints in the CFI object ++ */ ++static int cfi_ep_enable(struct cfiobject *cfi, struct dwc_otg_pcd *pcd, ++ struct dwc_otg_pcd_ep *ep) ++{ ++ cfi_ep_t *cfiep; ++ int retval = -DWC_E_NOT_SUPPORTED; ++ ++ CFI_INFO("%s: epname=%s; epnum=0x%02x\n", __func__, ++ "EP_" /*ep->ep.name */ , ep->desc->bEndpointAddress); ++ /* MAS - Check whether this endpoint already is in the list */ ++ cfiep = get_cfi_ep_by_pcd_ep(cfi, ep); ++ ++ if (NULL == cfiep) { ++ /* Allocate a cfi_ep_t object */ ++ cfiep = DWC_ALLOC(sizeof(cfi_ep_t)); ++ if (NULL == cfiep) { ++ CFI_INFO ++ ("Unable to allocate memory for in function %s\n", ++ __func__); ++ return -DWC_E_NO_MEMORY; ++ } ++ dwc_memset(cfiep, 0, sizeof(cfi_ep_t)); ++ ++ /* Save the dwc_otg_pcd_ep pointer in the cfiep object */ ++ cfiep->ep = ep; ++ ++ /* Allocate the DMA Descriptors chain of MAX_DMA_DESCS_PER_EP count */ ++ ep->dwc_ep.descs = ++ DWC_DMA_ALLOC(MAX_DMA_DESCS_PER_EP * ++ sizeof(dwc_otg_dma_desc_t), ++ &ep->dwc_ep.descs_dma_addr); ++ ++ if (NULL == ep->dwc_ep.descs) { ++ DWC_FREE(cfiep); ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ DWC_LIST_INIT(&cfiep->lh); ++ ++ /* Set the buffer mode to BM_STANDARD. It will be modified ++ * when building descriptors for a specific buffer mode */ ++ ep->dwc_ep.buff_mode = BM_STANDARD; ++ ++ /* Create and initialize the default values for this EP's Buffer modes */ ++ if ((retval = cfi_ep_init_defaults(pcd, cfiep)) < 0) ++ return retval; ++ ++ /* Add the cfi_ep_t object to the CFI object's list of active endpoints */ ++ DWC_LIST_INSERT_TAIL(&cfi->active_eps, &cfiep->lh); ++ retval = 0; ++ } else { /* The sought EP already is in the list */ ++ CFI_INFO("%s: The sought EP already is in the list\n", ++ __func__); ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function is called when the data stage of a 3-stage Control Write request ++ * is complete. ++ * ++ */ ++static int cfi_ctrl_write_complete(struct cfiobject *cfi, ++ struct dwc_otg_pcd *pcd) ++{ ++ uint32_t addr, reg_value; ++ uint16_t wIndex, wValue; ++ uint8_t bRequest; ++ uint8_t *buf = cfi->buf_out.buf; ++ //struct usb_ctrlrequest *ctrl_req = &cfi->ctrl_req_saved; ++ struct cfi_usb_ctrlrequest *ctrl_req = &cfi->ctrl_req; ++ int retval = -DWC_E_NOT_SUPPORTED; ++ ++ CFI_INFO("%s\n", __func__); ++ ++ bRequest = ctrl_req->bRequest; ++ wIndex = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wIndex); ++ wValue = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wValue); ++ ++ /* ++ * Save the pointer to the data stage in the ctrl_req's field. ++ * The request should be already saved in the command stage by now. ++ */ ++ ctrl_req->data = cfi->buf_out.buf; ++ cfi->need_status_in_complete = 0; ++ cfi->need_gadget_att = 0; ++ ++ switch (bRequest) { ++ case VEN_CORE_WRITE_REGISTER: ++ /* The buffer contains raw data of the new value for the register */ ++ reg_value = *((uint32_t *) buf); ++ if (wValue == 0) { ++ addr = 0; ++ //addr = (uint32_t) pcd->otg_dev->os_dep.base; ++ addr += wIndex; ++ } else { ++ addr = (wValue << 16) | wIndex; ++ } ++ ++ //writel(reg_value, addr); ++ ++ retval = 0; ++ cfi->need_status_in_complete = 1; ++ break; ++ ++ case VEN_CORE_SET_FEATURE: ++ /* The buffer contains raw data of the new value of the feature */ ++ retval = cfi_set_feature_value(pcd); ++ if (retval < 0) ++ return retval; ++ ++ cfi->need_status_in_complete = 1; ++ break; ++ ++ default: ++ break; ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function builds the DMA descriptors for the SG buffer mode. ++ */ ++static void cfi_build_sg_descs(struct cfiobject *cfi, cfi_ep_t * cfiep, ++ dwc_otg_pcd_request_t * req) ++{ ++ struct dwc_otg_pcd_ep *ep = cfiep->ep; ++ ddma_sg_buffer_setup_t *sgval = cfiep->bm_sg; ++ struct dwc_otg_dma_desc *desc = cfiep->ep->dwc_ep.descs; ++ struct dwc_otg_dma_desc *desc_last = cfiep->ep->dwc_ep.descs; ++ dma_addr_t buff_addr = req->dma; ++ int i; ++ uint32_t txsize, off; ++ ++ txsize = sgval->wSize; ++ off = sgval->bOffset; ++ ++// CFI_INFO("%s: %s TXSIZE=0x%08x; OFFSET=0x%08x\n", ++// __func__, cfiep->ep->ep.name, txsize, off); ++ ++ for (i = 0; i < sgval->bCount; i++) { ++ desc->status.b.bs = BS_HOST_BUSY; ++ desc->buf = buff_addr; ++ desc->status.b.l = 0; ++ desc->status.b.ioc = 0; ++ desc->status.b.sp = 0; ++ desc->status.b.bytes = txsize; ++ desc->status.b.bs = BS_HOST_READY; ++ ++ /* Set the next address of the buffer */ ++ buff_addr += txsize + off; ++ desc_last = desc; ++ desc++; ++ } ++ ++ /* Set the last, ioc and sp bits on the Last DMA Descriptor */ ++ desc_last->status.b.l = 1; ++ desc_last->status.b.ioc = 1; ++ desc_last->status.b.sp = ep->dwc_ep.sent_zlp; ++ /* Save the last DMA descriptor pointer */ ++ cfiep->dma_desc_last = desc_last; ++ cfiep->desc_count = sgval->bCount; ++} ++ ++/** ++ * This function builds the DMA descriptors for the Concatenation buffer mode. ++ */ ++static void cfi_build_concat_descs(struct cfiobject *cfi, cfi_ep_t * cfiep, ++ dwc_otg_pcd_request_t * req) ++{ ++ struct dwc_otg_pcd_ep *ep = cfiep->ep; ++ ddma_concat_buffer_setup_t *concatval = cfiep->bm_concat; ++ struct dwc_otg_dma_desc *desc = cfiep->ep->dwc_ep.descs; ++ struct dwc_otg_dma_desc *desc_last = cfiep->ep->dwc_ep.descs; ++ dma_addr_t buff_addr = req->dma; ++ int i; ++ uint16_t *txsize; ++ ++ txsize = concatval->wTxBytes; ++ ++ for (i = 0; i < concatval->hdr.bDescCount; i++) { ++ desc->buf = buff_addr; ++ desc->status.b.bs = BS_HOST_BUSY; ++ desc->status.b.l = 0; ++ desc->status.b.ioc = 0; ++ desc->status.b.sp = 0; ++ desc->status.b.bytes = *txsize; ++ desc->status.b.bs = BS_HOST_READY; ++ ++ txsize++; ++ /* Set the next address of the buffer */ ++ buff_addr += UGETW(ep->desc->wMaxPacketSize); ++ desc_last = desc; ++ desc++; ++ } ++ ++ /* Set the last, ioc and sp bits on the Last DMA Descriptor */ ++ desc_last->status.b.l = 1; ++ desc_last->status.b.ioc = 1; ++ desc_last->status.b.sp = ep->dwc_ep.sent_zlp; ++ cfiep->dma_desc_last = desc_last; ++ cfiep->desc_count = concatval->hdr.bDescCount; ++} ++ ++/** ++ * This function builds the DMA descriptors for the Circular buffer mode ++ */ ++static void cfi_build_circ_descs(struct cfiobject *cfi, cfi_ep_t * cfiep, ++ dwc_otg_pcd_request_t * req) ++{ ++ /* @todo: MAS - add implementation when this feature needs to be tested */ ++} ++ ++/** ++ * This function builds the DMA descriptors for the Alignment buffer mode ++ */ ++static void cfi_build_align_descs(struct cfiobject *cfi, cfi_ep_t * cfiep, ++ dwc_otg_pcd_request_t * req) ++{ ++ struct dwc_otg_pcd_ep *ep = cfiep->ep; ++ ddma_align_buffer_setup_t *alignval = cfiep->bm_align; ++ struct dwc_otg_dma_desc *desc = cfiep->ep->dwc_ep.descs; ++ dma_addr_t buff_addr = req->dma; ++ ++ desc->status.b.bs = BS_HOST_BUSY; ++ desc->status.b.l = 1; ++ desc->status.b.ioc = 1; ++ desc->status.b.sp = ep->dwc_ep.sent_zlp; ++ desc->status.b.bytes = req->length; ++ /* Adjust the buffer alignment */ ++ desc->buf = (buff_addr + alignval->bAlign); ++ desc->status.b.bs = BS_HOST_READY; ++ cfiep->dma_desc_last = desc; ++ cfiep->desc_count = 1; ++} ++ ++/** ++ * This function builds the DMA descriptors chain for different modes of the ++ * buffer setup of an endpoint. ++ */ ++static void cfi_build_descriptors(struct cfiobject *cfi, ++ struct dwc_otg_pcd *pcd, ++ struct dwc_otg_pcd_ep *ep, ++ dwc_otg_pcd_request_t * req) ++{ ++ cfi_ep_t *cfiep; ++ ++ /* Get the cfiep by the dwc_otg_pcd_ep */ ++ cfiep = get_cfi_ep_by_pcd_ep(cfi, ep); ++ if (NULL == cfiep) { ++ CFI_INFO("%s: Unable to find a matching active endpoint\n", ++ __func__); ++ return; ++ } ++ ++ cfiep->xfer_len = req->length; ++ ++ /* Iterate through all the DMA descriptors */ ++ switch (cfiep->ep->dwc_ep.buff_mode) { ++ case BM_SG: ++ cfi_build_sg_descs(cfi, cfiep, req); ++ break; ++ ++ case BM_CONCAT: ++ cfi_build_concat_descs(cfi, cfiep, req); ++ break; ++ ++ case BM_CIRCULAR: ++ cfi_build_circ_descs(cfi, cfiep, req); ++ break; ++ ++ case BM_ALIGN: ++ cfi_build_align_descs(cfi, cfiep, req); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++/** ++ * Allocate DMA buffer for different Buffer modes. ++ */ ++static void *cfi_ep_alloc_buf(struct cfiobject *cfi, struct dwc_otg_pcd *pcd, ++ struct dwc_otg_pcd_ep *ep, dma_addr_t * dma, ++ unsigned size, gfp_t flags) ++{ ++ return DWC_DMA_ALLOC(size, dma); ++} ++ ++/** ++ * This function initializes the CFI object. ++ */ ++int init_cfi(cfiobject_t * cfiobj) ++{ ++ CFI_INFO("%s\n", __func__); ++ ++ /* Allocate a buffer for IN XFERs */ ++ cfiobj->buf_in.buf = ++ DWC_DMA_ALLOC(CFI_IN_BUF_LEN, &cfiobj->buf_in.addr); ++ if (NULL == cfiobj->buf_in.buf) { ++ CFI_INFO("Unable to allocate buffer for INs\n"); ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ /* Allocate a buffer for OUT XFERs */ ++ cfiobj->buf_out.buf = ++ DWC_DMA_ALLOC(CFI_OUT_BUF_LEN, &cfiobj->buf_out.addr); ++ if (NULL == cfiobj->buf_out.buf) { ++ CFI_INFO("Unable to allocate buffer for OUT\n"); ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ /* Initialize the callback function pointers */ ++ cfiobj->ops.release = cfi_release; ++ cfiobj->ops.ep_enable = cfi_ep_enable; ++ cfiobj->ops.ctrl_write_complete = cfi_ctrl_write_complete; ++ cfiobj->ops.build_descriptors = cfi_build_descriptors; ++ cfiobj->ops.ep_alloc_buf = cfi_ep_alloc_buf; ++ ++ /* Initialize the list of active endpoints in the CFI object */ ++ DWC_LIST_INIT(&cfiobj->active_eps); ++ ++ return 0; ++} ++ ++/** ++ * This function reads the required feature's current value into the buffer ++ * ++ * @retval: Returns negative as error, or the data length of the feature ++ */ ++static int cfi_get_feature_value(uint8_t * buf, uint16_t buflen, ++ struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *ctrl_req) ++{ ++ int retval = -DWC_E_NOT_SUPPORTED; ++ struct dwc_otg_core_if *coreif = GET_CORE_IF(pcd); ++ uint16_t dfifo, rxfifo, txfifo; ++ ++ switch (ctrl_req->wIndex) { ++ /* Whether the DDMA is enabled or not */ ++ case FT_ID_DMA_MODE: ++ *buf = (coreif->dma_enable && coreif->dma_desc_enable) ? 1 : 0; ++ retval = 1; ++ break; ++ ++ case FT_ID_DMA_BUFFER_SETUP: ++ retval = cfi_ep_get_sg_val(buf, pcd, ctrl_req); ++ break; ++ ++ case FT_ID_DMA_BUFF_ALIGN: ++ retval = cfi_ep_get_align_val(buf, pcd, ctrl_req); ++ break; ++ ++ case FT_ID_DMA_CONCAT_SETUP: ++ retval = cfi_ep_get_concat_val(buf, pcd, ctrl_req); ++ break; ++ ++ case FT_ID_DMA_CIRCULAR: ++ CFI_INFO("GetFeature value (FT_ID_DMA_CIRCULAR)\n"); ++ break; ++ ++ case FT_ID_THRESHOLD_SETUP: ++ CFI_INFO("GetFeature value (FT_ID_THRESHOLD_SETUP)\n"); ++ break; ++ ++ case FT_ID_DFIFO_DEPTH: ++ dfifo = get_dfifo_size(coreif); ++ *((uint16_t *) buf) = dfifo; ++ retval = sizeof(uint16_t); ++ break; ++ ++ case FT_ID_TX_FIFO_DEPTH: ++ retval = get_txfifo_size(pcd, ctrl_req->wValue); ++ if (retval >= 0) { ++ txfifo = retval; ++ *((uint16_t *) buf) = txfifo; ++ retval = sizeof(uint16_t); ++ } ++ break; ++ ++ case FT_ID_RX_FIFO_DEPTH: ++ retval = get_rxfifo_size(coreif, ctrl_req->wValue); ++ if (retval >= 0) { ++ rxfifo = retval; ++ *((uint16_t *) buf) = rxfifo; ++ retval = sizeof(uint16_t); ++ } ++ break; ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function resets the SG for the specified EP to its default value ++ */ ++static int cfi_reset_sg_val(cfi_ep_t * cfiep) ++{ ++ dwc_memset(cfiep->bm_sg, 0, sizeof(ddma_sg_buffer_setup_t)); ++ return 0; ++} ++ ++/** ++ * This function resets the Alignment for the specified EP to its default value ++ */ ++static int cfi_reset_align_val(cfi_ep_t * cfiep) ++{ ++ dwc_memset(cfiep->bm_sg, 0, sizeof(ddma_sg_buffer_setup_t)); ++ return 0; ++} ++ ++/** ++ * This function resets the Concatenation for the specified EP to its default value ++ * This function will also set the value of the wTxBytes field to NULL after ++ * freeing the memory previously allocated for this field. ++ */ ++static int cfi_reset_concat_val(cfi_ep_t * cfiep) ++{ ++ /* First we need to free the wTxBytes field */ ++ if (cfiep->bm_concat->wTxBytes) { ++ DWC_FREE(cfiep->bm_concat->wTxBytes); ++ cfiep->bm_concat->wTxBytes = NULL; ++ } ++ ++ dwc_memset(cfiep->bm_concat, 0, sizeof(ddma_concat_buffer_setup_t)); ++ return 0; ++} ++ ++/** ++ * This function resets all the buffer setups of the specified endpoint ++ */ ++static int cfi_ep_reset_all_setup_vals(cfi_ep_t * cfiep) ++{ ++ cfi_reset_sg_val(cfiep); ++ cfi_reset_align_val(cfiep); ++ cfi_reset_concat_val(cfiep); ++ return 0; ++} ++ ++static int cfi_handle_reset_fifo_val(struct dwc_otg_pcd *pcd, uint8_t ep_addr, ++ uint8_t rx_rst, uint8_t tx_rst) ++{ ++ int retval = -DWC_E_INVALID; ++ uint16_t tx_siz[15]; ++ uint16_t rx_siz = 0; ++ dwc_otg_pcd_ep_t *ep = NULL; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_core_params_t *params = GET_CORE_IF(pcd)->core_params; ++ ++ if (rx_rst) { ++ rx_siz = params->dev_rx_fifo_size; ++ params->dev_rx_fifo_size = GET_CORE_IF(pcd)->init_rxfsiz; ++ } ++ ++ if (tx_rst) { ++ if (ep_addr == 0) { ++ int i; ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ tx_siz[i] = ++ core_if->core_params->dev_tx_fifo_size[i]; ++ core_if->core_params->dev_tx_fifo_size[i] = ++ core_if->init_txfsiz[i]; ++ } ++ } else { ++ ++ ep = get_ep_by_addr(pcd, ep_addr); ++ ++ if (NULL == ep) { ++ CFI_INFO ++ ("%s: Unable to get the endpoint addr=0x%02x\n", ++ __func__, ep_addr); ++ return -DWC_E_INVALID; ++ } ++ ++ tx_siz[0] = ++ params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - ++ 1]; ++ params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1] = ++ GET_CORE_IF(pcd)->init_txfsiz[ep-> ++ dwc_ep.tx_fifo_num - ++ 1]; ++ } ++ } ++ ++ if (resize_fifos(GET_CORE_IF(pcd))) { ++ retval = 0; ++ } else { ++ CFI_INFO ++ ("%s: Error resetting the feature Reset All(FIFO size)\n", ++ __func__); ++ if (rx_rst) { ++ params->dev_rx_fifo_size = rx_siz; ++ } ++ ++ if (tx_rst) { ++ if (ep_addr == 0) { ++ int i; ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; ++ i++) { ++ core_if-> ++ core_params->dev_tx_fifo_size[i] = ++ tx_siz[i]; ++ } ++ } else { ++ params->dev_tx_fifo_size[ep-> ++ dwc_ep.tx_fifo_num - ++ 1] = tx_siz[0]; ++ } ++ } ++ retval = -DWC_E_INVALID; ++ } ++ return retval; ++} ++ ++static int cfi_handle_reset_all(struct dwc_otg_pcd *pcd, uint8_t addr) ++{ ++ int retval = 0; ++ cfi_ep_t *cfiep; ++ cfiobject_t *cfi = pcd->cfi; ++ dwc_list_link_t *tmp; ++ ++ retval = cfi_handle_reset_fifo_val(pcd, addr, 1, 1); ++ if (retval < 0) { ++ return retval; ++ } ++ ++ /* If the EP address is known then reset the features for only that EP */ ++ if (addr) { ++ cfiep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == cfiep) { ++ CFI_INFO("%s: Error getting the EP address 0x%02x\n", ++ __func__, addr); ++ return -DWC_E_INVALID; ++ } ++ retval = cfi_ep_reset_all_setup_vals(cfiep); ++ cfiep->ep->dwc_ep.buff_mode = BM_STANDARD; ++ } ++ /* Otherwise (wValue == 0), reset all features of all EP's */ ++ else { ++ /* Traverse all the active EP's and reset the feature(s) value(s) */ ++ //list_for_each_entry(cfiep, &cfi->active_eps, lh) { ++ DWC_LIST_FOREACH(tmp, &cfi->active_eps) { ++ cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh); ++ retval = cfi_ep_reset_all_setup_vals(cfiep); ++ cfiep->ep->dwc_ep.buff_mode = BM_STANDARD; ++ if (retval < 0) { ++ CFI_INFO ++ ("%s: Error resetting the feature Reset All\n", ++ __func__); ++ return retval; ++ } ++ } ++ } ++ return retval; ++} ++ ++static int cfi_handle_reset_dma_buff_setup(struct dwc_otg_pcd *pcd, ++ uint8_t addr) ++{ ++ int retval = 0; ++ cfi_ep_t *cfiep; ++ cfiobject_t *cfi = pcd->cfi; ++ dwc_list_link_t *tmp; ++ ++ /* If the EP address is known then reset the features for only that EP */ ++ if (addr) { ++ cfiep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == cfiep) { ++ CFI_INFO("%s: Error getting the EP address 0x%02x\n", ++ __func__, addr); ++ return -DWC_E_INVALID; ++ } ++ retval = cfi_reset_sg_val(cfiep); ++ } ++ /* Otherwise (wValue == 0), reset all features of all EP's */ ++ else { ++ /* Traverse all the active EP's and reset the feature(s) value(s) */ ++ //list_for_each_entry(cfiep, &cfi->active_eps, lh) { ++ DWC_LIST_FOREACH(tmp, &cfi->active_eps) { ++ cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh); ++ retval = cfi_reset_sg_val(cfiep); ++ if (retval < 0) { ++ CFI_INFO ++ ("%s: Error resetting the feature Buffer Setup\n", ++ __func__); ++ return retval; ++ } ++ } ++ } ++ return retval; ++} ++ ++static int cfi_handle_reset_concat_val(struct dwc_otg_pcd *pcd, uint8_t addr) ++{ ++ int retval = 0; ++ cfi_ep_t *cfiep; ++ cfiobject_t *cfi = pcd->cfi; ++ dwc_list_link_t *tmp; ++ ++ /* If the EP address is known then reset the features for only that EP */ ++ if (addr) { ++ cfiep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == cfiep) { ++ CFI_INFO("%s: Error getting the EP address 0x%02x\n", ++ __func__, addr); ++ return -DWC_E_INVALID; ++ } ++ retval = cfi_reset_concat_val(cfiep); ++ } ++ /* Otherwise (wValue == 0), reset all features of all EP's */ ++ else { ++ /* Traverse all the active EP's and reset the feature(s) value(s) */ ++ //list_for_each_entry(cfiep, &cfi->active_eps, lh) { ++ DWC_LIST_FOREACH(tmp, &cfi->active_eps) { ++ cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh); ++ retval = cfi_reset_concat_val(cfiep); ++ if (retval < 0) { ++ CFI_INFO ++ ("%s: Error resetting the feature Concatenation Value\n", ++ __func__); ++ return retval; ++ } ++ } ++ } ++ return retval; ++} ++ ++static int cfi_handle_reset_align_val(struct dwc_otg_pcd *pcd, uint8_t addr) ++{ ++ int retval = 0; ++ cfi_ep_t *cfiep; ++ cfiobject_t *cfi = pcd->cfi; ++ dwc_list_link_t *tmp; ++ ++ /* If the EP address is known then reset the features for only that EP */ ++ if (addr) { ++ cfiep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == cfiep) { ++ CFI_INFO("%s: Error getting the EP address 0x%02x\n", ++ __func__, addr); ++ return -DWC_E_INVALID; ++ } ++ retval = cfi_reset_align_val(cfiep); ++ } ++ /* Otherwise (wValue == 0), reset all features of all EP's */ ++ else { ++ /* Traverse all the active EP's and reset the feature(s) value(s) */ ++ //list_for_each_entry(cfiep, &cfi->active_eps, lh) { ++ DWC_LIST_FOREACH(tmp, &cfi->active_eps) { ++ cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh); ++ retval = cfi_reset_align_val(cfiep); ++ if (retval < 0) { ++ CFI_INFO ++ ("%s: Error resetting the feature Aliignment Value\n", ++ __func__); ++ return retval; ++ } ++ } ++ } ++ return retval; ++ ++} ++ ++static int cfi_preproc_reset(struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req) ++{ ++ int retval = 0; ++ ++ switch (req->wIndex) { ++ case 0: ++ /* Reset all features */ ++ retval = cfi_handle_reset_all(pcd, req->wValue & 0xff); ++ break; ++ ++ case FT_ID_DMA_BUFFER_SETUP: ++ /* Reset the SG buffer setup */ ++ retval = ++ cfi_handle_reset_dma_buff_setup(pcd, req->wValue & 0xff); ++ break; ++ ++ case FT_ID_DMA_CONCAT_SETUP: ++ /* Reset the Concatenation buffer setup */ ++ retval = cfi_handle_reset_concat_val(pcd, req->wValue & 0xff); ++ break; ++ ++ case FT_ID_DMA_BUFF_ALIGN: ++ /* Reset the Alignment buffer setup */ ++ retval = cfi_handle_reset_align_val(pcd, req->wValue & 0xff); ++ break; ++ ++ case FT_ID_TX_FIFO_DEPTH: ++ retval = ++ cfi_handle_reset_fifo_val(pcd, req->wValue & 0xff, 0, 1); ++ pcd->cfi->need_gadget_att = 0; ++ break; ++ ++ case FT_ID_RX_FIFO_DEPTH: ++ retval = cfi_handle_reset_fifo_val(pcd, 0, 1, 0); ++ pcd->cfi->need_gadget_att = 0; ++ break; ++ default: ++ break; ++ } ++ return retval; ++} ++ ++/** ++ * This function sets a new value for the SG buffer setup. ++ */ ++static int cfi_ep_set_sg_val(uint8_t * buf, struct dwc_otg_pcd *pcd) ++{ ++ uint8_t inaddr, outaddr; ++ cfi_ep_t *epin, *epout; ++ ddma_sg_buffer_setup_t *psgval; ++ uint32_t desccount, size; ++ ++ CFI_INFO("%s\n", __func__); ++ ++ psgval = (ddma_sg_buffer_setup_t *) buf; ++ desccount = (uint32_t) psgval->bCount; ++ size = (uint32_t) psgval->wSize; ++ ++ /* Check the DMA descriptor count */ ++ if ((desccount > MAX_DMA_DESCS_PER_EP) || (desccount == 0)) { ++ CFI_INFO ++ ("%s: The count of DMA Descriptors should be between 1 and %d\n", ++ __func__, MAX_DMA_DESCS_PER_EP); ++ return -DWC_E_INVALID; ++ } ++ ++ /* Check the DMA descriptor count */ ++ ++ if (size == 0) { ++ ++ CFI_INFO("%s: The transfer size should be at least 1 byte\n", ++ __func__); ++ ++ return -DWC_E_INVALID; ++ ++ } ++ ++ inaddr = psgval->bInEndpointAddress; ++ outaddr = psgval->bOutEndpointAddress; ++ ++ epin = get_cfi_ep_by_addr(pcd->cfi, inaddr); ++ epout = get_cfi_ep_by_addr(pcd->cfi, outaddr); ++ ++ if (NULL == epin || NULL == epout) { ++ CFI_INFO ++ ("%s: Unable to get the endpoints inaddr=0x%02x outaddr=0x%02x\n", ++ __func__, inaddr, outaddr); ++ return -DWC_E_INVALID; ++ } ++ ++ epin->ep->dwc_ep.buff_mode = BM_SG; ++ dwc_memcpy(epin->bm_sg, psgval, sizeof(ddma_sg_buffer_setup_t)); ++ ++ epout->ep->dwc_ep.buff_mode = BM_SG; ++ dwc_memcpy(epout->bm_sg, psgval, sizeof(ddma_sg_buffer_setup_t)); ++ ++ return 0; ++} ++ ++/** ++ * This function sets a new value for the buffer Alignment setup. ++ */ ++static int cfi_ep_set_alignment_val(uint8_t * buf, struct dwc_otg_pcd *pcd) ++{ ++ cfi_ep_t *ep; ++ uint8_t addr; ++ ddma_align_buffer_setup_t *palignval; ++ ++ palignval = (ddma_align_buffer_setup_t *) buf; ++ addr = palignval->bEndpointAddress; ++ ++ ep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ ++ if (NULL == ep) { ++ CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n", ++ __func__, addr); ++ return -DWC_E_INVALID; ++ } ++ ++ ep->ep->dwc_ep.buff_mode = BM_ALIGN; ++ dwc_memcpy(ep->bm_align, palignval, sizeof(ddma_align_buffer_setup_t)); ++ ++ return 0; ++} ++ ++/** ++ * This function sets a new value for the Concatenation buffer setup. ++ */ ++static int cfi_ep_set_concat_val(uint8_t * buf, struct dwc_otg_pcd *pcd) ++{ ++ uint8_t addr; ++ cfi_ep_t *ep; ++ struct _ddma_concat_buffer_setup_hdr *pConcatValHdr; ++ uint16_t *pVals; ++ uint32_t desccount; ++ int i; ++ uint16_t mps; ++ ++ pConcatValHdr = (struct _ddma_concat_buffer_setup_hdr *)buf; ++ desccount = (uint32_t) pConcatValHdr->bDescCount; ++ pVals = (uint16_t *) (buf + BS_CONCAT_VAL_HDR_LEN); ++ ++ /* Check the DMA descriptor count */ ++ if (desccount > MAX_DMA_DESCS_PER_EP) { ++ CFI_INFO("%s: Maximum DMA Descriptor count should be %d\n", ++ __func__, MAX_DMA_DESCS_PER_EP); ++ return -DWC_E_INVALID; ++ } ++ ++ addr = pConcatValHdr->bEndpointAddress; ++ ep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == ep) { ++ CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n", ++ __func__, addr); ++ return -DWC_E_INVALID; ++ } ++ ++ mps = UGETW(ep->ep->desc->wMaxPacketSize); ++ ++#if 0 ++ for (i = 0; i < desccount; i++) { ++ CFI_INFO("%s: wTxSize[%d]=0x%04x\n", __func__, i, pVals[i]); ++ } ++ CFI_INFO("%s: epname=%s; mps=%d\n", __func__, ep->ep->ep.name, mps); ++#endif ++ ++ /* Check the wTxSizes to be less than or equal to the mps */ ++ for (i = 0; i < desccount; i++) { ++ if (pVals[i] > mps) { ++ CFI_INFO ++ ("%s: ERROR - the wTxSize[%d] should be <= MPS (wTxSize=%d)\n", ++ __func__, i, pVals[i]); ++ return -DWC_E_INVALID; ++ } ++ } ++ ++ ep->ep->dwc_ep.buff_mode = BM_CONCAT; ++ dwc_memcpy(ep->bm_concat, pConcatValHdr, BS_CONCAT_VAL_HDR_LEN); ++ ++ /* Free the previously allocated storage for the wTxBytes */ ++ if (ep->bm_concat->wTxBytes) { ++ DWC_FREE(ep->bm_concat->wTxBytes); ++ } ++ ++ /* Allocate a new storage for the wTxBytes field */ ++ ep->bm_concat->wTxBytes = ++ DWC_ALLOC(sizeof(uint16_t) * pConcatValHdr->bDescCount); ++ if (NULL == ep->bm_concat->wTxBytes) { ++ CFI_INFO("%s: Unable to allocate memory\n", __func__); ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ /* Copy the new values into the wTxBytes filed */ ++ dwc_memcpy(ep->bm_concat->wTxBytes, buf + BS_CONCAT_VAL_HDR_LEN, ++ sizeof(uint16_t) * pConcatValHdr->bDescCount); ++ ++ return 0; ++} ++ ++/** ++ * This function calculates the total of all FIFO sizes ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * ++ * @return The total of data FIFO sizes. ++ * ++ */ ++static uint16_t get_dfifo_size(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_params_t *params = core_if->core_params; ++ uint16_t dfifo_total = 0; ++ int i; ++ ++ /* The shared RxFIFO size */ ++ dfifo_total = ++ params->dev_rx_fifo_size + params->dev_nperio_tx_fifo_size; ++ ++ /* Add up each TxFIFO size to the total */ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ dfifo_total += params->dev_tx_fifo_size[i]; ++ } ++ ++ return dfifo_total; ++} ++ ++/** ++ * This function returns Rx FIFO size ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * ++ * @return The total of data FIFO sizes. ++ * ++ */ ++static int32_t get_rxfifo_size(dwc_otg_core_if_t * core_if, uint16_t wValue) ++{ ++ switch (wValue >> 8) { ++ case 0: ++ return (core_if->pwron_rxfsiz < ++ 32768) ? core_if->pwron_rxfsiz : 32768; ++ break; ++ case 1: ++ return core_if->core_params->dev_rx_fifo_size; ++ break; ++ default: ++ return -DWC_E_INVALID; ++ break; ++ } ++} ++ ++/** ++ * This function returns Tx FIFO size for IN EP ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * ++ * @return The total of data FIFO sizes. ++ * ++ */ ++static int32_t get_txfifo_size(struct dwc_otg_pcd *pcd, uint16_t wValue) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ ++ ep = get_ep_by_addr(pcd, wValue & 0xff); ++ ++ if (NULL == ep) { ++ CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n", ++ __func__, wValue & 0xff); ++ return -DWC_E_INVALID; ++ } ++ ++ if (!ep->dwc_ep.is_in) { ++ CFI_INFO ++ ("%s: No Tx FIFO assingned to the Out endpoint addr=0x%02x\n", ++ __func__, wValue & 0xff); ++ return -DWC_E_INVALID; ++ } ++ ++ switch (wValue >> 8) { ++ case 0: ++ return (GET_CORE_IF(pcd)->pwron_txfsiz ++ [ep->dwc_ep.tx_fifo_num - 1] < ++ 768) ? GET_CORE_IF(pcd)->pwron_txfsiz[ep-> ++ dwc_ep.tx_fifo_num ++ - 1] : 32768; ++ break; ++ case 1: ++ return GET_CORE_IF(pcd)->core_params-> ++ dev_tx_fifo_size[ep->dwc_ep.num - 1]; ++ break; ++ default: ++ return -DWC_E_INVALID; ++ break; ++ } ++} ++ ++/** ++ * This function checks if the submitted combination of ++ * device mode FIFO sizes is possible or not. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * ++ * @return 1 if possible, 0 otherwise. ++ * ++ */ ++static uint8_t check_fifo_sizes(dwc_otg_core_if_t * core_if) ++{ ++ uint16_t dfifo_actual = 0; ++ dwc_otg_core_params_t *params = core_if->core_params; ++ uint16_t start_addr = 0; ++ int i; ++ ++ dfifo_actual = ++ params->dev_rx_fifo_size + params->dev_nperio_tx_fifo_size; ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ dfifo_actual += params->dev_tx_fifo_size[i]; ++ } ++ ++ if (dfifo_actual > core_if->total_fifo_size) { ++ return 0; ++ } ++ ++ if (params->dev_rx_fifo_size > 32768 || params->dev_rx_fifo_size < 16) ++ return 0; ++ ++ if (params->dev_nperio_tx_fifo_size > 32768 ++ || params->dev_nperio_tx_fifo_size < 16) ++ return 0; ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ ++ if (params->dev_tx_fifo_size[i] > 768 ++ || params->dev_tx_fifo_size[i] < 4) ++ return 0; ++ } ++ ++ if (params->dev_rx_fifo_size > core_if->pwron_rxfsiz) ++ return 0; ++ start_addr = params->dev_rx_fifo_size; ++ ++ if (params->dev_nperio_tx_fifo_size > core_if->pwron_gnptxfsiz) ++ return 0; ++ start_addr += params->dev_nperio_tx_fifo_size; ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ ++ if (params->dev_tx_fifo_size[i] > core_if->pwron_txfsiz[i]) ++ return 0; ++ start_addr += params->dev_tx_fifo_size[i]; ++ } ++ ++ return 1; ++} ++ ++/** ++ * This function resizes Device mode FIFOs ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * ++ * @return 1 if successful, 0 otherwise ++ * ++ */ ++static uint8_t resize_fifos(dwc_otg_core_if_t * core_if) ++{ ++ int i = 0; ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ dwc_otg_core_params_t *params = core_if->core_params; ++ uint32_t rx_fifo_size; ++ fifosize_data_t nptxfifosize; ++ fifosize_data_t txfifosize[15]; ++ ++ uint32_t rx_fsz_bak; ++ uint32_t nptxfsz_bak; ++ uint32_t txfsz_bak[15]; ++ ++ uint16_t start_address; ++ uint8_t retval = 1; ++ ++ if (!check_fifo_sizes(core_if)) { ++ return 0; ++ } ++ ++ /* Configure data FIFO sizes */ ++ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) { ++ rx_fsz_bak = DWC_READ_REG32(&global_regs->grxfsiz); ++ rx_fifo_size = params->dev_rx_fifo_size; ++ DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size); ++ ++ /* ++ * Tx FIFOs These FIFOs are numbered from 1 to 15. ++ * Indexes of the FIFO size module parameters in the ++ * dev_tx_fifo_size array and the FIFO size registers in ++ * the dtxfsiz array run from 0 to 14. ++ */ ++ ++ /* Non-periodic Tx FIFO */ ++ nptxfsz_bak = DWC_READ_REG32(&global_regs->gnptxfsiz); ++ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size; ++ start_address = params->dev_rx_fifo_size; ++ nptxfifosize.b.startaddr = start_address; ++ ++ DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32); ++ ++ start_address += nptxfifosize.b.depth; ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ txfsz_bak[i] = DWC_READ_REG32(&global_regs->dtxfsiz[i]); ++ ++ txfifosize[i].b.depth = params->dev_tx_fifo_size[i]; ++ txfifosize[i].b.startaddr = start_address; ++ DWC_WRITE_REG32(&global_regs->dtxfsiz[i], ++ txfifosize[i].d32); ++ ++ start_address += txfifosize[i].b.depth; ++ } ++ ++ /** Check if register values are set correctly */ ++ if (rx_fifo_size != DWC_READ_REG32(&global_regs->grxfsiz)) { ++ retval = 0; ++ } ++ ++ if (nptxfifosize.d32 != DWC_READ_REG32(&global_regs->gnptxfsiz)) { ++ retval = 0; ++ } ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ if (txfifosize[i].d32 != ++ DWC_READ_REG32(&global_regs->dtxfsiz[i])) { ++ retval = 0; ++ } ++ } ++ ++ /** If register values are not set correctly, reset old values */ ++ if (retval == 0) { ++ DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fsz_bak); ++ ++ /* Non-periodic Tx FIFO */ ++ DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfsz_bak); ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ DWC_WRITE_REG32(&global_regs->dtxfsiz[i], ++ txfsz_bak[i]); ++ } ++ } ++ } else { ++ return 0; ++ } ++ ++ /* Flush the FIFOs */ ++ dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */ ++ dwc_otg_flush_rx_fifo(core_if); ++ ++ return retval; ++} ++ ++/** ++ * This function sets a new value for the buffer Alignment setup. ++ */ ++static int cfi_ep_set_tx_fifo_val(uint8_t * buf, dwc_otg_pcd_t * pcd) ++{ ++ int retval; ++ uint32_t fsiz; ++ uint16_t size; ++ uint16_t ep_addr; ++ dwc_otg_pcd_ep_t *ep; ++ dwc_otg_core_params_t *params = GET_CORE_IF(pcd)->core_params; ++ tx_fifo_size_setup_t *ptxfifoval; ++ ++ ptxfifoval = (tx_fifo_size_setup_t *) buf; ++ ep_addr = ptxfifoval->bEndpointAddress; ++ size = ptxfifoval->wDepth; ++ ++ ep = get_ep_by_addr(pcd, ep_addr); ++ ++ CFI_INFO ++ ("%s: Set Tx FIFO size: endpoint addr=0x%02x, depth=%d, FIFO Num=%d\n", ++ __func__, ep_addr, size, ep->dwc_ep.tx_fifo_num); ++ ++ if (NULL == ep) { ++ CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n", ++ __func__, ep_addr); ++ return -DWC_E_INVALID; ++ } ++ ++ fsiz = params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1]; ++ params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1] = size; ++ ++ if (resize_fifos(GET_CORE_IF(pcd))) { ++ retval = 0; ++ } else { ++ CFI_INFO ++ ("%s: Error setting the feature Tx FIFO Size for EP%d\n", ++ __func__, ep_addr); ++ params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1] = fsiz; ++ retval = -DWC_E_INVALID; ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function sets a new value for the buffer Alignment setup. ++ */ ++static int cfi_set_rx_fifo_val(uint8_t * buf, dwc_otg_pcd_t * pcd) ++{ ++ int retval; ++ uint32_t fsiz; ++ uint16_t size; ++ dwc_otg_core_params_t *params = GET_CORE_IF(pcd)->core_params; ++ rx_fifo_size_setup_t *prxfifoval; ++ ++ prxfifoval = (rx_fifo_size_setup_t *) buf; ++ size = prxfifoval->wDepth; ++ ++ fsiz = params->dev_rx_fifo_size; ++ params->dev_rx_fifo_size = size; ++ ++ if (resize_fifos(GET_CORE_IF(pcd))) { ++ retval = 0; ++ } else { ++ CFI_INFO("%s: Error setting the feature Rx FIFO Size\n", ++ __func__); ++ params->dev_rx_fifo_size = fsiz; ++ retval = -DWC_E_INVALID; ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function reads the SG of an EP's buffer setup into the buffer buf ++ */ ++static int cfi_ep_get_sg_val(uint8_t * buf, struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req) ++{ ++ int retval = -DWC_E_INVALID; ++ uint8_t addr; ++ cfi_ep_t *ep; ++ ++ /* The Low Byte of the wValue contains a non-zero address of the endpoint */ ++ addr = req->wValue & 0xFF; ++ if (addr == 0) /* The address should be non-zero */ ++ return retval; ++ ++ ep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == ep) { ++ CFI_INFO("%s: Unable to get the endpoint address(0x%02x)\n", ++ __func__, addr); ++ return retval; ++ } ++ ++ dwc_memcpy(buf, ep->bm_sg, BS_SG_VAL_DESC_LEN); ++ retval = BS_SG_VAL_DESC_LEN; ++ return retval; ++} ++ ++/** ++ * This function reads the Concatenation value of an EP's buffer mode into ++ * the buffer buf ++ */ ++static int cfi_ep_get_concat_val(uint8_t * buf, struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req) ++{ ++ int retval = -DWC_E_INVALID; ++ uint8_t addr; ++ cfi_ep_t *ep; ++ uint8_t desc_count; ++ ++ /* The Low Byte of the wValue contains a non-zero address of the endpoint */ ++ addr = req->wValue & 0xFF; ++ if (addr == 0) /* The address should be non-zero */ ++ return retval; ++ ++ ep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == ep) { ++ CFI_INFO("%s: Unable to get the endpoint address(0x%02x)\n", ++ __func__, addr); ++ return retval; ++ } ++ ++ /* Copy the header to the buffer */ ++ dwc_memcpy(buf, ep->bm_concat, BS_CONCAT_VAL_HDR_LEN); ++ /* Advance the buffer pointer by the header size */ ++ buf += BS_CONCAT_VAL_HDR_LEN; ++ ++ desc_count = ep->bm_concat->hdr.bDescCount; ++ /* Copy alll the wTxBytes to the buffer */ ++ dwc_memcpy(buf, ep->bm_concat->wTxBytes, sizeof(uid16_t) * desc_count); ++ ++ retval = BS_CONCAT_VAL_HDR_LEN + sizeof(uid16_t) * desc_count; ++ return retval; ++} ++ ++/** ++ * This function reads the buffer Alignment value of an EP's buffer mode into ++ * the buffer buf ++ * ++ * @return The total number of bytes copied to the buffer or negative error code. ++ */ ++static int cfi_ep_get_align_val(uint8_t * buf, struct dwc_otg_pcd *pcd, ++ struct cfi_usb_ctrlrequest *req) ++{ ++ int retval = -DWC_E_INVALID; ++ uint8_t addr; ++ cfi_ep_t *ep; ++ ++ /* The Low Byte of the wValue contains a non-zero address of the endpoint */ ++ addr = req->wValue & 0xFF; ++ if (addr == 0) /* The address should be non-zero */ ++ return retval; ++ ++ ep = get_cfi_ep_by_addr(pcd->cfi, addr); ++ if (NULL == ep) { ++ CFI_INFO("%s: Unable to get the endpoint address(0x%02x)\n", ++ __func__, addr); ++ return retval; ++ } ++ ++ dwc_memcpy(buf, ep->bm_align, BS_ALIGN_VAL_HDR_LEN); ++ retval = BS_ALIGN_VAL_HDR_LEN; ++ ++ return retval; ++} ++ ++/** ++ * This function sets a new value for the specified feature ++ * ++ * @param pcd A pointer to the PCD object ++ * ++ * @return 0 if successful, negative error code otherwise to stall the DCE. ++ */ ++static int cfi_set_feature_value(struct dwc_otg_pcd *pcd) ++{ ++ int retval = -DWC_E_NOT_SUPPORTED; ++ uint16_t wIndex, wValue; ++ uint8_t bRequest; ++ struct dwc_otg_core_if *coreif; ++ cfiobject_t *cfi = pcd->cfi; ++ struct cfi_usb_ctrlrequest *ctrl_req; ++ uint8_t *buf; ++ ctrl_req = &cfi->ctrl_req; ++ ++ buf = pcd->cfi->ctrl_req.data; ++ ++ coreif = GET_CORE_IF(pcd); ++ bRequest = ctrl_req->bRequest; ++ wIndex = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wIndex); ++ wValue = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wValue); ++ ++ /* See which feature is to be modified */ ++ switch (wIndex) { ++ case FT_ID_DMA_BUFFER_SETUP: ++ /* Modify the feature */ ++ if ((retval = cfi_ep_set_sg_val(buf, pcd)) < 0) ++ return retval; ++ ++ /* And send this request to the gadget */ ++ cfi->need_gadget_att = 1; ++ break; ++ ++ case FT_ID_DMA_BUFF_ALIGN: ++ if ((retval = cfi_ep_set_alignment_val(buf, pcd)) < 0) ++ return retval; ++ cfi->need_gadget_att = 1; ++ break; ++ ++ case FT_ID_DMA_CONCAT_SETUP: ++ /* Modify the feature */ ++ if ((retval = cfi_ep_set_concat_val(buf, pcd)) < 0) ++ return retval; ++ cfi->need_gadget_att = 1; ++ break; ++ ++ case FT_ID_DMA_CIRCULAR: ++ CFI_INFO("FT_ID_DMA_CIRCULAR\n"); ++ break; ++ ++ case FT_ID_THRESHOLD_SETUP: ++ CFI_INFO("FT_ID_THRESHOLD_SETUP\n"); ++ break; ++ ++ case FT_ID_DFIFO_DEPTH: ++ CFI_INFO("FT_ID_DFIFO_DEPTH\n"); ++ break; ++ ++ case FT_ID_TX_FIFO_DEPTH: ++ CFI_INFO("FT_ID_TX_FIFO_DEPTH\n"); ++ if ((retval = cfi_ep_set_tx_fifo_val(buf, pcd)) < 0) ++ return retval; ++ cfi->need_gadget_att = 0; ++ break; ++ ++ case FT_ID_RX_FIFO_DEPTH: ++ CFI_INFO("FT_ID_RX_FIFO_DEPTH\n"); ++ if ((retval = cfi_set_rx_fifo_val(buf, pcd)) < 0) ++ return retval; ++ cfi->need_gadget_att = 0; ++ break; ++ } ++ ++ return retval; ++} ++ ++#endif //DWC_UTE_CFI +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cfi.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cfi.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,320 @@ ++/* ========================================================================== ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#if !defined(__DWC_OTG_CFI_H__) ++#define __DWC_OTG_CFI_H__ ++ ++#include "dwc_otg_pcd.h" ++#include "dwc_cfi_common.h" ++ ++/** ++ * @file ++ * This file contains the CFI related OTG PCD specific common constants, ++ * interfaces(functions and macros) and data structures.The CFI Protocol is an ++ * optional interface for internal testing purposes that a DUT may implement to ++ * support testing of configurable features. ++ * ++ */ ++ ++struct dwc_otg_pcd; ++struct dwc_otg_pcd_ep; ++ ++/** OTG CFI Features (properties) ID constants */ ++/** This is a request for all Core Features */ ++#define FT_ID_DMA_MODE 0x0001 ++#define FT_ID_DMA_BUFFER_SETUP 0x0002 ++#define FT_ID_DMA_BUFF_ALIGN 0x0003 ++#define FT_ID_DMA_CONCAT_SETUP 0x0004 ++#define FT_ID_DMA_CIRCULAR 0x0005 ++#define FT_ID_THRESHOLD_SETUP 0x0006 ++#define FT_ID_DFIFO_DEPTH 0x0007 ++#define FT_ID_TX_FIFO_DEPTH 0x0008 ++#define FT_ID_RX_FIFO_DEPTH 0x0009 ++ ++/**********************************************************/ ++#define CFI_INFO_DEF ++ ++#ifdef CFI_INFO_DEF ++#define CFI_INFO(fmt...) DWC_PRINTF("CFI: " fmt); ++#else ++#define CFI_INFO(fmt...) ++#endif ++ ++#define min(x,y) ({ \ ++ x < y ? x : y; }) ++ ++#define max(x,y) ({ \ ++ x > y ? x : y; }) ++ ++/** ++ * Descriptor DMA SG Buffer setup structure (SG buffer). This structure is ++ * also used for setting up a buffer for Circular DDMA. ++ */ ++struct _ddma_sg_buffer_setup { ++#define BS_SG_VAL_DESC_LEN 6 ++ /* The OUT EP address */ ++ uint8_t bOutEndpointAddress; ++ /* The IN EP address */ ++ uint8_t bInEndpointAddress; ++ /* Number of bytes to put between transfer segments (must be DWORD boundaries) */ ++ uint8_t bOffset; ++ /* The number of transfer segments (a DMA descriptors per each segment) */ ++ uint8_t bCount; ++ /* Size (in byte) of each transfer segment */ ++ uint16_t wSize; ++} __attribute__ ((packed)); ++typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t; ++ ++/** Descriptor DMA Concatenation Buffer setup structure */ ++struct _ddma_concat_buffer_setup_hdr { ++#define BS_CONCAT_VAL_HDR_LEN 4 ++ /* The endpoint for which the buffer is to be set up */ ++ uint8_t bEndpointAddress; ++ /* The count of descriptors to be used */ ++ uint8_t bDescCount; ++ /* The total size of the transfer */ ++ uint16_t wSize; ++} __attribute__ ((packed)); ++typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t; ++ ++/** Descriptor DMA Concatenation Buffer setup structure */ ++struct _ddma_concat_buffer_setup { ++ /* The SG header */ ++ ddma_concat_buffer_setup_hdr_t hdr; ++ ++ /* The XFER sizes pointer (allocated dynamically) */ ++ uint16_t *wTxBytes; ++} __attribute__ ((packed)); ++typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t; ++ ++/** Descriptor DMA Alignment Buffer setup structure */ ++struct _ddma_align_buffer_setup { ++#define BS_ALIGN_VAL_HDR_LEN 2 ++ uint8_t bEndpointAddress; ++ uint8_t bAlign; ++} __attribute__ ((packed)); ++typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t; ++ ++/** Transmit FIFO Size setup structure */ ++struct _tx_fifo_size_setup { ++ uint8_t bEndpointAddress; ++ uint16_t wDepth; ++} __attribute__ ((packed)); ++typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t; ++ ++/** Transmit FIFO Size setup structure */ ++struct _rx_fifo_size_setup { ++ uint16_t wDepth; ++} __attribute__ ((packed)); ++typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t; ++ ++/** ++ * struct cfi_usb_ctrlrequest - the CFI implementation of the struct usb_ctrlrequest ++ * This structure encapsulates the standard usb_ctrlrequest and adds a pointer ++ * to the data returned in the data stage of a 3-stage Control Write requests. ++ */ ++struct cfi_usb_ctrlrequest { ++ uint8_t bRequestType; ++ uint8_t bRequest; ++ uint16_t wValue; ++ uint16_t wIndex; ++ uint16_t wLength; ++ uint8_t *data; ++} UPACKED; ++ ++/*---------------------------------------------------------------------------*/ ++ ++/** ++ * The CFI wrapper of the enabled and activated dwc_otg_pcd_ep structures. ++ * This structure is used to store the buffer setup data for any ++ * enabled endpoint in the PCD. ++ */ ++struct cfi_ep { ++ /* Entry for the list container */ ++ dwc_list_link_t lh; ++ /* Pointer to the active PCD endpoint structure */ ++ struct dwc_otg_pcd_ep *ep; ++ /* The last descriptor in the chain of DMA descriptors of the endpoint */ ++ struct dwc_otg_dma_desc *dma_desc_last; ++ /* The SG feature value */ ++ ddma_sg_buffer_setup_t *bm_sg; ++ /* The Circular feature value */ ++ ddma_sg_buffer_setup_t *bm_circ; ++ /* The Concatenation feature value */ ++ ddma_concat_buffer_setup_t *bm_concat; ++ /* The Alignment feature value */ ++ ddma_align_buffer_setup_t *bm_align; ++ /* XFER length */ ++ uint32_t xfer_len; ++ /* ++ * Count of DMA descriptors currently used. ++ * The total should not exceed the MAX_DMA_DESCS_PER_EP value ++ * defined in the dwc_otg_cil.h ++ */ ++ uint32_t desc_count; ++}; ++typedef struct cfi_ep cfi_ep_t; ++ ++typedef struct cfi_dma_buff { ++#define CFI_IN_BUF_LEN 1024 ++#define CFI_OUT_BUF_LEN 1024 ++ dma_addr_t addr; ++ uint8_t *buf; ++} cfi_dma_buff_t; ++ ++struct cfiobject; ++ ++/** ++ * This is the interface for the CFI operations. ++ * ++ * @param ep_enable Called when any endpoint is enabled and activated. ++ * @param release Called when the CFI object is released and it needs to correctly ++ * deallocate the dynamic memory ++ * @param ctrl_write_complete Called when the data stage of the request is complete ++ */ ++typedef struct cfi_ops { ++ int (*ep_enable) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd, ++ struct dwc_otg_pcd_ep * ep); ++ void *(*ep_alloc_buf) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd, ++ struct dwc_otg_pcd_ep * ep, dma_addr_t * dma, ++ unsigned size, gfp_t flags); ++ void (*release) (struct cfiobject * cfi); ++ int (*ctrl_write_complete) (struct cfiobject * cfi, ++ struct dwc_otg_pcd * pcd); ++ void (*build_descriptors) (struct cfiobject * cfi, ++ struct dwc_otg_pcd * pcd, ++ struct dwc_otg_pcd_ep * ep, ++ dwc_otg_pcd_request_t * req); ++} cfi_ops_t; ++ ++struct cfiobject { ++ cfi_ops_t ops; ++ struct dwc_otg_pcd *pcd; ++ struct usb_gadget *gadget; ++ ++ /* Buffers used to send/receive CFI-related request data */ ++ cfi_dma_buff_t buf_in; ++ cfi_dma_buff_t buf_out; ++ ++ /* CFI specific Control request wrapper */ ++ struct cfi_usb_ctrlrequest ctrl_req; ++ ++ /* The list of active EP's in the PCD of type cfi_ep_t */ ++ dwc_list_link_t active_eps; ++ ++ /* This flag shall control the propagation of a specific request ++ * to the gadget's processing routines. ++ * 0 - no gadget handling ++ * 1 - the gadget needs to know about this request (w/o completing a status ++ * phase - just return a 0 to the _setup callback) ++ */ ++ uint8_t need_gadget_att; ++ ++ /* Flag indicating whether the status IN phase needs to be ++ * completed by the PCD ++ */ ++ uint8_t need_status_in_complete; ++}; ++typedef struct cfiobject cfiobject_t; ++ ++#define DUMP_MSG ++ ++#if defined(DUMP_MSG) ++static inline void dump_msg(const u8 * buf, unsigned int length) ++{ ++ unsigned int start, num, i; ++ char line[52], *p; ++ ++ if (length >= 512) ++ return; ++ ++ start = 0; ++ while (length > 0) { ++ num = min(length, 16u); ++ p = line; ++ for (i = 0; i < num; ++i) { ++ if (i == 8) ++ *p++ = ' '; ++ DWC_SPRINTF(p, " %02x", buf[i]); ++ p += 3; ++ } ++ *p = 0; ++ DWC_DEBUG("%6x: %s\n", start, line); ++ buf += num; ++ start += num; ++ length -= num; ++ } ++} ++#else ++static inline void dump_msg(const u8 * buf, unsigned int length) ++{ ++} ++#endif ++ ++/** ++ * This function returns a pointer to cfi_ep_t object with the addr address. ++ */ ++static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi, ++ uint8_t addr) ++{ ++ struct cfi_ep *pcfiep; ++ dwc_list_link_t *tmp; ++ ++ DWC_LIST_FOREACH(tmp, &cfi->active_eps) { ++ pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh); ++ ++ if (pcfiep->ep->desc->bEndpointAddress == addr) { ++ return pcfiep; ++ } ++ } ++ ++ return NULL; ++} ++ ++/** ++ * This function returns a pointer to cfi_ep_t object that matches ++ * the dwc_otg_pcd_ep object. ++ */ ++static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi, ++ struct dwc_otg_pcd_ep *ep) ++{ ++ struct cfi_ep *pcfiep = NULL; ++ dwc_list_link_t *tmp; ++ ++ DWC_LIST_FOREACH(tmp, &cfi->active_eps) { ++ pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh); ++ if (pcfiep->ep == ep) { ++ return pcfiep; ++ } ++ } ++ return NULL; ++} ++ ++int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl); ++ ++#endif /* (__DWC_OTG_CFI_H__) */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cil.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cil.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,7151 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $ ++ * $Revision: #191 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++/** @file ++ * ++ * The Core Interface Layer provides basic services for accessing and ++ * managing the DWC_otg hardware. These services are used by both the ++ * Host Controller Driver and the Peripheral Controller Driver. ++ * ++ * The CIL manages the memory map for the core so that the HCD and PCD ++ * don't have to do this separately. It also handles basic tasks like ++ * reading/writing the registers and data FIFOs in the controller. ++ * Some of the data access functions provide encapsulation of several ++ * operations required to perform a task, such as writing multiple ++ * registers to start a transfer. Finally, the CIL performs basic ++ * services that are not specific to either the host or device modes ++ * of operation. These services include management of the OTG Host ++ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A ++ * Diagnostic API is also provided to allow testing of the controller ++ * hardware. ++ * ++ * The Core Interface Layer has the following requirements: ++ * - Provides basic controller operations. ++ * - Minimal use of OS services. ++ * - The OS services used will be abstracted by using inline functions ++ * or macros. ++ * ++ */ ++ ++#include "dwc_os.h" ++#include "dwc_otg_regs.h" ++#include "dwc_otg_cil.h" ++ ++static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if); ++ ++/** ++ * This function is called to initialize the DWC_otg CSR data ++ * structures. The register addresses in the device and host ++ * structures are initialized from the base address supplied by the ++ * caller. The calling function must make the OS calls to get the ++ * base address of the DWC_otg controller registers. The core_params ++ * argument holds the parameters that specify how the core should be ++ * configured. ++ * ++ * @param reg_base_addr Base address of DWC_otg core registers ++ * ++ */ ++dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr) ++{ ++ dwc_otg_core_if_t *core_if = 0; ++ dwc_otg_dev_if_t *dev_if = 0; ++ dwc_otg_host_if_t *host_if = 0; ++ uint8_t *reg_base = (uint8_t *) reg_base_addr; ++ int i = 0; ++ ++ DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr); ++ ++ core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t)); ++ ++ if (core_if == NULL) { ++ DWC_DEBUGPL(DBG_CIL, ++ "Allocation of dwc_otg_core_if_t failed\n"); ++ return 0; ++ } ++ core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base; ++ ++ /* ++ * Allocate the Device Mode structures. ++ */ ++ dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t)); ++ ++ if (dev_if == NULL) { ++ DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n"); ++ DWC_FREE(core_if); ++ return 0; ++ } ++ ++ dev_if->dev_global_regs = ++ (dwc_otg_device_global_regs_t *) (reg_base + ++ DWC_DEV_GLOBAL_REG_OFFSET); ++ ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *) ++ (reg_base + DWC_DEV_IN_EP_REG_OFFSET + ++ (i * DWC_EP_REG_OFFSET)); ++ ++ dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *) ++ (reg_base + DWC_DEV_OUT_EP_REG_OFFSET + ++ (i * DWC_EP_REG_OFFSET)); ++ DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n", ++ i, &dev_if->in_ep_regs[i]->diepctl); ++ DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n", ++ i, &dev_if->out_ep_regs[i]->doepctl); ++ } ++ ++ dev_if->speed = 0; // unknown ++ ++ core_if->dev_if = dev_if; ++ ++ /* ++ * Allocate the Host Mode structures. ++ */ ++ host_if = DWC_ALLOC(sizeof(dwc_otg_host_if_t)); ++ ++ if (host_if == NULL) { ++ DWC_DEBUGPL(DBG_CIL, ++ "Allocation of dwc_otg_host_if_t failed\n"); ++ DWC_FREE(dev_if); ++ DWC_FREE(core_if); ++ return 0; ++ } ++ ++ host_if->host_global_regs = (dwc_otg_host_global_regs_t *) ++ (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET); ++ ++ host_if->hprt0 = ++ (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET); ++ ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ host_if->hc_regs[i] = (dwc_otg_hc_regs_t *) ++ (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET + ++ (i * DWC_OTG_CHAN_REGS_OFFSET)); ++ DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n", ++ i, &host_if->hc_regs[i]->hcchar); ++ } ++ ++ host_if->num_host_channels = MAX_EPS_CHANNELS; ++ core_if->host_if = host_if; ++ ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ core_if->data_fifo[i] = ++ (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET + ++ (i * DWC_OTG_DATA_FIFO_SIZE)); ++ DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08lx\n", ++ i, (unsigned long)core_if->data_fifo[i]); ++ } ++ ++ core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET); ++ ++ /* Initiate lx_state to L3 disconnected state */ ++ core_if->lx_state = DWC_OTG_L3; ++ /* ++ * Store the contents of the hardware configuration registers here for ++ * easy access later. ++ */ ++ core_if->hwcfg1.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1); ++ core_if->hwcfg2.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2); ++ core_if->hwcfg3.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3); ++ core_if->hwcfg4.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4); ++ ++ /* Force host mode to get HPTXFSIZ exact power on value */ ++ { ++ gusbcfg_data_t gusbcfg = {.d32 = 0 }; ++ gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ gusbcfg.b.force_host_mode = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32); ++ dwc_mdelay(100); ++ core_if->hptxfsiz.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz); ++ gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ gusbcfg.b.force_host_mode = 0; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32); ++ dwc_mdelay(100); ++ } ++ ++ DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32); ++ DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32); ++ DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32); ++ DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32); ++ ++ core_if->hcfg.d32 = ++ DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg); ++ core_if->dcfg.d32 = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ ++ DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32); ++ DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32); ++ ++ DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode); ++ DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture); ++ DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep); ++ DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n", ++ core_if->hwcfg2.b.num_host_chan); ++ DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n", ++ core_if->hwcfg2.b.nonperio_tx_q_depth); ++ DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n", ++ core_if->hwcfg2.b.host_perio_tx_q_depth); ++ DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n", ++ core_if->hwcfg2.b.dev_token_q_depth); ++ ++ DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n", ++ core_if->hwcfg3.b.dfifo_depth); ++ DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n", ++ core_if->hwcfg3.b.xfer_size_cntr_width); ++ ++ /* ++ * Set the SRP sucess bit for FS-I2c ++ */ ++ core_if->srp_success = 0; ++ core_if->srp_timer_started = 0; ++ ++ /* ++ * Create new workqueue and init works ++ */ ++ core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg"); ++ if (core_if->wq_otg == 0) { ++ DWC_WARN("DWC_WORKQ_ALLOC failed\n"); ++ DWC_FREE(host_if); ++ DWC_FREE(dev_if); ++ DWC_FREE(core_if); ++ return 0; ++ } ++ ++ core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid); ++ ++ DWC_PRINTF("Core Release: %x.%x%x%x\n", ++ (core_if->snpsid >> 12 & 0xF), ++ (core_if->snpsid >> 8 & 0xF), ++ (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF)); ++ ++ core_if->wkp_timer = DWC_TIMER_ALLOC("Wake Up Timer", ++ w_wakeup_detected, core_if); ++ if (core_if->wkp_timer == 0) { ++ DWC_WARN("DWC_TIMER_ALLOC failed\n"); ++ DWC_FREE(host_if); ++ DWC_FREE(dev_if); ++ DWC_WORKQ_FREE(core_if->wq_otg); ++ DWC_FREE(core_if); ++ return 0; ++ } ++ ++ if (dwc_otg_setup_params(core_if)) { ++ DWC_WARN("Error while setting core params\n"); ++ } ++ ++ core_if->hibernation_suspend = 0; ++ ++ /** ADP initialization */ ++ dwc_otg_adp_init(core_if); ++ ++ return core_if; ++} ++ ++/** ++ * This function frees the structures allocated by dwc_otg_cil_init(). ++ * ++ * @param core_if The core interface pointer returned from ++ * dwc_otg_cil_init(). ++ * ++ */ ++void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if) ++{ ++ dctl_data_t dctl = {.d32 = 0 }; ++ DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if); ++ ++ /* Disable all interrupts */ ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 1, 0); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0); ++ ++ dctl.b.sftdiscon = 1; ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, ++ dctl.d32); ++ } ++ ++ if (core_if->wq_otg) { ++ DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500); ++ DWC_WORKQ_FREE(core_if->wq_otg); ++ } ++ if (core_if->dev_if) { ++ DWC_FREE(core_if->dev_if); ++ } ++ if (core_if->host_if) { ++ DWC_FREE(core_if->host_if); ++ } ++ ++ /** Remove ADP Stuff */ ++ dwc_otg_adp_remove(core_if); ++ if (core_if->core_params) { ++ DWC_FREE(core_if->core_params); ++ } ++ if (core_if->wkp_timer) { ++ DWC_TIMER_FREE(core_if->wkp_timer); ++ } ++ if (core_if->srp_timer) { ++ DWC_TIMER_FREE(core_if->srp_timer); ++ } ++ DWC_FREE(core_if); ++} ++ ++/** ++ * This function enables the controller's Global Interrupt in the AHB Config ++ * register. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if) ++{ ++ gahbcfg_data_t ahbcfg = {.d32 = 0 }; ++ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32); ++} ++ ++/** ++ * This function disables the controller's Global Interrupt in the AHB Config ++ * register. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if) ++{ ++ gahbcfg_data_t ahbcfg = {.d32 = 0 }; ++ ahbcfg.b.glblintrmsk = 1; /* Disable interrupts */ ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0); ++} ++ ++/** ++ * This function initializes the commmon interrupts, used in both ++ * device and host modes. ++ * ++ * @param core_if Programming view of the DWC_otg controller ++ * ++ */ ++static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ /* Clear any pending OTG Interrupts */ ++ DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF); ++ ++ /* Clear any pending interrupts */ ++ DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* ++ * Enable the interrupts in the GINTMSK. ++ */ ++ intr_mask.b.modemismatch = 1; ++ intr_mask.b.otgintr = 1; ++ ++ if (!core_if->dma_enable) { ++ intr_mask.b.rxstsqlvl = 1; ++ } ++ ++ intr_mask.b.conidstschng = 1; ++ intr_mask.b.wkupintr = 1; ++ intr_mask.b.disconnect = 0; ++ intr_mask.b.usbsuspend = 1; ++ intr_mask.b.sessreqintr = 1; ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ if (core_if->core_params->lpm_enable) { ++ intr_mask.b.lpmtranrcvd = 1; ++ } ++#endif ++ DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32); ++} ++ ++/* ++ * The restore operation is modified to support Synopsys Emulated Powerdown and ++ * Hibernation. This function is for exiting from Device mode hibernation by ++ * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup. ++ * @param core_if Programming view of DWC_otg controller. ++ * @param rem_wakeup - indicates whether resume is initiated by Device or Host. ++ * @param reset - indicates whether resume is initiated by Reset. ++ */ ++int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if, ++ int rem_wakeup, int reset) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ dctl_data_t dctl = {.d32 = 0 }; ++ ++ int timeout = 2000; ++ ++ if (!core_if->hibernation_suspend) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return 1; ++ } ++ ++ DWC_DEBUGPL(DBG_PCD, "%s called\n", __FUNCTION__); ++ /* Switch-on voltage to the core */ ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Reset core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Assert Restore signal */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.restore = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable power clamps */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ if (rem_wakeup) { ++ dwc_udelay(70); ++ } ++ ++ /* Deassert Reset core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable PMU interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Mask interrupts from gpwrdn */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.connect_det_msk = 1; ++ gpwrdn.b.srp_det_msk = 1; ++ gpwrdn.b.disconn_det_msk = 1; ++ gpwrdn.b.rst_det_msk = 1; ++ gpwrdn.b.lnstchng_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Indicates that we are going out from hibernation */ ++ core_if->hibernation_suspend = 0; ++ ++ /* ++ * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1 ++ * indicates restore from remote_wakeup ++ */ ++ restore_essential_regs(core_if, rem_wakeup, 0); ++ ++ /* ++ * Wait a little for seeing new value of variable hibernation_suspend if ++ * Restore done interrupt received before polling ++ */ ++ dwc_udelay(10); ++ ++ if (core_if->hibernation_suspend == 0) { ++ /* ++ * Wait For Restore_done Interrupt. This mechanism of polling the ++ * interrupt is introduced to avoid any possible race conditions ++ */ ++ do { ++ gintsts_data_t gintsts; ++ gintsts.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ if (gintsts.b.restoredone) { ++ gintsts.d32 = 0; ++ gintsts.b.restoredone = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs-> ++ gintsts, gintsts.d32); ++ DWC_PRINTF("Restore Done Interrupt seen\n"); ++ break; ++ } ++ dwc_udelay(10); ++ } while (--timeout); ++ if (!timeout) { ++ DWC_PRINTF("Restore Done interrupt wasn't generated here\n"); ++ } ++ } ++ /* Clear all pending interupts */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* De-assert Restore */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.restore = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ if (!rem_wakeup) { ++ pcgcctl.d32 = 0; ++ pcgcctl.b.rstpdwnmodule = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0); ++ } ++ ++ /* Restore GUSBCFG and DCFG */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, ++ core_if->gr_backup->gusbcfg_local); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, ++ core_if->dr_backup->dcfg); ++ ++ /* De-assert Wakeup Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ if (!rem_wakeup) { ++ /* Set Device programming done bit */ ++ dctl.b.pwronprgdone = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ } else { ++ /* Start Remote Wakeup Signaling */ ++ dctl.d32 = core_if->dr_backup->dctl; ++ dctl.b.rmtwkupsig = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32); ++ } ++ ++ dwc_mdelay(2); ++ /* Clear all pending interupts */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* Restore global registers */ ++ dwc_otg_restore_global_regs(core_if); ++ /* Restore device global registers */ ++ dwc_otg_restore_dev_regs(core_if, rem_wakeup); ++ ++ if (rem_wakeup) { ++ dwc_mdelay(7); ++ dctl.d32 = 0; ++ dctl.b.rmtwkupsig = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0); ++ } ++ ++ core_if->hibernation_suspend = 0; ++ /* The core will be in ON STATE */ ++ core_if->lx_state = DWC_OTG_L0; ++ DWC_PRINTF("Hibernation recovery completes here\n"); ++ ++ return 1; ++} ++ ++/* ++ * The restore operation is modified to support Synopsys Emulated Powerdown and ++ * Hibernation. This function is for exiting from Host mode hibernation by ++ * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup. ++ * @param core_if Programming view of DWC_otg controller. ++ * @param rem_wakeup - indicates whether resume is initiated by Device or Host. ++ * @param reset - indicates whether resume is initiated by Reset. ++ */ ++int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if, ++ int rem_wakeup, int reset) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++ ++ int timeout = 2000; ++ ++ DWC_DEBUGPL(DBG_HCD, "%s called\n", __FUNCTION__); ++ /* Switch-on voltage to the core */ ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Reset core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Assert Restore signal */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.restore = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable power clamps */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ if (!rem_wakeup) { ++ dwc_udelay(50); ++ } ++ ++ /* Deassert Reset core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable PMU interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.connect_det_msk = 1; ++ gpwrdn.b.srp_det_msk = 1; ++ gpwrdn.b.disconn_det_msk = 1; ++ gpwrdn.b.rst_det_msk = 1; ++ gpwrdn.b.lnstchng_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Indicates that we are going out from hibernation */ ++ core_if->hibernation_suspend = 0; ++ ++ /* Set Restore Essential Regs bit in PCGCCTL register */ ++ restore_essential_regs(core_if, rem_wakeup, 1); ++ ++ /* Wait a little for seeing new value of variable hibernation_suspend if ++ * Restore done interrupt received before polling */ ++ dwc_udelay(10); ++ ++ if (core_if->hibernation_suspend == 0) { ++ /* Wait For Restore_done Interrupt. This mechanism of polling the ++ * interrupt is introduced to avoid any possible race conditions ++ */ ++ do { ++ gintsts_data_t gintsts; ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ if (gintsts.b.restoredone) { ++ gintsts.d32 = 0; ++ gintsts.b.restoredone = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ DWC_DEBUGPL(DBG_HCD,"Restore Done Interrupt seen\n"); ++ break; ++ } ++ dwc_udelay(10); ++ } while (--timeout); ++ if (!timeout) { ++ DWC_WARN("Restore Done interrupt wasn't generated\n"); ++ } ++ } ++ ++ /* Set the flag's value to 0 again after receiving restore done interrupt */ ++ core_if->hibernation_suspend = 0; ++ ++ /* This step is not described in functional spec but if not wait for this ++ * delay, mismatch interrupts occurred because just after restore core is ++ * in Device mode(gintsts.curmode == 0) */ ++ dwc_mdelay(100); ++ ++ /* Clear all pending interrupts */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* De-assert Restore */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.restore = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Restore GUSBCFG and HCFG */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, ++ core_if->gr_backup->gusbcfg_local); ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, ++ core_if->hr_backup->hcfg_local); ++ ++ /* De-assert Wakeup Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Start the Resume operation by programming HPRT0 */ ++ hprt0.d32 = core_if->hr_backup->hprt0_local; ++ hprt0.b.prtpwr = 1; ++ hprt0.b.prtena = 0; ++ hprt0.b.prtsusp = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ DWC_PRINTF("Resume Starts Now\n"); ++ if (!reset) { // Indicates it is Resume Operation ++ hprt0.d32 = core_if->hr_backup->hprt0_local; ++ hprt0.b.prtres = 1; ++ hprt0.b.prtpwr = 1; ++ hprt0.b.prtena = 0; ++ hprt0.b.prtsusp = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ if (!rem_wakeup) ++ hprt0.b.prtres = 0; ++ /* Wait for Resume time and then program HPRT again */ ++ dwc_mdelay(100); ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ } else { // Indicates it is Reset Operation ++ hprt0.d32 = core_if->hr_backup->hprt0_local; ++ hprt0.b.prtrst = 1; ++ hprt0.b.prtpwr = 1; ++ hprt0.b.prtena = 0; ++ hprt0.b.prtsusp = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ /* Wait for Reset time and then program HPRT again */ ++ dwc_mdelay(60); ++ hprt0.b.prtrst = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ } ++ /* Clear all interrupt status */ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtconndet = 1; ++ hprt0.b.prtenchng = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ /* Clear all pending interupts */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* Restore global registers */ ++ dwc_otg_restore_global_regs(core_if); ++ /* Restore host global registers */ ++ dwc_otg_restore_host_regs(core_if, reset); ++ ++ /* The core will be in ON STATE */ ++ core_if->lx_state = DWC_OTG_L0; ++ DWC_PRINTF("Hibernation recovery is complete here\n"); ++ return 0; ++} ++ ++/** Saves some register values into system memory. */ ++int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if) ++{ ++ struct dwc_otg_global_regs_backup *gr; ++ int i; ++ ++ gr = core_if->gr_backup; ++ if (!gr) { ++ gr = DWC_ALLOC(sizeof(*gr)); ++ if (!gr) { ++ return -DWC_E_NO_MEMORY; ++ } ++ core_if->gr_backup = gr; ++ } ++ ++ gr->gotgctl_local = DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); ++ gr->gahbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg); ++ gr->gusbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ gr->grxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz); ++ gr->gnptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz); ++ gr->hptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz); ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ gr->glpmcfg_local = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++#endif ++ gr->gi2cctl_local = DWC_READ_REG32(&core_if->core_global_regs->gi2cctl); ++ gr->pcgcctl_local = DWC_READ_REG32(core_if->pcgcctl); ++ gr->gdfifocfg_local = ++ DWC_READ_REG32(&core_if->core_global_regs->gdfifocfg); ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ gr->dtxfsiz_local[i] = ++ DWC_READ_REG32(&(core_if->core_global_regs->dtxfsiz[i])); ++ } ++ ++ DWC_DEBUGPL(DBG_ANY, "===========Backing Global registers==========\n"); ++ DWC_DEBUGPL(DBG_ANY, "Backed up gotgctl = %08x\n", gr->gotgctl_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up gahbcfg = %08x\n", gr->gahbcfg_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up gusbcfg = %08x\n", gr->gusbcfg_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up grxfsiz = %08x\n", gr->grxfsiz_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up gnptxfsiz = %08x\n", ++ gr->gnptxfsiz_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up hptxfsiz = %08x\n", ++ gr->hptxfsiz_local); ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg = %08x\n", gr->glpmcfg_local); ++#endif ++ DWC_DEBUGPL(DBG_ANY, "Backed up gi2cctl = %08x\n", gr->gi2cctl_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up pcgcctl = %08x\n", gr->pcgcctl_local); ++ DWC_DEBUGPL(DBG_ANY,"Backed up gdfifocfg = %08x\n",gr->gdfifocfg_local); ++ ++ return 0; ++} ++ ++/** Saves GINTMSK register before setting the msk bits. */ ++int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if) ++{ ++ struct dwc_otg_global_regs_backup *gr; ++ ++ gr = core_if->gr_backup; ++ if (!gr) { ++ gr = DWC_ALLOC(sizeof(*gr)); ++ if (!gr) { ++ return -DWC_E_NO_MEMORY; ++ } ++ core_if->gr_backup = gr; ++ } ++ ++ gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); ++ ++ DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n"); ++ DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local); ++ ++ return 0; ++} ++ ++int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if) ++{ ++ struct dwc_otg_dev_regs_backup *dr; ++ int i; ++ ++ dr = core_if->dr_backup; ++ if (!dr) { ++ dr = DWC_ALLOC(sizeof(*dr)); ++ if (!dr) { ++ return -DWC_E_NO_MEMORY; ++ } ++ core_if->dr_backup = dr; ++ } ++ ++ dr->dcfg = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ dr->dctl = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl); ++ dr->daintmsk = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk); ++ dr->diepmsk = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk); ++ dr->doepmsk = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk); ++ ++ for (i = 0; i < core_if->dev_if->num_in_eps; ++i) { ++ dr->diepctl[i] = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl); ++ dr->dieptsiz[i] = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz); ++ dr->diepdma[i] = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma); ++ } ++ ++ DWC_DEBUGPL(DBG_ANY, ++ "=============Backing Host registers==============\n"); ++ DWC_DEBUGPL(DBG_ANY, "Backed up dcfg = %08x\n", dr->dcfg); ++ DWC_DEBUGPL(DBG_ANY, "Backed up dctl = %08x\n", dr->dctl); ++ DWC_DEBUGPL(DBG_ANY, "Backed up daintmsk = %08x\n", ++ dr->daintmsk); ++ DWC_DEBUGPL(DBG_ANY, "Backed up diepmsk = %08x\n", dr->diepmsk); ++ DWC_DEBUGPL(DBG_ANY, "Backed up doepmsk = %08x\n", dr->doepmsk); ++ for (i = 0; i < core_if->dev_if->num_in_eps; ++i) { ++ DWC_DEBUGPL(DBG_ANY, "Backed up diepctl[%d] = %08x\n", i, ++ dr->diepctl[i]); ++ DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d] = %08x\n", ++ i, dr->dieptsiz[i]); ++ DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d] = %08x\n", i, ++ dr->diepdma[i]); ++ } ++ ++ return 0; ++} ++ ++int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if) ++{ ++ struct dwc_otg_host_regs_backup *hr; ++ int i; ++ ++ hr = core_if->hr_backup; ++ if (!hr) { ++ hr = DWC_ALLOC(sizeof(*hr)); ++ if (!hr) { ++ return -DWC_E_NO_MEMORY; ++ } ++ core_if->hr_backup = hr; ++ } ++ ++ hr->hcfg_local = ++ DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg); ++ hr->haintmsk_local = ++ DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk); ++ for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) { ++ hr->hcintmsk_local[i] = ++ DWC_READ_REG32(&core_if->host_if->hc_regs[i]->hcintmsk); ++ } ++ hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0); ++ hr->hfir_local = ++ DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir); ++ ++ DWC_DEBUGPL(DBG_ANY, ++ "=============Backing Host registers===============\n"); ++ DWC_DEBUGPL(DBG_ANY, "Backed up hcfg = %08x\n", ++ hr->hcfg_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up haintmsk = %08x\n", hr->haintmsk_local); ++ for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) { ++ DWC_DEBUGPL(DBG_ANY, "Backed up hcintmsk[%02d]=%08x\n", i, ++ hr->hcintmsk_local[i]); ++ } ++ DWC_DEBUGPL(DBG_ANY, "Backed up hprt0 = %08x\n", ++ hr->hprt0_local); ++ DWC_DEBUGPL(DBG_ANY, "Backed up hfir = %08x\n", ++ hr->hfir_local); ++ ++ return 0; ++} ++ ++int dwc_otg_restore_global_regs(dwc_otg_core_if_t *core_if) ++{ ++ struct dwc_otg_global_regs_backup *gr; ++ int i; ++ ++ gr = core_if->gr_backup; ++ if (!gr) { ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, gr->gotgctl_local); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gr->gintmsk_local); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gr->gusbcfg_local); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gr->gahbcfg_local); ++ DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, gr->grxfsiz_local); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, ++ gr->gnptxfsiz_local); ++ DWC_WRITE_REG32(&core_if->core_global_regs->hptxfsiz, ++ gr->hptxfsiz_local); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gdfifocfg, ++ gr->gdfifocfg_local); ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ DWC_WRITE_REG32(&core_if->core_global_regs->dtxfsiz[i], ++ gr->dtxfsiz_local[i]); ++ } ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ DWC_WRITE_REG32(core_if->host_if->hprt0, 0x0000100A); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, ++ (gr->gahbcfg_local)); ++ return 0; ++} ++ ++int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup) ++{ ++ struct dwc_otg_dev_regs_backup *dr; ++ int i; ++ ++ dr = core_if->dr_backup; ++ ++ if (!dr) { ++ return -DWC_E_INVALID; ++ } ++ ++ if (!rem_wakeup) { ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, ++ dr->dctl); ++ } ++ ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, dr->daintmsk); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, dr->diepmsk); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, dr->doepmsk); ++ ++ for (i = 0; i < core_if->dev_if->num_in_eps; ++i) { ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz, dr->dieptsiz[i]); ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma, dr->diepdma[i]); ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl, dr->diepctl[i]); ++ } ++ ++ return 0; ++} ++ ++int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset) ++{ ++ struct dwc_otg_host_regs_backup *hr; ++ int i; ++ hr = core_if->hr_backup; ++ ++ if (!hr) { ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local); ++ //if (!reset) ++ //{ ++ // DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local); ++ //} ++ ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk, ++ hr->haintmsk_local); ++ for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) { ++ DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk, ++ hr->hcintmsk_local[i]); ++ } ++ ++ return 0; ++} ++ ++int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if) ++{ ++ struct dwc_otg_global_regs_backup *gr; ++ ++ gr = core_if->gr_backup; ++ ++ /* Restore values for LPM and I2C */ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, gr->glpmcfg_local); ++#endif ++ DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local); ++ ++ return 0; ++} ++ ++int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host) ++{ ++ struct dwc_otg_global_regs_backup *gr; ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ gahbcfg_data_t gahbcfg = {.d32 = 0 }; ++ gusbcfg_data_t gusbcfg = {.d32 = 0 }; ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ ++ /* Restore LPM and I2C registers */ ++ restore_lpm_i2c_regs(core_if); ++ ++ /* Set PCGCCTL to 0 */ ++ DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000); ++ ++ gr = core_if->gr_backup; ++ /* Load restore values for [31:14] bits */ ++ DWC_WRITE_REG32(core_if->pcgcctl, ++ ((gr->pcgcctl_local & 0xffffc000) | 0x00020000)); ++ ++ /* Umnask global Interrupt in GAHBCFG and restore it */ ++ gahbcfg.d32 = gr->gahbcfg_local; ++ gahbcfg.b.glblintrmsk = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32); ++ ++ /* Clear all pending interupts */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* Unmask restore done interrupt */ ++ gintmsk.b.restoredone = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32); ++ ++ /* Restore GUSBCFG and HCFG/DCFG */ ++ gusbcfg.d32 = core_if->gr_backup->gusbcfg_local; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32); ++ ++ if (is_host) { ++ hcfg_data_t hcfg = {.d32 = 0 }; ++ hcfg.d32 = core_if->hr_backup->hcfg_local; ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, ++ hcfg.d32); ++ ++ /* Load restore values for [31:14] bits */ ++ pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000; ++ pcgcctl.d32 = gr->pcgcctl_local | 0x00020000; ++ ++ if (rmode) ++ pcgcctl.b.restoremode = 1; ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ dwc_udelay(10); ++ ++ /* Load restore values for [31:14] bits and set EssRegRestored bit */ ++ pcgcctl.d32 = gr->pcgcctl_local | 0xffffc000; ++ pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000; ++ pcgcctl.b.ess_reg_restored = 1; ++ if (rmode) ++ pcgcctl.b.restoremode = 1; ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ } else { ++ dcfg_data_t dcfg = {.d32 = 0 }; ++ dcfg.d32 = core_if->dr_backup->dcfg; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32); ++ ++ /* Load restore values for [31:14] bits */ ++ pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000; ++ pcgcctl.d32 = gr->pcgcctl_local | 0x00020000; ++ if (!rmode) { ++ pcgcctl.d32 |= 0x208; ++ } ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ dwc_udelay(10); ++ ++ /* Load restore values for [31:14] bits */ ++ pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000; ++ pcgcctl.d32 = gr->pcgcctl_local | 0x00020000; ++ pcgcctl.b.ess_reg_restored = 1; ++ if (!rmode) ++ pcgcctl.d32 |= 0x208; ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ } ++ ++ return 0; ++} ++ ++/** ++ * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY ++ * type. ++ */ ++static void init_fslspclksel(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t val; ++ hcfg_data_t hcfg; ++ ++ if (((core_if->hwcfg2.b.hs_phy_type == 2) && ++ (core_if->hwcfg2.b.fs_phy_type == 1) && ++ (core_if->core_params->ulpi_fs_ls)) || ++ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) { ++ /* Full speed PHY */ ++ val = DWC_HCFG_48_MHZ; ++ } else { ++ /* High speed PHY running at full speed or high speed */ ++ val = DWC_HCFG_30_60_MHZ; ++ } ++ ++ DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val); ++ hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg); ++ hcfg.b.fslspclksel = val; ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32); ++} ++ ++/** ++ * Initializes the DevSpd field of the DCFG register depending on the PHY type ++ * and the enumeration speed of the device. ++ */ ++static void init_devspd(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t val; ++ dcfg_data_t dcfg; ++ ++ if (((core_if->hwcfg2.b.hs_phy_type == 2) && ++ (core_if->hwcfg2.b.fs_phy_type == 1) && ++ (core_if->core_params->ulpi_fs_ls)) || ++ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) { ++ /* Full speed PHY */ ++ val = 0x3; ++ } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) { ++ /* High speed PHY running at full speed */ ++ val = 0x1; ++ } else { ++ /* High speed PHY running at high speed */ ++ val = 0x0; ++ } ++ ++ DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val); ++ ++ dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ dcfg.b.devspd = val; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32); ++} ++ ++/** ++ * This function calculates the number of IN EPS ++ * using GHWCFG1 and GHWCFG2 registers values ++ * ++ * @param core_if Programming view of the DWC_otg controller ++ */ ++static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t num_in_eps = 0; ++ uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep; ++ uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3; ++ uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps; ++ int i; ++ ++ for (i = 0; i < num_eps; ++i) { ++ if (!(hwcfg1 & 0x1)) ++ num_in_eps++; ++ ++ hwcfg1 >>= 2; ++ } ++ ++ if (core_if->hwcfg4.b.ded_fifo_en) { ++ num_in_eps = ++ (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps; ++ } ++ ++ return num_in_eps; ++} ++ ++/** ++ * This function calculates the number of OUT EPS ++ * using GHWCFG1 and GHWCFG2 registers values ++ * ++ * @param core_if Programming view of the DWC_otg controller ++ */ ++static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t num_out_eps = 0; ++ uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep; ++ uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2; ++ int i; ++ ++ for (i = 0; i < num_eps; ++i) { ++ if (!(hwcfg1 & 0x1)) ++ num_out_eps++; ++ ++ hwcfg1 >>= 2; ++ } ++ return num_out_eps; ++} ++ ++/** ++ * This function initializes the DWC_otg controller registers and ++ * prepares the core for device mode or host mode operation. ++ * ++ * @param core_if Programming view of the DWC_otg controller ++ * ++ */ ++void dwc_otg_core_init(dwc_otg_core_if_t * core_if) ++{ ++ int i = 0; ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ gahbcfg_data_t ahbcfg = {.d32 = 0 }; ++ gusbcfg_data_t usbcfg = {.d32 = 0 }; ++ gi2cctl_data_t i2cctl = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p) regs at %p\n", ++ core_if, global_regs); ++ ++ /* Common Initialization */ ++ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg); ++ ++ /* Program the ULPI External VBUS bit if needed */ ++ usbcfg.b.ulpi_ext_vbus_drv = ++ (core_if->core_params->phy_ulpi_ext_vbus == ++ DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0; ++ ++ /* Set external TS Dline pulsing */ ++ usbcfg.b.term_sel_dl_pulse = ++ (core_if->core_params->ts_dline == 1) ? 1 : 0; ++ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32); ++ ++ /* Reset the Controller */ ++ dwc_otg_core_reset(core_if); ++ ++ core_if->adp_enable = core_if->core_params->adp_supp_enable; ++ core_if->power_down = core_if->core_params->power_down; ++ core_if->otg_sts = 0; ++ ++ /* Initialize parameters from Hardware configuration registers. */ ++ dev_if->num_in_eps = calc_num_in_eps(core_if); ++ dev_if->num_out_eps = calc_num_out_eps(core_if); ++ ++ DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n", ++ core_if->hwcfg4.b.num_dev_perio_in_ep); ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) { ++ dev_if->perio_tx_fifo_size[i] = ++ DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16; ++ DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n", ++ i, dev_if->perio_tx_fifo_size[i]); ++ } ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ dev_if->tx_fifo_size[i] = ++ DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16; ++ DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n", ++ i, dev_if->tx_fifo_size[i]); ++ } ++ ++ core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth; ++ core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz); ++ core_if->nperio_tx_fifo_size = ++ DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16; ++ ++ DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", ++ core_if->nperio_tx_fifo_size); ++ ++ /* This programming sequence needs to happen in FS mode before any other ++ * programming occurs */ ++ if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) && ++ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) { ++ /* If FS mode with FS PHY */ ++ ++ /* core_init() is now called on every switch so only call the ++ * following for the first time through. */ ++ if (!core_if->phy_init_done) { ++ core_if->phy_init_done = 1; ++ DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n"); ++ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg); ++ usbcfg.b.physel = 1; ++ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32); ++ ++ /* Reset after a PHY select */ ++ dwc_otg_core_reset(core_if); ++ } ++ ++ /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also ++ * do this on HNP Dev/Host mode switches (done in dev_init and ++ * host_init). */ ++ if (dwc_otg_is_host_mode(core_if)) { ++ init_fslspclksel(core_if); ++ } else { ++ init_devspd(core_if); ++ } ++ ++ if (core_if->core_params->i2c_enable) { ++ DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n"); ++ /* Program GUSBCFG.OtgUtmifsSel to I2C */ ++ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg); ++ usbcfg.b.otgutmifssel = 1; ++ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32); ++ ++ /* Program GI2CCTL.I2CEn */ ++ i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl); ++ i2cctl.b.i2cdevaddr = 1; ++ i2cctl.b.i2cen = 0; ++ DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32); ++ i2cctl.b.i2cen = 1; ++ DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32); ++ } ++ ++ } /* endif speed == DWC_SPEED_PARAM_FULL */ ++ else { ++ /* High speed PHY. */ ++ if (!core_if->phy_init_done) { ++ core_if->phy_init_done = 1; ++ /* HS PHY parameters. These parameters are preserved ++ * during soft reset so only program the first time. Do ++ * a soft reset immediately after setting phyif. */ ++ ++ if (core_if->core_params->phy_type == 2) { ++ /* ULPI interface */ ++ usbcfg.b.ulpi_utmi_sel = 1; ++ usbcfg.b.phyif = 0; ++ usbcfg.b.ddrsel = ++ core_if->core_params->phy_ulpi_ddr; ++ } else if (core_if->core_params->phy_type == 1) { ++ /* UTMI+ interface */ ++ usbcfg.b.ulpi_utmi_sel = 0; ++ if (core_if->core_params->phy_utmi_width == 16) { ++ usbcfg.b.phyif = 1; ++ ++ } else { ++ usbcfg.b.phyif = 0; ++ } ++ } else { ++ DWC_ERROR("FS PHY TYPE\n"); ++ } ++ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32); ++ /* Reset after setting the PHY parameters */ ++ dwc_otg_core_reset(core_if); ++ } ++ } ++ ++ if ((core_if->hwcfg2.b.hs_phy_type == 2) && ++ (core_if->hwcfg2.b.fs_phy_type == 1) && ++ (core_if->core_params->ulpi_fs_ls)) { ++ DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n"); ++ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg); ++ usbcfg.b.ulpi_fsls = 1; ++ usbcfg.b.ulpi_clk_sus_m = 1; ++ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32); ++ } else { ++ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg); ++ usbcfg.b.ulpi_fsls = 0; ++ usbcfg.b.ulpi_clk_sus_m = 0; ++ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32); ++ } ++ ++ /* Program the GAHBCFG Register. */ ++ switch (core_if->hwcfg2.b.architecture) { ++ ++ case DWC_SLAVE_ONLY_ARCH: ++ DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n"); ++ ahbcfg.b.nptxfemplvl_txfemplvl = ++ DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY; ++ ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY; ++ core_if->dma_enable = 0; ++ core_if->dma_desc_enable = 0; ++ break; ++ ++ case DWC_EXT_DMA_ARCH: ++ DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n"); ++ { ++ uint8_t brst_sz = core_if->core_params->dma_burst_size; ++ ahbcfg.b.hburstlen = 0; ++ while (brst_sz > 1) { ++ ahbcfg.b.hburstlen++; ++ brst_sz >>= 1; ++ } ++ } ++ core_if->dma_enable = (core_if->core_params->dma_enable != 0); ++ core_if->dma_desc_enable = ++ (core_if->core_params->dma_desc_enable != 0); ++ break; ++ ++ case DWC_INT_DMA_ARCH: ++ DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n"); ++ /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for ++ Host mode ISOC in issue fix - vahrama */ ++ /* Broadcom had altered to (1<<3)|(0<<0) - WRESP=1, max 4 beats */ ++ ahbcfg.b.hburstlen = (1<<3)|(0<<0);//DWC_GAHBCFG_INT_DMA_BURST_INCR4; ++ core_if->dma_enable = (core_if->core_params->dma_enable != 0); ++ core_if->dma_desc_enable = ++ (core_if->core_params->dma_desc_enable != 0); ++ break; ++ ++ } ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable) { ++ DWC_PRINTF("Using Descriptor DMA mode\n"); ++ } else { ++ DWC_PRINTF("Using Buffer DMA mode\n"); ++ ++ } ++ } else { ++ DWC_PRINTF("Using Slave mode\n"); ++ core_if->dma_desc_enable = 0; ++ } ++ ++ if (core_if->core_params->ahb_single) { ++ ahbcfg.b.ahbsingle = 1; ++ } ++ ++ ahbcfg.b.dmaenable = core_if->dma_enable; ++ DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32); ++ ++ core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en; ++ ++ core_if->pti_enh_enable = core_if->core_params->pti_enable != 0; ++ core_if->multiproc_int_enable = core_if->core_params->mpi_enable; ++ DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n", ++ ((core_if->pti_enh_enable) ? "enabled" : "disabled")); ++ DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n", ++ ((core_if->multiproc_int_enable) ? "enabled" : "disabled")); ++ ++ /* ++ * Program the GUSBCFG register. ++ */ ++ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg); ++ ++ switch (core_if->hwcfg2.b.op_mode) { ++ case DWC_MODE_HNP_SRP_CAPABLE: ++ usbcfg.b.hnpcap = (core_if->core_params->otg_cap == ++ DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE); ++ usbcfg.b.srpcap = (core_if->core_params->otg_cap != ++ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); ++ break; ++ ++ case DWC_MODE_SRP_ONLY_CAPABLE: ++ usbcfg.b.hnpcap = 0; ++ usbcfg.b.srpcap = (core_if->core_params->otg_cap != ++ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); ++ break; ++ ++ case DWC_MODE_NO_HNP_SRP_CAPABLE: ++ usbcfg.b.hnpcap = 0; ++ usbcfg.b.srpcap = 0; ++ break; ++ ++ case DWC_MODE_SRP_CAPABLE_DEVICE: ++ usbcfg.b.hnpcap = 0; ++ usbcfg.b.srpcap = (core_if->core_params->otg_cap != ++ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); ++ break; ++ ++ case DWC_MODE_NO_SRP_CAPABLE_DEVICE: ++ usbcfg.b.hnpcap = 0; ++ usbcfg.b.srpcap = 0; ++ break; ++ ++ case DWC_MODE_SRP_CAPABLE_HOST: ++ usbcfg.b.hnpcap = 0; ++ usbcfg.b.srpcap = (core_if->core_params->otg_cap != ++ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); ++ break; ++ ++ case DWC_MODE_NO_SRP_CAPABLE_HOST: ++ usbcfg.b.hnpcap = 0; ++ usbcfg.b.srpcap = 0; ++ break; ++ } ++ ++ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32); ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ if (core_if->core_params->lpm_enable) { ++ glpmcfg_data_t lpmcfg = {.d32 = 0 }; ++ ++ /* To enable LPM support set lpm_cap_en bit */ ++ lpmcfg.b.lpm_cap_en = 1; ++ ++ /* Make AppL1Res ACK */ ++ lpmcfg.b.appl_resp = 1; ++ ++ /* Retry 3 times */ ++ lpmcfg.b.retry_count = 3; ++ ++ DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg, ++ 0, lpmcfg.d32); ++ ++ } ++#endif ++ if (core_if->core_params->ic_usb_cap) { ++ gusbcfg_data_t gusbcfg = {.d32 = 0 }; ++ gusbcfg.b.ic_usb_cap = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg, ++ 0, gusbcfg.d32); ++ } ++ { ++ gotgctl_data_t gotgctl = {.d32 = 0 }; ++ gotgctl.b.otgver = core_if->core_params->otg_ver; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0, ++ gotgctl.d32); ++ /* Set OTG version supported */ ++ core_if->otg_ver = core_if->core_params->otg_ver; ++ DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n", ++ core_if->core_params->otg_ver, core_if->otg_ver); ++ } ++ ++ ++ /* Enable common interrupts */ ++ dwc_otg_enable_common_interrupts(core_if); ++ ++ /* Do device or host intialization based on mode during PCD ++ * and HCD initialization */ ++ if (dwc_otg_is_host_mode(core_if)) { ++ DWC_DEBUGPL(DBG_ANY, "Host Mode\n"); ++ core_if->op_state = A_HOST; ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "Device Mode\n"); ++ core_if->op_state = B_PERIPHERAL; ++#ifdef DWC_DEVICE_ONLY ++ dwc_otg_core_dev_init(core_if); ++#endif ++ } ++} ++ ++/** ++ * This function enables the Device mode interrupts. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ */ ++void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if) ++{ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ ++ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__); ++ ++ /* Disable all interrupts. */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, 0); ++ ++ /* Clear any pending interrupts */ ++ DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* Enable the common interrupts */ ++ dwc_otg_enable_common_interrupts(core_if); ++ ++ /* Enable interrupts */ ++ intr_mask.b.usbreset = 1; ++ intr_mask.b.enumdone = 1; ++ /* Disable Disconnect interrupt in Device mode */ ++ intr_mask.b.disconnect = 0; ++ ++ if (!core_if->multiproc_int_enable) { ++ intr_mask.b.inepintr = 1; ++ intr_mask.b.outepintr = 1; ++ } ++ ++ intr_mask.b.erlysuspend = 1; ++ ++ if (core_if->en_multiple_tx_fifo == 0) { ++ intr_mask.b.epmismatch = 1; ++ } ++ ++ //intr_mask.b.incomplisoout = 1; ++ intr_mask.b.incomplisoin = 1; ++ ++/* Enable the ignore frame number for ISOC xfers - MAS */ ++/* Disable to support high bandwith ISOC transfers - manukz */ ++#if 0 ++#ifdef DWC_UTE_PER_IO ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable) { ++ dctl_data_t dctl1 = {.d32 = 0 }; ++ dctl1.b.ifrmnum = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ dctl, 0, dctl1.d32); ++ DWC_DEBUG("----Enabled Ignore frame number (0x%08x)", ++ DWC_READ_REG32(&core_if->dev_if-> ++ dev_global_regs->dctl)); ++ } ++ } ++#endif ++#endif ++#ifdef DWC_EN_ISOC ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable == 0) { ++ if (core_if->pti_enh_enable) { ++ dctl_data_t dctl = {.d32 = 0 }; ++ dctl.b.ifrmnum = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ dev_if->dev_global_regs->dctl, ++ 0, dctl.d32); ++ } else { ++ intr_mask.b.incomplisoin = 1; ++ intr_mask.b.incomplisoout = 1; ++ } ++ } ++ } else { ++ intr_mask.b.incomplisoin = 1; ++ intr_mask.b.incomplisoout = 1; ++ } ++#endif /* DWC_EN_ISOC */ ++ ++ /** @todo NGS: Should this be a module parameter? */ ++#ifdef USE_PERIODIC_EP ++ intr_mask.b.isooutdrop = 1; ++ intr_mask.b.eopframe = 1; ++ intr_mask.b.incomplisoin = 1; ++ intr_mask.b.incomplisoout = 1; ++#endif ++ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32); ++ ++ DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ++ DWC_READ_REG32(&global_regs->gintmsk)); ++} ++ ++/** ++ * This function initializes the DWC_otg controller registers for ++ * device mode. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * ++ */ ++void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if) ++{ ++ int i; ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ dwc_otg_core_params_t *params = core_if->core_params; ++ dcfg_data_t dcfg = {.d32 = 0 }; ++ depctl_data_t diepctl = {.d32 = 0 }; ++ grstctl_t resetctl = {.d32 = 0 }; ++ uint32_t rx_fifo_size; ++ fifosize_data_t nptxfifosize; ++ fifosize_data_t txfifosize; ++ dthrctl_data_t dthrctl; ++ fifosize_data_t ptxfifosize; ++ uint16_t rxfsiz, nptxfsiz; ++ gdfifocfg_data_t gdfifocfg = {.d32 = 0 }; ++ hwcfg3_data_t hwcfg3 = {.d32 = 0 }; ++ ++ /* Restart the Phy Clock */ ++ DWC_WRITE_REG32(core_if->pcgcctl, 0); ++ ++ /* Device configuration register */ ++ init_devspd(core_if); ++ dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg); ++ dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0; ++ dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80; ++ /* Enable Device OUT NAK in case of DDMA mode*/ ++ if (core_if->core_params->dev_out_nak) { ++ dcfg.b.endevoutnak = 1; ++ } ++ ++ if (core_if->core_params->cont_on_bna) { ++ dctl_data_t dctl = {.d32 = 0 }; ++ dctl.b.encontonbna = 1; ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ } ++ ++ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32); ++ ++ /* Configure data FIFO sizes */ ++ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) { ++ DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", ++ core_if->total_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", ++ params->dev_rx_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", ++ params->dev_nperio_tx_fifo_size); ++ ++ /* Rx FIFO */ ++ DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->grxfsiz)); ++ ++#ifdef DWC_UTE_CFI ++ core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz); ++ core_if->init_rxfsiz = params->dev_rx_fifo_size; ++#endif ++ rx_fifo_size = params->dev_rx_fifo_size; ++ DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size); ++ ++ DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->grxfsiz)); ++ ++ /** Set Periodic Tx FIFO Mask all bits 0 */ ++ core_if->p_tx_msk = 0; ++ ++ /** Set Tx FIFO Mask all bits 0 */ ++ core_if->tx_msk = 0; ++ ++ if (core_if->en_multiple_tx_fifo == 0) { ++ /* Non-periodic Tx FIFO */ ++ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->gnptxfsiz)); ++ ++ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size; ++ nptxfifosize.b.startaddr = params->dev_rx_fifo_size; ++ ++ DWC_WRITE_REG32(&global_regs->gnptxfsiz, ++ nptxfifosize.d32); ++ ++ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->gnptxfsiz)); ++ ++ /**@todo NGS: Fix Periodic FIFO Sizing! */ ++ /* ++ * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15. ++ * Indexes of the FIFO size module parameters in the ++ * dev_perio_tx_fifo_size array and the FIFO size registers in ++ * the dptxfsiz array run from 0 to 14. ++ */ ++ /** @todo Finish debug of this */ ++ ptxfifosize.b.startaddr = ++ nptxfifosize.b.startaddr + nptxfifosize.b.depth; ++ for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) { ++ ptxfifosize.b.depth = ++ params->dev_perio_tx_fifo_size[i]; ++ DWC_DEBUGPL(DBG_CIL, ++ "initial dtxfsiz[%d]=%08x\n", i, ++ DWC_READ_REG32(&global_regs->dtxfsiz ++ [i])); ++ DWC_WRITE_REG32(&global_regs->dtxfsiz[i], ++ ptxfifosize.d32); ++ DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n", ++ i, ++ DWC_READ_REG32(&global_regs->dtxfsiz ++ [i])); ++ ptxfifosize.b.startaddr += ptxfifosize.b.depth; ++ } ++ } else { ++ /* ++ * Tx FIFOs These FIFOs are numbered from 1 to 15. ++ * Indexes of the FIFO size module parameters in the ++ * dev_tx_fifo_size array and the FIFO size registers in ++ * the dtxfsiz array run from 0 to 14. ++ */ ++ ++ /* Non-periodic Tx FIFO */ ++ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->gnptxfsiz)); ++ ++#ifdef DWC_UTE_CFI ++ core_if->pwron_gnptxfsiz = ++ (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16); ++ core_if->init_gnptxfsiz = ++ params->dev_nperio_tx_fifo_size; ++#endif ++ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size; ++ nptxfifosize.b.startaddr = params->dev_rx_fifo_size; ++ ++ DWC_WRITE_REG32(&global_regs->gnptxfsiz, ++ nptxfifosize.d32); ++ ++ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->gnptxfsiz)); ++ ++ txfifosize.b.startaddr = ++ nptxfifosize.b.startaddr + nptxfifosize.b.depth; ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) { ++ ++ txfifosize.b.depth = ++ params->dev_tx_fifo_size[i]; ++ ++ DWC_DEBUGPL(DBG_CIL, ++ "initial dtxfsiz[%d]=%08x\n", ++ i, ++ DWC_READ_REG32(&global_regs->dtxfsiz ++ [i])); ++ ++#ifdef DWC_UTE_CFI ++ core_if->pwron_txfsiz[i] = ++ (DWC_READ_REG32 ++ (&global_regs->dtxfsiz[i]) >> 16); ++ core_if->init_txfsiz[i] = ++ params->dev_tx_fifo_size[i]; ++#endif ++ DWC_WRITE_REG32(&global_regs->dtxfsiz[i], ++ txfifosize.d32); ++ ++ DWC_DEBUGPL(DBG_CIL, ++ "new dtxfsiz[%d]=%08x\n", ++ i, ++ DWC_READ_REG32(&global_regs->dtxfsiz ++ [i])); ++ ++ txfifosize.b.startaddr += txfifosize.b.depth; ++ } ++ if (core_if->snpsid <= OTG_CORE_REV_2_94a) { ++ /* Calculating DFIFOCFG for Device mode to include RxFIFO and NPTXFIFO */ ++ gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg); ++ hwcfg3.d32 = DWC_READ_REG32(&global_regs->ghwcfg3); ++ gdfifocfg.b.gdfifocfg = (DWC_READ_REG32(&global_regs->ghwcfg3) >> 16); ++ DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32); ++ rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff); ++ nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16); ++ gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz; ++ DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32); ++ } ++ } ++ ++ /* Flush the FIFOs */ ++ dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */ ++ dwc_otg_flush_rx_fifo(core_if); ++ ++ /* Flush the Learning Queue. */ ++ resetctl.b.intknqflsh = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32); ++ ++ if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) { ++ core_if->start_predict = 0; ++ for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) { ++ core_if->nextep_seq[i] = 0xff; // 0xff - EP not active ++ } ++ core_if->nextep_seq[0] = 0; ++ core_if->first_in_nextep_seq = 0; ++ diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl); ++ diepctl.b.nextep = 0; ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32); ++ ++ /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */ ++ dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg); ++ dcfg.b.epmscnt = 2; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32); ++ ++ DWC_DEBUGPL(DBG_CILV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n", ++ __func__, core_if->first_in_nextep_seq); ++ for (i=0; i <= core_if->dev_if->num_in_eps; i++) { ++ DWC_DEBUGPL(DBG_CILV, "%2d ", core_if->nextep_seq[i]); ++ } ++ DWC_DEBUGPL(DBG_CILV,"\n"); ++ } ++ ++ /* Clear all pending Device Interrupts */ ++ /** @todo - if the condition needed to be checked ++ * or in any case all pending interrutps should be cleared? ++ */ ++ if (core_if->multiproc_int_enable) { ++ for (i = 0; i < core_if->dev_if->num_in_eps; ++i) { ++ DWC_WRITE_REG32(&dev_if-> ++ dev_global_regs->diepeachintmsk[i], 0); ++ } ++ } ++ ++ for (i = 0; i < core_if->dev_if->num_out_eps; ++i) { ++ DWC_WRITE_REG32(&dev_if-> ++ dev_global_regs->doepeachintmsk[i], 0); ++ } ++ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF); ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0); ++ } else { ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0); ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0); ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF); ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0); ++ } ++ ++ for (i = 0; i <= dev_if->num_in_eps; i++) { ++ depctl_data_t depctl; ++ depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ if (depctl.b.epena) { ++ depctl.d32 = 0; ++ depctl.b.epdis = 1; ++ depctl.b.snak = 1; ++ } else { ++ depctl.d32 = 0; ++ } ++ ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32); ++ ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0); ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0); ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF); ++ } ++ ++ for (i = 0; i <= dev_if->num_out_eps; i++) { ++ depctl_data_t depctl; ++ depctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl); ++ if (depctl.b.epena) { ++ dctl_data_t dctl = {.d32 = 0 }; ++ gintmsk_data_t gintsts = {.d32 = 0 }; ++ doepint_data_t doepint = {.d32 = 0 }; ++ dctl.b.sgoutnak = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ do { ++ dwc_udelay(10); ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ } while (!gintsts.b.goutnakeff); ++ gintsts.d32 = 0; ++ gintsts.b.goutnakeff = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ depctl.d32 = 0; ++ depctl.b.epdis = 1; ++ depctl.b.snak = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepctl, depctl.d32); ++ do { ++ dwc_udelay(10); ++ doepint.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[i]->doepint); ++ } while (!doepint.b.epdisabled); ++ ++ doepint.b.epdisabled = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepint, doepint.d32); ++ ++ dctl.d32 = 0; ++ dctl.b.cgoutnak = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ } else { ++ depctl.d32 = 0; ++ } ++ ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32); ++ ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0); ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0); ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF); ++ } ++ ++ if (core_if->en_multiple_tx_fifo && core_if->dma_enable) { ++ dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1; ++ dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1; ++ dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1; ++ ++ dev_if->rx_thr_length = params->rx_thr_length; ++ dev_if->tx_thr_length = params->tx_thr_length; ++ ++ dev_if->setup_desc_index = 0; ++ ++ dthrctl.d32 = 0; ++ dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en; ++ dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en; ++ dthrctl.b.tx_thr_len = dev_if->tx_thr_length; ++ dthrctl.b.rx_thr_en = dev_if->rx_thr_en; ++ dthrctl.b.rx_thr_len = dev_if->rx_thr_length; ++ dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio; ++ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl, ++ dthrctl.d32); ++ ++ DWC_DEBUGPL(DBG_CIL, ++ "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n", ++ dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en, ++ dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len, ++ dthrctl.b.rx_thr_len); ++ ++ } ++ ++ dwc_otg_enable_device_interrupts(core_if); ++ ++ { ++ diepmsk_data_t msk = {.d32 = 0 }; ++ msk.b.txfifoundrn = 1; ++ if (core_if->multiproc_int_enable) { ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs-> ++ diepeachintmsk[0], msk.d32, msk.d32); ++ } else { ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, ++ msk.d32, msk.d32); ++ } ++ } ++ ++ if (core_if->multiproc_int_enable) { ++ /* Set NAK on Babble */ ++ dctl_data_t dctl = {.d32 = 0 }; ++ dctl.b.nakonbble = 1; ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ } ++ ++ if (core_if->snpsid >= OTG_CORE_REV_2_94a) { ++ dctl_data_t dctl = {.d32 = 0 }; ++ dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl); ++ dctl.b.sftdiscon = 0; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32); ++ } ++} ++ ++/** ++ * This function enables the Host mode interrupts. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ */ ++void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_CIL, "%s(%p)\n", __func__, core_if); ++ ++ /* Disable all interrupts. */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, 0); ++ ++ /* Clear any pending interrupts. */ ++ DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF); ++ ++ /* Enable the common interrupts */ ++ dwc_otg_enable_common_interrupts(core_if); ++ ++ /* ++ * Enable host mode interrupts without disturbing common ++ * interrupts. ++ */ ++ ++ intr_mask.b.disconnect = 1; ++ intr_mask.b.portintr = 1; ++ intr_mask.b.hcintr = 1; ++ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32); ++} ++ ++/** ++ * This function disables the Host Mode interrupts. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ */ ++void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__); ++ ++ /* ++ * Disable host mode interrupts without disturbing common ++ * interrupts. ++ */ ++ intr_mask.b.sofintr = 1; ++ intr_mask.b.portintr = 1; ++ intr_mask.b.hcintr = 1; ++ intr_mask.b.ptxfempty = 1; ++ intr_mask.b.nptxfempty = 1; ++ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0); ++} ++ ++/** ++ * This function initializes the DWC_otg controller registers for ++ * host mode. ++ * ++ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the ++ * request queues. Host channels are reset to ensure that they are ready for ++ * performing transfers. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * ++ */ ++void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ dwc_otg_host_if_t *host_if = core_if->host_if; ++ dwc_otg_core_params_t *params = core_if->core_params; ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++ fifosize_data_t nptxfifosize; ++ fifosize_data_t ptxfifosize; ++ uint16_t rxfsiz, nptxfsiz, hptxfsiz; ++ gdfifocfg_data_t gdfifocfg = {.d32 = 0 }; ++ int i; ++ hcchar_data_t hcchar; ++ hcfg_data_t hcfg; ++ hfir_data_t hfir; ++ dwc_otg_hc_regs_t *hc_regs; ++ int num_channels; ++ gotgctl_data_t gotgctl = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if); ++ ++ /* Restart the Phy Clock */ ++ DWC_WRITE_REG32(core_if->pcgcctl, 0); ++ ++ /* Initialize Host Configuration Register */ ++ init_fslspclksel(core_if); ++ if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) { ++ hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg); ++ hcfg.b.fslssupp = 1; ++ DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32); ++ ++ } ++ ++ /* This bit allows dynamic reloading of the HFIR register ++ * during runtime. This bit needs to be programmed during ++ * initial configuration and its value must not be changed ++ * during runtime.*/ ++ if (core_if->core_params->reload_ctl == 1) { ++ hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir); ++ hfir.b.hfirrldctrl = 1; ++ DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32); ++ } ++ ++ if (core_if->core_params->dma_desc_enable) { ++ uint8_t op_mode = core_if->hwcfg2.b.op_mode; ++ if (! ++ (core_if->hwcfg4.b.desc_dma ++ && (core_if->snpsid >= OTG_CORE_REV_2_90a) ++ && ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ++ || (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) ++ || (op_mode == ++ DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG) ++ || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST) ++ || (op_mode == ++ DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) { ++ ++ DWC_ERROR("Host can't operate in Descriptor DMA mode.\n" ++ "Either core version is below 2.90a or " ++ "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n" ++ "To run the driver in Buffer DMA host mode set dma_desc_enable " ++ "module parameter to 0.\n"); ++ return; ++ } ++ hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg); ++ hcfg.b.descdma = 1; ++ DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32); ++ } ++ ++ /* Configure data FIFO sizes */ ++ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) { ++ DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", ++ core_if->total_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", ++ params->host_rx_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", ++ params->host_nperio_tx_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n", ++ params->host_perio_tx_fifo_size); ++ ++ /* Rx FIFO */ ++ DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->grxfsiz)); ++ DWC_WRITE_REG32(&global_regs->grxfsiz, ++ params->host_rx_fifo_size); ++ DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->grxfsiz)); ++ ++ /* Non-periodic Tx FIFO */ ++ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->gnptxfsiz)); ++ nptxfifosize.b.depth = params->host_nperio_tx_fifo_size; ++ nptxfifosize.b.startaddr = params->host_rx_fifo_size; ++ DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32); ++ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->gnptxfsiz)); ++ ++ /* Periodic Tx FIFO */ ++ DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->hptxfsiz)); ++ ptxfifosize.b.depth = params->host_perio_tx_fifo_size; ++ ptxfifosize.b.startaddr = ++ nptxfifosize.b.startaddr + nptxfifosize.b.depth; ++ DWC_WRITE_REG32(&global_regs->hptxfsiz, ptxfifosize.d32); ++ DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n", ++ DWC_READ_REG32(&global_regs->hptxfsiz)); ++ ++ if (core_if->en_multiple_tx_fifo ++ && core_if->snpsid <= OTG_CORE_REV_2_94a) { ++ /* Global DFIFOCFG calculation for Host mode - include RxFIFO, NPTXFIFO and HPTXFIFO */ ++ gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg); ++ rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff); ++ nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16); ++ hptxfsiz = (DWC_READ_REG32(&global_regs->hptxfsiz) >> 16); ++ gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz + hptxfsiz; ++ DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32); ++ } ++ } ++ ++ /* TODO - check this */ ++ /* Clear Host Set HNP Enable in the OTG Control Register */ ++ gotgctl.b.hstsethnpen = 1; ++ DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0); ++ /* Make sure the FIFOs are flushed. */ ++ dwc_otg_flush_tx_fifo(core_if, 0x10 /* all TX FIFOs */ ); ++ dwc_otg_flush_rx_fifo(core_if); ++ ++ /* Clear Host Set HNP Enable in the OTG Control Register */ ++ gotgctl.b.hstsethnpen = 1; ++ DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0); ++ ++ if (!core_if->core_params->dma_desc_enable) { ++ /* Flush out any leftover queued requests. */ ++ num_channels = core_if->core_params->host_channels; ++ ++ for (i = 0; i < num_channels; i++) { ++ hc_regs = core_if->host_if->hc_regs[i]; ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.chen = 0; ++ hcchar.b.chdis = 1; ++ hcchar.b.epdir = 0; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ } ++ ++ /* Halt all channels to put them into a known state. */ ++ for (i = 0; i < num_channels; i++) { ++ int count = 0; ++ hc_regs = core_if->host_if->hc_regs[i]; ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.chen = 1; ++ hcchar.b.chdis = 1; ++ hcchar.b.epdir = 0; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d regs %p\n", __func__, i, hc_regs); ++ do { ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ if (++count > 1000) { ++ DWC_ERROR ++ ("%s: Unable to clear halt on channel %d (timeout HCCHAR 0x%X @%p)\n", ++ __func__, i, hcchar.d32, &hc_regs->hcchar); ++ break; ++ } ++ dwc_udelay(1); ++ } while (hcchar.b.chen); ++ } ++ } ++ ++ /* Turn on the vbus power. */ ++ DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state); ++ if (core_if->op_state == A_HOST) { ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr); ++ if (hprt0.b.prtpwr == 0) { ++ hprt0.b.prtpwr = 1; ++ DWC_WRITE_REG32(host_if->hprt0, hprt0.d32); ++ } ++ } ++ ++ dwc_otg_enable_host_interrupts(core_if); ++} ++ ++/** ++ * Prepares a host channel for transferring packets to/from a specific ++ * endpoint. The HCCHARn register is set up with the characteristics specified ++ * in _hc. Host channel interrupts that may need to be serviced while this ++ * transfer is in progress are enabled. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ * @param hc Information needed to initialize the host channel ++ */ ++void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc) ++{ ++ uint32_t intr_enable; ++ hcintmsk_data_t hc_intr_mask; ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ hcchar_data_t hcchar; ++ hcsplt_data_t hcsplt; ++ ++ uint8_t hc_num = hc->hc_num; ++ dwc_otg_host_if_t *host_if = core_if->host_if; ++ dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num]; ++ ++ /* Clear old interrupt conditions for this host channel. */ ++ hc_intr_mask.d32 = 0xFFFFFFFF; ++ hc_intr_mask.b.reserved14_31 = 0; ++ DWC_WRITE_REG32(&hc_regs->hcint, hc_intr_mask.d32); ++ ++ /* Enable channel interrupts required for this transfer. */ ++ hc_intr_mask.d32 = 0; ++ hc_intr_mask.b.chhltd = 1; ++ if (core_if->dma_enable) { ++ /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */ ++ if (!core_if->dma_desc_enable) ++ hc_intr_mask.b.ahberr = 1; ++ else { ++ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) ++ hc_intr_mask.b.xfercompl = 1; ++ } ++ ++ if (hc->error_state && !hc->do_split && ++ hc->ep_type != DWC_OTG_EP_TYPE_ISOC) { ++ hc_intr_mask.b.ack = 1; ++ if (hc->ep_is_in) { ++ hc_intr_mask.b.datatglerr = 1; ++ if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) { ++ hc_intr_mask.b.nak = 1; ++ } ++ } ++ } ++ } else { ++ switch (hc->ep_type) { ++ case DWC_OTG_EP_TYPE_CONTROL: ++ case DWC_OTG_EP_TYPE_BULK: ++ hc_intr_mask.b.xfercompl = 1; ++ hc_intr_mask.b.stall = 1; ++ hc_intr_mask.b.xacterr = 1; ++ hc_intr_mask.b.datatglerr = 1; ++ if (hc->ep_is_in) { ++ hc_intr_mask.b.bblerr = 1; ++ } else { ++ hc_intr_mask.b.nak = 1; ++ hc_intr_mask.b.nyet = 1; ++ if (hc->do_ping) { ++ hc_intr_mask.b.ack = 1; ++ } ++ } ++ ++ if (hc->do_split) { ++ hc_intr_mask.b.nak = 1; ++ if (hc->complete_split) { ++ hc_intr_mask.b.nyet = 1; ++ } else { ++ hc_intr_mask.b.ack = 1; ++ } ++ } ++ ++ if (hc->error_state) { ++ hc_intr_mask.b.ack = 1; ++ } ++ break; ++ case DWC_OTG_EP_TYPE_INTR: ++ hc_intr_mask.b.xfercompl = 1; ++ hc_intr_mask.b.nak = 1; ++ hc_intr_mask.b.stall = 1; ++ hc_intr_mask.b.xacterr = 1; ++ hc_intr_mask.b.datatglerr = 1; ++ hc_intr_mask.b.frmovrun = 1; ++ ++ if (hc->ep_is_in) { ++ hc_intr_mask.b.bblerr = 1; ++ } ++ if (hc->error_state) { ++ hc_intr_mask.b.ack = 1; ++ } ++ if (hc->do_split) { ++ if (hc->complete_split) { ++ hc_intr_mask.b.nyet = 1; ++ } else { ++ hc_intr_mask.b.ack = 1; ++ } ++ } ++ break; ++ case DWC_OTG_EP_TYPE_ISOC: ++ hc_intr_mask.b.xfercompl = 1; ++ hc_intr_mask.b.frmovrun = 1; ++ hc_intr_mask.b.ack = 1; ++ ++ if (hc->ep_is_in) { ++ hc_intr_mask.b.xacterr = 1; ++ hc_intr_mask.b.bblerr = 1; ++ } ++ break; ++ } ++ } ++ DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32); ++ ++ /* Enable the top level host channel interrupt. */ ++ intr_enable = (1 << hc_num); ++ DWC_MODIFY_REG32(&host_if->host_global_regs->haintmsk, 0, intr_enable); ++ ++ /* Make sure host channel interrupts are enabled. */ ++ gintmsk.b.hcintr = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32); ++ ++ /* ++ * Program the HCCHARn register with the endpoint characteristics for ++ * the current transfer. ++ */ ++ hcchar.d32 = 0; ++ hcchar.b.devaddr = hc->dev_addr; ++ hcchar.b.epnum = hc->ep_num; ++ hcchar.b.epdir = hc->ep_is_in; ++ hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW); ++ hcchar.b.eptype = hc->ep_type; ++ hcchar.b.mps = hc->max_packet; ++ ++ DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32); ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d, Dev Addr %d, EP #%d\n", ++ __func__, hc->hc_num, hcchar.b.devaddr, hcchar.b.epnum); ++ DWC_DEBUGPL(DBG_HCDV, " Is In %d, Is Low Speed %d, EP Type %d, " ++ "Max Pkt %d, Multi Cnt %d\n", ++ hcchar.b.epdir, hcchar.b.lspddev, hcchar.b.eptype, ++ hcchar.b.mps, hcchar.b.multicnt); ++ ++ /* ++ * Program the HCSPLIT register for SPLITs ++ */ ++ hcsplt.d32 = 0; ++ if (hc->do_split) { ++ DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", ++ hc->hc_num, ++ hc->complete_split ? "CSPLIT" : "SSPLIT"); ++ hcsplt.b.compsplt = hc->complete_split; ++ hcsplt.b.xactpos = hc->xact_pos; ++ hcsplt.b.hubaddr = hc->hub_addr; ++ hcsplt.b.prtaddr = hc->port_addr; ++ DWC_DEBUGPL(DBG_HCDV, "\t comp split %d\n", hc->complete_split); ++ DWC_DEBUGPL(DBG_HCDV, "\t xact pos %d\n", hc->xact_pos); ++ DWC_DEBUGPL(DBG_HCDV, "\t hub addr %d\n", hc->hub_addr); ++ DWC_DEBUGPL(DBG_HCDV, "\t port addr %d\n", hc->port_addr); ++ DWC_DEBUGPL(DBG_HCDV, "\t is_in %d\n", hc->ep_is_in); ++ DWC_DEBUGPL(DBG_HCDV, "\t Max Pkt: %d\n", hcchar.b.mps); ++ DWC_DEBUGPL(DBG_HCDV, "\t xferlen: %d\n", hc->xfer_len); ++ } ++ DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32); ++ ++} ++ ++/** ++ * Attempts to halt a host channel. This function should only be called in ++ * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under ++ * normal circumstances in DMA mode, the controller halts the channel when the ++ * transfer is complete or a condition occurs that requires application ++ * intervention. ++ * ++ * In slave mode, checks for a free request queue entry, then sets the Channel ++ * Enable and Channel Disable bits of the Host Channel Characteristics ++ * register of the specified channel to intiate the halt. If there is no free ++ * request queue entry, sets only the Channel Disable bit of the HCCHARn ++ * register to flush requests for this channel. In the latter case, sets a ++ * flag to indicate that the host channel needs to be halted when a request ++ * queue slot is open. ++ * ++ * In DMA mode, always sets the Channel Enable and Channel Disable bits of the ++ * HCCHARn register. The controller ensures there is space in the request ++ * queue before submitting the halt request. ++ * ++ * Some time may elapse before the core flushes any posted requests for this ++ * host channel and halts. The Channel Halted interrupt handler completes the ++ * deactivation of the host channel. ++ * ++ * @param core_if Controller register interface. ++ * @param hc Host channel to halt. ++ * @param halt_status Reason for halting the channel. ++ */ ++void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if, ++ dwc_hc_t * hc, dwc_otg_halt_status_e halt_status) ++{ ++ gnptxsts_data_t nptxsts; ++ hptxsts_data_t hptxsts; ++ hcchar_data_t hcchar; ++ dwc_otg_hc_regs_t *hc_regs; ++ dwc_otg_core_global_regs_t *global_regs; ++ dwc_otg_host_global_regs_t *host_global_regs; ++ ++ hc_regs = core_if->host_if->hc_regs[hc->hc_num]; ++ global_regs = core_if->core_global_regs; ++ host_global_regs = core_if->host_if->host_global_regs; ++ ++ DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS), ++ "halt_status = %d\n", halt_status); ++ ++ if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE || ++ halt_status == DWC_OTG_HC_XFER_AHB_ERR) { ++ /* ++ * Disable all channel interrupts except Ch Halted. The QTD ++ * and QH state associated with this transfer has been cleared ++ * (in the case of URB_DEQUEUE), so the channel needs to be ++ * shut down carefully to prevent crashes. ++ */ ++ hcintmsk_data_t hcintmsk; ++ hcintmsk.d32 = 0; ++ hcintmsk.b.chhltd = 1; ++ DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32); ++ ++ /* ++ * Make sure no other interrupts besides halt are currently ++ * pending. Handling another interrupt could cause a crash due ++ * to the QTD and QH state. ++ */ ++ DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32); ++ ++ /* ++ * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR ++ * even if the channel was already halted for some other ++ * reason. ++ */ ++ hc->halt_status = halt_status; ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ if (hcchar.b.chen == 0) { ++ /* ++ * The channel is either already halted or it hasn't ++ * started yet. In DMA mode, the transfer may halt if ++ * it finishes normally or a condition occurs that ++ * requires driver intervention. Don't want to halt ++ * the channel again. In either Slave or DMA mode, ++ * it's possible that the transfer has been assigned ++ * to a channel, but not started yet when an URB is ++ * dequeued. Don't want to halt a channel that hasn't ++ * started yet. ++ */ ++ return; ++ } ++ } ++ if (hc->halt_pending) { ++ /* ++ * A halt has already been issued for this channel. This might ++ * happen when a transfer is aborted by a higher level in ++ * the stack. ++ */ ++#ifdef DEBUG ++ DWC_PRINTF ++ ("*** %s: Channel %d, _hc->halt_pending already set ***\n", ++ __func__, hc->hc_num); ++ ++#endif ++ return; ++ } ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* No need to set the bit in DDMA for disabling the channel */ ++ //TODO check it everywhere channel is disabled ++ if (!core_if->core_params->dma_desc_enable) ++ hcchar.b.chen = 1; ++ hcchar.b.chdis = 1; ++ ++ if (!core_if->dma_enable) { ++ /* Check for space in the request queue to issue the halt. */ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL || ++ hc->ep_type == DWC_OTG_EP_TYPE_BULK) { ++ nptxsts.d32 = DWC_READ_REG32(&global_regs->gnptxsts); ++ if (nptxsts.b.nptxqspcavail == 0) { ++ hcchar.b.chen = 0; ++ } ++ } else { ++ hptxsts.d32 = ++ DWC_READ_REG32(&host_global_regs->hptxsts); ++ if ((hptxsts.b.ptxqspcavail == 0) ++ || (core_if->queuing_high_bandwidth)) { ++ hcchar.b.chen = 0; ++ } ++ } ++ } ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ ++ hc->halt_status = halt_status; ++ ++ if (hcchar.b.chen) { ++ hc->halt_pending = 1; ++ hc->halt_on_queue = 0; ++ } else { ++ hc->halt_on_queue = 1; ++ } ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); ++ DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32); ++ DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending); ++ DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue); ++ DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status); ++ ++ return; ++} ++ ++/** ++ * Clears the transfer state for a host channel. This function is normally ++ * called after a transfer is done and the host channel is being released. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param hc Identifies the host channel to clean up. ++ */ ++void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc) ++{ ++ dwc_otg_hc_regs_t *hc_regs; ++ ++ hc->xfer_started = 0; ++ ++ /* ++ * Clear channel interrupt enables and any unhandled channel interrupt ++ * conditions. ++ */ ++ hc_regs = core_if->host_if->hc_regs[hc->hc_num]; ++ DWC_WRITE_REG32(&hc_regs->hcintmsk, 0); ++ DWC_WRITE_REG32(&hc_regs->hcint, 0xFFFFFFFF); ++#ifdef DEBUG ++ DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]); ++#endif ++} ++ ++/** ++ * Sets the channel property that indicates in which frame a periodic transfer ++ * should occur. This is always set to the _next_ frame. This function has no ++ * effect on non-periodic transfers. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param hc Identifies the host channel to set up and its properties. ++ * @param hcchar Current value of the HCCHAR register for the specified host ++ * channel. ++ */ ++static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if, ++ dwc_hc_t * hc, hcchar_data_t * hcchar) ++{ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || ++ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ hfnum_data_t hfnum; ++ hfnum.d32 = ++ DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum); ++ ++ /* 1 if _next_ frame is odd, 0 if it's even */ ++ hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1; ++#ifdef DEBUG ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split ++ && !hc->complete_split) { ++ switch (hfnum.b.frnum & 0x7) { ++ case 7: ++ core_if->hfnum_7_samples++; ++ core_if->hfnum_7_frrem_accum += hfnum.b.frrem; ++ break; ++ case 0: ++ core_if->hfnum_0_samples++; ++ core_if->hfnum_0_frrem_accum += hfnum.b.frrem; ++ break; ++ default: ++ core_if->hfnum_other_samples++; ++ core_if->hfnum_other_frrem_accum += ++ hfnum.b.frrem; ++ break; ++ } ++ } ++#endif ++ } ++} ++ ++#ifdef DEBUG ++void hc_xfer_timeout(void *ptr) ++{ ++ hc_xfer_info_t *xfer_info = NULL; ++ int hc_num = 0; ++ ++ if (ptr) ++ xfer_info = (hc_xfer_info_t *) ptr; ++ ++ if (!xfer_info->hc) { ++ DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc); ++ return; ++ } ++ ++ hc_num = xfer_info->hc->hc_num; ++ DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num); ++ DWC_WARN(" start_hcchar_val 0x%08x\n", ++ xfer_info->core_if->start_hcchar_val[hc_num]); ++} ++#endif ++ ++void ep_xfer_timeout(void *ptr) ++{ ++ ep_xfer_info_t *xfer_info = NULL; ++ int ep_num = 0; ++ dctl_data_t dctl = {.d32 = 0 }; ++ gintsts_data_t gintsts = {.d32 = 0 }; ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ ++ if (ptr) ++ xfer_info = (ep_xfer_info_t *) ptr; ++ ++ if (!xfer_info->ep) { ++ DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep); ++ return; ++ } ++ ++ ep_num = xfer_info->ep->num; ++ DWC_WARN("%s: timeout on endpoit %d\n", __func__, ep_num); ++ /* Put the sate to 2 as it was time outed */ ++ xfer_info->state = 2; ++ ++ dctl.d32 = ++ DWC_READ_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl); ++ gintsts.d32 = ++ DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintsts); ++ gintmsk.d32 = ++ DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintmsk); ++ ++ if (!gintmsk.b.goutnakeff) { ++ /* Unmask it */ ++ gintmsk.b.goutnakeff = 1; ++ DWC_WRITE_REG32(&xfer_info->core_if->core_global_regs->gintmsk, ++ gintmsk.d32); ++ ++ } ++ ++ if (!gintsts.b.goutnakeff) { ++ dctl.b.sgoutnak = 1; ++ } ++ DWC_WRITE_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl, ++ dctl.d32); ++ ++} ++ ++void set_pid_isoc(dwc_hc_t * hc) ++{ ++ /* Set up the initial PID for the transfer. */ ++ if (hc->speed == DWC_OTG_EP_SPEED_HIGH) { ++ if (hc->ep_is_in) { ++ if (hc->multi_count == 1) { ++ hc->data_pid_start = DWC_OTG_HC_PID_DATA0; ++ } else if (hc->multi_count == 2) { ++ hc->data_pid_start = DWC_OTG_HC_PID_DATA1; ++ } else { ++ hc->data_pid_start = DWC_OTG_HC_PID_DATA2; ++ } ++ } else { ++ if (hc->multi_count == 1) { ++ hc->data_pid_start = DWC_OTG_HC_PID_DATA0; ++ } else { ++ hc->data_pid_start = DWC_OTG_HC_PID_MDATA; ++ } ++ } ++ } else { ++ hc->data_pid_start = DWC_OTG_HC_PID_DATA0; ++ } ++} ++ ++/** ++ * This function does the setup for a data transfer for a host channel and ++ * starts the transfer. May be called in either Slave mode or DMA mode. In ++ * Slave mode, the caller must ensure that there is sufficient space in the ++ * request queue and Tx Data FIFO. ++ * ++ * For an OUT transfer in Slave mode, it loads a data packet into the ++ * appropriate FIFO. If necessary, additional data packets will be loaded in ++ * the Host ISR. ++ * ++ * For an IN transfer in Slave mode, a data packet is requested. The data ++ * packets are unloaded from the Rx FIFO in the Host ISR. If necessary, ++ * additional data packets are requested in the Host ISR. ++ * ++ * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ ++ * register along with a packet count of 1 and the channel is enabled. This ++ * causes a single PING transaction to occur. Other fields in HCTSIZ are ++ * simply set to 0 since no data transfer occurs in this case. ++ * ++ * For a PING transfer in DMA mode, the HCTSIZ register is initialized with ++ * all the information required to perform the subsequent data transfer. In ++ * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the ++ * controller performs the entire PING protocol, then starts the data ++ * transfer. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param hc Information needed to initialize the host channel. The xfer_len ++ * value may be reduced to accommodate the max widths of the XferSize and ++ * PktCnt fields in the HCTSIZn register. The multi_count value may be changed ++ * to reflect the final xfer_len value. ++ */ ++void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc) ++{ ++ hcchar_data_t hcchar; ++ hctsiz_data_t hctsiz; ++ uint16_t num_packets; ++ uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size; ++ uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count; ++ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num]; ++ ++ hctsiz.d32 = 0; ++ ++ if (hc->do_ping) { ++ if (!core_if->dma_enable) { ++ dwc_otg_hc_do_ping(core_if, hc); ++ hc->xfer_started = 1; ++ return; ++ } else { ++ hctsiz.b.dopng = 1; ++ } ++ } ++ ++ if (hc->do_split) { ++ num_packets = 1; ++ ++ if (hc->complete_split && !hc->ep_is_in) { ++ /* For CSPLIT OUT Transfer, set the size to 0 so the ++ * core doesn't expect any data written to the FIFO */ ++ hc->xfer_len = 0; ++ } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) { ++ hc->xfer_len = hc->max_packet; ++ } else if (!hc->ep_is_in && (hc->xfer_len > 188)) { ++ hc->xfer_len = 188; ++ } ++ ++ hctsiz.b.xfersize = hc->xfer_len; ++ } else { ++ /* ++ * Ensure that the transfer length and packet count will fit ++ * in the widths allocated for them in the HCTSIZn register. ++ */ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || ++ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ /* ++ * Make sure the transfer size is no larger than one ++ * (micro)frame's worth of data. (A check was done ++ * when the periodic transfer was accepted to ensure ++ * that a (micro)frame's worth of data can be ++ * programmed into a channel.) ++ */ ++ uint32_t max_periodic_len = ++ hc->multi_count * hc->max_packet; ++ if (hc->xfer_len > max_periodic_len) { ++ hc->xfer_len = max_periodic_len; ++ } else { ++ } ++ } else if (hc->xfer_len > max_hc_xfer_size) { ++ /* Make sure that xfer_len is a multiple of max packet size. */ ++ hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1; ++ } ++ ++ if (hc->xfer_len > 0) { ++ num_packets = ++ (hc->xfer_len + hc->max_packet - ++ 1) / hc->max_packet; ++ if (num_packets > max_hc_pkt_count) { ++ num_packets = max_hc_pkt_count; ++ hc->xfer_len = num_packets * hc->max_packet; ++ } ++ } else { ++ /* Need 1 packet for transfer length of 0. */ ++ num_packets = 1; ++ } ++ ++ if (hc->ep_is_in) { ++ /* Always program an integral # of max packets for IN transfers. */ ++ hc->xfer_len = num_packets * hc->max_packet; ++ } ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || ++ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ /* ++ * Make sure that the multi_count field matches the ++ * actual transfer length. ++ */ ++ hc->multi_count = num_packets; ++ } ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) ++ set_pid_isoc(hc); ++ ++ hctsiz.b.xfersize = hc->xfer_len; ++ } ++ ++ hc->start_pkt_count = num_packets; ++ hctsiz.b.pktcnt = num_packets; ++ hctsiz.b.pid = hc->data_pid_start; ++ DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32); ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); ++ DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize); ++ DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt); ++ DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid); ++ ++ if (core_if->dma_enable) { ++ dwc_dma_t dma_addr; ++ if (hc->align_buff) { ++ dma_addr = hc->align_buff; ++ } else { ++ dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff); ++ } ++ DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr); ++ } ++ ++ /* Start the split */ ++ if (hc->do_split) { ++ hcsplt_data_t hcsplt; ++ hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt); ++ hcsplt.b.spltena = 1; ++ DWC_WRITE_REG32(&hc_regs->hcsplt, hcsplt.d32); ++ } ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.multicnt = hc->multi_count; ++ hc_set_even_odd_frame(core_if, hc, &hcchar); ++#ifdef DEBUG ++ core_if->start_hcchar_val[hc->hc_num] = hcchar.d32; ++ if (hcchar.b.chdis) { ++ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", ++ __func__, hc->hc_num, hcchar.d32); ++ } ++#endif ++ ++ /* Set host channel enable after all other setup is complete. */ ++ hcchar.b.chen = 1; ++ hcchar.b.chdis = 0; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ ++ hc->xfer_started = 1; ++ hc->requests++; ++ ++ if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) { ++ /* Load OUT packet into the appropriate Tx FIFO. */ ++ dwc_otg_hc_write_packet(core_if, hc); ++ } ++#ifdef DEBUG ++ if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) { ++ DWC_DEBUGPL(DBG_HCDV, "transfer %d from core_if %p\n", ++ hc->hc_num, core_if);//GRAYG ++ core_if->hc_xfer_info[hc->hc_num].core_if = core_if; ++ core_if->hc_xfer_info[hc->hc_num].hc = hc; ++ ++ /* Start a timer for this transfer. */ ++ DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000); ++ } ++#endif ++} ++ ++/** ++ * This function does the setup for a data transfer for a host channel ++ * and starts the transfer in Descriptor DMA mode. ++ * ++ * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set. ++ * Sets PID and NTD values. For periodic transfers ++ * initializes SCHED_INFO field with micro-frame bitmap. ++ * ++ * Initializes HCDMA register with descriptor list address and CTD value ++ * then starts the transfer via enabling the channel. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param hc Information needed to initialize the host channel. ++ */ ++void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc) ++{ ++ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num]; ++ hcchar_data_t hcchar; ++ hctsiz_data_t hctsiz; ++ hcdma_data_t hcdma; ++ ++ hctsiz.d32 = 0; ++ ++ if (hc->do_ping) ++ hctsiz.b_ddma.dopng = 1; ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) ++ set_pid_isoc(hc); ++ ++ /* Packet Count and Xfer Size are not used in Descriptor DMA mode */ ++ hctsiz.b_ddma.pid = hc->data_pid_start; ++ hctsiz.b_ddma.ntd = hc->ntd - 1; /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */ ++ hctsiz.b_ddma.schinfo = hc->schinfo; /* Non-zero only for high-speed interrupt endpoints */ ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); ++ DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid); ++ DWC_DEBUGPL(DBG_HCDV, " NTD: %d\n", hctsiz.b_ddma.ntd); ++ ++ DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32); ++ ++ hcdma.d32 = 0; ++ hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11; ++ ++ /* Always start from first descriptor. */ ++ hcdma.b.ctd = 0; ++ DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32); ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.multicnt = hc->multi_count; ++ ++#ifdef DEBUG ++ core_if->start_hcchar_val[hc->hc_num] = hcchar.d32; ++ if (hcchar.b.chdis) { ++ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", ++ __func__, hc->hc_num, hcchar.d32); ++ } ++#endif ++ ++ /* Set host channel enable after all other setup is complete. */ ++ hcchar.b.chen = 1; ++ hcchar.b.chdis = 0; ++ ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ ++ hc->xfer_started = 1; ++ hc->requests++; ++ ++#ifdef DEBUG ++ if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR) ++ && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) { ++ DWC_DEBUGPL(DBG_HCDV, "DMA transfer %d from core_if %p\n", ++ hc->hc_num, core_if);//GRAYG ++ core_if->hc_xfer_info[hc->hc_num].core_if = core_if; ++ core_if->hc_xfer_info[hc->hc_num].hc = hc; ++ /* Start a timer for this transfer. */ ++ DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000); ++ } ++#endif ++ ++} ++ ++/** ++ * This function continues a data transfer that was started by previous call ++ * to dwc_otg_hc_start_transfer. The caller must ensure there is ++ * sufficient space in the request queue and Tx Data FIFO. This function ++ * should only be called in Slave mode. In DMA mode, the controller acts ++ * autonomously to complete transfers programmed to a host channel. ++ * ++ * For an OUT transfer, a new data packet is loaded into the appropriate FIFO ++ * if there is any data remaining to be queued. For an IN transfer, another ++ * data packet is always requested. For the SETUP phase of a control transfer, ++ * this function does nothing. ++ * ++ * @return 1 if a new request is queued, 0 if no more requests are required ++ * for this transfer. ++ */ ++int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc) ++{ ++ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); ++ ++ if (hc->do_split) { ++ /* SPLITs always queue just once per channel */ ++ return 0; ++ } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) { ++ /* SETUPs are queued only once since they can't be NAKed. */ ++ return 0; ++ } else if (hc->ep_is_in) { ++ /* ++ * Always queue another request for other IN transfers. If ++ * back-to-back INs are issued and NAKs are received for both, ++ * the driver may still be processing the first NAK when the ++ * second NAK is received. When the interrupt handler clears ++ * the NAK interrupt for the first NAK, the second NAK will ++ * not be seen. So we can't depend on the NAK interrupt ++ * handler to requeue a NAKed request. Instead, IN requests ++ * are issued each time this function is called. When the ++ * transfer completes, the extra requests for the channel will ++ * be flushed. ++ */ ++ hcchar_data_t hcchar; ++ dwc_otg_hc_regs_t *hc_regs = ++ core_if->host_if->hc_regs[hc->hc_num]; ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hc_set_even_odd_frame(core_if, hc, &hcchar); ++ hcchar.b.chen = 1; ++ hcchar.b.chdis = 0; ++ DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n", ++ hcchar.d32); ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ hc->requests++; ++ return 1; ++ } else { ++ /* OUT transfers. */ ++ if (hc->xfer_count < hc->xfer_len) { ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || ++ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ hcchar_data_t hcchar; ++ dwc_otg_hc_regs_t *hc_regs; ++ hc_regs = core_if->host_if->hc_regs[hc->hc_num]; ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hc_set_even_odd_frame(core_if, hc, &hcchar); ++ } ++ ++ /* Load OUT packet into the appropriate Tx FIFO. */ ++ dwc_otg_hc_write_packet(core_if, hc); ++ hc->requests++; ++ return 1; ++ } else { ++ return 0; ++ } ++ } ++} ++ ++/** ++ * Starts a PING transfer. This function should only be called in Slave mode. ++ * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled. ++ */ ++void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc) ++{ ++ hcchar_data_t hcchar; ++ hctsiz_data_t hctsiz; ++ dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num]; ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); ++ ++ hctsiz.d32 = 0; ++ hctsiz.b.dopng = 1; ++ hctsiz.b.pktcnt = 1; ++ DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32); ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.chen = 1; ++ hcchar.b.chdis = 0; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++} ++ ++/* ++ * This function writes a packet into the Tx FIFO associated with the Host ++ * Channel. For a channel associated with a non-periodic EP, the non-periodic ++ * Tx FIFO is written. For a channel associated with a periodic EP, the ++ * periodic Tx FIFO is written. This function should only be called in Slave ++ * mode. ++ * ++ * Upon return the xfer_buff and xfer_count fields in _hc are incremented by ++ * then number of bytes written to the Tx FIFO. ++ */ ++void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc) ++{ ++ uint32_t i; ++ uint32_t remaining_count; ++ uint32_t byte_count; ++ uint32_t dword_count; ++ ++ uint32_t *data_buff = (uint32_t *) (hc->xfer_buff); ++ uint32_t *data_fifo = core_if->data_fifo[hc->hc_num]; ++ ++ remaining_count = hc->xfer_len - hc->xfer_count; ++ if (remaining_count > hc->max_packet) { ++ byte_count = hc->max_packet; ++ } else { ++ byte_count = remaining_count; ++ } ++ ++ dword_count = (byte_count + 3) / 4; ++ ++ if ((((unsigned long)data_buff) & 0x3) == 0) { ++ /* xfer_buff is DWORD aligned. */ ++ for (i = 0; i < dword_count; i++, data_buff++) { ++ DWC_WRITE_REG32(data_fifo, *data_buff); ++ } ++ } else { ++ /* xfer_buff is not DWORD aligned. */ ++ for (i = 0; i < dword_count; i++, data_buff++) { ++ uint32_t data; ++ data = ++ (data_buff[0] | data_buff[1] << 8 | data_buff[2] << ++ 16 | data_buff[3] << 24); ++ DWC_WRITE_REG32(data_fifo, data); ++ } ++ } ++ ++ hc->xfer_count += byte_count; ++ hc->xfer_buff += byte_count; ++} ++ ++/** ++ * Gets the current USB frame number. This is the frame number from the last ++ * SOF packet. ++ */ ++uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if) ++{ ++ dsts_data_t dsts; ++ dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ ++ /* read current frame/microframe number from DSTS register */ ++ return dsts.b.soffn; ++} ++ ++/** ++ * Calculates and gets the frame Interval value of HFIR register according PHY ++ * type and speed.The application can modify a value of HFIR register only after ++ * the Port Enable bit of the Host Port Control and Status register ++ * (HPRT.PrtEnaPort) has been set. ++*/ ++ ++uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if) ++{ ++ gusbcfg_data_t usbcfg; ++ hwcfg2_data_t hwcfg2; ++ hprt0_data_t hprt0; ++ int clock = 60; // default value ++ usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ hwcfg2.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2); ++ hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0); ++ if (!usbcfg.b.physel && usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif) ++ clock = 60; ++ if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3) ++ clock = 48; ++ if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel && ++ !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif) ++ clock = 30; ++ if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel && ++ !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif) ++ clock = 60; ++ if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel && ++ !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif) ++ clock = 48; ++ if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2) ++ clock = 48; ++ if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1) ++ clock = 48; ++ if (hprt0.b.prtspd == 0) ++ /* High speed case */ ++ return 125 * clock; ++ else ++ /* FS/LS case */ ++ return 1000 * clock; ++} ++ ++/** ++ * This function reads a setup packet from the Rx FIFO into the destination ++ * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl) ++ * Interrupt routine when a SETUP packet has been received in Slave mode. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param dest Destination buffer for packet data. ++ */ ++void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest) ++{ ++ device_grxsts_data_t status; ++ /* Get the 8 bytes of a setup transaction data */ ++ ++ /* Pop 2 DWORDS off the receive data FIFO into memory */ ++ dest[0] = DWC_READ_REG32(core_if->data_fifo[0]); ++ dest[1] = DWC_READ_REG32(core_if->data_fifo[0]); ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ status.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->grxstsp); ++ DWC_DEBUGPL(DBG_ANY, ++ "EP:%d BCnt:%d " "pktsts:%x Frame:%d(0x%0x)\n", ++ status.b.epnum, status.b.bcnt, status.b.pktsts, ++ status.b.fn, status.b.fn); ++ } ++} ++ ++/** ++ * This function enables EP0 OUT to receive SETUP packets and configures EP0 ++ * IN for transmitting packets. It is normally called when the ++ * "Enumeration Done" interrupt occurs. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP0 data. ++ */ ++void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ dsts_data_t dsts; ++ depctl_data_t diepctl; ++ depctl_data_t doepctl; ++ dctl_data_t dctl = {.d32 = 0 }; ++ ++ ep->stp_rollover = 0; ++ /* Read the Device Status and Endpoint 0 Control registers */ ++ dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts); ++ diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl); ++ doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl); ++ ++ /* Set the MPS of the IN EP based on the enumeration speed */ ++ switch (dsts.b.enumspd) { ++ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: ++ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: ++ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ: ++ diepctl.b.mps = DWC_DEP0CTL_MPS_64; ++ break; ++ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ: ++ diepctl.b.mps = DWC_DEP0CTL_MPS_8; ++ break; ++ } ++ ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32); ++ ++ /* Enable OUT EP for receive */ ++ if (core_if->snpsid <= OTG_CORE_REV_2_94a) { ++ doepctl.b.epena = 1; ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32); ++ } ++#ifdef VERBOSE ++ DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n", ++ DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl)); ++ DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n", ++ DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl)); ++#endif ++ dctl.b.cgnpinnak = 1; ++ ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); ++ DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n", ++ DWC_READ_REG32(&dev_if->dev_global_regs->dctl)); ++ ++} ++ ++/** ++ * This function activates an EP. The Device EP control register for ++ * the EP is configured as defined in the ep structure. Note: This ++ * function is not used for EP0. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to activate. ++ */ ++void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ depctl_data_t depctl; ++ volatile uint32_t *addr; ++ daint_data_t daintmsk = {.d32 = 0 }; ++ dcfg_data_t dcfg; ++ uint8_t i; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num, ++ (ep->is_in ? "IN" : "OUT")); ++ ++#ifdef DWC_UTE_PER_IO ++ ep->xiso_frame_num = 0xFFFFFFFF; ++ ep->xiso_active_xfers = 0; ++ ep->xiso_queued_xfers = 0; ++#endif ++ /* Read DEPCTLn register */ ++ if (ep->is_in == 1) { ++ addr = &dev_if->in_ep_regs[ep->num]->diepctl; ++ daintmsk.ep.in = 1 << ep->num; ++ } else { ++ addr = &dev_if->out_ep_regs[ep->num]->doepctl; ++ daintmsk.ep.out = 1 << ep->num; ++ } ++ ++ /* If the EP is already active don't change the EP Control ++ * register. */ ++ depctl.d32 = DWC_READ_REG32(addr); ++ if (!depctl.b.usbactep) { ++ depctl.b.mps = ep->maxpacket; ++ depctl.b.eptype = ep->type; ++ depctl.b.txfnum = ep->tx_fifo_num; ++ ++ if (ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ depctl.b.setd0pid = 1; // ??? ++ } else { ++ depctl.b.setd0pid = 1; ++ } ++ depctl.b.usbactep = 1; ++ ++ /* Update nextep_seq array and EPMSCNT in DCFG*/ ++ if (!(depctl.b.eptype & 1) && (ep->is_in == 1)) { // NP IN EP ++ for (i = 0; i <= core_if->dev_if->num_in_eps; i++) { ++ if (core_if->nextep_seq[i] == core_if->first_in_nextep_seq) ++ break; ++ } ++ core_if->nextep_seq[i] = ep->num; ++ core_if->nextep_seq[ep->num] = core_if->first_in_nextep_seq; ++ depctl.b.nextep = core_if->nextep_seq[ep->num]; ++ dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg); ++ dcfg.b.epmscnt++; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32); ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "%s first_in_nextep_seq= %2d; nextep_seq[]:\n", ++ __func__, core_if->first_in_nextep_seq); ++ for (i=0; i <= core_if->dev_if->num_in_eps; i++) { ++ DWC_DEBUGPL(DBG_PCDV, "%2d\n", ++ core_if->nextep_seq[i]); ++ } ++ ++ } ++ ++ ++ DWC_WRITE_REG32(addr, depctl.d32); ++ DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr)); ++ } ++ ++ /* Enable the Interrupt for this EP */ ++ if (core_if->multiproc_int_enable) { ++ if (ep->is_in == 1) { ++ diepmsk_data_t diepmsk = {.d32 = 0 }; ++ diepmsk.b.xfercompl = 1; ++ diepmsk.b.timeout = 1; ++ diepmsk.b.epdisabled = 1; ++ diepmsk.b.ahberr = 1; ++ diepmsk.b.intknepmis = 1; ++ if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) ++ diepmsk.b.intknepmis = 0; ++ diepmsk.b.txfifoundrn = 1; //????? ++ if (ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ diepmsk.b.nak = 1; ++ } ++ ++ ++ ++/* ++ if (core_if->dma_desc_enable) { ++ diepmsk.b.bna = 1; ++ } ++*/ ++/* ++ if (core_if->dma_enable) { ++ doepmsk.b.nak = 1; ++ } ++*/ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs-> ++ diepeachintmsk[ep->num], diepmsk.d32); ++ ++ } else { ++ doepmsk_data_t doepmsk = {.d32 = 0 }; ++ doepmsk.b.xfercompl = 1; ++ doepmsk.b.ahberr = 1; ++ doepmsk.b.epdisabled = 1; ++ if (ep->type == DWC_OTG_EP_TYPE_ISOC) ++ doepmsk.b.outtknepdis = 1; ++ ++/* ++ ++ if (core_if->dma_desc_enable) { ++ doepmsk.b.bna = 1; ++ } ++*/ ++/* ++ doepmsk.b.babble = 1; ++ doepmsk.b.nyet = 1; ++ doepmsk.b.nak = 1; ++*/ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs-> ++ doepeachintmsk[ep->num], doepmsk.d32); ++ } ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk, ++ 0, daintmsk.d32); ++ } else { ++ if (ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ if (ep->is_in) { ++ diepmsk_data_t diepmsk = {.d32 = 0 }; ++ diepmsk.b.nak = 1; ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32); ++ } else { ++ doepmsk_data_t doepmsk = {.d32 = 0 }; ++ doepmsk.b.outtknepdis = 1; ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->doepmsk, 0, doepmsk.d32); ++ } ++ } ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk, ++ 0, daintmsk.d32); ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n", ++ DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk)); ++ ++ ep->stall_clear_flag = 0; ++ ++ return; ++} ++ ++/** ++ * This function deactivates an EP. This is done by clearing the USB Active ++ * EP bit in the Device EP control register. Note: This function is not used ++ * for EP0. EP0 cannot be deactivated. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to deactivate. ++ */ ++void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ depctl_data_t depctl = {.d32 = 0 }; ++ volatile uint32_t *addr; ++ daint_data_t daintmsk = {.d32 = 0 }; ++ dcfg_data_t dcfg; ++ uint8_t i = 0; ++ ++#ifdef DWC_UTE_PER_IO ++ ep->xiso_frame_num = 0xFFFFFFFF; ++ ep->xiso_active_xfers = 0; ++ ep->xiso_queued_xfers = 0; ++#endif ++ ++ /* Read DEPCTLn register */ ++ if (ep->is_in == 1) { ++ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl; ++ daintmsk.ep.in = 1 << ep->num; ++ } else { ++ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl; ++ daintmsk.ep.out = 1 << ep->num; ++ } ++ ++ depctl.d32 = DWC_READ_REG32(addr); ++ ++ depctl.b.usbactep = 0; ++ ++ /* Update nextep_seq array and EPMSCNT in DCFG*/ ++ if (!(depctl.b.eptype & 1) && ep->is_in == 1) { // NP EP IN ++ for (i = 0; i <= core_if->dev_if->num_in_eps; i++) { ++ if (core_if->nextep_seq[i] == ep->num) ++ break; ++ } ++ core_if->nextep_seq[i] = core_if->nextep_seq[ep->num]; ++ if (core_if->first_in_nextep_seq == ep->num) ++ core_if->first_in_nextep_seq = i; ++ core_if->nextep_seq[ep->num] = 0xff; ++ depctl.b.nextep = 0; ++ dcfg.d32 = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ dcfg.b.epmscnt--; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, ++ dcfg.d32); ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "%s first_in_nextep_seq= %2d; nextep_seq[]:\n", ++ __func__, core_if->first_in_nextep_seq); ++ for (i=0; i <= core_if->dev_if->num_in_eps; i++) { ++ DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]); ++ } ++ } ++ ++ if (ep->is_in == 1) ++ depctl.b.txfnum = 0; ++ ++ if (core_if->dma_desc_enable) ++ depctl.b.epdis = 1; ++ ++ DWC_WRITE_REG32(addr, depctl.d32); ++ depctl.d32 = DWC_READ_REG32(addr); ++ if (core_if->dma_enable && ep->type == DWC_OTG_EP_TYPE_ISOC ++ && depctl.b.epena) { ++ depctl_data_t depctl = {.d32 = 0}; ++ if (ep->is_in) { ++ diepint_data_t diepint = {.d32 = 0}; ++ ++ depctl.b.snak = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]-> ++ diepctl, depctl.d32); ++ do { ++ dwc_udelay(10); ++ diepint.d32 = ++ DWC_READ_REG32(&core_if-> ++ dev_if->in_ep_regs[ep->num]-> ++ diepint); ++ } while (!diepint.b.inepnakeff); ++ diepint.b.inepnakeff = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]-> ++ diepint, diepint.d32); ++ depctl.d32 = 0; ++ depctl.b.epdis = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]-> ++ diepctl, depctl.d32); ++ do { ++ dwc_udelay(10); ++ diepint.d32 = ++ DWC_READ_REG32(&core_if-> ++ dev_if->in_ep_regs[ep->num]-> ++ diepint); ++ } while (!diepint.b.epdisabled); ++ diepint.b.epdisabled = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]-> ++ diepint, diepint.d32); ++ } else { ++ dctl_data_t dctl = {.d32 = 0}; ++ gintmsk_data_t gintsts = {.d32 = 0}; ++ doepint_data_t doepint = {.d32 = 0}; ++ dctl.b.sgoutnak = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ dctl, 0, dctl.d32); ++ do { ++ dwc_udelay(10); ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ } while (!gintsts.b.goutnakeff); ++ gintsts.d32 = 0; ++ gintsts.b.goutnakeff = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ depctl.d32 = 0; ++ depctl.b.epdis = 1; ++ depctl.b.snak = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32); ++ do ++ { ++ dwc_udelay(10); ++ doepint.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[ep->num]->doepint); ++ } while (!doepint.b.epdisabled); ++ ++ doepint.b.epdisabled = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32); ++ ++ dctl.d32 = 0; ++ dctl.b.cgoutnak = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ } ++ } ++ ++ /* Disable the Interrupt for this EP */ ++ if (core_if->multiproc_int_enable) { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->deachintmsk, ++ daintmsk.d32, 0); ++ ++ if (ep->is_in == 1) { ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs-> ++ diepeachintmsk[ep->num], 0); ++ } else { ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs-> ++ doepeachintmsk[ep->num], 0); ++ } ++ } else { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk, ++ daintmsk.d32, 0); ++ } ++ ++} ++ ++/** ++ * This function initializes dma descriptor chain. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ */ ++static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ uint32_t offset; ++ uint32_t xfer_est; ++ int i; ++ unsigned maxxfer_local, total_len; ++ ++ if (!ep->is_in && ep->type == DWC_OTG_EP_TYPE_INTR && ++ (ep->maxpacket%4)) { ++ maxxfer_local = ep->maxpacket; ++ total_len = ep->xfer_len; ++ } else { ++ maxxfer_local = ep->maxxfer; ++ total_len = ep->total_len; ++ } ++ ++ ep->desc_cnt = (total_len / maxxfer_local) + ++ ((total_len % maxxfer_local) ? 1 : 0); ++ ++ if (!ep->desc_cnt) ++ ep->desc_cnt = 1; ++ ++ if (ep->desc_cnt > MAX_DMA_DESC_CNT) ++ ep->desc_cnt = MAX_DMA_DESC_CNT; ++ ++ dma_desc = ep->desc_addr; ++ if (maxxfer_local == ep->maxpacket) { ++ if ((total_len % maxxfer_local) && ++ (total_len/maxxfer_local < MAX_DMA_DESC_CNT)) { ++ xfer_est = (ep->desc_cnt - 1) * maxxfer_local + ++ (total_len % maxxfer_local); ++ } else ++ xfer_est = ep->desc_cnt * maxxfer_local; ++ } else ++ xfer_est = total_len; ++ offset = 0; ++ for (i = 0; i < ep->desc_cnt; ++i) { ++ /** DMA Descriptor Setup */ ++ if (xfer_est > maxxfer_local) { ++ dma_desc->status.b.bs = BS_HOST_BUSY; ++ dma_desc->status.b.l = 0; ++ dma_desc->status.b.ioc = 0; ++ dma_desc->status.b.sp = 0; ++ dma_desc->status.b.bytes = maxxfer_local; ++ dma_desc->buf = ep->dma_addr + offset; ++ dma_desc->status.b.sts = 0; ++ dma_desc->status.b.bs = BS_HOST_READY; ++ ++ xfer_est -= maxxfer_local; ++ offset += maxxfer_local; ++ } else { ++ dma_desc->status.b.bs = BS_HOST_BUSY; ++ dma_desc->status.b.l = 1; ++ dma_desc->status.b.ioc = 1; ++ if (ep->is_in) { ++ dma_desc->status.b.sp = ++ (xfer_est % ++ ep->maxpacket) ? 1 : ((ep-> ++ sent_zlp) ? 1 : 0); ++ dma_desc->status.b.bytes = xfer_est; ++ } else { ++ if (maxxfer_local == ep->maxpacket) ++ dma_desc->status.b.bytes = xfer_est; ++ else ++ dma_desc->status.b.bytes = ++ xfer_est + ((4 - (xfer_est & 0x3)) & 0x3); ++ } ++ ++ dma_desc->buf = ep->dma_addr + offset; ++ dma_desc->status.b.sts = 0; ++ dma_desc->status.b.bs = BS_HOST_READY; ++ } ++ dma_desc++; ++ } ++} ++/** ++ * This function is called when to write ISOC data into appropriate dedicated ++ * periodic FIFO. ++ */ ++static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep) ++{ ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ dwc_otg_dev_in_ep_regs_t *ep_regs; ++ dtxfsts_data_t txstatus = {.d32 = 0 }; ++ uint32_t len = 0; ++ int epnum = dwc_ep->num; ++ int dwords; ++ ++ DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum); ++ ++ ep_regs = core_if->dev_if->in_ep_regs[epnum]; ++ ++ len = dwc_ep->xfer_len - dwc_ep->xfer_count; ++ ++ if (len > dwc_ep->maxpacket) { ++ len = dwc_ep->maxpacket; ++ } ++ ++ dwords = (len + 3) / 4; ++ ++ /* While there is space in the queue and space in the FIFO and ++ * More data to tranfer, Write packets to the Tx FIFO */ ++ txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts); ++ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32); ++ ++ while (txstatus.b.txfspcavail > dwords && ++ dwc_ep->xfer_count < dwc_ep->xfer_len && dwc_ep->xfer_len != 0) { ++ /* Write the FIFO */ ++ dwc_otg_ep_write_packet(core_if, dwc_ep, 0); ++ ++ len = dwc_ep->xfer_len - dwc_ep->xfer_count; ++ if (len > dwc_ep->maxpacket) { ++ len = dwc_ep->maxpacket; ++ } ++ ++ dwords = (len + 3) / 4; ++ txstatus.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts); ++ DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum, ++ txstatus.d32); ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, ++ DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts)); ++ ++ return 1; ++} ++/** ++ * This function does the setup for a data transfer for an EP and ++ * starts the transfer. For an IN transfer, the packets will be ++ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers, ++ * the packets are unloaded from the Rx FIFO in the ISR. the ISR. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ */ ++ ++void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ depctl_data_t depctl; ++ deptsiz_data_t deptsiz; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__); ++ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d " ++ "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n", ++ ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len, ++ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff, ++ ep->total_len); ++ /* IN endpoint */ ++ if (ep->is_in == 1) { ++ dwc_otg_dev_in_ep_regs_t *in_regs = ++ core_if->dev_if->in_ep_regs[ep->num]; ++ ++ gnptxsts_data_t gtxstatus; ++ ++ gtxstatus.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->gnptxsts); ++ ++ if (core_if->en_multiple_tx_fifo == 0 ++ && gtxstatus.b.nptxqspcavail == 0 && !core_if->dma_enable) { ++#ifdef DEBUG ++ DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32); ++#endif ++ return; ++ } ++ ++ depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl)); ++ deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz)); ++ ++ if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT) ++ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ? ++ ep->maxxfer : (ep->total_len - ep->xfer_len); ++ else ++ ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ? ++ MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len); ++ ++ ++ /* Zero Length Packet? */ ++ if ((ep->xfer_len - ep->xfer_count) == 0) { ++ deptsiz.b.xfersize = 0; ++ deptsiz.b.pktcnt = 1; ++ } else { ++ /* Program the transfer size and packet count ++ * as follows: xfersize = N * maxpacket + ++ * short_packet pktcnt = N + (short_packet ++ * exist ? 1 : 0) ++ */ ++ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count; ++ deptsiz.b.pktcnt = ++ (ep->xfer_len - ep->xfer_count - 1 + ++ ep->maxpacket) / ep->maxpacket; ++ if (deptsiz.b.pktcnt > MAX_PKT_CNT) { ++ deptsiz.b.pktcnt = MAX_PKT_CNT; ++ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; ++ } ++ if (ep->type == DWC_OTG_EP_TYPE_ISOC) ++ deptsiz.b.mc = deptsiz.b.pktcnt; ++ } ++ ++ /* Write the DMA register */ ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable == 0) { ++ if (ep->type != DWC_OTG_EP_TYPE_ISOC) ++ deptsiz.b.mc = 1; ++ DWC_WRITE_REG32(&in_regs->dieptsiz, ++ deptsiz.d32); ++ DWC_WRITE_REG32(&(in_regs->diepdma), ++ (uint32_t) ep->dma_addr); ++ } else { ++#ifdef DWC_UTE_CFI ++ /* The descriptor chain should be already initialized by now */ ++ if (ep->buff_mode != BM_STANDARD) { ++ DWC_WRITE_REG32(&in_regs->diepdma, ++ ep->descs_dma_addr); ++ } else { ++#endif ++ init_dma_desc_chain(core_if, ep); ++ /** DIEPDMAn Register write */ ++ DWC_WRITE_REG32(&in_regs->diepdma, ++ ep->dma_desc_addr); ++#ifdef DWC_UTE_CFI ++ } ++#endif ++ } ++ } else { ++ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32); ++ if (ep->type != DWC_OTG_EP_TYPE_ISOC) { ++ /** ++ * Enable the Non-Periodic Tx FIFO empty interrupt, ++ * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode, ++ * the data will be written into the fifo by the ISR. ++ */ ++ if (core_if->en_multiple_tx_fifo == 0) { ++ intr_mask.b.nptxfempty = 1; ++ DWC_MODIFY_REG32 ++ (&core_if->core_global_regs->gintmsk, ++ intr_mask.d32, intr_mask.d32); ++ } else { ++ /* Enable the Tx FIFO Empty Interrupt for this EP */ ++ if (ep->xfer_len > 0) { ++ uint32_t fifoemptymsk = 0; ++ fifoemptymsk = 1 << ep->num; ++ DWC_MODIFY_REG32 ++ (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk, ++ 0, fifoemptymsk); ++ ++ } ++ } ++ } else { ++ write_isoc_tx_fifo(core_if, ep); ++ } ++ } ++ if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) ++ depctl.b.nextep = core_if->nextep_seq[ep->num]; ++ ++ if (ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ dsts_data_t dsts = {.d32 = 0}; ++ if (ep->bInterval == 1) { ++ dsts.d32 = ++ DWC_READ_REG32(&core_if->dev_if-> ++ dev_global_regs->dsts); ++ ep->frame_num = dsts.b.soffn + ep->bInterval; ++ if (ep->frame_num > 0x3FFF) { ++ ep->frm_overrun = 1; ++ ep->frame_num &= 0x3FFF; ++ } else ++ ep->frm_overrun = 0; ++ if (ep->frame_num & 0x1) { ++ depctl.b.setd1pid = 1; ++ } else { ++ depctl.b.setd0pid = 1; ++ } ++ } ++ } ++ /* EP enable, IN data in FIFO */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32); ++ ++ } else { ++ /* OUT endpoint */ ++ dwc_otg_dev_out_ep_regs_t *out_regs = ++ core_if->dev_if->out_ep_regs[ep->num]; ++ ++ depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl)); ++ deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz)); ++ ++ if (!core_if->dma_desc_enable) { ++ if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT) ++ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ? ++ ep->maxxfer : (ep->total_len - ep->xfer_len); ++ else ++ ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len ++ - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len); ++ } ++ ++ /* Program the transfer size and packet count as follows: ++ * ++ * pktcnt = N ++ * xfersize = N * maxpacket ++ */ ++ if ((ep->xfer_len - ep->xfer_count) == 0) { ++ /* Zero Length Packet */ ++ deptsiz.b.xfersize = ep->maxpacket; ++ deptsiz.b.pktcnt = 1; ++ } else { ++ deptsiz.b.pktcnt = ++ (ep->xfer_len - ep->xfer_count + ++ (ep->maxpacket - 1)) / ep->maxpacket; ++ if (deptsiz.b.pktcnt > MAX_PKT_CNT) { ++ deptsiz.b.pktcnt = MAX_PKT_CNT; ++ } ++ if (!core_if->dma_desc_enable) { ++ ep->xfer_len = ++ deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count; ++ } ++ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count; ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n", ++ ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt); ++ ++ if (core_if->dma_enable) { ++ if (!core_if->dma_desc_enable) { ++ DWC_WRITE_REG32(&out_regs->doeptsiz, ++ deptsiz.d32); ++ ++ DWC_WRITE_REG32(&(out_regs->doepdma), ++ (uint32_t) ep->dma_addr); ++ } else { ++#ifdef DWC_UTE_CFI ++ /* The descriptor chain should be already initialized by now */ ++ if (ep->buff_mode != BM_STANDARD) { ++ DWC_WRITE_REG32(&out_regs->doepdma, ++ ep->descs_dma_addr); ++ } else { ++#endif ++ /** This is used for interrupt out transfers*/ ++ if (!ep->xfer_len) ++ ep->xfer_len = ep->total_len; ++ init_dma_desc_chain(core_if, ep); ++ ++ if (core_if->core_params->dev_out_nak) { ++ if (ep->type == DWC_OTG_EP_TYPE_BULK) { ++ deptsiz.b.pktcnt = (ep->total_len + ++ (ep->maxpacket - 1)) / ep->maxpacket; ++ deptsiz.b.xfersize = ep->total_len; ++ /* Remember initial value of doeptsiz */ ++ core_if->start_doeptsiz_val[ep->num] = deptsiz.d32; ++ DWC_WRITE_REG32(&out_regs->doeptsiz, ++ deptsiz.d32); ++ } ++ } ++ /** DOEPDMAn Register write */ ++ DWC_WRITE_REG32(&out_regs->doepdma, ++ ep->dma_desc_addr); ++#ifdef DWC_UTE_CFI ++ } ++#endif ++ } ++ } else { ++ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32); ++ } ++ ++ if (ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ dsts_data_t dsts = {.d32 = 0}; ++ if (ep->bInterval == 1) { ++ dsts.d32 = ++ DWC_READ_REG32(&core_if->dev_if-> ++ dev_global_regs->dsts); ++ ep->frame_num = dsts.b.soffn + ep->bInterval; ++ if (ep->frame_num > 0x3FFF) { ++ ep->frm_overrun = 1; ++ ep->frame_num &= 0x3FFF; ++ } else ++ ep->frm_overrun = 0; ++ ++ if (ep->frame_num & 0x1) { ++ depctl.b.setd1pid = 1; ++ } else { ++ depctl.b.setd0pid = 1; ++ } ++ } ++ } ++ ++ /* EP enable */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ ++ DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32); ++ ++ DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n", ++ DWC_READ_REG32(&out_regs->doepctl), ++ DWC_READ_REG32(&out_regs->doeptsiz)); ++ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n", ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs-> ++ daintmsk), ++ DWC_READ_REG32(&core_if->core_global_regs-> ++ gintmsk)); ++ ++ /* Timer is scheduling only for out bulk transfers for ++ * "Device DDMA OUT NAK Enhancement" feature to inform user ++ * about received data payload in case of timeout ++ */ ++ if (core_if->core_params->dev_out_nak) { ++ if (ep->type == DWC_OTG_EP_TYPE_BULK) { ++ core_if->ep_xfer_info[ep->num].core_if = core_if; ++ core_if->ep_xfer_info[ep->num].ep = ep; ++ core_if->ep_xfer_info[ep->num].state = 1; ++ ++ /* Start a timer for this transfer. */ ++ DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000); ++ } ++ } ++ } ++} ++ ++/** ++ * This function setup a zero length transfer in Buffer DMA and ++ * Slave modes for usb requests with zero field set ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ * ++ */ ++void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ ++ depctl_data_t depctl; ++ deptsiz_data_t deptsiz; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__); ++ DWC_PRINTF("zero length transfer is called\n"); ++ ++ /* IN endpoint */ ++ if (ep->is_in == 1) { ++ dwc_otg_dev_in_ep_regs_t *in_regs = ++ core_if->dev_if->in_ep_regs[ep->num]; ++ ++ depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl)); ++ deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz)); ++ ++ deptsiz.b.xfersize = 0; ++ deptsiz.b.pktcnt = 1; ++ ++ /* Write the DMA register */ ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable == 0) { ++ deptsiz.b.mc = 1; ++ DWC_WRITE_REG32(&in_regs->dieptsiz, ++ deptsiz.d32); ++ DWC_WRITE_REG32(&(in_regs->diepdma), ++ (uint32_t) ep->dma_addr); ++ } ++ } else { ++ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32); ++ /** ++ * Enable the Non-Periodic Tx FIFO empty interrupt, ++ * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode, ++ * the data will be written into the fifo by the ISR. ++ */ ++ if (core_if->en_multiple_tx_fifo == 0) { ++ intr_mask.b.nptxfempty = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs->gintmsk, ++ intr_mask.d32, intr_mask.d32); ++ } else { ++ /* Enable the Tx FIFO Empty Interrupt for this EP */ ++ if (ep->xfer_len > 0) { ++ uint32_t fifoemptymsk = 0; ++ fifoemptymsk = 1 << ep->num; ++ DWC_MODIFY_REG32(&core_if-> ++ dev_if->dev_global_regs->dtknqr4_fifoemptymsk, ++ 0, fifoemptymsk); ++ } ++ } ++ } ++ ++ if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) ++ depctl.b.nextep = core_if->nextep_seq[ep->num]; ++ /* EP enable, IN data in FIFO */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32); ++ ++ } else { ++ /* OUT endpoint */ ++ dwc_otg_dev_out_ep_regs_t *out_regs = ++ core_if->dev_if->out_ep_regs[ep->num]; ++ ++ depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl)); ++ deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz)); ++ ++ /* Zero Length Packet */ ++ deptsiz.b.xfersize = ep->maxpacket; ++ deptsiz.b.pktcnt = 1; ++ ++ if (core_if->dma_enable) { ++ if (!core_if->dma_desc_enable) { ++ DWC_WRITE_REG32(&out_regs->doeptsiz, ++ deptsiz.d32); ++ ++ DWC_WRITE_REG32(&(out_regs->doepdma), ++ (uint32_t) ep->dma_addr); ++ } ++ } else { ++ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32); ++ } ++ ++ /* EP enable */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ ++ DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32); ++ ++ } ++} ++ ++/** ++ * This function does the setup for a data transfer for EP0 and starts ++ * the transfer. For an IN transfer, the packets will be loaded into ++ * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are ++ * unloaded from the Rx FIFO in the ISR. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP0 data. ++ */ ++void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ depctl_data_t depctl; ++ deptsiz0_data_t deptsiz; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ ++ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d " ++ "xfer_buff=%p start_xfer_buff=%p \n", ++ ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len, ++ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff); ++ ++ ep->total_len = ep->xfer_len; ++ ++ /* IN endpoint */ ++ if (ep->is_in == 1) { ++ dwc_otg_dev_in_ep_regs_t *in_regs = ++ core_if->dev_if->in_ep_regs[0]; ++ ++ gnptxsts_data_t gtxstatus; ++ ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ depctl.d32 = DWC_READ_REG32(&in_regs->diepctl); ++ if (depctl.b.epena) ++ return; ++ } ++ ++ gtxstatus.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->gnptxsts); ++ ++ /* If dedicated FIFO every time flush fifo before enable ep*/ ++ if (core_if->en_multiple_tx_fifo && core_if->snpsid >= OTG_CORE_REV_3_00a) ++ dwc_otg_flush_tx_fifo(core_if, ep->tx_fifo_num); ++ ++ if (core_if->en_multiple_tx_fifo == 0 ++ && gtxstatus.b.nptxqspcavail == 0 ++ && !core_if->dma_enable) { ++#ifdef DEBUG ++ deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz); ++ DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n", ++ DWC_READ_REG32(&in_regs->diepctl)); ++ DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n", ++ deptsiz.d32, ++ deptsiz.b.xfersize, deptsiz.b.pktcnt); ++ DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n", ++ gtxstatus.d32); ++#endif ++ return; ++ } ++ ++ depctl.d32 = DWC_READ_REG32(&in_regs->diepctl); ++ deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz); ++ ++ /* Zero Length Packet? */ ++ if (ep->xfer_len == 0) { ++ deptsiz.b.xfersize = 0; ++ deptsiz.b.pktcnt = 1; ++ } else { ++ /* Program the transfer size and packet count ++ * as follows: xfersize = N * maxpacket + ++ * short_packet pktcnt = N + (short_packet ++ * exist ? 1 : 0) ++ */ ++ if (ep->xfer_len > ep->maxpacket) { ++ ep->xfer_len = ep->maxpacket; ++ deptsiz.b.xfersize = ep->maxpacket; ++ } else { ++ deptsiz.b.xfersize = ep->xfer_len; ++ } ++ deptsiz.b.pktcnt = 1; ++ ++ } ++ DWC_DEBUGPL(DBG_PCDV, ++ "IN len=%d xfersize=%d pktcnt=%d [%08x]\n", ++ ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt, ++ deptsiz.d32); ++ ++ /* Write the DMA register */ ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable == 0) { ++ DWC_WRITE_REG32(&in_regs->dieptsiz, ++ deptsiz.d32); ++ ++ DWC_WRITE_REG32(&(in_regs->diepdma), ++ (uint32_t) ep->dma_addr); ++ } else { ++ dma_desc = core_if->dev_if->in_desc_addr; ++ ++ /** DMA Descriptor Setup */ ++ dma_desc->status.b.bs = BS_HOST_BUSY; ++ dma_desc->status.b.l = 1; ++ dma_desc->status.b.ioc = 1; ++ dma_desc->status.b.sp = ++ (ep->xfer_len == ep->maxpacket) ? 0 : 1; ++ dma_desc->status.b.bytes = ep->xfer_len; ++ dma_desc->buf = ep->dma_addr; ++ dma_desc->status.b.sts = 0; ++ dma_desc->status.b.bs = BS_HOST_READY; ++ ++ /** DIEPDMA0 Register write */ ++ DWC_WRITE_REG32(&in_regs->diepdma, ++ core_if-> ++ dev_if->dma_in_desc_addr); ++ } ++ } else { ++ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32); ++ } ++ ++ if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) ++ depctl.b.nextep = core_if->nextep_seq[ep->num]; ++ /* EP enable, IN data in FIFO */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32); ++ ++ /** ++ * Enable the Non-Periodic Tx FIFO empty interrupt, the ++ * data will be written into the fifo by the ISR. ++ */ ++ if (!core_if->dma_enable) { ++ if (core_if->en_multiple_tx_fifo == 0) { ++ intr_mask.b.nptxfempty = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs->gintmsk, ++ intr_mask.d32, intr_mask.d32); ++ } else { ++ /* Enable the Tx FIFO Empty Interrupt for this EP */ ++ if (ep->xfer_len > 0) { ++ uint32_t fifoemptymsk = 0; ++ fifoemptymsk |= 1 << ep->num; ++ DWC_MODIFY_REG32(&core_if-> ++ dev_if->dev_global_regs->dtknqr4_fifoemptymsk, ++ 0, fifoemptymsk); ++ } ++ } ++ } ++ } else { ++ /* OUT endpoint */ ++ dwc_otg_dev_out_ep_regs_t *out_regs = ++ core_if->dev_if->out_ep_regs[0]; ++ ++ depctl.d32 = DWC_READ_REG32(&out_regs->doepctl); ++ deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz); ++ ++ /* Program the transfer size and packet count as follows: ++ * xfersize = N * (maxpacket + 4 - (maxpacket % 4)) ++ * pktcnt = N */ ++ /* Zero Length Packet */ ++ deptsiz.b.xfersize = ep->maxpacket; ++ deptsiz.b.pktcnt = 1; ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) ++ deptsiz.b.supcnt = 3; ++ ++ DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n", ++ ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt); ++ ++ if (core_if->dma_enable) { ++ if (!core_if->dma_desc_enable) { ++ DWC_WRITE_REG32(&out_regs->doeptsiz, ++ deptsiz.d32); ++ ++ DWC_WRITE_REG32(&(out_regs->doepdma), ++ (uint32_t) ep->dma_addr); ++ } else { ++ dma_desc = core_if->dev_if->out_desc_addr; ++ ++ /** DMA Descriptor Setup */ ++ dma_desc->status.b.bs = BS_HOST_BUSY; ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ dma_desc->status.b.mtrf = 0; ++ dma_desc->status.b.sr = 0; ++ } ++ dma_desc->status.b.l = 1; ++ dma_desc->status.b.ioc = 1; ++ dma_desc->status.b.bytes = ep->maxpacket; ++ dma_desc->buf = ep->dma_addr; ++ dma_desc->status.b.sts = 0; ++ dma_desc->status.b.bs = BS_HOST_READY; ++ ++ /** DOEPDMA0 Register write */ ++ DWC_WRITE_REG32(&out_regs->doepdma, ++ core_if->dev_if-> ++ dma_out_desc_addr); ++ } ++ } else { ++ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32); ++ } ++ ++ /* EP enable */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32); ++ } ++} ++ ++/** ++ * This function continues control IN transfers started by ++ * dwc_otg_ep0_start_transfer, when the transfer does not fit in a ++ * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one ++ * bit for the packet count. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP0 data. ++ */ ++void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ depctl_data_t depctl; ++ deptsiz0_data_t deptsiz; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ ++ if (ep->is_in == 1) { ++ dwc_otg_dev_in_ep_regs_t *in_regs = ++ core_if->dev_if->in_ep_regs[0]; ++ gnptxsts_data_t tx_status = {.d32 = 0 }; ++ ++ tx_status.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->gnptxsts); ++ /** @todo Should there be check for room in the Tx ++ * Status Queue. If not remove the code above this comment. */ ++ ++ depctl.d32 = DWC_READ_REG32(&in_regs->diepctl); ++ deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz); ++ ++ /* Program the transfer size and packet count ++ * as follows: xfersize = N * maxpacket + ++ * short_packet pktcnt = N + (short_packet ++ * exist ? 1 : 0) ++ */ ++ ++ if (core_if->dma_desc_enable == 0) { ++ deptsiz.b.xfersize = ++ (ep->total_len - ep->xfer_count) > ++ ep->maxpacket ? ep->maxpacket : (ep->total_len - ++ ep->xfer_count); ++ deptsiz.b.pktcnt = 1; ++ if (core_if->dma_enable == 0) { ++ ep->xfer_len += deptsiz.b.xfersize; ++ } else { ++ ep->xfer_len = deptsiz.b.xfersize; ++ } ++ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32); ++ } else { ++ ep->xfer_len = ++ (ep->total_len - ep->xfer_count) > ++ ep->maxpacket ? ep->maxpacket : (ep->total_len - ++ ep->xfer_count); ++ ++ dma_desc = core_if->dev_if->in_desc_addr; ++ ++ /** DMA Descriptor Setup */ ++ dma_desc->status.b.bs = BS_HOST_BUSY; ++ dma_desc->status.b.l = 1; ++ dma_desc->status.b.ioc = 1; ++ dma_desc->status.b.sp = ++ (ep->xfer_len == ep->maxpacket) ? 0 : 1; ++ dma_desc->status.b.bytes = ep->xfer_len; ++ dma_desc->buf = ep->dma_addr; ++ dma_desc->status.b.sts = 0; ++ dma_desc->status.b.bs = BS_HOST_READY; ++ ++ /** DIEPDMA0 Register write */ ++ DWC_WRITE_REG32(&in_regs->diepdma, ++ core_if->dev_if->dma_in_desc_addr); ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "IN len=%d xfersize=%d pktcnt=%d [%08x]\n", ++ ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt, ++ deptsiz.d32); ++ ++ /* Write the DMA register */ ++ if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) { ++ if (core_if->dma_desc_enable == 0) ++ DWC_WRITE_REG32(&(in_regs->diepdma), ++ (uint32_t) ep->dma_addr); ++ } ++ if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) ++ depctl.b.nextep = core_if->nextep_seq[ep->num]; ++ /* EP enable, IN data in FIFO */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32); ++ ++ /** ++ * Enable the Non-Periodic Tx FIFO empty interrupt, the ++ * data will be written into the fifo by the ISR. ++ */ ++ if (!core_if->dma_enable) { ++ if (core_if->en_multiple_tx_fifo == 0) { ++ /* First clear it from GINTSTS */ ++ intr_mask.b.nptxfempty = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs->gintmsk, ++ intr_mask.d32, intr_mask.d32); ++ ++ } else { ++ /* Enable the Tx FIFO Empty Interrupt for this EP */ ++ if (ep->xfer_len > 0) { ++ uint32_t fifoemptymsk = 0; ++ fifoemptymsk |= 1 << ep->num; ++ DWC_MODIFY_REG32(&core_if-> ++ dev_if->dev_global_regs->dtknqr4_fifoemptymsk, ++ 0, fifoemptymsk); ++ } ++ } ++ } ++ } else { ++ dwc_otg_dev_out_ep_regs_t *out_regs = ++ core_if->dev_if->out_ep_regs[0]; ++ ++ depctl.d32 = DWC_READ_REG32(&out_regs->doepctl); ++ deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz); ++ ++ /* Program the transfer size and packet count ++ * as follows: xfersize = N * maxpacket + ++ * short_packet pktcnt = N + (short_packet ++ * exist ? 1 : 0) ++ */ ++ deptsiz.b.xfersize = ep->maxpacket; ++ deptsiz.b.pktcnt = 1; ++ ++ if (core_if->dma_desc_enable == 0) { ++ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32); ++ } else { ++ dma_desc = core_if->dev_if->out_desc_addr; ++ ++ /** DMA Descriptor Setup */ ++ dma_desc->status.b.bs = BS_HOST_BUSY; ++ dma_desc->status.b.l = 1; ++ dma_desc->status.b.ioc = 1; ++ dma_desc->status.b.bytes = ep->maxpacket; ++ dma_desc->buf = ep->dma_addr; ++ dma_desc->status.b.sts = 0; ++ dma_desc->status.b.bs = BS_HOST_READY; ++ ++ /** DOEPDMA0 Register write */ ++ DWC_WRITE_REG32(&out_regs->doepdma, ++ core_if->dev_if->dma_out_desc_addr); ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "IN len=%d xfersize=%d pktcnt=%d [%08x]\n", ++ ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt, ++ deptsiz.d32); ++ ++ /* Write the DMA register */ ++ if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) { ++ if (core_if->dma_desc_enable == 0) ++ DWC_WRITE_REG32(&(out_regs->doepdma), ++ (uint32_t) ep->dma_addr); ++ ++ } ++ ++ /* EP enable, IN data in FIFO */ ++ depctl.b.cnak = 1; ++ depctl.b.epena = 1; ++ DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32); ++ ++ } ++} ++ ++#ifdef DEBUG ++void dump_msg(const u8 * buf, unsigned int length) ++{ ++ unsigned int start, num, i; ++ char line[52], *p; ++ ++ if (length >= 512) ++ return; ++ start = 0; ++ while (length > 0) { ++ num = length < 16u ? length : 16u; ++ p = line; ++ for (i = 0; i < num; ++i) { ++ if (i == 8) ++ *p++ = ' '; ++ DWC_SPRINTF(p, " %02x", buf[i]); ++ p += 3; ++ } ++ *p = 0; ++ DWC_PRINTF("%6x: %s\n", start, line); ++ buf += num; ++ start += num; ++ length -= num; ++ } ++} ++#else ++static inline void dump_msg(const u8 * buf, unsigned int length) ++{ ++} ++#endif ++ ++/** ++ * This function writes a packet into the Tx FIFO associated with the ++ * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For ++ * periodic EPs the periodic Tx FIFO associated with the EP is written ++ * with all packets for the next micro-frame. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to write packet for. ++ * @param dma Indicates if DMA is being used. ++ */ ++void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep, ++ int dma) ++{ ++ /** ++ * The buffer is padded to DWORD on a per packet basis in ++ * slave/dma mode if the MPS is not DWORD aligned. The last ++ * packet, if short, is also padded to a multiple of DWORD. ++ * ++ * ep->xfer_buff always starts DWORD aligned in memory and is a ++ * multiple of DWORD in length ++ * ++ * ep->xfer_len can be any number of bytes ++ * ++ * ep->xfer_count is a multiple of ep->maxpacket until the last ++ * packet ++ * ++ * FIFO access is DWORD */ ++ ++ uint32_t i; ++ uint32_t byte_count; ++ uint32_t dword_count; ++ uint32_t *fifo; ++ uint32_t *data_buff = (uint32_t *) ep->xfer_buff; ++ ++ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if, ++ ep); ++ if (ep->xfer_count >= ep->xfer_len) { ++ DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num); ++ return; ++ } ++ ++ /* Find the byte length of the packet either short packet or MPS */ ++ if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) { ++ byte_count = ep->xfer_len - ep->xfer_count; ++ } else { ++ byte_count = ep->maxpacket; ++ } ++ ++ /* Find the DWORD length, padded by extra bytes as neccessary if MPS ++ * is not a multiple of DWORD */ ++ dword_count = (byte_count + 3) / 4; ++ ++#ifdef VERBOSE ++ dump_msg(ep->xfer_buff, byte_count); ++#endif ++ ++ /**@todo NGS Where are the Periodic Tx FIFO addresses ++ * intialized? What should this be? */ ++ ++ fifo = core_if->data_fifo[ep->num]; ++ ++ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n", ++ fifo, data_buff, *data_buff, byte_count); ++ ++ if (!dma) { ++ for (i = 0; i < dword_count; i++, data_buff++) { ++ DWC_WRITE_REG32(fifo, *data_buff); ++ } ++ } ++ ++ ep->xfer_count += byte_count; ++ ep->xfer_buff += byte_count; ++ ep->dma_addr += byte_count; ++} ++ ++/** ++ * Set the EP STALL. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to set the stall on. ++ */ ++void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ depctl_data_t depctl; ++ volatile uint32_t *depctl_addr; ++ ++ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num, ++ (ep->is_in ? "IN" : "OUT")); ++ ++ if (ep->is_in == 1) { ++ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl); ++ depctl.d32 = DWC_READ_REG32(depctl_addr); ++ ++ /* set the disable and stall bits */ ++ if (depctl.b.epena) { ++ depctl.b.epdis = 1; ++ } ++ depctl.b.stall = 1; ++ DWC_WRITE_REG32(depctl_addr, depctl.d32); ++ } else { ++ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl); ++ depctl.d32 = DWC_READ_REG32(depctl_addr); ++ ++ /* set the stall bit */ ++ depctl.b.stall = 1; ++ DWC_WRITE_REG32(depctl_addr, depctl.d32); ++ } ++ ++ DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr)); ++ ++ return; ++} ++ ++/** ++ * Clear the EP STALL. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to clear stall from. ++ */ ++void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ depctl_data_t depctl; ++ volatile uint32_t *depctl_addr; ++ ++ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num, ++ (ep->is_in ? "IN" : "OUT")); ++ ++ if (ep->is_in == 1) { ++ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl); ++ } else { ++ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl); ++ } ++ ++ depctl.d32 = DWC_READ_REG32(depctl_addr); ++ ++ /* clear the stall bits */ ++ depctl.b.stall = 0; ++ ++ /* ++ * USB Spec 9.4.5: For endpoints using data toggle, regardless ++ * of whether an endpoint has the Halt feature set, a ++ * ClearFeature(ENDPOINT_HALT) request always results in the ++ * data toggle being reinitialized to DATA0. ++ */ ++ if (ep->type == DWC_OTG_EP_TYPE_INTR || ++ ep->type == DWC_OTG_EP_TYPE_BULK) { ++ depctl.b.setd0pid = 1; /* DATA0 */ ++ } ++ ++ DWC_WRITE_REG32(depctl_addr, depctl.d32); ++ DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr)); ++ return; ++} ++ ++/** ++ * This function reads a packet from the Rx FIFO into the destination ++ * buffer. To read SETUP data use dwc_otg_read_setup_packet. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param dest Destination buffer for the packet. ++ * @param bytes Number of bytes to copy to the destination. ++ */ ++void dwc_otg_read_packet(dwc_otg_core_if_t * core_if, ++ uint8_t * dest, uint16_t bytes) ++{ ++ int i; ++ int word_count = (bytes + 3) / 4; ++ ++ volatile uint32_t *fifo = core_if->data_fifo[0]; ++ uint32_t *data_buff = (uint32_t *) dest; ++ ++ /** ++ * @todo Account for the case where _dest is not dword aligned. This ++ * requires reading data from the FIFO into a uint32_t temp buffer, ++ * then moving it into the data buffer. ++ */ ++ ++ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__, ++ core_if, dest, bytes); ++ ++ for (i = 0; i < word_count; i++, data_buff++) { ++ *data_buff = DWC_READ_REG32(fifo); ++ } ++ ++ return; ++} ++ ++/** ++ * This functions reads the device registers and prints them ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if) ++{ ++ int i; ++ volatile uint32_t *addr; ++ ++ DWC_PRINTF("Device Global Registers\n"); ++ addr = &core_if->dev_if->dev_global_regs->dcfg; ++ DWC_PRINTF("DCFG @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->dctl; ++ DWC_PRINTF("DCTL @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->dsts; ++ DWC_PRINTF("DSTS @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->diepmsk; ++ DWC_PRINTF("DIEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->doepmsk; ++ DWC_PRINTF("DOEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->daint; ++ DWC_PRINTF("DAINT @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->daintmsk; ++ DWC_PRINTF("DAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->dtknqr1; ++ DWC_PRINTF("DTKNQR1 @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ if (core_if->hwcfg2.b.dev_token_q_depth > 6) { ++ addr = &core_if->dev_if->dev_global_regs->dtknqr2; ++ DWC_PRINTF("DTKNQR2 @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ } ++ ++ addr = &core_if->dev_if->dev_global_regs->dvbusdis; ++ DWC_PRINTF("DVBUSID @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ ++ addr = &core_if->dev_if->dev_global_regs->dvbuspulse; ++ DWC_PRINTF("DVBUSPULSE @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ ++ addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl; ++ DWC_PRINTF("DTKNQR3_DTHRCTL @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ ++ if (core_if->hwcfg2.b.dev_token_q_depth > 22) { ++ addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk; ++ DWC_PRINTF("DTKNQR4 @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ } ++ ++ addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk; ++ DWC_PRINTF("FIFOEMPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ ++ if (core_if->hwcfg2.b.multi_proc_int) { ++ ++ addr = &core_if->dev_if->dev_global_regs->deachint; ++ DWC_PRINTF("DEACHINT @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->dev_global_regs->deachintmsk; ++ DWC_PRINTF("DEACHINTMSK @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ ++ for (i = 0; i <= core_if->dev_if->num_in_eps; i++) { ++ addr = ++ &core_if->dev_if-> ++ dev_global_regs->diepeachintmsk[i]; ++ DWC_PRINTF("DIEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n", ++ i, (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ } ++ ++ for (i = 0; i <= core_if->dev_if->num_out_eps; i++) { ++ addr = ++ &core_if->dev_if-> ++ dev_global_regs->doepeachintmsk[i]; ++ DWC_PRINTF("DOEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n", ++ i, (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ } ++ } ++ ++ for (i = 0; i <= core_if->dev_if->num_in_eps; i++) { ++ DWC_PRINTF("Device IN EP %d Registers\n", i); ++ addr = &core_if->dev_if->in_ep_regs[i]->diepctl; ++ DWC_PRINTF("DIEPCTL @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->in_ep_regs[i]->diepint; ++ DWC_PRINTF("DIEPINT @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz; ++ DWC_PRINTF("DIETSIZ @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->in_ep_regs[i]->diepdma; ++ DWC_PRINTF("DIEPDMA @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts; ++ DWC_PRINTF("DTXFSTS @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->in_ep_regs[i]->diepdmab; ++ DWC_PRINTF("DIEPDMAB @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, 0 /*DWC_READ_REG32(addr) */ ); ++ } ++ ++ for (i = 0; i <= core_if->dev_if->num_out_eps; i++) { ++ DWC_PRINTF("Device OUT EP %d Registers\n", i); ++ addr = &core_if->dev_if->out_ep_regs[i]->doepctl; ++ DWC_PRINTF("DOEPCTL @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->out_ep_regs[i]->doepint; ++ DWC_PRINTF("DOEPINT @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz; ++ DWC_PRINTF("DOETSIZ @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->dev_if->out_ep_regs[i]->doepdma; ++ DWC_PRINTF("DOEPDMA @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ if (core_if->dma_enable) { /* Don't access this register in SLAVE mode */ ++ addr = &core_if->dev_if->out_ep_regs[i]->doepdmab; ++ DWC_PRINTF("DOEPDMAB @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ } ++ ++ } ++} ++ ++/** ++ * This functions reads the SPRAM and prints its content ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if) ++{ ++ volatile uint8_t *addr, *start_addr, *end_addr; ++ ++ DWC_PRINTF("SPRAM Data:\n"); ++ start_addr = (void *)core_if->core_global_regs; ++ DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr); ++ start_addr += 0x00028000; ++ end_addr = (void *)core_if->core_global_regs; ++ end_addr += 0x000280e0; ++ ++ for (addr = start_addr; addr < end_addr; addr += 16) { ++ DWC_PRINTF ++ ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n", ++ (unsigned long)addr, addr[0], addr[1], addr[2], addr[3], ++ addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], ++ addr[10], addr[11], addr[12], addr[13], addr[14], addr[15] ++ ); ++ } ++ ++ return; ++} ++ ++/** ++ * This function reads the host registers and prints them ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if) ++{ ++ int i; ++ volatile uint32_t *addr; ++ ++ DWC_PRINTF("Host Global Registers\n"); ++ addr = &core_if->host_if->host_global_regs->hcfg; ++ DWC_PRINTF("HCFG @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->host_global_regs->hfir; ++ DWC_PRINTF("HFIR @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->host_global_regs->hfnum; ++ DWC_PRINTF("HFNUM @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->host_global_regs->hptxsts; ++ DWC_PRINTF("HPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->host_global_regs->haint; ++ DWC_PRINTF("HAINT @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->host_global_regs->haintmsk; ++ DWC_PRINTF("HAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ if (core_if->dma_desc_enable) { ++ addr = &core_if->host_if->host_global_regs->hflbaddr; ++ DWC_PRINTF("HFLBADDR @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ } ++ ++ addr = core_if->host_if->hprt0; ++ DWC_PRINTF("HPRT0 @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ ++ for (i = 0; i < core_if->core_params->host_channels; i++) { ++ DWC_PRINTF("Host Channel %d Specific Registers\n", i); ++ addr = &core_if->host_if->hc_regs[i]->hcchar; ++ DWC_PRINTF("HCCHAR @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->hc_regs[i]->hcsplt; ++ DWC_PRINTF("HCSPLT @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->hc_regs[i]->hcint; ++ DWC_PRINTF("HCINT @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->hc_regs[i]->hcintmsk; ++ DWC_PRINTF("HCINTMSK @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->hc_regs[i]->hctsiz; ++ DWC_PRINTF("HCTSIZ @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->host_if->hc_regs[i]->hcdma; ++ DWC_PRINTF("HCDMA @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ if (core_if->dma_desc_enable) { ++ addr = &core_if->host_if->hc_regs[i]->hcdmab; ++ DWC_PRINTF("HCDMAB @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ } ++ ++ } ++ return; ++} ++ ++/** ++ * This function reads the core global registers and prints them ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if) ++{ ++ int i, ep_num; ++ volatile uint32_t *addr; ++ char *txfsiz; ++ ++ DWC_PRINTF("Core Global Registers\n"); ++ addr = &core_if->core_global_regs->gotgctl; ++ DWC_PRINTF("GOTGCTL @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gotgint; ++ DWC_PRINTF("GOTGINT @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gahbcfg; ++ DWC_PRINTF("GAHBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gusbcfg; ++ DWC_PRINTF("GUSBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->grstctl; ++ DWC_PRINTF("GRSTCTL @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gintsts; ++ DWC_PRINTF("GINTSTS @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gintmsk; ++ DWC_PRINTF("GINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->grxstsr; ++ DWC_PRINTF("GRXSTSR @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->grxfsiz; ++ DWC_PRINTF("GRXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gnptxfsiz; ++ DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gnptxsts; ++ DWC_PRINTF("GNPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gi2cctl; ++ DWC_PRINTF("GI2CCTL @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gpvndctl; ++ DWC_PRINTF("GPVNDCTL @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->ggpio; ++ DWC_PRINTF("GGPIO @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->guid; ++ DWC_PRINTF("GUID @0x%08lX : 0x%08X\n", ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gsnpsid; ++ DWC_PRINTF("GSNPSID @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->ghwcfg1; ++ DWC_PRINTF("GHWCFG1 @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->ghwcfg2; ++ DWC_PRINTF("GHWCFG2 @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->ghwcfg3; ++ DWC_PRINTF("GHWCFG3 @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->ghwcfg4; ++ DWC_PRINTF("GHWCFG4 @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->glpmcfg; ++ DWC_PRINTF("GLPMCFG @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gpwrdn; ++ DWC_PRINTF("GPWRDN @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->gdfifocfg; ++ DWC_PRINTF("GDFIFOCFG @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ addr = &core_if->core_global_regs->adpctl; ++ DWC_PRINTF("ADPCTL @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ dwc_otg_adp_read_reg(core_if)); ++ addr = &core_if->core_global_regs->hptxfsiz; ++ DWC_PRINTF("HPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++ ++ if (core_if->en_multiple_tx_fifo == 0) { ++ ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep; ++ txfsiz = "DPTXFSIZ"; ++ } else { ++ ep_num = core_if->hwcfg4.b.num_in_eps; ++ txfsiz = "DIENPTXF"; ++ } ++ for (i = 0; i < ep_num; i++) { ++ addr = &core_if->core_global_regs->dtxfsiz[i]; ++ DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1, ++ (unsigned long)addr, DWC_READ_REG32(addr)); ++ } ++ addr = core_if->pcgcctl; ++ DWC_PRINTF("PCGCCTL @0x%08lX : 0x%08X\n", (unsigned long)addr, ++ DWC_READ_REG32(addr)); ++} ++ ++/** ++ * Flush a Tx FIFO. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param num Tx FIFO to flush. ++ */ ++void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ volatile grstctl_t greset = {.d32 = 0 }; ++ int count = 0; ++ ++ DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num); ++ ++ greset.b.txfflsh = 1; ++ greset.b.txfnum = num; ++ DWC_WRITE_REG32(&global_regs->grstctl, greset.d32); ++ ++ do { ++ greset.d32 = DWC_READ_REG32(&global_regs->grstctl); ++ if (++count > 10000) { ++ DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n", ++ __func__, greset.d32, ++ DWC_READ_REG32(&global_regs->gnptxsts)); ++ break; ++ } ++ dwc_udelay(1); ++ } while (greset.b.txfflsh == 1); ++ ++ /* Wait for 3 PHY Clocks */ ++ dwc_udelay(1); ++} ++ ++/** ++ * Flush Rx FIFO. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ volatile grstctl_t greset = {.d32 = 0 }; ++ int count = 0; ++ ++ DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__); ++ /* ++ * ++ */ ++ greset.b.rxfflsh = 1; ++ DWC_WRITE_REG32(&global_regs->grstctl, greset.d32); ++ ++ do { ++ greset.d32 = DWC_READ_REG32(&global_regs->grstctl); ++ if (++count > 10000) { ++ DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, ++ greset.d32); ++ break; ++ } ++ dwc_udelay(1); ++ } while (greset.b.rxfflsh == 1); ++ ++ /* Wait for 3 PHY Clocks */ ++ dwc_udelay(1); ++} ++ ++/** ++ * Do core a soft reset of the core. Be careful with this because it ++ * resets all the internal state machines of the core. ++ */ ++void dwc_otg_core_reset(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ volatile grstctl_t greset = {.d32 = 0 }; ++ int count = 0; ++ ++ DWC_DEBUGPL(DBG_CILV, "%s\n", __func__); ++ /* Wait for AHB master IDLE state. */ ++ do { ++ dwc_udelay(10); ++ greset.d32 = DWC_READ_REG32(&global_regs->grstctl); ++ if (++count > 100000) { ++ DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__, ++ greset.d32); ++ return; ++ } ++ } ++ while (greset.b.ahbidle == 0); ++ ++ /* Core Soft Reset */ ++ count = 0; ++ greset.b.csftrst = 1; ++ DWC_WRITE_REG32(&global_regs->grstctl, greset.d32); ++ do { ++ greset.d32 = DWC_READ_REG32(&global_regs->grstctl); ++ if (++count > 10000) { ++ DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", ++ __func__, greset.d32); ++ break; ++ } ++ dwc_udelay(1); ++ } ++ while (greset.b.csftrst == 1); ++ ++ /* Wait for 3 PHY Clocks */ ++ dwc_mdelay(100); ++} ++ ++uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if) ++{ ++ return (dwc_otg_mode(_core_if) != DWC_HOST_MODE); ++} ++ ++uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if) ++{ ++ return (dwc_otg_mode(_core_if) == DWC_HOST_MODE); ++} ++ ++/** ++ * Register HCD callbacks. The callbacks are used to start and stop ++ * the HCD for interrupt processing. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param cb the HCD callback structure. ++ * @param p pointer to be passed to callback function (usb_hcd*). ++ */ ++void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if, ++ dwc_otg_cil_callbacks_t * cb, void *p) ++{ ++ core_if->hcd_cb = cb; ++ cb->p = p; ++} ++ ++/** ++ * Register PCD callbacks. The callbacks are used to start and stop ++ * the PCD for interrupt processing. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param cb the PCD callback structure. ++ * @param p pointer to be passed to callback function (pcd*). ++ */ ++void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if, ++ dwc_otg_cil_callbacks_t * cb, void *p) ++{ ++ core_if->pcd_cb = cb; ++ cb->p = p; ++} ++ ++#ifdef DWC_EN_ISOC ++ ++/** ++ * This function writes isoc data per 1 (micro)frame into tx fifo ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ * ++ */ ++void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ dwc_otg_dev_in_ep_regs_t *ep_regs; ++ dtxfsts_data_t txstatus = {.d32 = 0 }; ++ uint32_t len = 0; ++ uint32_t dwords; ++ ++ ep->xfer_len = ep->data_per_frame; ++ ep->xfer_count = 0; ++ ++ ep_regs = core_if->dev_if->in_ep_regs[ep->num]; ++ ++ len = ep->xfer_len - ep->xfer_count; ++ ++ if (len > ep->maxpacket) { ++ len = ep->maxpacket; ++ } ++ ++ dwords = (len + 3) / 4; ++ ++ /* While there is space in the queue and space in the FIFO and ++ * More data to tranfer, Write packets to the Tx FIFO */ ++ txstatus.d32 = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts); ++ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32); ++ ++ while (txstatus.b.txfspcavail > dwords && ++ ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) { ++ /* Write the FIFO */ ++ dwc_otg_ep_write_packet(core_if, ep, 0); ++ ++ len = ep->xfer_len - ep->xfer_count; ++ if (len > ep->maxpacket) { ++ len = ep->maxpacket; ++ } ++ ++ dwords = (len + 3) / 4; ++ txstatus.d32 = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]-> ++ dtxfsts); ++ DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num, ++ txstatus.d32); ++ } ++} ++ ++/** ++ * This function initializes a descriptor chain for Isochronous transfer ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ * ++ */ ++void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * ep) ++{ ++ deptsiz_data_t deptsiz = {.d32 = 0 }; ++ depctl_data_t depctl = {.d32 = 0 }; ++ dsts_data_t dsts = {.d32 = 0 }; ++ volatile uint32_t *addr; ++ ++ if (ep->is_in) { ++ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl; ++ } else { ++ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl; ++ } ++ ++ ep->xfer_len = ep->data_per_frame; ++ ep->xfer_count = 0; ++ ep->xfer_buff = ep->cur_pkt_addr; ++ ep->dma_addr = ep->cur_pkt_dma_addr; ++ ++ if (ep->is_in) { ++ /* Program the transfer size and packet count ++ * as follows: xfersize = N * maxpacket + ++ * short_packet pktcnt = N + (short_packet ++ * exist ? 1 : 0) ++ */ ++ deptsiz.b.xfersize = ep->xfer_len; ++ deptsiz.b.pktcnt = ++ (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; ++ deptsiz.b.mc = deptsiz.b.pktcnt; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz, ++ deptsiz.d32); ++ ++ /* Write the DMA register */ ++ if (core_if->dma_enable) { ++ DWC_WRITE_REG32(& ++ (core_if->dev_if->in_ep_regs[ep->num]-> ++ diepdma), (uint32_t) ep->dma_addr); ++ } ++ } else { ++ deptsiz.b.pktcnt = ++ (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket; ++ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; ++ ++ DWC_WRITE_REG32(&core_if->dev_if-> ++ out_ep_regs[ep->num]->doeptsiz, deptsiz.d32); ++ ++ if (core_if->dma_enable) { ++ DWC_WRITE_REG32(& ++ (core_if->dev_if-> ++ out_ep_regs[ep->num]->doepdma), ++ (uint32_t) ep->dma_addr); ++ } ++ } ++ ++ /** Enable endpoint, clear nak */ ++ ++ depctl.d32 = 0; ++ if (ep->bInterval == 1) { ++ dsts.d32 = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ ep->next_frame = dsts.b.soffn + ep->bInterval; ++ ++ if (ep->next_frame & 0x1) { ++ depctl.b.setd1pid = 1; ++ } else { ++ depctl.b.setd0pid = 1; ++ } ++ } else { ++ ep->next_frame += ep->bInterval; ++ ++ if (ep->next_frame & 0x1) { ++ depctl.b.setd1pid = 1; ++ } else { ++ depctl.b.setd0pid = 1; ++ } ++ } ++ depctl.b.epena = 1; ++ depctl.b.cnak = 1; ++ ++ DWC_MODIFY_REG32(addr, 0, depctl.d32); ++ depctl.d32 = DWC_READ_REG32(addr); ++ ++ if (ep->is_in && core_if->dma_enable == 0) { ++ write_isoc_frame_data(core_if, ep); ++ } ++ ++} ++#endif /* DWC_EN_ISOC */ ++ ++static void dwc_otg_set_uninitialized(int32_t * p, int size) ++{ ++ int i; ++ for (i = 0; i < size; i++) { ++ p[i] = -1; ++ } ++} ++ ++static int dwc_otg_param_initialized(int32_t val) ++{ ++ return val != -1; ++} ++ ++static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if) ++{ ++ int i; ++ core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params)); ++ if (!core_if->core_params) { ++ return -DWC_E_NO_MEMORY; ++ } ++ dwc_otg_set_uninitialized((int32_t *) core_if->core_params, ++ sizeof(*core_if->core_params) / ++ sizeof(int32_t)); ++ DWC_PRINTF("Setting default values for core params\n"); ++ dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default); ++ dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default); ++ dwc_otg_set_param_dma_desc_enable(core_if, ++ dwc_param_dma_desc_enable_default); ++ dwc_otg_set_param_opt(core_if, dwc_param_opt_default); ++ dwc_otg_set_param_dma_burst_size(core_if, ++ dwc_param_dma_burst_size_default); ++ dwc_otg_set_param_host_support_fs_ls_low_power(core_if, ++ dwc_param_host_support_fs_ls_low_power_default); ++ dwc_otg_set_param_enable_dynamic_fifo(core_if, ++ dwc_param_enable_dynamic_fifo_default); ++ dwc_otg_set_param_data_fifo_size(core_if, ++ dwc_param_data_fifo_size_default); ++ dwc_otg_set_param_dev_rx_fifo_size(core_if, ++ dwc_param_dev_rx_fifo_size_default); ++ dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if, ++ dwc_param_dev_nperio_tx_fifo_size_default); ++ dwc_otg_set_param_host_rx_fifo_size(core_if, ++ dwc_param_host_rx_fifo_size_default); ++ dwc_otg_set_param_host_nperio_tx_fifo_size(core_if, ++ dwc_param_host_nperio_tx_fifo_size_default); ++ dwc_otg_set_param_host_perio_tx_fifo_size(core_if, ++ dwc_param_host_perio_tx_fifo_size_default); ++ dwc_otg_set_param_max_transfer_size(core_if, ++ dwc_param_max_transfer_size_default); ++ dwc_otg_set_param_max_packet_count(core_if, ++ dwc_param_max_packet_count_default); ++ dwc_otg_set_param_host_channels(core_if, ++ dwc_param_host_channels_default); ++ dwc_otg_set_param_dev_endpoints(core_if, ++ dwc_param_dev_endpoints_default); ++ dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default); ++ dwc_otg_set_param_speed(core_if, dwc_param_speed_default); ++ dwc_otg_set_param_host_ls_low_power_phy_clk(core_if, ++ dwc_param_host_ls_low_power_phy_clk_default); ++ dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default); ++ dwc_otg_set_param_phy_ulpi_ext_vbus(core_if, ++ dwc_param_phy_ulpi_ext_vbus_default); ++ dwc_otg_set_param_phy_utmi_width(core_if, ++ dwc_param_phy_utmi_width_default); ++ dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default); ++ dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default); ++ dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default); ++ dwc_otg_set_param_en_multiple_tx_fifo(core_if, ++ dwc_param_en_multiple_tx_fifo_default); ++ for (i = 0; i < 15; i++) { ++ dwc_otg_set_param_dev_perio_tx_fifo_size(core_if, ++ dwc_param_dev_perio_tx_fifo_size_default, ++ i); ++ } ++ ++ for (i = 0; i < 15; i++) { ++ dwc_otg_set_param_dev_tx_fifo_size(core_if, ++ dwc_param_dev_tx_fifo_size_default, ++ i); ++ } ++ dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default); ++ dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default); ++ dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default); ++ dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default); ++ dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default); ++ dwc_otg_set_param_tx_thr_length(core_if, ++ dwc_param_tx_thr_length_default); ++ dwc_otg_set_param_rx_thr_length(core_if, ++ dwc_param_rx_thr_length_default); ++ dwc_otg_set_param_ahb_thr_ratio(core_if, ++ dwc_param_ahb_thr_ratio_default); ++ dwc_otg_set_param_power_down(core_if, dwc_param_power_down_default); ++ dwc_otg_set_param_reload_ctl(core_if, dwc_param_reload_ctl_default); ++ dwc_otg_set_param_dev_out_nak(core_if, dwc_param_dev_out_nak_default); ++ dwc_otg_set_param_cont_on_bna(core_if, dwc_param_cont_on_bna_default); ++ dwc_otg_set_param_ahb_single(core_if, dwc_param_ahb_single_default); ++ dwc_otg_set_param_otg_ver(core_if, dwc_param_otg_ver_default); ++ dwc_otg_set_param_adp_enable(core_if, dwc_param_adp_enable_default); ++ DWC_PRINTF("Finished setting default values for core params\n"); ++ ++ return 0; ++} ++ ++uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->dma_enable; ++} ++ ++/* Checks if the parameter is outside of its valid range of values */ ++#define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \ ++ (((_param_) < (_low_)) || \ ++ ((_param_) > (_high_))) ++ ++/* Parameter access functions */ ++int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int valid; ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 2)) { ++ DWC_WARN("Wrong value for otg_cap parameter\n"); ++ DWC_WARN("otg_cap parameter must be 0,1 or 2\n"); ++ retval = -DWC_E_INVALID; ++ goto out; ++ } ++ ++ valid = 1; ++ switch (val) { ++ case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE: ++ if (core_if->hwcfg2.b.op_mode != ++ DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ++ valid = 0; ++ break; ++ case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE: ++ if ((core_if->hwcfg2.b.op_mode != ++ DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ++ && (core_if->hwcfg2.b.op_mode != ++ DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) ++ && (core_if->hwcfg2.b.op_mode != ++ DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ++ && (core_if->hwcfg2.b.op_mode != ++ DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) { ++ valid = 0; ++ } ++ break; ++ case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE: ++ /* always valid */ ++ break; ++ } ++ if (!valid) { ++ if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) { ++ DWC_ERROR ++ ("%d invalid for otg_cap paremter. Check HW configuration.\n", ++ val); ++ } ++ val = ++ (((core_if->hwcfg2.b.op_mode == ++ DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ++ || (core_if->hwcfg2.b.op_mode == ++ DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) ++ || (core_if->hwcfg2.b.op_mode == ++ DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ++ || (core_if->hwcfg2.b.op_mode == ++ DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ? ++ DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE : ++ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->otg_cap = val; ++out: ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->otg_cap; ++} ++ ++int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for opt parameter\n"); ++ return -DWC_E_INVALID; ++ } ++ core_if->core_params->opt = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->opt; ++} ++ ++int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for dma enable\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) { ++ if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) { ++ DWC_ERROR ++ ("%d invalid for dma_enable paremter. Check HW configuration.\n", ++ val); ++ } ++ val = 0; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->dma_enable = val; ++ if (val == 0) { ++ dwc_otg_set_param_dma_desc_enable(core_if, 0); ++ } ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->dma_enable; ++} ++ ++int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for dma_enable\n"); ++ DWC_WARN("dma_desc_enable must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 1) ++ && ((dwc_otg_get_param_dma_enable(core_if) == 0) ++ || (core_if->hwcfg4.b.desc_dma == 0))) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->dma_desc_enable)) { ++ DWC_ERROR ++ ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n", ++ val); ++ } ++ val = 0; ++ retval = -DWC_E_INVALID; ++ } ++ core_if->core_params->dma_desc_enable = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->dma_desc_enable; ++} ++ ++int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for host_support_fs_low_power\n"); ++ DWC_WARN("host_support_fs_low_power must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ core_if->core_params->host_support_fs_ls_low_power = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * ++ core_if) ++{ ++ return core_if->core_params->host_support_fs_ls_low_power; ++} ++ ++int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for enable_dynamic_fifo\n"); ++ DWC_WARN("enable_dynamic_fifo must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->enable_dynamic_fifo)) { ++ DWC_ERROR ++ ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n", ++ val); ++ } ++ val = 0; ++ retval = -DWC_E_INVALID; ++ } ++ core_if->core_params->enable_dynamic_fifo = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->enable_dynamic_fifo; ++} ++ ++int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 32, 32768)) { ++ DWC_WARN("Wrong value for data_fifo_size\n"); ++ DWC_WARN("data_fifo_size must be 32-32768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > core_if->hwcfg3.b.dfifo_depth) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->data_fifo_size)) { ++ DWC_ERROR ++ ("%d invalid for data_fifo_size parameter. Check HW configuration.\n", ++ val); ++ } ++ val = core_if->hwcfg3.b.dfifo_depth; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->data_fifo_size = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->data_fifo_size; ++} ++ ++int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 16, 32768)) { ++ DWC_WARN("Wrong value for dev_rx_fifo_size\n"); ++ DWC_WARN("dev_rx_fifo_size must be 16-32768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) { ++ if (dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) { ++ DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val); ++ } ++ val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->dev_rx_fifo_size = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->dev_rx_fifo_size; ++} ++ ++int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 16, 32768)) { ++ DWC_WARN("Wrong value for dev_nperio_tx_fifo\n"); ++ DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->dev_nperio_tx_fifo_size)) { ++ DWC_ERROR ++ ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n", ++ val); ++ } ++ val = ++ (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> ++ 16); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->dev_nperio_tx_fifo_size = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->dev_nperio_tx_fifo_size; ++} ++ ++int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 16, 32768)) { ++ DWC_WARN("Wrong value for host_rx_fifo_size\n"); ++ DWC_WARN("host_rx_fifo_size must be 16-32768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->host_rx_fifo_size)) { ++ DWC_ERROR ++ ("%d invalid for host_rx_fifo_size. Check HW configuration.\n", ++ val); ++ } ++ val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->host_rx_fifo_size = val; ++ return retval; ++ ++} ++ ++int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->host_rx_fifo_size; ++} ++ ++int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 16, 32768)) { ++ DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n"); ++ DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->host_nperio_tx_fifo_size)) { ++ DWC_ERROR ++ ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n", ++ val); ++ } ++ val = ++ (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> ++ 16); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->host_nperio_tx_fifo_size = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->host_nperio_tx_fifo_size; ++} ++ ++int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 16, 32768)) { ++ DWC_WARN("Wrong value for host_perio_tx_fifo_size\n"); ++ DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > ((core_if->hptxfsiz.d32) >> 16)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->host_perio_tx_fifo_size)) { ++ DWC_ERROR ++ ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n", ++ val); ++ } ++ val = (core_if->hptxfsiz.d32) >> 16; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->host_perio_tx_fifo_size = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->host_perio_tx_fifo_size; ++} ++ ++int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) { ++ DWC_WARN("Wrong value for max_transfer_size\n"); ++ DWC_WARN("max_transfer_size must be 2047-524288\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->max_transfer_size)) { ++ DWC_ERROR ++ ("%d invalid for max_transfer_size. Check HW configuration.\n", ++ val); ++ } ++ val = ++ ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) - ++ 1); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->max_transfer_size = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->max_transfer_size; ++} ++ ++int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 15, 511)) { ++ DWC_WARN("Wrong value for max_packet_count\n"); ++ DWC_WARN("max_packet_count must be 15-511\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->max_packet_count)) { ++ DWC_ERROR ++ ("%d invalid for max_packet_count. Check HW configuration.\n", ++ val); ++ } ++ val = ++ ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->max_packet_count = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->max_packet_count; ++} ++ ++int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 1, 16)) { ++ DWC_WARN("Wrong value for host_channels\n"); ++ DWC_WARN("host_channels must be 1-16\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > (core_if->hwcfg2.b.num_host_chan + 1)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->host_channels)) { ++ DWC_ERROR ++ ("%d invalid for host_channels. Check HW configurations.\n", ++ val); ++ } ++ val = (core_if->hwcfg2.b.num_host_chan + 1); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->host_channels = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->host_channels; ++} ++ ++int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 1, 15)) { ++ DWC_WARN("Wrong value for dev_endpoints\n"); ++ DWC_WARN("dev_endpoints must be 1-15\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > (core_if->hwcfg2.b.num_dev_ep)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->dev_endpoints)) { ++ DWC_ERROR ++ ("%d invalid for dev_endpoints. Check HW configurations.\n", ++ val); ++ } ++ val = core_if->hwcfg2.b.num_dev_ep; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->dev_endpoints = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->dev_endpoints; ++} ++ ++int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ int valid = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 2)) { ++ DWC_WARN("Wrong value for phy_type\n"); ++ DWC_WARN("phy_type must be 0,1 or 2\n"); ++ return -DWC_E_INVALID; ++ } ++#ifndef NO_FS_PHY_HW_CHECKS ++ if ((val == DWC_PHY_TYPE_PARAM_UTMI) && ++ ((core_if->hwcfg2.b.hs_phy_type == 1) || ++ (core_if->hwcfg2.b.hs_phy_type == 3))) { ++ valid = 1; ++ } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) && ++ ((core_if->hwcfg2.b.hs_phy_type == 2) || ++ (core_if->hwcfg2.b.hs_phy_type == 3))) { ++ valid = 1; ++ } else if ((val == DWC_PHY_TYPE_PARAM_FS) && ++ (core_if->hwcfg2.b.fs_phy_type == 1)) { ++ valid = 1; ++ } ++ if (!valid) { ++ if (dwc_otg_param_initialized(core_if->core_params->phy_type)) { ++ DWC_ERROR ++ ("%d invalid for phy_type. Check HW configurations.\n", ++ val); ++ } ++ if (core_if->hwcfg2.b.hs_phy_type) { ++ if ((core_if->hwcfg2.b.hs_phy_type == 3) || ++ (core_if->hwcfg2.b.hs_phy_type == 1)) { ++ val = DWC_PHY_TYPE_PARAM_UTMI; ++ } else { ++ val = DWC_PHY_TYPE_PARAM_ULPI; ++ } ++ } ++ retval = -DWC_E_INVALID; ++ } ++#endif ++ core_if->core_params->phy_type = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->phy_type; ++} ++ ++int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for speed parameter\n"); ++ DWC_WARN("max_speed parameter must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ if ((val == 0) ++ && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) { ++ if (dwc_otg_param_initialized(core_if->core_params->speed)) { ++ DWC_ERROR ++ ("%d invalid for speed paremter. Check HW configuration.\n", ++ val); ++ } ++ val = ++ (dwc_otg_get_param_phy_type(core_if) == ++ DWC_PHY_TYPE_PARAM_FS ? 1 : 0); ++ retval = -DWC_E_INVALID; ++ } ++ core_if->core_params->speed = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->speed; ++} ++ ++int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN ++ ("Wrong value for host_ls_low_power_phy_clk parameter\n"); ++ DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ) ++ && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->host_ls_low_power_phy_clk)) { ++ DWC_ERROR ++ ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n", ++ val); ++ } ++ val = ++ (dwc_otg_get_param_phy_type(core_if) == ++ DWC_PHY_TYPE_PARAM_FS) ? ++ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : ++ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->host_ls_low_power_phy_clk = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->host_ls_low_power_phy_clk; ++} ++ ++int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for phy_ulpi_ddr\n"); ++ DWC_WARN("phy_upli_ddr must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->phy_ulpi_ddr = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->phy_ulpi_ddr; ++} ++ ++int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n"); ++ DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->phy_ulpi_ext_vbus = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->phy_ulpi_ext_vbus; ++} ++ ++int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) { ++ DWC_WARN("Wrong valaue for phy_utmi_width\n"); ++ DWC_WARN("phy_utmi_width must be 8 or 16\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->phy_utmi_width = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->phy_utmi_width; ++} ++ ++int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong valaue for ulpi_fs_ls\n"); ++ DWC_WARN("ulpi_fs_ls must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->ulpi_fs_ls = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->ulpi_fs_ls; ++} ++ ++int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong valaue for ts_dline\n"); ++ DWC_WARN("ts_dline must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->ts_dline = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->ts_dline; ++} ++ ++int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong valaue for i2c_enable\n"); ++ DWC_WARN("i2c_enable must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++#ifndef NO_FS_PHY_HW_CHECK ++ if (val == 1 && core_if->hwcfg3.b.i2c == 0) { ++ if (dwc_otg_param_initialized(core_if->core_params->i2c_enable)) { ++ DWC_ERROR ++ ("%d invalid for i2c_enable. Check HW configuration.\n", ++ val); ++ } ++ val = 0; ++ retval = -DWC_E_INVALID; ++ } ++#endif ++ ++ core_if->core_params->i2c_enable = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->i2c_enable; ++} ++ ++int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val, int fifo_num) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 4, 768)) { ++ DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n"); ++ DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > ++ (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) { ++ DWC_ERROR ++ ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", ++ val, fifo_num); ++ } ++ val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num])); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int fifo_num) ++{ ++ return core_if->core_params->dev_perio_tx_fifo_size[fifo_num]; ++} ++ ++int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if, ++ int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n"); ++ DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->en_multiple_tx_fifo)) { ++ DWC_ERROR ++ ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n", ++ val); ++ } ++ val = 0; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->en_multiple_tx_fifo = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->en_multiple_tx_fifo; ++} ++ ++int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val, ++ int fifo_num) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 4, 768)) { ++ DWC_WARN("Wrong value for dev_tx_fifo_size\n"); ++ DWC_WARN("dev_tx_fifo_size must be 4-768\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val > ++ (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->dev_tx_fifo_size[fifo_num])) { ++ DWC_ERROR ++ ("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n", ++ val, fifo_num); ++ } ++ val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num])); ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->dev_tx_fifo_size[fifo_num] = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int fifo_num) ++{ ++ return core_if->core_params->dev_tx_fifo_size[fifo_num]; ++} ++ ++int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 7)) { ++ DWC_WARN("Wrong value for thr_ctl\n"); ++ DWC_WARN("thr_ctl must be 0-7\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val != 0) && ++ (!dwc_otg_get_param_dma_enable(core_if) || ++ !core_if->hwcfg4.b.ded_fifo_en)) { ++ if (dwc_otg_param_initialized(core_if->core_params->thr_ctl)) { ++ DWC_ERROR ++ ("%d invalid for parameter thr_ctl. Check HW configuration.\n", ++ val); ++ } ++ val = 0; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->thr_ctl = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->thr_ctl; ++} ++ ++int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("Wrong value for lpm_enable\n"); ++ DWC_WARN("lpm_enable must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val && !core_if->hwcfg3.b.otg_lpm_en) { ++ if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) { ++ DWC_ERROR ++ ("%d invalid for parameter lpm_enable. Check HW configuration.\n", ++ val); ++ } ++ val = 0; ++ retval = -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->lpm_enable = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->lpm_enable; ++} ++ ++int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 8, 128)) { ++ DWC_WARN("Wrong valaue for tx_thr_length\n"); ++ DWC_WARN("tx_thr_length must be 8 - 128\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->tx_thr_length = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->tx_thr_length; ++} ++ ++int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 8, 128)) { ++ DWC_WARN("Wrong valaue for rx_thr_length\n"); ++ DWC_WARN("rx_thr_length must be 8 - 128\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->rx_thr_length = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->rx_thr_length; ++} ++ ++int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ if (DWC_OTG_PARAM_TEST(val, 1, 1) && ++ DWC_OTG_PARAM_TEST(val, 4, 4) && ++ DWC_OTG_PARAM_TEST(val, 8, 8) && ++ DWC_OTG_PARAM_TEST(val, 16, 16) && ++ DWC_OTG_PARAM_TEST(val, 32, 32) && ++ DWC_OTG_PARAM_TEST(val, 64, 64) && ++ DWC_OTG_PARAM_TEST(val, 128, 128) && ++ DWC_OTG_PARAM_TEST(val, 256, 256)) { ++ DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val); ++ return -DWC_E_INVALID; ++ } ++ core_if->core_params->dma_burst_size = val; ++ return 0; ++} ++ ++int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->dma_burst_size; ++} ++ ++int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val); ++ return -DWC_E_INVALID; ++ } ++ if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) { ++ if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) { ++ DWC_ERROR ++ ("%d invalid for parameter pti_enable. Check HW configuration.\n", ++ val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->pti_enable = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->pti_enable; ++} ++ ++int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val); ++ return -DWC_E_INVALID; ++ } ++ if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) { ++ if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) { ++ DWC_ERROR ++ ("%d invalid for parameter mpi_enable. Check HW configuration.\n", ++ val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->mpi_enable = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->mpi_enable; ++} ++ ++int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val); ++ return -DWC_E_INVALID; ++ } ++ if (val && (core_if->hwcfg3.b.adp_supp == 0)) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->adp_supp_enable)) { ++ DWC_ERROR ++ ("%d invalid for parameter adp_enable. Check HW configuration.\n", ++ val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->adp_supp_enable = val; ++ /*Set OTG version 2.0 in case of enabling ADP*/ ++ if (val) ++ dwc_otg_set_param_otg_ver(core_if, 1); ++ ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->adp_supp_enable; ++} ++ ++int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val); ++ DWC_WARN("ic_usb_cap must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val && (core_if->hwcfg2.b.otg_enable_ic_usb == 0)) { ++ if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) { ++ DWC_ERROR ++ ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n", ++ val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->ic_usb_cap = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->ic_usb_cap; ++} ++ ++int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ int valid = 1; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 3)) { ++ DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val); ++ DWC_WARN("ahb_thr_ratio must be 0 - 3\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (val ++ && (core_if->snpsid < OTG_CORE_REV_2_81a ++ || !dwc_otg_get_param_thr_ctl(core_if))) { ++ valid = 0; ++ } else if (val ++ && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) < ++ 4)) { ++ valid = 0; ++ } ++ if (valid == 0) { ++ if (dwc_otg_param_initialized ++ (core_if->core_params->ahb_thr_ratio)) { ++ DWC_ERROR ++ ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n", ++ val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ ++ core_if->core_params->ahb_thr_ratio = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->ahb_thr_ratio; ++} ++ ++int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ int valid = 1; ++ hwcfg4_data_t hwcfg4 = {.d32 = 0 }; ++ hwcfg4.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4); ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 3)) { ++ DWC_WARN("`%d' invalid for parameter `power_down'\n", val); ++ DWC_WARN("power_down must be 0 - 2\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) { ++ valid = 0; ++ } ++ if ((val == 3) ++ && ((core_if->snpsid < OTG_CORE_REV_3_00a) ++ || (hwcfg4.b.xhiber == 0))) { ++ valid = 0; ++ } ++ if (valid == 0) { ++ if (dwc_otg_param_initialized(core_if->core_params->power_down)) { ++ DWC_ERROR ++ ("%d invalid for parameter power_down. Check HW configuration.\n", ++ val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->power_down = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->power_down; ++} ++ ++int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ int valid = 1; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val); ++ DWC_WARN("reload_ctl must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) { ++ valid = 0; ++ } ++ if (valid == 0) { ++ if (dwc_otg_param_initialized(core_if->core_params->reload_ctl)) { ++ DWC_ERROR("%d invalid for parameter reload_ctl." ++ "Check HW configuration.\n", val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->reload_ctl = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->reload_ctl; ++} ++ ++int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ int valid = 1; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val); ++ DWC_WARN("dev_out_nak must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) || ++ !(core_if->core_params->dma_desc_enable))) { ++ valid = 0; ++ } ++ if (valid == 0) { ++ if (dwc_otg_param_initialized(core_if->core_params->dev_out_nak)) { ++ DWC_ERROR("%d invalid for parameter dev_out_nak." ++ "Check HW configuration.\n", val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->dev_out_nak = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->dev_out_nak; ++} ++ ++int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ int valid = 1; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val); ++ DWC_WARN("cont_on_bna must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) || ++ !(core_if->core_params->dma_desc_enable))) { ++ valid = 0; ++ } ++ if (valid == 0) { ++ if (dwc_otg_param_initialized(core_if->core_params->cont_on_bna)) { ++ DWC_ERROR("%d invalid for parameter cont_on_bna." ++ "Check HW configuration.\n", val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->cont_on_bna = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->cont_on_bna; ++} ++ ++int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ int valid = 1; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val); ++ DWC_WARN("ahb_single must be 0 or 1\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) { ++ valid = 0; ++ } ++ if (valid == 0) { ++ if (dwc_otg_param_initialized(core_if->core_params->ahb_single)) { ++ DWC_ERROR("%d invalid for parameter ahb_single." ++ "Check HW configuration.\n", val); ++ } ++ retval = -DWC_E_INVALID; ++ val = 0; ++ } ++ core_if->core_params->ahb_single = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->ahb_single; ++} ++ ++int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val) ++{ ++ int retval = 0; ++ ++ if (DWC_OTG_PARAM_TEST(val, 0, 1)) { ++ DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val); ++ DWC_WARN ++ ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ core_if->core_params->otg_ver = val; ++ return retval; ++} ++ ++int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->core_params->otg_ver; ++} ++ ++uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if) ++{ ++ gotgctl_data_t otgctl; ++ otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ return otgctl.b.hstnegscs; ++} ++ ++uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if) ++{ ++ gotgctl_data_t otgctl; ++ otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ return otgctl.b.sesreqscs; ++} ++ ++void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ if(core_if->otg_ver == 0) { ++ gotgctl_data_t otgctl; ++ otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ otgctl.b.hnpreq = val; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, otgctl.d32); ++ } else { ++ core_if->otg_sts = val; ++ } ++} ++ ++uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->snpsid; ++} ++ ++uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if) ++{ ++ gintsts_data_t gintsts; ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ return gintsts.b.curmode; ++} ++ ++uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if) ++{ ++ gusbcfg_data_t usbcfg; ++ usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ return usbcfg.b.hnpcap; ++} ++ ++void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ gusbcfg_data_t usbcfg; ++ usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ usbcfg.b.hnpcap = val; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32); ++} ++ ++uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if) ++{ ++ gusbcfg_data_t usbcfg; ++ usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ return usbcfg.b.srpcap; ++} ++ ++void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ gusbcfg_data_t usbcfg; ++ usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ usbcfg.b.srpcap = val; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32); ++} ++ ++uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if) ++{ ++ dcfg_data_t dcfg; ++ /* originally: dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); */ ++ ++ dcfg.d32 = -1; //GRAYG ++ DWC_DEBUGPL(DBG_CILV, "%s - core_if(%p)\n", __func__, core_if); ++ if (NULL == core_if) ++ DWC_ERROR("reg request with NULL core_if\n"); ++ DWC_DEBUGPL(DBG_CILV, "%s - core_if(%p)->dev_if(%p)\n", __func__, ++ core_if, core_if->dev_if); ++ if (NULL == core_if->dev_if) ++ DWC_ERROR("reg request with NULL dev_if\n"); ++ DWC_DEBUGPL(DBG_CILV, "%s - core_if(%p)->dev_if(%p)->" ++ "dev_global_regs(%p)\n", __func__, ++ core_if, core_if->dev_if, ++ core_if->dev_if->dev_global_regs); ++ if (NULL == core_if->dev_if->dev_global_regs) ++ DWC_ERROR("reg request with NULL dev_global_regs\n"); ++ else { ++ DWC_DEBUGPL(DBG_CILV, "%s - &core_if(%p)->dev_if(%p)->" ++ "dev_global_regs(%p)->dcfg = %p\n", __func__, ++ core_if, core_if->dev_if, ++ core_if->dev_if->dev_global_regs, ++ &core_if->dev_if->dev_global_regs->dcfg); ++ dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ } ++ return dcfg.b.devspd; ++} ++ ++void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ dcfg_data_t dcfg; ++ dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ dcfg.b.devspd = val; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32); ++} ++ ++uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if) ++{ ++ hprt0_data_t hprt0; ++ hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0); ++ return hprt0.b.prtconnsts; ++} ++ ++uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if) ++{ ++ dsts_data_t dsts; ++ dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ return dsts.b.enumspd; ++} ++ ++uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if) ++{ ++ hprt0_data_t hprt0; ++ hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0); ++ return hprt0.b.prtpwr; ++ ++} ++ ++uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if) ++{ ++ return core_if->hibernation_suspend; ++} ++ ++void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ hprt0_data_t hprt0; ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtpwr = val; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++} ++ ++uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if) ++{ ++ hprt0_data_t hprt0; ++ hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0); ++ return hprt0.b.prtsusp; ++ ++} ++ ++void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ hprt0_data_t hprt0; ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtsusp = val; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++} ++ ++uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if) ++{ ++ hfir_data_t hfir; ++ hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir); ++ return hfir.b.frint; ++ ++} ++ ++void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ hfir_data_t hfir; ++ uint32_t fram_int; ++ fram_int = calc_frame_interval(core_if); ++ hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir); ++ if (!core_if->core_params->reload_ctl) { ++ DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is" ++ "not set to 1.\nShould load driver with reload_ctl=1" ++ " module parameter\n"); ++ return; ++ } ++ switch (fram_int) { ++ case 3750: ++ if ((val < 3350) || (val > 4150)) { ++ DWC_WARN("HFIR interval for HS core and 30 MHz" ++ "clock freq should be from 3350 to 4150\n"); ++ return; ++ } ++ break; ++ case 30000: ++ if ((val < 26820) || (val > 33180)) { ++ DWC_WARN("HFIR interval for FS/LS core and 30 MHz" ++ "clock freq should be from 26820 to 33180\n"); ++ return; ++ } ++ break; ++ case 6000: ++ if ((val < 5360) || (val > 6640)) { ++ DWC_WARN("HFIR interval for HS core and 48 MHz" ++ "clock freq should be from 5360 to 6640\n"); ++ return; ++ } ++ break; ++ case 48000: ++ if ((val < 42912) || (val > 53088)) { ++ DWC_WARN("HFIR interval for FS/LS core and 48 MHz" ++ "clock freq should be from 42912 to 53088\n"); ++ return; ++ } ++ break; ++ case 7500: ++ if ((val < 6700) || (val > 8300)) { ++ DWC_WARN("HFIR interval for HS core and 60 MHz" ++ "clock freq should be from 6700 to 8300\n"); ++ return; ++ } ++ break; ++ case 60000: ++ if ((val < 53640) || (val > 65536)) { ++ DWC_WARN("HFIR interval for FS/LS core and 60 MHz" ++ "clock freq should be from 53640 to 65536\n"); ++ return; ++ } ++ break; ++ default: ++ DWC_WARN("Unknown frame interval\n"); ++ return; ++ break; ++ ++ } ++ hfir.b.frint = val; ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32); ++} ++ ++uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if) ++{ ++ hcfg_data_t hcfg; ++ hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg); ++ return hcfg.b.modechtimen; ++ ++} ++ ++void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ hcfg_data_t hcfg; ++ hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg); ++ hcfg.b.modechtimen = val; ++ DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32); ++} ++ ++void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ hprt0_data_t hprt0; ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtres = val; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++} ++ ++uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if) ++{ ++ dctl_data_t dctl; ++ dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl); ++ return dctl.b.rmtwkupsig; ++} ++ ++uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ ++ DWC_ASSERT(! ++ ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts), ++ "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n", ++ core_if->lx_state, lpmcfg.b.prt_sleep_sts); ++ ++ return lpmcfg.b.prt_sleep_sts; ++} ++ ++uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ return lpmcfg.b.rem_wkup_en; ++} ++ ++uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ return lpmcfg.b.appl_resp; ++} ++ ++void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ lpmcfg.b.appl_resp = val; ++ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32); ++} ++ ++uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ return lpmcfg.b.hsic_connect; ++} ++ ++void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ lpmcfg.b.hsic_connect = val; ++ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32); ++} ++ ++uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ return lpmcfg.b.inv_sel_hsic; ++ ++} ++ ++void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ lpmcfg.b.inv_sel_hsic = val; ++ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32); ++} ++ ++uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++} ++ ++void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val); ++} ++ ++uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++} ++ ++void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val); ++} ++ ++uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz); ++} ++ ++void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val); ++} ++ ++uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz); ++} ++ ++void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val); ++} ++ ++uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl); ++} ++ ++void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val); ++} ++ ++uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->ggpio); ++} ++ ++void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val); ++} ++ ++uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(core_if->host_if->hprt0); ++ ++} ++ ++void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(core_if->host_if->hprt0, val); ++} ++ ++uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->guid); ++} ++ ++void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val) ++{ ++ DWC_WRITE_REG32(&core_if->core_global_regs->guid, val); ++} ++ ++uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if) ++{ ++ return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz); ++} ++ ++uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if) ++{ ++ return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103); ++} ++ ++/** ++ * Start the SRP timer to detect when the SRP does not complete within ++ * 6 seconds. ++ * ++ * @param core_if the pointer to core_if strucure. ++ */ ++void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if) ++{ ++ core_if->srp_timer_started = 1; ++ DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 /* 6 secs */ ); ++} ++ ++void dwc_otg_initiate_srp(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl); ++ gotgctl_data_t mem; ++ gotgctl_data_t val; ++ ++ val.d32 = DWC_READ_REG32(addr); ++ if (val.b.sesreq) { ++ DWC_ERROR("Session Request Already active!\n"); ++ return; ++ } ++ ++ DWC_INFO("Session Request Initated\n"); //NOTICE ++ mem.d32 = DWC_READ_REG32(addr); ++ mem.b.sesreq = 1; ++ DWC_WRITE_REG32(addr, mem.d32); ++ ++ /* Start the SRP timer */ ++ dwc_otg_pcd_start_srp_timer(core_if); ++ return; ++} +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cil.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cil.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1464 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.h $ ++ * $Revision: #123 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#if !defined(__DWC_CIL_H__) ++#define __DWC_CIL_H__ ++ ++#include "dwc_list.h" ++#include "dwc_otg_dbg.h" ++#include "dwc_otg_regs.h" ++ ++#include "dwc_otg_core_if.h" ++#include "dwc_otg_adp.h" ++ ++/** ++ * @file ++ * This file contains the interface to the Core Interface Layer. ++ */ ++ ++#ifdef DWC_UTE_CFI ++ ++#define MAX_DMA_DESCS_PER_EP 256 ++ ++/** ++ * Enumeration for the data buffer mode ++ */ ++typedef enum _data_buffer_mode { ++ BM_STANDARD = 0, /* data buffer is in normal mode */ ++ BM_SG = 1, /* data buffer uses the scatter/gather mode */ ++ BM_CONCAT = 2, /* data buffer uses the concatenation mode */ ++ BM_CIRCULAR = 3, /* data buffer uses the circular DMA mode */ ++ BM_ALIGN = 4 /* data buffer is in buffer alignment mode */ ++} data_buffer_mode_e; ++#endif //DWC_UTE_CFI ++ ++/** Macros defined for DWC OTG HW Release version */ ++ ++#define OTG_CORE_REV_2_60a 0x4F54260A ++#define OTG_CORE_REV_2_71a 0x4F54271A ++#define OTG_CORE_REV_2_72a 0x4F54272A ++#define OTG_CORE_REV_2_80a 0x4F54280A ++#define OTG_CORE_REV_2_81a 0x4F54281A ++#define OTG_CORE_REV_2_90a 0x4F54290A ++#define OTG_CORE_REV_2_91a 0x4F54291A ++#define OTG_CORE_REV_2_92a 0x4F54292A ++#define OTG_CORE_REV_2_93a 0x4F54293A ++#define OTG_CORE_REV_2_94a 0x4F54294A ++#define OTG_CORE_REV_3_00a 0x4F54300A ++ ++/** ++ * Information for each ISOC packet. ++ */ ++typedef struct iso_pkt_info { ++ uint32_t offset; ++ uint32_t length; ++ int32_t status; ++} iso_pkt_info_t; ++ ++/** ++ * The dwc_ep structure represents the state of a single ++ * endpoint when acting in device mode. It contains the data items ++ * needed for an endpoint to be activated and transfer packets. ++ */ ++typedef struct dwc_ep { ++ /** EP number used for register address lookup */ ++ uint8_t num; ++ /** EP direction 0 = OUT */ ++ unsigned is_in:1; ++ /** EP active. */ ++ unsigned active:1; ++ ++ /** ++ * Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use non-periodic ++ * Tx FIFO. If dedicated Tx FIFOs are enabled Tx FIFO # FOR IN EPs*/ ++ unsigned tx_fifo_num:4; ++ /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */ ++ unsigned type:2; ++#define DWC_OTG_EP_TYPE_CONTROL 0 ++#define DWC_OTG_EP_TYPE_ISOC 1 ++#define DWC_OTG_EP_TYPE_BULK 2 ++#define DWC_OTG_EP_TYPE_INTR 3 ++ ++ /** DATA start PID for INTR and BULK EP */ ++ unsigned data_pid_start:1; ++ /** Frame (even/odd) for ISOC EP */ ++ unsigned even_odd_frame:1; ++ /** Max Packet bytes */ ++ unsigned maxpacket:11; ++ ++ /** Max Transfer size */ ++ uint32_t maxxfer; ++ ++ /** @name Transfer state */ ++ /** @{ */ ++ ++ /** ++ * Pointer to the beginning of the transfer buffer -- do not modify ++ * during transfer. ++ */ ++ ++ dwc_dma_t dma_addr; ++ ++ dwc_dma_t dma_desc_addr; ++ dwc_otg_dev_dma_desc_t *desc_addr; ++ ++ uint8_t *start_xfer_buff; ++ /** pointer to the transfer buffer */ ++ uint8_t *xfer_buff; ++ /** Number of bytes to transfer */ ++ unsigned xfer_len:19; ++ /** Number of bytes transferred. */ ++ unsigned xfer_count:19; ++ /** Sent ZLP */ ++ unsigned sent_zlp:1; ++ /** Total len for control transfer */ ++ unsigned total_len:19; ++ ++ /** stall clear flag */ ++ unsigned stall_clear_flag:1; ++ ++ /** SETUP pkt cnt rollover flag for EP0 out*/ ++ unsigned stp_rollover; ++ ++#ifdef DWC_UTE_CFI ++ /* The buffer mode */ ++ data_buffer_mode_e buff_mode; ++ ++ /* The chain of DMA descriptors. ++ * MAX_DMA_DESCS_PER_EP will be allocated for each active EP. ++ */ ++ dwc_otg_dma_desc_t *descs; ++ ++ /* The DMA address of the descriptors chain start */ ++ dma_addr_t descs_dma_addr; ++ /** This variable stores the length of the last enqueued request */ ++ uint32_t cfi_req_len; ++#endif //DWC_UTE_CFI ++ ++/** Max DMA Descriptor count for any EP */ ++#define MAX_DMA_DESC_CNT 256 ++ /** Allocated DMA Desc count */ ++ uint32_t desc_cnt; ++ ++ /** bInterval */ ++ uint32_t bInterval; ++ /** Next frame num to setup next ISOC transfer */ ++ uint32_t frame_num; ++ /** Indicates SOF number overrun in DSTS */ ++ uint8_t frm_overrun; ++ ++#ifdef DWC_UTE_PER_IO ++ /** Next frame num for which will be setup DMA Desc */ ++ uint32_t xiso_frame_num; ++ /** bInterval */ ++ uint32_t xiso_bInterval; ++ /** Count of currently active transfers - shall be either 0 or 1 */ ++ int xiso_active_xfers; ++ int xiso_queued_xfers; ++#endif ++#ifdef DWC_EN_ISOC ++ /** ++ * Variables specific for ISOC EPs ++ * ++ */ ++ /** DMA addresses of ISOC buffers */ ++ dwc_dma_t dma_addr0; ++ dwc_dma_t dma_addr1; ++ ++ dwc_dma_t iso_dma_desc_addr; ++ dwc_otg_dev_dma_desc_t *iso_desc_addr; ++ ++ /** pointer to the transfer buffers */ ++ uint8_t *xfer_buff0; ++ uint8_t *xfer_buff1; ++ ++ /** number of ISOC Buffer is processing */ ++ uint32_t proc_buf_num; ++ /** Interval of ISOC Buffer processing */ ++ uint32_t buf_proc_intrvl; ++ /** Data size for regular frame */ ++ uint32_t data_per_frame; ++ ++ /* todo - pattern data support is to be implemented in the future */ ++ /** Data size for pattern frame */ ++ uint32_t data_pattern_frame; ++ /** Frame number of pattern data */ ++ uint32_t sync_frame; ++ ++ /** bInterval */ ++ uint32_t bInterval; ++ /** ISO Packet number per frame */ ++ uint32_t pkt_per_frm; ++ /** Next frame num for which will be setup DMA Desc */ ++ uint32_t next_frame; ++ /** Number of packets per buffer processing */ ++ uint32_t pkt_cnt; ++ /** Info for all isoc packets */ ++ iso_pkt_info_t *pkt_info; ++ /** current pkt number */ ++ uint32_t cur_pkt; ++ /** current pkt number */ ++ uint8_t *cur_pkt_addr; ++ /** current pkt number */ ++ uint32_t cur_pkt_dma_addr; ++#endif /* DWC_EN_ISOC */ ++ ++/** @} */ ++} dwc_ep_t; ++ ++/* ++ * Reasons for halting a host channel. ++ */ ++typedef enum dwc_otg_halt_status { ++ DWC_OTG_HC_XFER_NO_HALT_STATUS, ++ DWC_OTG_HC_XFER_COMPLETE, ++ DWC_OTG_HC_XFER_URB_COMPLETE, ++ DWC_OTG_HC_XFER_ACK, ++ DWC_OTG_HC_XFER_NAK, ++ DWC_OTG_HC_XFER_NYET, ++ DWC_OTG_HC_XFER_STALL, ++ DWC_OTG_HC_XFER_XACT_ERR, ++ DWC_OTG_HC_XFER_FRAME_OVERRUN, ++ DWC_OTG_HC_XFER_BABBLE_ERR, ++ DWC_OTG_HC_XFER_DATA_TOGGLE_ERR, ++ DWC_OTG_HC_XFER_AHB_ERR, ++ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE, ++ DWC_OTG_HC_XFER_URB_DEQUEUE ++} dwc_otg_halt_status_e; ++ ++/** ++ * Host channel descriptor. This structure represents the state of a single ++ * host channel when acting in host mode. It contains the data items needed to ++ * transfer packets to an endpoint via a host channel. ++ */ ++typedef struct dwc_hc { ++ /** Host channel number used for register address lookup */ ++ uint8_t hc_num; ++ ++ /** Device to access */ ++ unsigned dev_addr:7; ++ ++ /** EP to access */ ++ unsigned ep_num:4; ++ ++ /** EP direction. 0: OUT, 1: IN */ ++ unsigned ep_is_in:1; ++ ++ /** ++ * EP speed. ++ * One of the following values: ++ * - DWC_OTG_EP_SPEED_LOW ++ * - DWC_OTG_EP_SPEED_FULL ++ * - DWC_OTG_EP_SPEED_HIGH ++ */ ++ unsigned speed:2; ++#define DWC_OTG_EP_SPEED_LOW 0 ++#define DWC_OTG_EP_SPEED_FULL 1 ++#define DWC_OTG_EP_SPEED_HIGH 2 ++ ++ /** ++ * Endpoint type. ++ * One of the following values: ++ * - DWC_OTG_EP_TYPE_CONTROL: 0 ++ * - DWC_OTG_EP_TYPE_ISOC: 1 ++ * - DWC_OTG_EP_TYPE_BULK: 2 ++ * - DWC_OTG_EP_TYPE_INTR: 3 ++ */ ++ unsigned ep_type:2; ++ ++ /** Max packet size in bytes */ ++ unsigned max_packet:11; ++ ++ /** ++ * PID for initial transaction. ++ * 0: DATA0,
++ * 1: DATA2,
++ * 2: DATA1,
++ * 3: MDATA (non-Control EP), ++ * SETUP (Control EP) ++ */ ++ unsigned data_pid_start:2; ++#define DWC_OTG_HC_PID_DATA0 0 ++#define DWC_OTG_HC_PID_DATA2 1 ++#define DWC_OTG_HC_PID_DATA1 2 ++#define DWC_OTG_HC_PID_MDATA 3 ++#define DWC_OTG_HC_PID_SETUP 3 ++ ++ /** Number of periodic transactions per (micro)frame */ ++ unsigned multi_count:2; ++ ++ /** @name Transfer State */ ++ /** @{ */ ++ ++ /** Pointer to the current transfer buffer position. */ ++ uint8_t *xfer_buff; ++ /** ++ * In Buffer DMA mode this buffer will be used ++ * if xfer_buff is not DWORD aligned. ++ */ ++ dwc_dma_t align_buff; ++ /** Total number of bytes to transfer. */ ++ uint32_t xfer_len; ++ /** Number of bytes transferred so far. */ ++ uint32_t xfer_count; ++ /** Packet count at start of transfer.*/ ++ uint16_t start_pkt_count; ++ ++ /** ++ * Flag to indicate whether the transfer has been started. Set to 1 if ++ * it has been started, 0 otherwise. ++ */ ++ uint8_t xfer_started; ++ ++ /** ++ * Set to 1 to indicate that a PING request should be issued on this ++ * channel. If 0, process normally. ++ */ ++ uint8_t do_ping; ++ ++ /** ++ * Set to 1 to indicate that the error count for this transaction is ++ * non-zero. Set to 0 if the error count is 0. ++ */ ++ uint8_t error_state; ++ ++ /** ++ * Set to 1 to indicate that this channel should be halted the next ++ * time a request is queued for the channel. This is necessary in ++ * slave mode if no request queue space is available when an attempt ++ * is made to halt the channel. ++ */ ++ uint8_t halt_on_queue; ++ ++ /** ++ * Set to 1 if the host channel has been halted, but the core is not ++ * finished flushing queued requests. Otherwise 0. ++ */ ++ uint8_t halt_pending; ++ ++ /** ++ * Reason for halting the host channel. ++ */ ++ dwc_otg_halt_status_e halt_status; ++ ++ /* ++ * Split settings for the host channel ++ */ ++ uint8_t do_split; /**< Enable split for the channel */ ++ uint8_t complete_split; /**< Enable complete split */ ++ uint8_t hub_addr; /**< Address of high speed hub */ ++ ++ uint8_t port_addr; /**< Port of the low/full speed device */ ++ /** Split transaction position ++ * One of the following values: ++ * - DWC_HCSPLIT_XACTPOS_MID ++ * - DWC_HCSPLIT_XACTPOS_BEGIN ++ * - DWC_HCSPLIT_XACTPOS_END ++ * - DWC_HCSPLIT_XACTPOS_ALL */ ++ uint8_t xact_pos; ++ ++ /** Set when the host channel does a short read. */ ++ uint8_t short_read; ++ ++ /** ++ * Number of requests issued for this channel since it was assigned to ++ * the current transfer (not counting PINGs). ++ */ ++ uint8_t requests; ++ ++ /** ++ * Queue Head for the transfer being processed by this channel. ++ */ ++ struct dwc_otg_qh *qh; ++ ++ /** @} */ ++ ++ /** Entry in list of host channels. */ ++ DWC_CIRCLEQ_ENTRY(dwc_hc) hc_list_entry; ++ ++ /** @name Descriptor DMA support */ ++ /** @{ */ ++ ++ /** Number of Transfer Descriptors */ ++ uint16_t ntd; ++ ++ /** Descriptor List DMA address */ ++ dwc_dma_t desc_list_addr; ++ ++ /** Scheduling micro-frame bitmap. */ ++ uint8_t schinfo; ++ ++ /** @} */ ++} dwc_hc_t; ++ ++/** ++ * The following parameters may be specified when starting the module. These ++ * parameters define how the DWC_otg controller should be configured. ++ */ ++typedef struct dwc_otg_core_params { ++ int32_t opt; ++ ++ /** ++ * Specifies the OTG capabilities. The driver will automatically ++ * detect the value for this parameter if none is specified. ++ * 0 - HNP and SRP capable (default) ++ * 1 - SRP Only capable ++ * 2 - No HNP/SRP capable ++ */ ++ int32_t otg_cap; ++ ++ /** ++ * Specifies whether to use slave or DMA mode for accessing the data ++ * FIFOs. The driver will automatically detect the value for this ++ * parameter if none is specified. ++ * 0 - Slave ++ * 1 - DMA (default, if available) ++ */ ++ int32_t dma_enable; ++ ++ /** ++ * When DMA mode is enabled specifies whether to use address DMA or DMA ++ * Descriptor mode for accessing the data FIFOs in device mode. The driver ++ * will automatically detect the value for this if none is specified. ++ * 0 - address DMA ++ * 1 - DMA Descriptor(default, if available) ++ */ ++ int32_t dma_desc_enable; ++ /** The DMA Burst size (applicable only for External DMA ++ * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32) ++ */ ++ int32_t dma_burst_size; /* Translate this to GAHBCFG values */ ++ ++ /** ++ * Specifies the maximum speed of operation in host and device mode. ++ * The actual speed depends on the speed of the attached device and ++ * the value of phy_type. The actual speed depends on the speed of the ++ * attached device. ++ * 0 - High Speed (default) ++ * 1 - Full Speed ++ */ ++ int32_t speed; ++ /** Specifies whether low power mode is supported when attached ++ * to a Full Speed or Low Speed device in host mode. ++ * 0 - Don't support low power mode (default) ++ * 1 - Support low power mode ++ */ ++ int32_t host_support_fs_ls_low_power; ++ ++ /** Specifies the PHY clock rate in low power mode when connected to a ++ * Low Speed device in host mode. This parameter is applicable only if ++ * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS ++ * then defaults to 6 MHZ otherwise 48 MHZ. ++ * ++ * 0 - 48 MHz ++ * 1 - 6 MHz ++ */ ++ int32_t host_ls_low_power_phy_clk; ++ ++ /** ++ * 0 - Use cC FIFO size parameters ++ * 1 - Allow dynamic FIFO sizing (default) ++ */ ++ int32_t enable_dynamic_fifo; ++ ++ /** Total number of 4-byte words in the data FIFO memory. This ++ * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic ++ * Tx FIFOs. ++ * 32 to 32768 (default 8192) ++ * Note: The total FIFO memory depth in the FPGA configuration is 8192. ++ */ ++ int32_t data_fifo_size; ++ ++ /** Number of 4-byte words in the Rx FIFO in device mode when dynamic ++ * FIFO sizing is enabled. ++ * 16 to 32768 (default 1064) ++ */ ++ int32_t dev_rx_fifo_size; ++ ++ /** Number of 4-byte words in the non-periodic Tx FIFO in device mode ++ * when dynamic FIFO sizing is enabled. ++ * 16 to 32768 (default 1024) ++ */ ++ int32_t dev_nperio_tx_fifo_size; ++ ++ /** Number of 4-byte words in each of the periodic Tx FIFOs in device ++ * mode when dynamic FIFO sizing is enabled. ++ * 4 to 768 (default 256) ++ */ ++ uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS]; ++ ++ /** Number of 4-byte words in the Rx FIFO in host mode when dynamic ++ * FIFO sizing is enabled. ++ * 16 to 32768 (default 1024) ++ */ ++ int32_t host_rx_fifo_size; ++ ++ /** Number of 4-byte words in the non-periodic Tx FIFO in host mode ++ * when Dynamic FIFO sizing is enabled in the core. ++ * 16 to 32768 (default 1024) ++ */ ++ int32_t host_nperio_tx_fifo_size; ++ ++ /** Number of 4-byte words in the host periodic Tx FIFO when dynamic ++ * FIFO sizing is enabled. ++ * 16 to 32768 (default 1024) ++ */ ++ int32_t host_perio_tx_fifo_size; ++ ++ /** The maximum transfer size supported in bytes. ++ * 2047 to 65,535 (default 65,535) ++ */ ++ int32_t max_transfer_size; ++ ++ /** The maximum number of packets in a transfer. ++ * 15 to 511 (default 511) ++ */ ++ int32_t max_packet_count; ++ ++ /** The number of host channel registers to use. ++ * 1 to 16 (default 12) ++ * Note: The FPGA configuration supports a maximum of 12 host channels. ++ */ ++ int32_t host_channels; ++ ++ /** The number of endpoints in addition to EP0 available for device ++ * mode operations. ++ * 1 to 15 (default 6 IN and OUT) ++ * Note: The FPGA configuration supports a maximum of 6 IN and OUT ++ * endpoints in addition to EP0. ++ */ ++ int32_t dev_endpoints; ++ ++ /** ++ * Specifies the type of PHY interface to use. By default, the driver ++ * will automatically detect the phy_type. ++ * ++ * 0 - Full Speed PHY ++ * 1 - UTMI+ (default) ++ * 2 - ULPI ++ */ ++ int32_t phy_type; ++ ++ /** ++ * Specifies the UTMI+ Data Width. This parameter is ++ * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI ++ * PHY_TYPE, this parameter indicates the data width between ++ * the MAC and the ULPI Wrapper.) Also, this parameter is ++ * applicable only if the OTG_HSPHY_WIDTH cC parameter was set ++ * to "8 and 16 bits", meaning that the core has been ++ * configured to work at either data path width. ++ * ++ * 8 or 16 bits (default 16) ++ */ ++ int32_t phy_utmi_width; ++ ++ /** ++ * Specifies whether the ULPI operates at double or single ++ * data rate. This parameter is only applicable if PHY_TYPE is ++ * ULPI. ++ * ++ * 0 - single data rate ULPI interface with 8 bit wide data ++ * bus (default) ++ * 1 - double data rate ULPI interface with 4 bit wide data ++ * bus ++ */ ++ int32_t phy_ulpi_ddr; ++ ++ /** ++ * Specifies whether to use the internal or external supply to ++ * drive the vbus with a ULPI phy. ++ */ ++ int32_t phy_ulpi_ext_vbus; ++ ++ /** ++ * Specifies whether to use the I2Cinterface for full speed PHY. This ++ * parameter is only applicable if PHY_TYPE is FS. ++ * 0 - No (default) ++ * 1 - Yes ++ */ ++ int32_t i2c_enable; ++ ++ int32_t ulpi_fs_ls; ++ ++ int32_t ts_dline; ++ ++ /** ++ * Specifies whether dedicated transmit FIFOs are ++ * enabled for non periodic IN endpoints in device mode ++ * 0 - No ++ * 1 - Yes ++ */ ++ int32_t en_multiple_tx_fifo; ++ ++ /** Number of 4-byte words in each of the Tx FIFOs in device ++ * mode when dynamic FIFO sizing is enabled. ++ * 4 to 768 (default 256) ++ */ ++ uint32_t dev_tx_fifo_size[MAX_TX_FIFOS]; ++ ++ /** Thresholding enable flag- ++ * bit 0 - enable non-ISO Tx thresholding ++ * bit 1 - enable ISO Tx thresholding ++ * bit 2 - enable Rx thresholding ++ */ ++ uint32_t thr_ctl; ++ ++ /** Thresholding length for Tx ++ * FIFOs in 32 bit DWORDs ++ */ ++ uint32_t tx_thr_length; ++ ++ /** Thresholding length for Rx ++ * FIFOs in 32 bit DWORDs ++ */ ++ uint32_t rx_thr_length; ++ ++ /** ++ * Specifies whether LPM (Link Power Management) support is enabled ++ */ ++ int32_t lpm_enable; ++ ++ /** Per Transfer Interrupt ++ * mode enable flag ++ * 1 - Enabled ++ * 0 - Disabled ++ */ ++ int32_t pti_enable; ++ ++ /** Multi Processor Interrupt ++ * mode enable flag ++ * 1 - Enabled ++ * 0 - Disabled ++ */ ++ int32_t mpi_enable; ++ ++ /** IS_USB Capability ++ * 1 - Enabled ++ * 0 - Disabled ++ */ ++ int32_t ic_usb_cap; ++ ++ /** AHB Threshold Ratio ++ * 2'b00 AHB Threshold = MAC Threshold ++ * 2'b01 AHB Threshold = 1/2 MAC Threshold ++ * 2'b10 AHB Threshold = 1/4 MAC Threshold ++ * 2'b11 AHB Threshold = 1/8 MAC Threshold ++ */ ++ int32_t ahb_thr_ratio; ++ ++ /** ADP Support ++ * 1 - Enabled ++ * 0 - Disabled ++ */ ++ int32_t adp_supp_enable; ++ ++ /** HFIR Reload Control ++ * 0 - The HFIR cannot be reloaded dynamically. ++ * 1 - Allow dynamic reloading of the HFIR register during runtime. ++ */ ++ int32_t reload_ctl; ++ ++ /** DCFG: Enable device Out NAK ++ * 0 - The core does not set NAK after Bulk Out transfer complete. ++ * 1 - The core sets NAK after Bulk OUT transfer complete. ++ */ ++ int32_t dev_out_nak; ++ ++ /** DCFG: Enable Continue on BNA ++ * After receiving BNA interrupt the core disables the endpoint,when the ++ * endpoint is re-enabled by the application the core starts processing ++ * 0 - from the DOEPDMA descriptor ++ * 1 - from the descriptor which received the BNA. ++ */ ++ int32_t cont_on_bna; ++ ++ /** GAHBCFG: AHB Single Support ++ * This bit when programmed supports SINGLE transfers for remainder ++ * data in a transfer for DMA mode of operation. ++ * 0 - in this case the remainder data will be sent using INCR burst size. ++ * 1 - in this case the remainder data will be sent using SINGLE burst size. ++ */ ++ int32_t ahb_single; ++ ++ /** Core Power down mode ++ * 0 - No Power Down is enabled ++ * 1 - Reserved ++ * 2 - Complete Power Down (Hibernation) ++ */ ++ int32_t power_down; ++ ++ /** OTG revision supported ++ * 0 - OTG 1.3 revision ++ * 1 - OTG 2.0 revision ++ */ ++ int32_t otg_ver; ++ ++} dwc_otg_core_params_t; ++ ++#ifdef DEBUG ++struct dwc_otg_core_if; ++typedef struct hc_xfer_info { ++ struct dwc_otg_core_if *core_if; ++ dwc_hc_t *hc; ++} hc_xfer_info_t; ++#endif ++ ++typedef struct ep_xfer_info { ++ struct dwc_otg_core_if *core_if; ++ dwc_ep_t *ep; ++ uint8_t state; ++} ep_xfer_info_t; ++/* ++ * Device States ++ */ ++typedef enum dwc_otg_lx_state { ++ /** On state */ ++ DWC_OTG_L0, ++ /** LPM sleep state*/ ++ DWC_OTG_L1, ++ /** USB suspend state*/ ++ DWC_OTG_L2, ++ /** Off state*/ ++ DWC_OTG_L3 ++} dwc_otg_lx_state_e; ++ ++struct dwc_otg_global_regs_backup { ++ uint32_t gotgctl_local; ++ uint32_t gintmsk_local; ++ uint32_t gahbcfg_local; ++ uint32_t gusbcfg_local; ++ uint32_t grxfsiz_local; ++ uint32_t gnptxfsiz_local; ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ uint32_t glpmcfg_local; ++#endif ++ uint32_t gi2cctl_local; ++ uint32_t hptxfsiz_local; ++ uint32_t pcgcctl_local; ++ uint32_t gdfifocfg_local; ++ uint32_t dtxfsiz_local[MAX_EPS_CHANNELS]; ++ uint32_t gpwrdn_local; ++ uint32_t xhib_pcgcctl; ++ uint32_t xhib_gpwrdn; ++}; ++ ++struct dwc_otg_host_regs_backup { ++ uint32_t hcfg_local; ++ uint32_t haintmsk_local; ++ uint32_t hcintmsk_local[MAX_EPS_CHANNELS]; ++ uint32_t hprt0_local; ++ uint32_t hfir_local; ++}; ++ ++struct dwc_otg_dev_regs_backup { ++ uint32_t dcfg; ++ uint32_t dctl; ++ uint32_t daintmsk; ++ uint32_t diepmsk; ++ uint32_t doepmsk; ++ uint32_t diepctl[MAX_EPS_CHANNELS]; ++ uint32_t dieptsiz[MAX_EPS_CHANNELS]; ++ uint32_t diepdma[MAX_EPS_CHANNELS]; ++}; ++/** ++ * The dwc_otg_core_if structure contains information needed to manage ++ * the DWC_otg controller acting in either host or device mode. It ++ * represents the programming view of the controller as a whole. ++ */ ++struct dwc_otg_core_if { ++ /** Parameters that define how the core should be configured.*/ ++ dwc_otg_core_params_t *core_params; ++ ++ /** Core Global registers starting at offset 000h. */ ++ dwc_otg_core_global_regs_t *core_global_regs; ++ ++ /** Device-specific information */ ++ dwc_otg_dev_if_t *dev_if; ++ /** Host-specific information */ ++ dwc_otg_host_if_t *host_if; ++ ++ /** Value from SNPSID register */ ++ uint32_t snpsid; ++ ++ /* ++ * Set to 1 if the core PHY interface bits in USBCFG have been ++ * initialized. ++ */ ++ uint8_t phy_init_done; ++ ++ /* ++ * SRP Success flag, set by srp success interrupt in FS I2C mode ++ */ ++ uint8_t srp_success; ++ uint8_t srp_timer_started; ++ /** Timer for SRP. If it expires before SRP is successful ++ * clear the SRP. */ ++ dwc_timer_t *srp_timer; ++ ++#ifdef DWC_DEV_SRPCAP ++ /* This timer is needed to power on the hibernated host core if SRP is not ++ * initiated on connected SRP capable device for limited period of time ++ */ ++ uint8_t pwron_timer_started; ++ dwc_timer_t *pwron_timer; ++#endif ++ /* Common configuration information */ ++ /** Power and Clock Gating Control Register */ ++ volatile uint32_t *pcgcctl; ++#define DWC_OTG_PCGCCTL_OFFSET 0xE00 ++ ++ /** Push/pop addresses for endpoints or host channels.*/ ++ uint32_t *data_fifo[MAX_EPS_CHANNELS]; ++#define DWC_OTG_DATA_FIFO_OFFSET 0x1000 ++#define DWC_OTG_DATA_FIFO_SIZE 0x1000 ++ ++ /** Total RAM for FIFOs (Bytes) */ ++ uint16_t total_fifo_size; ++ /** Size of Rx FIFO (Bytes) */ ++ uint16_t rx_fifo_size; ++ /** Size of Non-periodic Tx FIFO (Bytes) */ ++ uint16_t nperio_tx_fifo_size; ++ ++ /** 1 if DMA is enabled, 0 otherwise. */ ++ uint8_t dma_enable; ++ ++ /** 1 if DMA descriptor is enabled, 0 otherwise. */ ++ uint8_t dma_desc_enable; ++ ++ /** 1 if PTI Enhancement mode is enabled, 0 otherwise. */ ++ uint8_t pti_enh_enable; ++ ++ /** 1 if MPI Enhancement mode is enabled, 0 otherwise. */ ++ uint8_t multiproc_int_enable; ++ ++ /** 1 if dedicated Tx FIFOs are enabled, 0 otherwise. */ ++ uint8_t en_multiple_tx_fifo; ++ ++ /** Set to 1 if multiple packets of a high-bandwidth transfer is in ++ * process of being queued */ ++ uint8_t queuing_high_bandwidth; ++ ++ /** Hardware Configuration -- stored here for convenience.*/ ++ hwcfg1_data_t hwcfg1; ++ hwcfg2_data_t hwcfg2; ++ hwcfg3_data_t hwcfg3; ++ hwcfg4_data_t hwcfg4; ++ fifosize_data_t hptxfsiz; ++ ++ /** Host and Device Configuration -- stored here for convenience.*/ ++ hcfg_data_t hcfg; ++ dcfg_data_t dcfg; ++ ++ /** The operational State, during transations ++ * (a_host>>a_peripherial and b_device=>b_host) this may not ++ * match the core but allows the software to determine ++ * transitions. ++ */ ++ uint8_t op_state; ++ ++ /** ++ * Set to 1 if the HCD needs to be restarted on a session request ++ * interrupt. This is required if no connector ID status change has ++ * occurred since the HCD was last disconnected. ++ */ ++ uint8_t restart_hcd_on_session_req; ++ ++ /** HCD callbacks */ ++ /** A-Device is a_host */ ++#define A_HOST (1) ++ /** A-Device is a_suspend */ ++#define A_SUSPEND (2) ++ /** A-Device is a_peripherial */ ++#define A_PERIPHERAL (3) ++ /** B-Device is operating as a Peripheral. */ ++#define B_PERIPHERAL (4) ++ /** B-Device is operating as a Host. */ ++#define B_HOST (5) ++ ++ /** HCD callbacks */ ++ struct dwc_otg_cil_callbacks *hcd_cb; ++ /** PCD callbacks */ ++ struct dwc_otg_cil_callbacks *pcd_cb; ++ ++ /** Device mode Periodic Tx FIFO Mask */ ++ uint32_t p_tx_msk; ++ /** Device mode Periodic Tx FIFO Mask */ ++ uint32_t tx_msk; ++ ++ /** Workqueue object used for handling several interrupts */ ++ dwc_workq_t *wq_otg; ++ ++ /** Timer object used for handling "Wakeup Detected" Interrupt */ ++ dwc_timer_t *wkp_timer; ++ /** This arrays used for debug purposes for DEV OUT NAK enhancement */ ++ uint32_t start_doeptsiz_val[MAX_EPS_CHANNELS]; ++ ep_xfer_info_t ep_xfer_info[MAX_EPS_CHANNELS]; ++ dwc_timer_t *ep_xfer_timer[MAX_EPS_CHANNELS]; ++#ifdef DEBUG ++ uint32_t start_hcchar_val[MAX_EPS_CHANNELS]; ++ ++ hc_xfer_info_t hc_xfer_info[MAX_EPS_CHANNELS]; ++ dwc_timer_t *hc_xfer_timer[MAX_EPS_CHANNELS]; ++ ++ uint32_t hfnum_7_samples; ++ uint64_t hfnum_7_frrem_accum; ++ uint32_t hfnum_0_samples; ++ uint64_t hfnum_0_frrem_accum; ++ uint32_t hfnum_other_samples; ++ uint64_t hfnum_other_frrem_accum; ++#endif ++ ++#ifdef DWC_UTE_CFI ++ uint16_t pwron_rxfsiz; ++ uint16_t pwron_gnptxfsiz; ++ uint16_t pwron_txfsiz[15]; ++ ++ uint16_t init_rxfsiz; ++ uint16_t init_gnptxfsiz; ++ uint16_t init_txfsiz[15]; ++#endif ++ ++ /** Lx state of device */ ++ dwc_otg_lx_state_e lx_state; ++ ++ /** Saved Core Global registers */ ++ struct dwc_otg_global_regs_backup *gr_backup; ++ /** Saved Host registers */ ++ struct dwc_otg_host_regs_backup *hr_backup; ++ /** Saved Device registers */ ++ struct dwc_otg_dev_regs_backup *dr_backup; ++ ++ /** Power Down Enable */ ++ uint32_t power_down; ++ ++ /** ADP support Enable */ ++ uint32_t adp_enable; ++ ++ /** ADP structure object */ ++ dwc_otg_adp_t adp; ++ ++ /** hibernation/suspend flag */ ++ int hibernation_suspend; ++ ++ /** Device mode extended hibernation flag */ ++ int xhib; ++ ++ /** OTG revision supported */ ++ uint32_t otg_ver; ++ ++ /** OTG status flag used for HNP polling */ ++ uint8_t otg_sts; ++ ++ /** Pointer to either hcd->lock or pcd->lock */ ++ dwc_spinlock_t *lock; ++ ++ /** Start predict NextEP based on Learning Queue if equal 1, ++ * also used as counter of disabled NP IN EP's */ ++ uint8_t start_predict; ++ ++ /** NextEp sequence, including EP0: nextep_seq[] = EP if non-periodic and ++ * active, 0xff otherwise */ ++ uint8_t nextep_seq[MAX_EPS_CHANNELS]; ++ ++ /** Index of fisrt EP in nextep_seq array which should be re-enabled **/ ++ uint8_t first_in_nextep_seq; ++ ++ /** Frame number while entering to ISR - needed for ISOCs **/ ++ uint32_t frame_num; ++ ++}; ++ ++#ifdef DEBUG ++/* ++ * This function is called when transfer is timed out. ++ */ ++extern void hc_xfer_timeout(void *ptr); ++#endif ++ ++/* ++ * This function is called when transfer is timed out on endpoint. ++ */ ++extern void ep_xfer_timeout(void *ptr); ++ ++/* ++ * The following functions are functions for works ++ * using during handling some interrupts ++ */ ++extern void w_conn_id_status_change(void *p); ++ ++extern void w_wakeup_detected(void *p); ++ ++/** Saves global register values into system memory. */ ++extern int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if); ++/** Saves device register values into system memory. */ ++extern int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if); ++/** Saves host register values into system memory. */ ++extern int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if); ++/** Restore global register values. */ ++extern int dwc_otg_restore_global_regs(dwc_otg_core_if_t * core_if); ++/** Restore host register values. */ ++extern int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset); ++/** Restore device register values. */ ++extern int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, ++ int rem_wakeup); ++extern int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if); ++extern int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, ++ int is_host); ++ ++extern int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if, ++ int restore_mode, int reset); ++extern int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if, ++ int rem_wakeup, int reset); ++ ++/* ++ * The following functions support initialization of the CIL driver component ++ * and the DWC_otg controller. ++ */ ++extern void dwc_otg_core_host_init(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_core_dev_init(dwc_otg_core_if_t * _core_if); ++ ++/** @name Device CIL Functions ++ * The following functions support managing the DWC_otg controller in device ++ * mode. ++ */ ++/**@{*/ ++extern void dwc_otg_wakeup(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_read_setup_packet(dwc_otg_core_if_t * _core_if, ++ uint32_t * _dest); ++extern uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_ep0_activate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); ++extern void dwc_otg_ep_activate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); ++extern void dwc_otg_ep_deactivate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); ++extern void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * _core_if, ++ dwc_ep_t * _ep); ++extern void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * _core_if, ++ dwc_ep_t * _ep); ++extern void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * _core_if, ++ dwc_ep_t * _ep); ++extern void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * _core_if, ++ dwc_ep_t * _ep); ++extern void dwc_otg_ep_write_packet(dwc_otg_core_if_t * _core_if, ++ dwc_ep_t * _ep, int _dma); ++extern void dwc_otg_ep_set_stall(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); ++extern void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * _core_if, ++ dwc_ep_t * _ep); ++extern void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * _core_if); ++ ++#ifdef DWC_EN_ISOC ++extern void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * ep); ++extern void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * ep); ++#endif /* DWC_EN_ISOC */ ++/**@}*/ ++ ++/** @name Host CIL Functions ++ * The following functions support managing the DWC_otg controller in host ++ * mode. ++ */ ++/**@{*/ ++extern void dwc_otg_hc_init(dwc_otg_core_if_t * _core_if, dwc_hc_t * _hc); ++extern void dwc_otg_hc_halt(dwc_otg_core_if_t * _core_if, ++ dwc_hc_t * _hc, dwc_otg_halt_status_e _halt_status); ++extern void dwc_otg_hc_cleanup(dwc_otg_core_if_t * _core_if, dwc_hc_t * _hc); ++extern void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * _core_if, ++ dwc_hc_t * _hc); ++extern int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * _core_if, ++ dwc_hc_t * _hc); ++extern void dwc_otg_hc_do_ping(dwc_otg_core_if_t * _core_if, dwc_hc_t * _hc); ++extern void dwc_otg_hc_write_packet(dwc_otg_core_if_t * _core_if, ++ dwc_hc_t * _hc); ++extern void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * _core_if); ++ ++extern void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, ++ dwc_hc_t * hc); ++ ++extern uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if); ++ ++/* Macro used to clear one channel interrupt */ ++#define clear_hc_int(_hc_regs_, _intr_) \ ++do { \ ++ hcint_data_t hcint_clear = {.d32 = 0}; \ ++ hcint_clear.b._intr_ = 1; \ ++ DWC_WRITE_REG32(&(_hc_regs_)->hcint, hcint_clear.d32); \ ++} while (0) ++ ++/* ++ * Macro used to disable one channel interrupt. Channel interrupts are ++ * disabled when the channel is halted or released by the interrupt handler. ++ * There is no need to handle further interrupts of that type until the ++ * channel is re-assigned. In fact, subsequent handling may cause crashes ++ * because the channel structures are cleaned up when the channel is released. ++ */ ++#define disable_hc_int(_hc_regs_, _intr_) \ ++do { \ ++ hcintmsk_data_t hcintmsk = {.d32 = 0}; \ ++ hcintmsk.b._intr_ = 1; \ ++ DWC_MODIFY_REG32(&(_hc_regs_)->hcintmsk, hcintmsk.d32, 0); \ ++} while (0) ++ ++/** ++ * This function Reads HPRT0 in preparation to modify. It keeps the ++ * WC bits 0 so that if they are read as 1, they won't clear when you ++ * write it back ++ */ ++static inline uint32_t dwc_otg_read_hprt0(dwc_otg_core_if_t * _core_if) ++{ ++ hprt0_data_t hprt0; ++ hprt0.d32 = DWC_READ_REG32(_core_if->host_if->hprt0); ++ hprt0.b.prtena = 0; ++ hprt0.b.prtconndet = 0; ++ hprt0.b.prtenchng = 0; ++ hprt0.b.prtovrcurrchng = 0; ++ return hprt0.d32; ++} ++ ++/**@}*/ ++ ++/** @name Common CIL Functions ++ * The following functions support managing the DWC_otg controller in either ++ * device or host mode. ++ */ ++/**@{*/ ++ ++extern void dwc_otg_read_packet(dwc_otg_core_if_t * core_if, ++ uint8_t * dest, uint16_t bytes); ++ ++extern void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * _core_if, const int _num); ++extern void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_core_reset(dwc_otg_core_if_t * _core_if); ++ ++/** ++ * This function returns the Core Interrupt register. ++ */ ++static inline uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t * core_if) ++{ ++ return (DWC_READ_REG32(&core_if->core_global_regs->gintsts) & ++ DWC_READ_REG32(&core_if->core_global_regs->gintmsk)); ++} ++ ++/** ++ * This function returns the OTG Interrupt register. ++ */ ++static inline uint32_t dwc_otg_read_otg_intr(dwc_otg_core_if_t * core_if) ++{ ++ return (DWC_READ_REG32(&core_if->core_global_regs->gotgint)); ++} ++ ++/** ++ * This function reads the Device All Endpoints Interrupt register and ++ * returns the IN endpoint interrupt bits. ++ */ ++static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t * ++ core_if) ++{ ++ ++ uint32_t v; ++ ++ if (core_if->multiproc_int_enable) { ++ v = DWC_READ_REG32(&core_if->dev_if-> ++ dev_global_regs->deachint) & ++ DWC_READ_REG32(&core_if-> ++ dev_if->dev_global_regs->deachintmsk); ++ } else { ++ v = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daint) & ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk); ++ } ++ return (v & 0xffff); ++} ++ ++/** ++ * This function reads the Device All Endpoints Interrupt register and ++ * returns the OUT endpoint interrupt bits. ++ */ ++static inline uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t * ++ core_if) ++{ ++ uint32_t v; ++ ++ if (core_if->multiproc_int_enable) { ++ v = DWC_READ_REG32(&core_if->dev_if-> ++ dev_global_regs->deachint) & ++ DWC_READ_REG32(&core_if-> ++ dev_if->dev_global_regs->deachintmsk); ++ } else { ++ v = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daint) & ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk); ++ } ++ ++ return ((v & 0xffff0000) >> 16); ++} ++ ++/** ++ * This function returns the Device IN EP Interrupt register ++ */ ++static inline uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * ep) ++{ ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ uint32_t v, msk, emp; ++ ++ if (core_if->multiproc_int_enable) { ++ msk = ++ DWC_READ_REG32(&dev_if-> ++ dev_global_regs->diepeachintmsk[ep->num]); ++ emp = ++ DWC_READ_REG32(&dev_if-> ++ dev_global_regs->dtknqr4_fifoemptymsk); ++ msk |= ((emp >> ep->num) & 0x1) << 7; ++ v = DWC_READ_REG32(&dev_if->in_ep_regs[ep->num]->diepint) & msk; ++ } else { ++ msk = DWC_READ_REG32(&dev_if->dev_global_regs->diepmsk); ++ emp = ++ DWC_READ_REG32(&dev_if-> ++ dev_global_regs->dtknqr4_fifoemptymsk); ++ msk |= ((emp >> ep->num) & 0x1) << 7; ++ v = DWC_READ_REG32(&dev_if->in_ep_regs[ep->num]->diepint) & msk; ++ } ++ ++ return v; ++} ++ ++/** ++ * This function returns the Device OUT EP Interrupt register ++ */ ++static inline uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t * ++ _core_if, dwc_ep_t * _ep) ++{ ++ dwc_otg_dev_if_t *dev_if = _core_if->dev_if; ++ uint32_t v; ++ doepmsk_data_t msk = {.d32 = 0 }; ++ ++ if (_core_if->multiproc_int_enable) { ++ msk.d32 = ++ DWC_READ_REG32(&dev_if-> ++ dev_global_regs->doepeachintmsk[_ep->num]); ++ if (_core_if->pti_enh_enable) { ++ msk.b.pktdrpsts = 1; ++ } ++ v = DWC_READ_REG32(&dev_if-> ++ out_ep_regs[_ep->num]->doepint) & msk.d32; ++ } else { ++ msk.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->doepmsk); ++ if (_core_if->pti_enh_enable) { ++ msk.b.pktdrpsts = 1; ++ } ++ v = DWC_READ_REG32(&dev_if-> ++ out_ep_regs[_ep->num]->doepint) & msk.d32; ++ } ++ return v; ++} ++ ++/** ++ * This function returns the Host All Channel Interrupt register ++ */ ++static inline uint32_t dwc_otg_read_host_all_channels_intr(dwc_otg_core_if_t * ++ _core_if) ++{ ++ return (DWC_READ_REG32(&_core_if->host_if->host_global_regs->haint)); ++} ++ ++static inline uint32_t dwc_otg_read_host_channel_intr(dwc_otg_core_if_t * ++ _core_if, dwc_hc_t * _hc) ++{ ++ return (DWC_READ_REG32 ++ (&_core_if->host_if->hc_regs[_hc->hc_num]->hcint)); ++} ++ ++/** ++ * This function returns the mode of the operation, host or device. ++ * ++ * @return 0 - Device Mode, 1 - Host Mode ++ */ ++static inline uint32_t dwc_otg_mode(dwc_otg_core_if_t * _core_if) ++{ ++ return (DWC_READ_REG32(&_core_if->core_global_regs->gintsts) & 0x1); ++} ++ ++/**@}*/ ++ ++/** ++ * DWC_otg CIL callback structure. This structure allows the HCD and ++ * PCD to register functions used for starting and stopping the PCD ++ * and HCD for role change on for a DRD. ++ */ ++typedef struct dwc_otg_cil_callbacks { ++ /** Start function for role change */ ++ int (*start) (void *_p); ++ /** Stop Function for role change */ ++ int (*stop) (void *_p); ++ /** Disconnect Function for role change */ ++ int (*disconnect) (void *_p); ++ /** Resume/Remote wakeup Function */ ++ int (*resume_wakeup) (void *_p); ++ /** Suspend function */ ++ int (*suspend) (void *_p); ++ /** Session Start (SRP) */ ++ int (*session_start) (void *_p); ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ /** Sleep (switch to L0 state) */ ++ int (*sleep) (void *_p); ++#endif ++ /** Pointer passed to start() and stop() */ ++ void *p; ++} dwc_otg_cil_callbacks_t; ++ ++extern void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * _core_if, ++ dwc_otg_cil_callbacks_t * _cb, ++ void *_p); ++extern void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * _core_if, ++ dwc_otg_cil_callbacks_t * _cb, ++ void *_p); ++ ++void dwc_otg_initiate_srp(dwc_otg_core_if_t * core_if); ++ ++////////////////////////////////////////////////////////////////////// ++/** Start the HCD. Helper function for using the HCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_hcd_start(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->hcd_cb && core_if->hcd_cb->start) { ++ core_if->hcd_cb->start(core_if->hcd_cb->p); ++ } ++} ++ ++/** Stop the HCD. Helper function for using the HCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_hcd_stop(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->hcd_cb && core_if->hcd_cb->stop) { ++ core_if->hcd_cb->stop(core_if->hcd_cb->p); ++ } ++} ++ ++/** Disconnect the HCD. Helper function for using the HCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_hcd_disconnect(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->hcd_cb && core_if->hcd_cb->disconnect) { ++ core_if->hcd_cb->disconnect(core_if->hcd_cb->p); ++ } ++} ++ ++/** Inform the HCD the a New Session has begun. Helper function for ++ * using the HCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_hcd_session_start(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->hcd_cb && core_if->hcd_cb->session_start) { ++ core_if->hcd_cb->session_start(core_if->hcd_cb->p); ++ } ++} ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++/** ++ * Inform the HCD about LPM sleep. ++ * Helper function for using the HCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_hcd_sleep(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->hcd_cb && core_if->hcd_cb->sleep) { ++ core_if->hcd_cb->sleep(core_if->hcd_cb->p); ++ } ++} ++#endif ++ ++/** Resume the HCD. Helper function for using the HCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_hcd_resume(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->hcd_cb && core_if->hcd_cb->resume_wakeup) { ++ core_if->hcd_cb->resume_wakeup(core_if->hcd_cb->p); ++ } ++} ++ ++/** Start the PCD. Helper function for using the PCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_pcd_start(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->pcd_cb && core_if->pcd_cb->start) { ++ core_if->pcd_cb->start(core_if->pcd_cb->p); ++ } ++} ++ ++/** Stop the PCD. Helper function for using the PCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_pcd_stop(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->pcd_cb && core_if->pcd_cb->stop) { ++ core_if->pcd_cb->stop(core_if->pcd_cb->p); ++ } ++} ++ ++/** Suspend the PCD. Helper function for using the PCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_pcd_suspend(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->pcd_cb && core_if->pcd_cb->suspend) { ++ core_if->pcd_cb->suspend(core_if->pcd_cb->p); ++ } ++} ++ ++/** Resume the PCD. Helper function for using the PCD callbacks. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static inline void cil_pcd_resume(dwc_otg_core_if_t * core_if) ++{ ++ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) { ++ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p); ++ } ++} ++ ++////////////////////////////////////////////////////////////////////// ++ ++#endif +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1563 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil_intr.c $ ++ * $Revision: #32 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++/** @file ++ * ++ * The Core Interface Layer provides basic services for accessing and ++ * managing the DWC_otg hardware. These services are used by both the ++ * Host Controller Driver and the Peripheral Controller Driver. ++ * ++ * This file contains the Common Interrupt handlers. ++ */ ++#include "dwc_os.h" ++#include "dwc_otg_regs.h" ++#include "dwc_otg_cil.h" ++#include "dwc_otg_driver.h" ++#include "dwc_otg_pcd.h" ++#include "dwc_otg_hcd.h" ++ ++#ifdef DEBUG ++inline const char *op_state_str(dwc_otg_core_if_t * core_if) ++{ ++ return (core_if->op_state == A_HOST ? "a_host" : ++ (core_if->op_state == A_SUSPEND ? "a_suspend" : ++ (core_if->op_state == A_PERIPHERAL ? "a_peripheral" : ++ (core_if->op_state == B_PERIPHERAL ? "b_peripheral" : ++ (core_if->op_state == B_HOST ? "b_host" : "unknown"))))); ++} ++#endif ++ ++/** This function will log a debug message ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++int32_t dwc_otg_handle_mode_mismatch_intr(dwc_otg_core_if_t * core_if) ++{ ++ gintsts_data_t gintsts; ++ DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n", ++ dwc_otg_mode(core_if) ? "Host" : "Device"); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.modemismatch = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ return 1; ++} ++ ++/** ++ * This function handles the OTG Interrupts. It reads the OTG ++ * Interrupt Register (GOTGINT) to determine what interrupt has ++ * occurred. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ gotgint_data_t gotgint; ++ gotgctl_data_t gotgctl; ++ gintmsk_data_t gintmsk; ++ gpwrdn_data_t gpwrdn; ++ ++ gotgint.d32 = DWC_READ_REG32(&global_regs->gotgint); ++ gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl); ++ DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32, ++ op_state_str(core_if)); ++ ++ if (gotgint.b.sesenddet) { ++ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " ++ "Session End Detected++ (%s)\n", ++ op_state_str(core_if)); ++ gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl); ++ ++ if (core_if->op_state == B_HOST) { ++ cil_pcd_start(core_if); ++ core_if->op_state = B_PERIPHERAL; ++ } else { ++ /* If not B_HOST and Device HNP still set. HNP ++ * Did not succeed!*/ ++ if (gotgctl.b.devhnpen) { ++ DWC_DEBUGPL(DBG_ANY, "Session End Detected\n"); ++ __DWC_ERROR("Device Not Connected/Responding!\n"); ++ } ++ ++ /* If Session End Detected the B-Cable has ++ * been disconnected. */ ++ /* Reset PCD and Gadget driver to a ++ * clean state. */ ++ core_if->lx_state = DWC_OTG_L0; ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_pcd_stop(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ ++ if (core_if->adp_enable) { ++ if (core_if->power_down == 2) { ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs-> ++ gpwrdn, gpwrdn.d32, 0); ++ } ++ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ ++ dwc_otg_adp_sense_start(core_if); ++ } ++ } ++ ++ gotgctl.d32 = 0; ++ gotgctl.b.devhnpen = 1; ++ DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0); ++ } ++ if (gotgint.b.sesreqsucstschng) { ++ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " ++ "Session Reqeust Success Status Change++\n"); ++ gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl); ++ if (gotgctl.b.sesreqscs) { ++ ++ if ((core_if->core_params->phy_type == ++ DWC_PHY_TYPE_PARAM_FS) && (core_if->core_params->i2c_enable)) { ++ core_if->srp_success = 1; ++ } else { ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_pcd_resume(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ /* Clear Session Request */ ++ gotgctl.d32 = 0; ++ gotgctl.b.sesreq = 1; ++ DWC_MODIFY_REG32(&global_regs->gotgctl, ++ gotgctl.d32, 0); ++ } ++ } ++ } ++ if (gotgint.b.hstnegsucstschng) { ++ /* Print statements during the HNP interrupt handling ++ * can cause it to fail.*/ ++ gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl); ++ /* WA for 3.00a- HW is not setting cur_mode, even sometimes ++ * this does not help*/ ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) ++ dwc_udelay(100); ++ if (gotgctl.b.hstnegscs) { ++ if (dwc_otg_is_host_mode(core_if)) { ++ core_if->op_state = B_HOST; ++ /* ++ * Need to disable SOF interrupt immediately. ++ * When switching from device to host, the PCD ++ * interrupt handler won't handle the ++ * interrupt if host mode is already set. The ++ * HCD interrupt handler won't get called if ++ * the HCD state is HALT. This means that the ++ * interrupt does not get handled and Linux ++ * complains loudly. ++ */ ++ gintmsk.d32 = 0; ++ gintmsk.b.sofintr = 1; ++ DWC_MODIFY_REG32(&global_regs->gintmsk, ++ gintmsk.d32, 0); ++ /* Call callback function with spin lock released */ ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_pcd_stop(core_if); ++ /* ++ * Initialize the Core for Host mode. ++ */ ++ cil_hcd_start(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ core_if->op_state = B_HOST; ++ } ++ } else { ++ gotgctl.d32 = 0; ++ gotgctl.b.hnpreq = 1; ++ gotgctl.b.devhnpen = 1; ++ DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0); ++ DWC_DEBUGPL(DBG_ANY, "HNP Failed\n"); ++ __DWC_ERROR("Device Not Connected/Responding\n"); ++ } ++ } ++ if (gotgint.b.hstnegdet) { ++ /* The disconnect interrupt is set at the same time as ++ * Host Negotiation Detected. During the mode ++ * switch all interrupts are cleared so the disconnect ++ * interrupt handler will not get executed. ++ */ ++ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " ++ "Host Negotiation Detected++ (%s)\n", ++ (dwc_otg_is_host_mode(core_if) ? "Host" : ++ "Device")); ++ if (dwc_otg_is_device_mode(core_if)) { ++ DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n", ++ core_if->op_state); ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_hcd_disconnect(core_if); ++ cil_pcd_start(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ core_if->op_state = A_PERIPHERAL; ++ } else { ++ /* ++ * Need to disable SOF interrupt immediately. When ++ * switching from device to host, the PCD interrupt ++ * handler won't handle the interrupt if host mode is ++ * already set. The HCD interrupt handler won't get ++ * called if the HCD state is HALT. This means that ++ * the interrupt does not get handled and Linux ++ * complains loudly. ++ */ ++ gintmsk.d32 = 0; ++ gintmsk.b.sofintr = 1; ++ DWC_MODIFY_REG32(&global_regs->gintmsk, gintmsk.d32, 0); ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_pcd_stop(core_if); ++ cil_hcd_start(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ core_if->op_state = A_HOST; ++ } ++ } ++ if (gotgint.b.adevtoutchng) { ++ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " ++ "A-Device Timeout Change++\n"); ++ } ++ if (gotgint.b.debdone) { ++ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " "Debounce Done++\n"); ++ } ++ ++ /* Clear GOTGINT */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gotgint, gotgint.d32); ++ ++ return 1; ++} ++ ++void w_conn_id_status_change(void *p) ++{ ++ dwc_otg_core_if_t *core_if = p; ++ uint32_t count = 0; ++ gotgctl_data_t gotgctl = {.d32 = 0 }; ++ ++ gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32); ++ DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts); ++ ++ /* B-Device connector (Device Mode) */ ++ if (gotgctl.b.conidsts) { ++ /* Wait for switch to device mode. */ ++ while (!dwc_otg_is_device_mode(core_if)) { ++ DWC_PRINTF("Waiting for Peripheral Mode, Mode=%s\n", ++ (dwc_otg_is_host_mode(core_if) ? "Host" : ++ "Peripheral")); ++ dwc_mdelay(100); ++ if (++count > 10000) ++ break; ++ } ++ DWC_ASSERT(++count < 10000, ++ "Connection id status change timed out"); ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ } else { ++ /* A-Device connector (Host Mode) */ ++ while (!dwc_otg_is_host_mode(core_if)) { ++ DWC_PRINTF("Waiting for Host Mode, Mode=%s\n", ++ (dwc_otg_is_host_mode(core_if) ? "Host" : ++ "Peripheral")); ++ dwc_mdelay(100); ++ if (++count > 10000) ++ break; ++ } ++ DWC_ASSERT(++count < 10000, ++ "Connection id status change timed out"); ++ core_if->op_state = A_HOST; ++ /* ++ * Initialize the Core for Host mode. ++ */ ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_hcd_start(core_if); ++ } ++} ++ ++/** ++ * This function handles the Connector ID Status Change Interrupt. It ++ * reads the OTG Interrupt Register (GOTCTL) to determine whether this ++ * is a Device to Host Mode transition or a Host Mode to Device ++ * Transition. ++ * ++ * This only occurs when the cable is connected/removed from the PHY ++ * connector. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t * core_if) ++{ ++ ++ /* ++ * Need to disable SOF interrupt immediately. If switching from device ++ * to host, the PCD interrupt handler won't handle the interrupt if ++ * host mode is already set. The HCD interrupt handler won't get ++ * called if the HCD state is HALT. This means that the interrupt does ++ * not get handled and Linux complains loudly. ++ */ ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ gintsts_data_t gintsts = {.d32 = 0 }; ++ ++ gintmsk.b.sofintr = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0); ++ ++ DWC_DEBUGPL(DBG_CIL, ++ " ++Connector ID Status Change Interrupt++ (%s)\n", ++ (dwc_otg_is_host_mode(core_if) ? "Host" : "Device")); ++ ++ DWC_SPINUNLOCK(core_if->lock); ++ ++ /* ++ * Need to schedule a work, as there are possible DELAY function calls ++ * Release lock before scheduling workq as it holds spinlock during scheduling ++ */ ++ ++ DWC_WORKQ_SCHEDULE(core_if->wq_otg, w_conn_id_status_change, ++ core_if, "connection id status change"); ++ DWC_SPINLOCK(core_if->lock); ++ ++ /* Set flag and clear interrupt */ ++ gintsts.b.conidstschng = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that a device is initiating the Session ++ * Request Protocol to request the host to turn on bus power so a new ++ * session can begin. The handler responds by turning on bus power. If ++ * the DWC_otg controller is in low power mode, the handler brings the ++ * controller out of low power mode before turning on bus power. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++int32_t dwc_otg_handle_session_req_intr(dwc_otg_core_if_t * core_if) ++{ ++ gintsts_data_t gintsts; ++ ++#ifndef DWC_HOST_ONLY ++ DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n"); ++ ++ if (dwc_otg_is_device_mode(core_if)) { ++ DWC_PRINTF("SRP: Device mode\n"); ++ } else { ++ hprt0_data_t hprt0; ++ DWC_PRINTF("SRP: Host mode\n"); ++ ++ /* Turn on the port power bit. */ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtpwr = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ /* Start the Connection timer. So a message can be displayed ++ * if connect does not occur within 10 seconds. */ ++ cil_hcd_session_start(core_if); ++ } ++#endif ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.sessreqintr = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++void w_wakeup_detected(void *p) ++{ ++ dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) p; ++ /* ++ * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms ++ * so that OPT tests pass with all PHYs). ++ */ ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++#if 0 ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ /* Restart the Phy Clock */ ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0); ++ dwc_udelay(10); ++#endif //0 ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ DWC_DEBUGPL(DBG_ANY, "Resume: HPRT0=%0x\n", hprt0.d32); ++// dwc_mdelay(70); ++ hprt0.b.prtres = 0; /* Resume */ ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ DWC_DEBUGPL(DBG_ANY, "Clear Resume: HPRT0=%0x\n", ++ DWC_READ_REG32(core_if->host_if->hprt0)); ++ ++ cil_hcd_resume(core_if); ++ ++ /** Change to L0 state*/ ++ core_if->lx_state = DWC_OTG_L0; ++} ++ ++/** ++ * This interrupt indicates that the DWC_otg controller has detected a ++ * resume or remote wakeup sequence. If the DWC_otg controller is in ++ * low power mode, the handler must brings the controller out of low ++ * power mode. The controller automatically begins resume ++ * signaling. The handler schedules a time to stop resume signaling. ++ */ ++int32_t dwc_otg_handle_wakeup_detected_intr(dwc_otg_core_if_t * core_if) ++{ ++ gintsts_data_t gintsts; ++ ++ DWC_DEBUGPL(DBG_ANY, ++ "++Resume and Remote Wakeup Detected Interrupt++\n"); ++ ++ DWC_PRINTF("%s lxstate = %d\n", __func__, core_if->lx_state); ++ ++ if (dwc_otg_is_device_mode(core_if)) { ++ dctl_data_t dctl = {.d32 = 0 }; ++ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs-> ++ dsts)); ++ if (core_if->lx_state == DWC_OTG_L2) { ++#ifdef PARTIAL_POWER_DOWN ++ if (core_if->hwcfg4.b.power_optimiz) { ++ pcgcctl_data_t power = {.d32 = 0 }; ++ ++ power.d32 = DWC_READ_REG32(core_if->pcgcctl); ++ DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", ++ power.d32); ++ ++ power.b.stoppclk = 0; ++ DWC_WRITE_REG32(core_if->pcgcctl, power.d32); ++ ++ power.b.pwrclmp = 0; ++ DWC_WRITE_REG32(core_if->pcgcctl, power.d32); ++ ++ power.b.rstpdwnmodule = 0; ++ DWC_WRITE_REG32(core_if->pcgcctl, power.d32); ++ } ++#endif ++ /* Clear the Remote Wakeup Signaling */ ++ dctl.b.rmtwkupsig = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ dctl, dctl.d32, 0); ++ ++ DWC_SPINUNLOCK(core_if->lock); ++ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) { ++ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p); ++ } ++ DWC_SPINLOCK(core_if->lock); ++ } else { ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ lpmcfg.b.hird_thres &= (~(1 << 4)); ++ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, ++ lpmcfg.d32); ++ } ++ /** Change to L0 state*/ ++ core_if->lx_state = DWC_OTG_L0; ++ } else { ++ if (core_if->lx_state != DWC_OTG_L1) { ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ ++ /* Restart the Phy Clock */ ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0); ++ DWC_TIMER_SCHEDULE(core_if->wkp_timer, 71); ++ } else { ++ /** Change to L0 state*/ ++ core_if->lx_state = DWC_OTG_L0; ++ } ++ } ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.wkupintr = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that the Wakeup Logic has detected a ++ * Device disconnect. ++ */ ++static int32_t dwc_otg_handle_pwrdn_disconnect_intr(dwc_otg_core_if_t *core_if) ++{ ++ gpwrdn_data_t gpwrdn = { .d32 = 0 }; ++ gpwrdn_data_t gpwrdn_temp = { .d32 = 0 }; ++ gpwrdn_temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ ++ DWC_PRINTF("%s called\n", __FUNCTION__); ++ ++ if (!core_if->hibernation_suspend) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return 1; ++ } ++ ++ /* Switch on the voltage to the core */ ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Reset the core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Disable power clamps*/ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Remove reset the core signal */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable PMU interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ core_if->hibernation_suspend = 0; ++ ++ /* Disable PMU */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ if (gpwrdn_temp.b.idsts) { ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ } else { ++ core_if->op_state = A_HOST; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_hcd_start(core_if); ++ } ++ ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that the Wakeup Logic has detected a ++ * remote wakeup sequence. ++ */ ++static int32_t dwc_otg_handle_pwrdn_wakeup_detected_intr(dwc_otg_core_if_t * core_if) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ DWC_DEBUGPL(DBG_ANY, ++ "++Powerdown Remote Wakeup Detected Interrupt++\n"); ++ ++ if (!core_if->hibernation_suspend) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return 1; ++ } ++ ++ gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ if (gpwrdn.b.idsts) { // Device Mode ++ if ((core_if->power_down == 2) ++ && (core_if->hibernation_suspend == 1)) { ++ dwc_otg_device_hibernation_restore(core_if, 0, 0); ++ } ++ } else { ++ if ((core_if->power_down == 2) ++ && (core_if->hibernation_suspend == 1)) { ++ dwc_otg_host_hibernation_restore(core_if, 1, 0); ++ } ++ } ++ return 1; ++} ++ ++static int32_t dwc_otg_handle_pwrdn_idsts_change(dwc_otg_device_t *otg_dev) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ gpwrdn_data_t gpwrdn_temp = {.d32 = 0 }; ++ dwc_otg_core_if_t *core_if = otg_dev->core_if; ++ ++ DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__); ++ gpwrdn_temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ if (core_if->power_down == 2) { ++ if (!core_if->hibernation_suspend) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return 1; ++ } ++ DWC_DEBUGPL(DBG_ANY, "Exit from hibernation on ID sts change\n"); ++ /* Switch on the voltage to the core */ ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Reset the core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Disable power clamps */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Remove reset the core signal */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable PMU interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /*Indicates that we are exiting from hibernation */ ++ core_if->hibernation_suspend = 0; ++ ++ /* Disable PMU */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ gpwrdn.d32 = core_if->gr_backup->gpwrdn_local; ++ if (gpwrdn.b.dis_vbus == 1) { ++ gpwrdn.d32 = 0; ++ gpwrdn.b.dis_vbus = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ } ++ ++ if (gpwrdn_temp.b.idsts) { ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ } else { ++ core_if->op_state = A_HOST; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_hcd_start(core_if); ++ } ++ } ++ ++ if (core_if->adp_enable) { ++ uint8_t is_host = 0; ++ DWC_SPINUNLOCK(core_if->lock); ++ /* Change the core_if's lock to hcd/pcd lock depend on mode? */ ++#ifndef DWC_HOST_ONLY ++ if (gpwrdn_temp.b.idsts) ++ core_if->lock = otg_dev->pcd->lock; ++#endif ++#ifndef DWC_DEVICE_ONLY ++ if (!gpwrdn_temp.b.idsts) { ++ core_if->lock = otg_dev->hcd->lock; ++ is_host = 1; ++ } ++#endif ++ DWC_PRINTF("RESTART ADP\n"); ++ if (core_if->adp.probe_enabled) ++ dwc_otg_adp_probe_stop(core_if); ++ if (core_if->adp.sense_enabled) ++ dwc_otg_adp_sense_stop(core_if); ++ if (core_if->adp.sense_timer_started) ++ DWC_TIMER_CANCEL(core_if->adp.sense_timer); ++ if (core_if->adp.vbuson_timer_started) ++ DWC_TIMER_CANCEL(core_if->adp.vbuson_timer); ++ core_if->adp.probe_timer_values[0] = -1; ++ core_if->adp.probe_timer_values[1] = -1; ++ core_if->adp.sense_timer_started = 0; ++ core_if->adp.vbuson_timer_started = 0; ++ core_if->adp.probe_counter = 0; ++ core_if->adp.gpwrdn = 0; ++ ++ /* Disable PMU and restart ADP */ ++ gpwrdn_temp.d32 = 0; ++ gpwrdn_temp.b.pmuactv = 1; ++ gpwrdn_temp.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ DWC_PRINTF("Check point 1\n"); ++ dwc_mdelay(110); ++ dwc_otg_adp_start(core_if, is_host); ++ DWC_SPINLOCK(core_if->lock); ++ } ++ ++ ++ return 1; ++} ++ ++static int32_t dwc_otg_handle_pwrdn_session_change(dwc_otg_core_if_t * core_if) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ int32_t otg_cap_param = core_if->core_params->otg_cap; ++ DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__); ++ ++ gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ if (core_if->power_down == 2) { ++ if (!core_if->hibernation_suspend) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return 1; ++ } ++ ++ if ((otg_cap_param != DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE || ++ otg_cap_param != DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE) && ++ gpwrdn.b.bsessvld == 0) { ++ /* Save gpwrdn register for further usage if stschng interrupt */ ++ core_if->gr_backup->gpwrdn_local = ++ DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ /*Exit from ISR and wait for stschng interrupt with bsessvld = 1 */ ++ return 1; ++ } ++ ++ /* Switch on the voltage to the core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Reset the core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Disable power clamps */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Remove reset the core signal */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable PMU interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /*Indicates that we are exiting from hibernation */ ++ core_if->hibernation_suspend = 0; ++ ++ /* Disable PMU */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ ++ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE || ++ otg_cap_param == DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE) { ++ /* ++ * Initiate SRP after initial ADP probe. ++ */ ++ dwc_otg_initiate_srp(core_if); ++ } ++ } ++ ++ return 1; ++} ++/** ++ * This interrupt indicates that the Wakeup Logic has detected a ++ * status change either on IDDIG or BSessVld. ++ */ ++static uint32_t dwc_otg_handle_pwrdn_stschng_intr(dwc_otg_device_t *otg_dev) ++{ ++ int retval; ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ gpwrdn_data_t gpwrdn_temp = {.d32 = 0 }; ++ dwc_otg_core_if_t *core_if = otg_dev->core_if; ++ ++ DWC_PRINTF("%s called\n", __FUNCTION__); ++ ++ if (core_if->power_down == 2) { ++ if (core_if->hibernation_suspend <= 0) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return 1; ++ } else ++ gpwrdn_temp.d32 = core_if->gr_backup->gpwrdn_local; ++ ++ } else { ++ gpwrdn_temp.d32 = core_if->adp.gpwrdn; ++ } ++ ++ gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ ++ if (gpwrdn.b.idsts ^ gpwrdn_temp.b.idsts) { ++ retval = dwc_otg_handle_pwrdn_idsts_change(otg_dev); ++ } else if (gpwrdn.b.bsessvld ^ gpwrdn_temp.b.bsessvld) { ++ retval = dwc_otg_handle_pwrdn_session_change(core_if); ++ } ++ ++ return retval; ++} ++ ++/** ++ * This interrupt indicates that the Wakeup Logic has detected a ++ * SRP. ++ */ ++static int32_t dwc_otg_handle_pwrdn_srp_intr(dwc_otg_core_if_t * core_if) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ ++ DWC_PRINTF("%s called\n", __FUNCTION__); ++ ++ if (!core_if->hibernation_suspend) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return 1; ++ } ++#ifdef DWC_DEV_SRPCAP ++ if (core_if->pwron_timer_started) { ++ core_if->pwron_timer_started = 0; ++ DWC_TIMER_CANCEL(core_if->pwron_timer); ++ } ++#endif ++ ++ /* Switch on the voltage to the core */ ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Reset the core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Disable power clamps */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Remove reset the core signal */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable PMU interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Indicates that we are exiting from hibernation */ ++ core_if->hibernation_suspend = 0; ++ ++ /* Disable PMU */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Programm Disable VBUS to 0 */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.dis_vbus = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /*Initialize the core as Host */ ++ core_if->op_state = A_HOST; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_hcd_start(core_if); ++ ++ return 1; ++} ++ ++/** This interrupt indicates that restore command after Hibernation ++ * was completed by the core. */ ++int32_t dwc_otg_handle_restore_done_intr(dwc_otg_core_if_t * core_if) ++{ ++ pcgcctl_data_t pcgcctl; ++ DWC_DEBUGPL(DBG_ANY, "++Restore Done Interrupt++\n"); ++ ++ //TODO De-assert restore signal. 8.a ++ pcgcctl.d32 = DWC_READ_REG32(core_if->pcgcctl); ++ if (pcgcctl.b.restoremode == 1) { ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ /* ++ * If restore mode is Remote Wakeup, ++ * unmask Remote Wakeup interrupt. ++ */ ++ gintmsk.b.wkupintr = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, ++ 0, gintmsk.d32); ++ } ++ ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that a device has been disconnected from ++ * the root port. ++ */ ++int32_t dwc_otg_handle_disconnect_intr(dwc_otg_core_if_t * core_if) ++{ ++ gintsts_data_t gintsts; ++ ++ DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n", ++ (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"), ++ op_state_str(core_if)); ++ ++/** @todo Consolidate this if statement. */ ++#ifndef DWC_HOST_ONLY ++ if (core_if->op_state == B_HOST) { ++ /* If in device mode Disconnect and stop the HCD, then ++ * start the PCD. */ ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_hcd_disconnect(core_if); ++ cil_pcd_start(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ core_if->op_state = B_PERIPHERAL; ++ } else if (dwc_otg_is_device_mode(core_if)) { ++ gotgctl_data_t gotgctl = {.d32 = 0 }; ++ gotgctl.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->gotgctl); ++ if (gotgctl.b.hstsethnpen == 1) { ++ /* Do nothing, if HNP in process the OTG ++ * interrupt "Host Negotiation Detected" ++ * interrupt will do the mode switch. ++ */ ++ } else if (gotgctl.b.devhnpen == 0) { ++ /* If in device mode Disconnect and stop the HCD, then ++ * start the PCD. */ ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_hcd_disconnect(core_if); ++ cil_pcd_start(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ core_if->op_state = B_PERIPHERAL; ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "!a_peripheral && !devhnpen\n"); ++ } ++ } else { ++ if (core_if->op_state == A_HOST) { ++ /* A-Cable still connected but device disconnected. */ ++ cil_hcd_disconnect(core_if); ++ if (core_if->adp_enable) { ++ gpwrdn_data_t gpwrdn = { .d32 = 0 }; ++ cil_hcd_stop(core_if); ++ /* Enable Power Down Logic */ ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_otg_adp_probe_start(core_if); ++ ++ /* Power off the core */ ++ if (core_if->power_down == 2) { ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32 ++ (&core_if->core_global_regs->gpwrdn, ++ gpwrdn.d32, 0); ++ } ++ } ++ } ++ } ++#endif ++ /* Change to L3(OFF) state */ ++ core_if->lx_state = DWC_OTG_L3; ++ ++ gintsts.d32 = 0; ++ gintsts.b.disconnect = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that SUSPEND state has been detected on ++ * the USB. ++ * ++ * For HNP the USB Suspend interrupt signals the change from ++ * "a_peripheral" to "a_host". ++ * ++ * When power management is enabled the core will be put in low power ++ * mode. ++ */ ++int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if) ++{ ++ dsts_data_t dsts; ++ gintsts_data_t gintsts; ++ dcfg_data_t dcfg; ++ ++ DWC_DEBUGPL(DBG_ANY, "USB SUSPEND\n"); ++ ++ if (dwc_otg_is_device_mode(core_if)) { ++ /* Check the Device status register to determine if the Suspend ++ * state is active. */ ++ dsts.d32 = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32); ++ DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d " ++ "HWCFG4.power Optimize=%d\n", ++ dsts.b.suspsts, core_if->hwcfg4.b.power_optimiz); ++ ++#ifdef PARTIAL_POWER_DOWN ++/** @todo Add a module parameter for power management. */ ++ ++ if (dsts.b.suspsts && core_if->hwcfg4.b.power_optimiz) { ++ pcgcctl_data_t power = {.d32 = 0 }; ++ DWC_DEBUGPL(DBG_CIL, "suspend\n"); ++ ++ power.b.pwrclmp = 1; ++ DWC_WRITE_REG32(core_if->pcgcctl, power.d32); ++ ++ power.b.rstpdwnmodule = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, power.d32); ++ ++ power.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, power.d32); ++ ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "disconnect?\n"); ++ } ++#endif ++ /* PCD callback for suspend. Release the lock inside of callback function */ ++ cil_pcd_suspend(core_if); ++ if (core_if->power_down == 2) ++ { ++ dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ DWC_DEBUGPL(DBG_ANY,"lx_state = %08x\n",core_if->lx_state); ++ DWC_DEBUGPL(DBG_ANY," device address = %08d\n",dcfg.b.devaddr); ++ ++ if (core_if->lx_state != DWC_OTG_L3 && dcfg.b.devaddr) { ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ gusbcfg_data_t gusbcfg = {.d32 = 0 }; ++ ++ /* Change to L2(suspend) state */ ++ core_if->lx_state = DWC_OTG_L2; ++ ++ /* Clear interrupt in gintsts */ ++ gintsts.d32 = 0; ++ gintsts.b.usbsuspend = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs-> ++ gintsts, gintsts.d32); ++ DWC_PRINTF("Start of hibernation completed\n"); ++ dwc_otg_save_global_regs(core_if); ++ dwc_otg_save_dev_regs(core_if); ++ ++ gusbcfg.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs-> ++ gusbcfg); ++ if (gusbcfg.b.ulpi_utmi_sel == 1) { ++ /* ULPI interface */ ++ /* Suspend the Phy Clock */ ++ pcgcctl.d32 = 0; ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, ++ pcgcctl.d32); ++ dwc_udelay(10); ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ } else { ++ /* UTMI+ Interface */ ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, ++ pcgcctl.d32); ++ dwc_udelay(10); ++ } ++ ++ /* Set flag to indicate that we are in hibernation */ ++ core_if->hibernation_suspend = 1; ++ /* Enable interrupts from wake up logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Unmask device mode interrupts in GPWRDN */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.rst_det_msk = 1; ++ gpwrdn.b.lnstchng_msk = 1; ++ gpwrdn.b.sts_chngint_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Enable Power Down Clamp */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Switch off VDD */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ ++ /* Save gpwrdn register for further usage if stschng interrupt */ ++ core_if->gr_backup->gpwrdn_local = ++ DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ DWC_PRINTF("Hibernation completed\n"); ++ ++ return 1; ++ } ++ } else if (core_if->power_down == 3) { ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); ++ DWC_DEBUGPL(DBG_ANY, "lx_state = %08x\n",core_if->lx_state); ++ DWC_DEBUGPL(DBG_ANY, " device address = %08d\n",dcfg.b.devaddr); ++ ++ if (core_if->lx_state != DWC_OTG_L3 && dcfg.b.devaddr) { ++ DWC_DEBUGPL(DBG_ANY, "Start entering to extended hibernation\n"); ++ core_if->xhib = 1; ++ ++ /* Clear interrupt in gintsts */ ++ gintsts.d32 = 0; ++ gintsts.b.usbsuspend = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs-> ++ gintsts, gintsts.d32); ++ ++ dwc_otg_save_global_regs(core_if); ++ dwc_otg_save_dev_regs(core_if); ++ ++ /* Wait for 10 PHY clocks */ ++ dwc_udelay(10); ++ ++ /* Program GPIO register while entering to xHib */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, 0x1); ++ ++ pcgcctl.b.enbl_extnd_hiber = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32); ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32); ++ ++ pcgcctl.d32 = 0; ++ pcgcctl.b.extnd_hiber_pwrclmp = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32); ++ ++ pcgcctl.d32 = 0; ++ pcgcctl.b.extnd_hiber_switch = 1; ++ core_if->gr_backup->xhib_gpwrdn = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ core_if->gr_backup->xhib_pcgcctl = DWC_READ_REG32(core_if->pcgcctl) | pcgcctl.d32; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32); ++ ++ DWC_DEBUGPL(DBG_ANY, "Finished entering to extended hibernation\n"); ++ ++ return 1; ++ } ++ } ++ } else { ++ if (core_if->op_state == A_PERIPHERAL) { ++ DWC_DEBUGPL(DBG_ANY, "a_peripheral->a_host\n"); ++ /* Clear the a_peripheral flag, back to a_host. */ ++ DWC_SPINUNLOCK(core_if->lock); ++ cil_pcd_stop(core_if); ++ cil_hcd_start(core_if); ++ DWC_SPINLOCK(core_if->lock); ++ core_if->op_state = A_HOST; ++ } ++ } ++ ++ /* Change to L2(suspend) state */ ++ core_if->lx_state = DWC_OTG_L2; ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.usbsuspend = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++static int32_t dwc_otg_handle_xhib_exit_intr(dwc_otg_core_if_t * core_if) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ gahbcfg_data_t gahbcfg = {.d32 = 0 }; ++ ++ dwc_udelay(10); ++ ++ /* Program GPIO register while entering to xHib */ ++ DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, 0x0); ++ ++ pcgcctl.d32 = core_if->gr_backup->xhib_pcgcctl; ++ pcgcctl.b.extnd_hiber_pwrclmp = 0; ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ dwc_udelay(10); ++ ++ gpwrdn.d32 = core_if->gr_backup->xhib_gpwrdn; ++ gpwrdn.b.restore = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ restore_lpm_i2c_regs(core_if); ++ ++ pcgcctl.d32 = core_if->gr_backup->pcgcctl_local & (0x3FFFF << 14); ++ pcgcctl.b.max_xcvrselect = 1; ++ pcgcctl.b.ess_reg_restored = 0; ++ pcgcctl.b.extnd_hiber_switch = 0; ++ pcgcctl.b.extnd_hiber_pwrclmp = 0; ++ pcgcctl.b.enbl_extnd_hiber = 1; ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ ++ gahbcfg.d32 = core_if->gr_backup->gahbcfg_local; ++ gahbcfg.b.glblintrmsk = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32); ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF); ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0x1 << 16); ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, ++ core_if->gr_backup->gusbcfg_local); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, ++ core_if->dr_backup->dcfg); ++ ++ pcgcctl.d32 = 0; ++ pcgcctl.d32 = core_if->gr_backup->pcgcctl_local & (0x3FFFF << 14); ++ pcgcctl.b.max_xcvrselect = 1; ++ pcgcctl.d32 |= 0x608; ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ dwc_udelay(10); ++ ++ pcgcctl.d32 = 0; ++ pcgcctl.d32 = core_if->gr_backup->pcgcctl_local & (0x3FFFF << 14); ++ pcgcctl.b.max_xcvrselect = 1; ++ pcgcctl.b.ess_reg_restored = 1; ++ pcgcctl.b.enbl_extnd_hiber = 1; ++ pcgcctl.b.rstpdwnmodule = 1; ++ pcgcctl.b.restoremode = 1; ++ DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32); ++ ++ DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__); ++ ++ return 1; ++} ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++/** ++ * This function hadles LPM transaction received interrupt. ++ */ ++static int32_t dwc_otg_handle_lpm_intr(dwc_otg_core_if_t * core_if) ++{ ++ glpmcfg_data_t lpmcfg; ++ gintsts_data_t gintsts; ++ ++ if (!core_if->core_params->lpm_enable) { ++ DWC_PRINTF("Unexpected LPM interrupt\n"); ++ } ++ ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ DWC_PRINTF("LPM config register = 0x%08x\n", lpmcfg.d32); ++ ++ if (dwc_otg_is_host_mode(core_if)) { ++ cil_hcd_sleep(core_if); ++ } else { ++ lpmcfg.b.hird_thres |= (1 << 4); ++ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, ++ lpmcfg.d32); ++ } ++ ++ /* Examine prt_sleep_sts after TL1TokenTetry period max (10 us) */ ++ dwc_udelay(10); ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ if (lpmcfg.b.prt_sleep_sts) { ++ /* Save the current state */ ++ core_if->lx_state = DWC_OTG_L1; ++ } ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.lpmtranrcvd = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ return 1; ++} ++#endif /* CONFIG_USB_DWC_OTG_LPM */ ++ ++/** ++ * This function returns the Core Interrupt register. ++ */ ++static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if) ++{ ++ gahbcfg_data_t gahbcfg = {.d32 = 0 }; ++ gintsts_data_t gintsts; ++ gintmsk_data_t gintmsk; ++ gintmsk_data_t gintmsk_common = {.d32 = 0 }; ++ gintmsk_common.b.wkupintr = 1; ++ gintmsk_common.b.sessreqintr = 1; ++ gintmsk_common.b.conidstschng = 1; ++ gintmsk_common.b.otgintr = 1; ++ gintmsk_common.b.modemismatch = 1; ++ gintmsk_common.b.disconnect = 1; ++ gintmsk_common.b.usbsuspend = 1; ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ gintmsk_common.b.lpmtranrcvd = 1; ++#endif ++ gintmsk_common.b.restoredone = 1; ++ /** @todo: The port interrupt occurs while in device ++ * mode. Added code to CIL to clear the interrupt for now! ++ */ ++ gintmsk_common.b.portintr = 1; ++ ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); ++ gahbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg); ++ ++#ifdef DEBUG ++ /* if any common interrupts set */ ++ if (gintsts.d32 & gintmsk_common.d32) { ++ DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n", ++ gintsts.d32, gintmsk.d32); ++ } ++#endif ++ if (gahbcfg.b.glblintrmsk) ++ return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32); ++ else ++ return 0; ++ ++} ++ ++/* MACRO for clearing interupt bits in GPWRDN register */ ++#define CLEAR_GPWRDN_INTR(__core_if,__intr) \ ++do { \ ++ gpwrdn_data_t gpwrdn = {.d32=0}; \ ++ gpwrdn.b.__intr = 1; \ ++ DWC_MODIFY_REG32(&__core_if->core_global_regs->gpwrdn, \ ++ 0, gpwrdn.d32); \ ++} while (0) ++ ++/** ++ * Common interrupt handler. ++ * ++ * The common interrupts are those that occur in both Host and Device mode. ++ * This handler handles the following interrupts: ++ * - Mode Mismatch Interrupt ++ * - Disconnect Interrupt ++ * - OTG Interrupt ++ * - Connector ID Status Change Interrupt ++ * - Session Request Interrupt. ++ * - Resume / Remote Wakeup Detected Interrupt. ++ * - LPM Transaction Received Interrupt ++ * - ADP Transaction Received Interrupt ++ * ++ */ ++int32_t dwc_otg_handle_common_intr(void *dev) ++{ ++ int retval = 0; ++ gintsts_data_t gintsts; ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ dwc_otg_device_t *otg_dev = dev; ++ dwc_otg_core_if_t *core_if = otg_dev->core_if; ++ gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ if (dwc_otg_is_device_mode(core_if)) ++ core_if->frame_num = dwc_otg_get_frame_number(core_if); ++ ++ if (core_if->lock) ++ DWC_SPINLOCK(core_if->lock); ++ ++ if (core_if->power_down == 3 && core_if->xhib == 1) { ++ DWC_DEBUGPL(DBG_ANY, "Exiting from xHIB state\n"); ++ retval |= dwc_otg_handle_xhib_exit_intr(core_if); ++ core_if->xhib = 2; ++ if (core_if->lock) ++ DWC_SPINUNLOCK(core_if->lock); ++ ++ return retval; ++ } ++ ++ if (core_if->hibernation_suspend <= 0) { ++ gintsts.d32 = dwc_otg_read_common_intr(core_if); ++ ++ if (gintsts.b.modemismatch) { ++ retval |= dwc_otg_handle_mode_mismatch_intr(core_if); ++ } ++ if (gintsts.b.otgintr) { ++ retval |= dwc_otg_handle_otg_intr(core_if); ++ } ++ if (gintsts.b.conidstschng) { ++ retval |= ++ dwc_otg_handle_conn_id_status_change_intr(core_if); ++ } ++ if (gintsts.b.disconnect) { ++ retval |= dwc_otg_handle_disconnect_intr(core_if); ++ } ++ if (gintsts.b.sessreqintr) { ++ retval |= dwc_otg_handle_session_req_intr(core_if); ++ } ++ if (gintsts.b.wkupintr) { ++ retval |= dwc_otg_handle_wakeup_detected_intr(core_if); ++ } ++ if (gintsts.b.usbsuspend) { ++ retval |= dwc_otg_handle_usb_suspend_intr(core_if); ++ } ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ if (gintsts.b.lpmtranrcvd) { ++ retval |= dwc_otg_handle_lpm_intr(core_if); ++ } ++#endif ++ if (gintsts.b.restoredone) { ++ gintsts.d32 = 0; ++ if (core_if->power_down == 2) ++ core_if->hibernation_suspend = -1; ++ else if (core_if->power_down == 3 && core_if->xhib == 2) { ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ dctl_data_t dctl = {.d32 = 0 }; ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs-> ++ gintsts, 0xFFFFFFFF); ++ ++ DWC_DEBUGPL(DBG_ANY, ++ "RESTORE DONE generated\n"); ++ ++ gpwrdn.b.restore = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ pcgcctl.b.rstpdwnmodule = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0); ++ ++ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, core_if->gr_backup->gusbcfg_local); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, core_if->dr_backup->dcfg); ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, core_if->dr_backup->dctl); ++ dwc_udelay(50); ++ ++ dctl.b.pwronprgdone = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ dwc_udelay(10); ++ ++ dwc_otg_restore_global_regs(core_if); ++ dwc_otg_restore_dev_regs(core_if, 0); ++ ++ dctl.d32 = 0; ++ dctl.b.pwronprgdone = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0); ++ dwc_udelay(10); ++ ++ pcgcctl.d32 = 0; ++ pcgcctl.b.enbl_extnd_hiber = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0); ++ ++ /* The core will be in ON STATE */ ++ core_if->lx_state = DWC_OTG_L0; ++ core_if->xhib = 0; ++ ++ DWC_SPINUNLOCK(core_if->lock); ++ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) { ++ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p); ++ } ++ DWC_SPINLOCK(core_if->lock); ++ ++ } ++ ++ gintsts.b.restoredone = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts,gintsts.d32); ++ DWC_PRINTF(" --Restore done interrupt received-- \n"); ++ retval |= 1; ++ } ++ if (gintsts.b.portintr && dwc_otg_is_device_mode(core_if)) { ++ /* The port interrupt occurs while in device mode with HPRT0 ++ * Port Enable/Disable. ++ */ ++ gintsts.d32 = 0; ++ gintsts.b.portintr = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts,gintsts.d32); ++ retval |= 1; ++ ++ } ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "gpwrdn=%08x\n", gpwrdn.d32); ++ ++ if (gpwrdn.b.disconn_det && gpwrdn.b.disconn_det_msk) { ++ CLEAR_GPWRDN_INTR(core_if, disconn_det); ++ if (gpwrdn.b.linestate == 0) { ++ dwc_otg_handle_pwrdn_disconnect_intr(core_if); ++ } else { ++ DWC_PRINTF("Disconnect detected while linestate is not 0\n"); ++ } ++ ++ retval |= 1; ++ } ++ if (gpwrdn.b.lnstschng && gpwrdn.b.lnstchng_msk) { ++ CLEAR_GPWRDN_INTR(core_if, lnstschng); ++ /* remote wakeup from hibernation */ ++ if (gpwrdn.b.linestate == 2 || gpwrdn.b.linestate == 1) { ++ dwc_otg_handle_pwrdn_wakeup_detected_intr(core_if); ++ } else { ++ DWC_PRINTF("gpwrdn.linestate = %d\n", gpwrdn.b.linestate); ++ } ++ retval |= 1; ++ } ++ if (gpwrdn.b.rst_det && gpwrdn.b.rst_det_msk) { ++ CLEAR_GPWRDN_INTR(core_if, rst_det); ++ if (gpwrdn.b.linestate == 0) { ++ DWC_PRINTF("Reset detected\n"); ++ retval |= dwc_otg_device_hibernation_restore(core_if, 0, 1); ++ } ++ } ++ if (gpwrdn.b.srp_det && gpwrdn.b.srp_det_msk) { ++ CLEAR_GPWRDN_INTR(core_if, srp_det); ++ dwc_otg_handle_pwrdn_srp_intr(core_if); ++ retval |= 1; ++ } ++ } ++ /* Handle ADP interrupt here */ ++ if (gpwrdn.b.adp_int) { ++ DWC_PRINTF("ADP interrupt\n"); ++ CLEAR_GPWRDN_INTR(core_if, adp_int); ++ dwc_otg_adp_handle_intr(core_if); ++ retval |= 1; ++ } ++ if (gpwrdn.b.sts_chngint && gpwrdn.b.sts_chngint_msk) { ++ DWC_PRINTF("STS CHNG interrupt asserted\n"); ++ CLEAR_GPWRDN_INTR(core_if, sts_chngint); ++ dwc_otg_handle_pwrdn_stschng_intr(otg_dev); ++ ++ retval |= 1; ++ } ++ if (core_if->lock) ++ DWC_SPINUNLOCK(core_if->lock); ++ ++ return retval; ++} +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_core_if.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_core_if.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,705 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_core_if.h $ ++ * $Revision: #13 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#if !defined(__DWC_CORE_IF_H__) ++#define __DWC_CORE_IF_H__ ++ ++#include "dwc_os.h" ++ ++/** @file ++ * This file defines DWC_OTG Core API ++ */ ++ ++struct dwc_otg_core_if; ++typedef struct dwc_otg_core_if dwc_otg_core_if_t; ++ ++/** Maximum number of Periodic FIFOs */ ++#define MAX_PERIO_FIFOS 15 ++/** Maximum number of Periodic FIFOs */ ++#define MAX_TX_FIFOS 15 ++ ++/** Maximum number of Endpoints/HostChannels */ ++#define MAX_EPS_CHANNELS 16 ++ ++extern dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * _reg_base_addr); ++extern void dwc_otg_core_init(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_cil_remove(dwc_otg_core_if_t * _core_if); ++ ++extern void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * _core_if); ++ ++extern uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if); ++extern uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if); ++ ++extern uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if); ++ ++/** This function should be called on every hardware interrupt. */ ++extern int32_t dwc_otg_handle_common_intr(void *otg_dev); ++ ++/** @name OTG Core Parameters */ ++/** @{ */ ++ ++/** ++ * Specifies the OTG capabilities. The driver will automatically ++ * detect the value for this parameter if none is specified. ++ * 0 - HNP and SRP capable (default) ++ * 1 - SRP Only capable ++ * 2 - No HNP/SRP capable ++ */ ++extern int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val); ++extern int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if); ++#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0 ++#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1 ++#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2 ++#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE ++ ++extern int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val); ++extern int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if); ++#define dwc_param_opt_default 1 ++ ++/** ++ * Specifies whether to use slave or DMA mode for accessing the data ++ * FIFOs. The driver will automatically detect the value for this ++ * parameter if none is specified. ++ * 0 - Slave ++ * 1 - DMA (default, if available) ++ */ ++extern int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if); ++#define dwc_param_dma_enable_default 1 ++ ++/** ++ * When DMA mode is enabled specifies whether to use ++ * address DMA or DMA Descritor mode for accessing the data ++ * FIFOs in device mode. The driver will automatically detect ++ * the value for this parameter if none is specified. ++ * 0 - address DMA ++ * 1 - DMA Descriptor(default, if available) ++ */ ++extern int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if); ++//#define dwc_param_dma_desc_enable_default 1 ++#define dwc_param_dma_desc_enable_default 0 // Broadcom BCM2708 ++ ++/** The DMA Burst size (applicable only for External DMA ++ * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32) ++ */ ++extern int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if); ++#define dwc_param_dma_burst_size_default 32 ++ ++/** ++ * Specifies the maximum speed of operation in host and device mode. ++ * The actual speed depends on the speed of the attached device and ++ * the value of phy_type. The actual speed depends on the speed of the ++ * attached device. ++ * 0 - High Speed (default) ++ * 1 - Full Speed ++ */ ++extern int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val); ++extern int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if); ++#define dwc_param_speed_default 0 ++#define DWC_SPEED_PARAM_HIGH 0 ++#define DWC_SPEED_PARAM_FULL 1 ++ ++/** Specifies whether low power mode is supported when attached ++ * to a Full Speed or Low Speed device in host mode. ++ * 0 - Don't support low power mode (default) ++ * 1 - Support low power mode ++ */ ++extern int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * ++ core_if, int32_t val); ++extern int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t ++ * core_if); ++#define dwc_param_host_support_fs_ls_low_power_default 0 ++ ++/** Specifies the PHY clock rate in low power mode when connected to a ++ * Low Speed device in host mode. This parameter is applicable only if ++ * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS ++ * then defaults to 6 MHZ otherwise 48 MHZ. ++ * ++ * 0 - 48 MHz ++ * 1 - 6 MHz ++ */ ++extern int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * ++ core_if, int32_t val); ++extern int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * ++ core_if); ++#define dwc_param_host_ls_low_power_phy_clk_default 0 ++#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0 ++#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1 ++ ++/** ++ * 0 - Use cC FIFO size parameters ++ * 1 - Allow dynamic FIFO sizing (default) ++ */ ++extern int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * ++ core_if); ++#define dwc_param_enable_dynamic_fifo_default 1 ++ ++/** Total number of 4-byte words in the data FIFO memory. This ++ * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic ++ * Tx FIFOs. ++ * 32 to 32768 (default 8192) ++ * Note: The total FIFO memory depth in the FPGA configuration is 8192. ++ */ ++extern int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if); ++//#define dwc_param_data_fifo_size_default 8192 ++#define dwc_param_data_fifo_size_default 0xFF0 // Broadcom BCM2708 ++ ++/** Number of 4-byte words in the Rx FIFO in device mode when dynamic ++ * FIFO sizing is enabled. ++ * 16 to 32768 (default 1064) ++ */ ++extern int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if); ++#define dwc_param_dev_rx_fifo_size_default 1064 ++ ++/** Number of 4-byte words in the non-periodic Tx FIFO in device mode ++ * when dynamic FIFO sizing is enabled. ++ * 16 to 32768 (default 1024) ++ */ ++extern int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * ++ core_if, int32_t val); ++extern int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * ++ core_if); ++#define dwc_param_dev_nperio_tx_fifo_size_default 1024 ++ ++/** Number of 4-byte words in each of the periodic Tx FIFOs in device ++ * mode when dynamic FIFO sizing is enabled. ++ * 4 to 768 (default 256) ++ */ ++extern int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val, int fifo_num); ++extern int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * ++ core_if, int fifo_num); ++#define dwc_param_dev_perio_tx_fifo_size_default 256 ++ ++/** Number of 4-byte words in the Rx FIFO in host mode when dynamic ++ * FIFO sizing is enabled. ++ * 16 to 32768 (default 1024) ++ */ ++extern int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if); ++//#define dwc_param_host_rx_fifo_size_default 1024 ++#define dwc_param_host_rx_fifo_size_default 774 // Broadcom BCM2708 ++ ++/** Number of 4-byte words in the non-periodic Tx FIFO in host mode ++ * when Dynamic FIFO sizing is enabled in the core. ++ * 16 to 32768 (default 1024) ++ */ ++extern int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * ++ core_if, int32_t val); ++extern int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * ++ core_if); ++//#define dwc_param_host_nperio_tx_fifo_size_default 1024 ++#define dwc_param_host_nperio_tx_fifo_size_default 0x100 // Broadcom BCM2708 ++ ++/** Number of 4-byte words in the host periodic Tx FIFO when dynamic ++ * FIFO sizing is enabled. ++ * 16 to 32768 (default 1024) ++ */ ++extern int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * ++ core_if, int32_t val); ++extern int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * ++ core_if); ++//#define dwc_param_host_perio_tx_fifo_size_default 1024 ++#define dwc_param_host_perio_tx_fifo_size_default 0x200 // Broadcom BCM2708 ++ ++/** The maximum transfer size supported in bytes. ++ * 2047 to 65,535 (default 65,535) ++ */ ++extern int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if); ++#define dwc_param_max_transfer_size_default 65535 ++ ++/** The maximum number of packets in a transfer. ++ * 15 to 511 (default 511) ++ */ ++extern int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if); ++#define dwc_param_max_packet_count_default 511 ++ ++/** The number of host channel registers to use. ++ * 1 to 16 (default 12) ++ * Note: The FPGA configuration supports a maximum of 12 host channels. ++ */ ++extern int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if); ++//#define dwc_param_host_channels_default 12 ++#define dwc_param_host_channels_default 8 // Broadcom BCM2708 ++ ++/** The number of endpoints in addition to EP0 available for device ++ * mode operations. ++ * 1 to 15 (default 6 IN and OUT) ++ * Note: The FPGA configuration supports a maximum of 6 IN and OUT ++ * endpoints in addition to EP0. ++ */ ++extern int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if); ++#define dwc_param_dev_endpoints_default 6 ++ ++/** ++ * Specifies the type of PHY interface to use. By default, the driver ++ * will automatically detect the phy_type. ++ * ++ * 0 - Full Speed PHY ++ * 1 - UTMI+ (default) ++ * 2 - ULPI ++ */ ++extern int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val); ++extern int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if); ++#define DWC_PHY_TYPE_PARAM_FS 0 ++#define DWC_PHY_TYPE_PARAM_UTMI 1 ++#define DWC_PHY_TYPE_PARAM_ULPI 2 ++#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI ++ ++/** ++ * Specifies the UTMI+ Data Width. This parameter is ++ * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI ++ * PHY_TYPE, this parameter indicates the data width between ++ * the MAC and the ULPI Wrapper.) Also, this parameter is ++ * applicable only if the OTG_HSPHY_WIDTH cC parameter was set ++ * to "8 and 16 bits", meaning that the core has been ++ * configured to work at either data path width. ++ * ++ * 8 or 16 bits (default 16) ++ */ ++extern int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if); ++//#define dwc_param_phy_utmi_width_default 16 ++#define dwc_param_phy_utmi_width_default 8 // Broadcom BCM2708 ++ ++/** ++ * Specifies whether the ULPI operates at double or single ++ * data rate. This parameter is only applicable if PHY_TYPE is ++ * ULPI. ++ * ++ * 0 - single data rate ULPI interface with 8 bit wide data ++ * bus (default) ++ * 1 - double data rate ULPI interface with 4 bit wide data ++ * bus ++ */ ++extern int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if); ++#define dwc_param_phy_ulpi_ddr_default 0 ++ ++/** ++ * Specifies whether to use the internal or external supply to ++ * drive the vbus with a ULPI phy. ++ */ ++extern int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if); ++#define DWC_PHY_ULPI_INTERNAL_VBUS 0 ++#define DWC_PHY_ULPI_EXTERNAL_VBUS 1 ++#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS ++ ++/** ++ * Specifies whether to use the I2Cinterface for full speed PHY. This ++ * parameter is only applicable if PHY_TYPE is FS. ++ * 0 - No (default) ++ * 1 - Yes ++ */ ++extern int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if); ++#define dwc_param_i2c_enable_default 0 ++ ++extern int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if); ++#define dwc_param_ulpi_fs_ls_default 0 ++ ++extern int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val); ++extern int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if); ++#define dwc_param_ts_dline_default 0 ++ ++/** ++ * Specifies whether dedicated transmit FIFOs are ++ * enabled for non periodic IN endpoints in device mode ++ * 0 - No ++ * 1 - Yes ++ */ ++extern int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * ++ core_if); ++#define dwc_param_en_multiple_tx_fifo_default 1 ++ ++/** Number of 4-byte words in each of the Tx FIFOs in device ++ * mode when dynamic FIFO sizing is enabled. ++ * 4 to 768 (default 256) ++ */ ++extern int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int fifo_num, int32_t val); ++extern int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, ++ int fifo_num); ++#define dwc_param_dev_tx_fifo_size_default 768 ++ ++/** Thresholding enable flag- ++ * bit 0 - enable non-ISO Tx thresholding ++ * bit 1 - enable ISO Tx thresholding ++ * bit 2 - enable Rx thresholding ++ */ ++extern int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val); ++extern int32_t dwc_otg_get_thr_ctl(dwc_otg_core_if_t * core_if, int fifo_num); ++#define dwc_param_thr_ctl_default 0 ++ ++/** Thresholding length for Tx ++ * FIFOs in 32 bit DWORDs ++ */ ++extern int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_tx_thr_length(dwc_otg_core_if_t * core_if); ++#define dwc_param_tx_thr_length_default 64 ++ ++/** Thresholding length for Rx ++ * FIFOs in 32 bit DWORDs ++ */ ++extern int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_rx_thr_length(dwc_otg_core_if_t * core_if); ++#define dwc_param_rx_thr_length_default 64 ++ ++/** ++ * Specifies whether LPM (Link Power Management) support is enabled ++ */ ++extern int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if); ++#define dwc_param_lpm_enable_default 1 ++ ++/** ++ * Specifies whether PTI enhancement is enabled ++ */ ++extern int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if); ++#define dwc_param_pti_enable_default 0 ++ ++/** ++ * Specifies whether MPI enhancement is enabled ++ */ ++extern int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if); ++#define dwc_param_mpi_enable_default 0 ++ ++/** ++ * Specifies whether ADP capability is enabled ++ */ ++extern int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if); ++#define dwc_param_adp_enable_default 0 ++ ++/** ++ * Specifies whether IC_USB capability is enabled ++ */ ++ ++extern int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if); ++#define dwc_param_ic_usb_cap_default 0 ++ ++extern int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if); ++#define dwc_param_ahb_thr_ratio_default 0 ++ ++extern int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if); ++#define dwc_param_power_down_default 0 ++ ++extern int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if); ++#define dwc_param_reload_ctl_default 0 ++ ++extern int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if); ++#define dwc_param_dev_out_nak_default 0 ++ ++extern int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if); ++#define dwc_param_cont_on_bna_default 0 ++ ++extern int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, ++ int32_t val); ++extern int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if); ++#define dwc_param_ahb_single_default 0 ++ ++extern int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val); ++extern int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if); ++#define dwc_param_otg_ver_default 0 ++ ++/** @} */ ++ ++/** @name Access to registers and bit-fields */ ++ ++/** ++ * Dump core registers and SPRAM ++ */ ++extern void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_dump_spram(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_dump_host_registers(dwc_otg_core_if_t * _core_if); ++extern void dwc_otg_dump_global_registers(dwc_otg_core_if_t * _core_if); ++ ++/** ++ * Get host negotiation status. ++ */ ++extern uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get srp status ++ */ ++extern uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Set hnpreq bit in the GOTGCTL register. ++ */ ++extern void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get Content of SNPSID register. ++ */ ++extern uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get current mode. ++ * Returns 0 if in device mode, and 1 if in host mode. ++ */ ++extern uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get value of hnpcapable field in the GUSBCFG register ++ */ ++extern uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of hnpcapable field in the GUSBCFG register ++ */ ++extern void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of srpcapable field in the GUSBCFG register ++ */ ++extern uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of srpcapable field in the GUSBCFG register ++ */ ++extern void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of devspeed field in the DCFG register ++ */ ++extern uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of devspeed field in the DCFG register ++ */ ++extern void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get the value of busconnected field from the HPRT0 register ++ */ ++extern uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Gets the device enumeration Speed. ++ */ ++extern uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get value of prtpwr field from the HPRT0 register ++ */ ++extern uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get value of flag indicating core state - hibernated or not ++ */ ++extern uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Set value of prtpwr field from the HPRT0 register ++ */ ++extern void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of prtsusp field from the HPRT0 regsiter ++ */ ++extern uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of prtpwr field from the HPRT0 register ++ */ ++extern void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of ModeChTimEn field from the HCFG regsiter ++ */ ++extern uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of ModeChTimEn field from the HCFG regsiter ++ */ ++extern void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of Fram Interval field from the HFIR regsiter ++ */ ++extern uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of Frame Interval field from the HFIR regsiter ++ */ ++extern void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Set value of prtres field from the HPRT0 register ++ *FIXME Remove? ++ */ ++extern void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of rmtwkupsig bit in DCTL register ++ */ ++extern uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get value of prt_sleep_sts field from the GLPMCFG register ++ */ ++extern uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get value of rem_wkup_en field from the GLPMCFG register ++ */ ++extern uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Get value of appl_resp field from the GLPMCFG register ++ */ ++extern uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of appl_resp field from the GLPMCFG register ++ */ ++extern void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of hsic_connect field from the GLPMCFG register ++ */ ++extern uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of hsic_connect field from the GLPMCFG register ++ */ ++extern void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * Get value of inv_sel_hsic field from the GLPMCFG register. ++ */ ++extern uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if); ++/** ++ * Set value of inv_sel_hsic field from the GLPMFG register. ++ */ ++extern void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/* ++ * Some functions for accessing registers ++ */ ++ ++/** ++ * GOTGCTL register ++ */ ++extern uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * GUSBCFG register ++ */ ++extern uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * GRXFSIZ register ++ */ ++extern uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * GNPTXFSIZ register ++ */ ++extern uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++extern uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * GGPIO register ++ */ ++extern uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * GUID register ++ */ ++extern uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * HPRT0 register ++ */ ++extern uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if); ++extern void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val); ++ ++/** ++ * GHPTXFSIZE ++ */ ++extern uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if); ++ ++/** @} */ ++ ++#endif /* __DWC_CORE_IF_H__ */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_dbg.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_dbg.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,116 @@ ++/* ========================================================================== ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#ifndef __DWC_OTG_DBG_H__ ++#define __DWC_OTG_DBG_H__ ++ ++/** @file ++ * This file defines debug levels. ++ * Debugging support vanishes in non-debug builds. ++ */ ++ ++/** ++ * The Debug Level bit-mask variable. ++ */ ++extern uint32_t g_dbg_lvl; ++/** ++ * Set the Debug Level variable. ++ */ ++static inline uint32_t SET_DEBUG_LEVEL(const uint32_t new) ++{ ++ uint32_t old = g_dbg_lvl; ++ g_dbg_lvl = new; ++ return old; ++} ++ ++/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */ ++#define DBG_CIL (0x2) ++/** When debug level has the DBG_CILV bit set, display CIL Verbose debug ++ * messages */ ++#define DBG_CILV (0x20) ++/** When debug level has the DBG_PCD bit set, display PCD (Device) debug ++ * messages */ ++#define DBG_PCD (0x4) ++/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug ++ * messages */ ++#define DBG_PCDV (0x40) ++/** When debug level has the DBG_HCD bit set, display Host debug messages */ ++#define DBG_HCD (0x8) ++/** When debug level has the DBG_HCDV bit set, display Verbose Host debug ++ * messages */ ++#define DBG_HCDV (0x80) ++/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host ++ * mode. */ ++#define DBG_HCD_URB (0x800) ++/** When debug level has the DBG_HCDI bit set, display host interrupt ++ * messages. */ ++#define DBG_HCDI (0x1000) ++ ++/** When debug level has any bit set, display debug messages */ ++#define DBG_ANY (0xFF) ++ ++/** All debug messages off */ ++#define DBG_OFF 0 ++ ++/** Prefix string for DWC_DEBUG print macros. */ ++#define USB_DWC "DWC_otg: " ++ ++/** ++ * Print a debug message when the Global debug level variable contains ++ * the bit defined in lvl. ++ * ++ * @param[in] lvl - Debug level, use one of the DBG_ constants above. ++ * @param[in] x - like printf ++ * ++ * Example:

++ * ++ * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr); ++ * ++ *
++ * results in:
++ * ++ * usb-DWC_otg: dwc_otg_cil_init(ca867000) ++ * ++ */ ++#ifdef DEBUG ++ ++# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)__DWC_DEBUG(USB_DWC x ); }while(0) ++# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x ) ++ ++# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl) ++ ++#else ++ ++# define DWC_DEBUGPL(lvl, x...) do{}while(0) ++# define DWC_DEBUGP(x...) ++ ++# define CHK_DEBUG_LEVEL(level) (0) ++ ++#endif /*DEBUG*/ ++#endif +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_driver.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_driver.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1700 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $ ++ * $Revision: #92 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++/** @file ++ * The dwc_otg_driver module provides the initialization and cleanup entry ++ * points for the DWC_otg driver. This module will be dynamically installed ++ * after Linux is booted using the insmod command. When the module is ++ * installed, the dwc_otg_driver_init function is called. When the module is ++ * removed (using rmmod), the dwc_otg_driver_cleanup function is called. ++ * ++ * This module also defines a data structure for the dwc_otg_driver, which is ++ * used in conjunction with the standard ARM lm_device structure. These ++ * structures allow the OTG driver to comply with the standard Linux driver ++ * model in which devices and drivers are registered with a bus driver. This ++ * has the benefit that Linux can expose attributes of the driver and device ++ * in its special sysfs file system. Users can then read or write files in ++ * this file system to perform diagnostics on the driver components or the ++ * device. ++ */ ++ ++#include "dwc_otg_os_dep.h" ++#include "dwc_os.h" ++#include "dwc_otg_dbg.h" ++#include "dwc_otg_driver.h" ++#include "dwc_otg_attr.h" ++#include "dwc_otg_core_if.h" ++#include "dwc_otg_pcd_if.h" ++#include "dwc_otg_hcd_if.h" ++ ++#define DWC_DRIVER_VERSION "3.00a 10-AUG-2012" ++#define DWC_DRIVER_DESC "HS OTG USB Controller driver" ++ ++bool microframe_schedule=true; ++ ++static const char dwc_driver_name[] = "dwc_otg"; ++ ++extern int pcd_init( ++#ifdef LM_INTERFACE ++ struct lm_device *_dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *_dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *dev ++#endif ++ ); ++extern int hcd_init( ++#ifdef LM_INTERFACE ++ struct lm_device *_dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *_dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *dev ++#endif ++ ); ++ ++extern int pcd_remove( ++#ifdef LM_INTERFACE ++ struct lm_device *_dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *_dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *_dev ++#endif ++ ); ++ ++extern void hcd_remove( ++#ifdef LM_INTERFACE ++ struct lm_device *_dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *_dev ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *_dev ++#endif ++ ); ++ ++extern void dwc_otg_adp_start(dwc_otg_core_if_t * core_if, uint8_t is_host); ++ ++/*-------------------------------------------------------------------------*/ ++/* Encapsulate the module parameter settings */ ++ ++struct dwc_otg_driver_module_params { ++ int32_t opt; ++ int32_t otg_cap; ++ int32_t dma_enable; ++ int32_t dma_desc_enable; ++ int32_t dma_burst_size; ++ int32_t speed; ++ int32_t host_support_fs_ls_low_power; ++ int32_t host_ls_low_power_phy_clk; ++ int32_t enable_dynamic_fifo; ++ int32_t data_fifo_size; ++ int32_t dev_rx_fifo_size; ++ int32_t dev_nperio_tx_fifo_size; ++ uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS]; ++ int32_t host_rx_fifo_size; ++ int32_t host_nperio_tx_fifo_size; ++ int32_t host_perio_tx_fifo_size; ++ int32_t max_transfer_size; ++ int32_t max_packet_count; ++ int32_t host_channels; ++ int32_t dev_endpoints; ++ int32_t phy_type; ++ int32_t phy_utmi_width; ++ int32_t phy_ulpi_ddr; ++ int32_t phy_ulpi_ext_vbus; ++ int32_t i2c_enable; ++ int32_t ulpi_fs_ls; ++ int32_t ts_dline; ++ int32_t en_multiple_tx_fifo; ++ uint32_t dev_tx_fifo_size[MAX_TX_FIFOS]; ++ uint32_t thr_ctl; ++ uint32_t tx_thr_length; ++ uint32_t rx_thr_length; ++ int32_t pti_enable; ++ int32_t mpi_enable; ++ int32_t lpm_enable; ++ int32_t ic_usb_cap; ++ int32_t ahb_thr_ratio; ++ int32_t power_down; ++ int32_t reload_ctl; ++ int32_t dev_out_nak; ++ int32_t cont_on_bna; ++ int32_t ahb_single; ++ int32_t otg_ver; ++ int32_t adp_enable; ++}; ++ ++static struct dwc_otg_driver_module_params dwc_otg_module_params = { ++ .opt = -1, ++ .otg_cap = -1, ++ .dma_enable = -1, ++ .dma_desc_enable = -1, ++ .dma_burst_size = -1, ++ .speed = -1, ++ .host_support_fs_ls_low_power = -1, ++ .host_ls_low_power_phy_clk = -1, ++ .enable_dynamic_fifo = -1, ++ .data_fifo_size = -1, ++ .dev_rx_fifo_size = -1, ++ .dev_nperio_tx_fifo_size = -1, ++ .dev_perio_tx_fifo_size = { ++ /* dev_perio_tx_fifo_size_1 */ ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1 ++ /* 15 */ ++ }, ++ .host_rx_fifo_size = -1, ++ .host_nperio_tx_fifo_size = -1, ++ .host_perio_tx_fifo_size = -1, ++ .max_transfer_size = -1, ++ .max_packet_count = -1, ++ .host_channels = -1, ++ .dev_endpoints = -1, ++ .phy_type = -1, ++ .phy_utmi_width = -1, ++ .phy_ulpi_ddr = -1, ++ .phy_ulpi_ext_vbus = -1, ++ .i2c_enable = -1, ++ .ulpi_fs_ls = -1, ++ .ts_dline = -1, ++ .en_multiple_tx_fifo = -1, ++ .dev_tx_fifo_size = { ++ /* dev_tx_fifo_size */ ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1 ++ /* 15 */ ++ }, ++ .thr_ctl = -1, ++ .tx_thr_length = -1, ++ .rx_thr_length = -1, ++ .pti_enable = -1, ++ .mpi_enable = -1, ++ .lpm_enable = -1, ++ .ic_usb_cap = -1, ++ .ahb_thr_ratio = -1, ++ .power_down = -1, ++ .reload_ctl = -1, ++ .dev_out_nak = -1, ++ .cont_on_bna = -1, ++ .ahb_single = -1, ++ .otg_ver = -1, ++ .adp_enable = -1, ++}; ++ ++/** ++ * This function shows the Driver Version. ++ */ ++static ssize_t version_show(struct device_driver *dev, char *buf) ++{ ++ return snprintf(buf, sizeof(DWC_DRIVER_VERSION) + 2, "%s\n", ++ DWC_DRIVER_VERSION); ++} ++ ++static DRIVER_ATTR(version, S_IRUGO, version_show, NULL); ++ ++/** ++ * Global Debug Level Mask. ++ */ ++uint32_t g_dbg_lvl = 0; /* OFF */ ++ ++/** ++ * This function shows the driver Debug Level. ++ */ ++static ssize_t dbg_level_show(struct device_driver *drv, char *buf) ++{ ++ return sprintf(buf, "0x%0x\n", g_dbg_lvl); ++} ++ ++/** ++ * This function stores the driver Debug Level. ++ */ ++static ssize_t dbg_level_store(struct device_driver *drv, const char *buf, ++ size_t count) ++{ ++ g_dbg_lvl = simple_strtoul(buf, NULL, 16); ++ return count; ++} ++ ++static DRIVER_ATTR(debuglevel, S_IRUGO | S_IWUSR, dbg_level_show, ++ dbg_level_store); ++ ++/** ++ * This function is called during module intialization ++ * to pass module parameters to the DWC_OTG CORE. ++ */ ++static int set_parameters(dwc_otg_core_if_t * core_if) ++{ ++ int retval = 0; ++ int i; ++ ++ if (dwc_otg_module_params.otg_cap != -1) { ++ retval += ++ dwc_otg_set_param_otg_cap(core_if, ++ dwc_otg_module_params.otg_cap); ++ } ++ if (dwc_otg_module_params.dma_enable != -1) { ++ retval += ++ dwc_otg_set_param_dma_enable(core_if, ++ dwc_otg_module_params. ++ dma_enable); ++ } ++ if (dwc_otg_module_params.dma_desc_enable != -1) { ++ retval += ++ dwc_otg_set_param_dma_desc_enable(core_if, ++ dwc_otg_module_params. ++ dma_desc_enable); ++ } ++ if (dwc_otg_module_params.opt != -1) { ++ retval += ++ dwc_otg_set_param_opt(core_if, dwc_otg_module_params.opt); ++ } ++ if (dwc_otg_module_params.dma_burst_size != -1) { ++ retval += ++ dwc_otg_set_param_dma_burst_size(core_if, ++ dwc_otg_module_params. ++ dma_burst_size); ++ } ++ if (dwc_otg_module_params.host_support_fs_ls_low_power != -1) { ++ retval += ++ dwc_otg_set_param_host_support_fs_ls_low_power(core_if, ++ dwc_otg_module_params. ++ host_support_fs_ls_low_power); ++ } ++ if (dwc_otg_module_params.enable_dynamic_fifo != -1) { ++ retval += ++ dwc_otg_set_param_enable_dynamic_fifo(core_if, ++ dwc_otg_module_params. ++ enable_dynamic_fifo); ++ } ++ if (dwc_otg_module_params.data_fifo_size != -1) { ++ retval += ++ dwc_otg_set_param_data_fifo_size(core_if, ++ dwc_otg_module_params. ++ data_fifo_size); ++ } ++ if (dwc_otg_module_params.dev_rx_fifo_size != -1) { ++ retval += ++ dwc_otg_set_param_dev_rx_fifo_size(core_if, ++ dwc_otg_module_params. ++ dev_rx_fifo_size); ++ } ++ if (dwc_otg_module_params.dev_nperio_tx_fifo_size != -1) { ++ retval += ++ dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if, ++ dwc_otg_module_params. ++ dev_nperio_tx_fifo_size); ++ } ++ if (dwc_otg_module_params.host_rx_fifo_size != -1) { ++ retval += ++ dwc_otg_set_param_host_rx_fifo_size(core_if, ++ dwc_otg_module_params.host_rx_fifo_size); ++ } ++ if (dwc_otg_module_params.host_nperio_tx_fifo_size != -1) { ++ retval += ++ dwc_otg_set_param_host_nperio_tx_fifo_size(core_if, ++ dwc_otg_module_params. ++ host_nperio_tx_fifo_size); ++ } ++ if (dwc_otg_module_params.host_perio_tx_fifo_size != -1) { ++ retval += ++ dwc_otg_set_param_host_perio_tx_fifo_size(core_if, ++ dwc_otg_module_params. ++ host_perio_tx_fifo_size); ++ } ++ if (dwc_otg_module_params.max_transfer_size != -1) { ++ retval += ++ dwc_otg_set_param_max_transfer_size(core_if, ++ dwc_otg_module_params. ++ max_transfer_size); ++ } ++ if (dwc_otg_module_params.max_packet_count != -1) { ++ retval += ++ dwc_otg_set_param_max_packet_count(core_if, ++ dwc_otg_module_params. ++ max_packet_count); ++ } ++ if (dwc_otg_module_params.host_channels != -1) { ++ retval += ++ dwc_otg_set_param_host_channels(core_if, ++ dwc_otg_module_params. ++ host_channels); ++ } ++ if (dwc_otg_module_params.dev_endpoints != -1) { ++ retval += ++ dwc_otg_set_param_dev_endpoints(core_if, ++ dwc_otg_module_params. ++ dev_endpoints); ++ } ++ if (dwc_otg_module_params.phy_type != -1) { ++ retval += ++ dwc_otg_set_param_phy_type(core_if, ++ dwc_otg_module_params.phy_type); ++ } ++ if (dwc_otg_module_params.speed != -1) { ++ retval += ++ dwc_otg_set_param_speed(core_if, ++ dwc_otg_module_params.speed); ++ } ++ if (dwc_otg_module_params.host_ls_low_power_phy_clk != -1) { ++ retval += ++ dwc_otg_set_param_host_ls_low_power_phy_clk(core_if, ++ dwc_otg_module_params. ++ host_ls_low_power_phy_clk); ++ } ++ if (dwc_otg_module_params.phy_ulpi_ddr != -1) { ++ retval += ++ dwc_otg_set_param_phy_ulpi_ddr(core_if, ++ dwc_otg_module_params. ++ phy_ulpi_ddr); ++ } ++ if (dwc_otg_module_params.phy_ulpi_ext_vbus != -1) { ++ retval += ++ dwc_otg_set_param_phy_ulpi_ext_vbus(core_if, ++ dwc_otg_module_params. ++ phy_ulpi_ext_vbus); ++ } ++ if (dwc_otg_module_params.phy_utmi_width != -1) { ++ retval += ++ dwc_otg_set_param_phy_utmi_width(core_if, ++ dwc_otg_module_params. ++ phy_utmi_width); ++ } ++ if (dwc_otg_module_params.ulpi_fs_ls != -1) { ++ retval += ++ dwc_otg_set_param_ulpi_fs_ls(core_if, ++ dwc_otg_module_params.ulpi_fs_ls); ++ } ++ if (dwc_otg_module_params.ts_dline != -1) { ++ retval += ++ dwc_otg_set_param_ts_dline(core_if, ++ dwc_otg_module_params.ts_dline); ++ } ++ if (dwc_otg_module_params.i2c_enable != -1) { ++ retval += ++ dwc_otg_set_param_i2c_enable(core_if, ++ dwc_otg_module_params. ++ i2c_enable); ++ } ++ if (dwc_otg_module_params.en_multiple_tx_fifo != -1) { ++ retval += ++ dwc_otg_set_param_en_multiple_tx_fifo(core_if, ++ dwc_otg_module_params. ++ en_multiple_tx_fifo); ++ } ++ for (i = 0; i < 15; i++) { ++ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -1) { ++ retval += ++ dwc_otg_set_param_dev_perio_tx_fifo_size(core_if, ++ dwc_otg_module_params. ++ dev_perio_tx_fifo_size ++ [i], i); ++ } ++ } ++ ++ for (i = 0; i < 15; i++) { ++ if (dwc_otg_module_params.dev_tx_fifo_size[i] != -1) { ++ retval += dwc_otg_set_param_dev_tx_fifo_size(core_if, ++ dwc_otg_module_params. ++ dev_tx_fifo_size ++ [i], i); ++ } ++ } ++ if (dwc_otg_module_params.thr_ctl != -1) { ++ retval += ++ dwc_otg_set_param_thr_ctl(core_if, ++ dwc_otg_module_params.thr_ctl); ++ } ++ if (dwc_otg_module_params.mpi_enable != -1) { ++ retval += ++ dwc_otg_set_param_mpi_enable(core_if, ++ dwc_otg_module_params. ++ mpi_enable); ++ } ++ if (dwc_otg_module_params.pti_enable != -1) { ++ retval += ++ dwc_otg_set_param_pti_enable(core_if, ++ dwc_otg_module_params. ++ pti_enable); ++ } ++ if (dwc_otg_module_params.lpm_enable != -1) { ++ retval += ++ dwc_otg_set_param_lpm_enable(core_if, ++ dwc_otg_module_params. ++ lpm_enable); ++ } ++ if (dwc_otg_module_params.ic_usb_cap != -1) { ++ retval += ++ dwc_otg_set_param_ic_usb_cap(core_if, ++ dwc_otg_module_params. ++ ic_usb_cap); ++ } ++ if (dwc_otg_module_params.tx_thr_length != -1) { ++ retval += ++ dwc_otg_set_param_tx_thr_length(core_if, ++ dwc_otg_module_params.tx_thr_length); ++ } ++ if (dwc_otg_module_params.rx_thr_length != -1) { ++ retval += ++ dwc_otg_set_param_rx_thr_length(core_if, ++ dwc_otg_module_params. ++ rx_thr_length); ++ } ++ if (dwc_otg_module_params.ahb_thr_ratio != -1) { ++ retval += ++ dwc_otg_set_param_ahb_thr_ratio(core_if, ++ dwc_otg_module_params.ahb_thr_ratio); ++ } ++ if (dwc_otg_module_params.power_down != -1) { ++ retval += ++ dwc_otg_set_param_power_down(core_if, ++ dwc_otg_module_params.power_down); ++ } ++ if (dwc_otg_module_params.reload_ctl != -1) { ++ retval += ++ dwc_otg_set_param_reload_ctl(core_if, ++ dwc_otg_module_params.reload_ctl); ++ } ++ ++ if (dwc_otg_module_params.dev_out_nak != -1) { ++ retval += ++ dwc_otg_set_param_dev_out_nak(core_if, ++ dwc_otg_module_params.dev_out_nak); ++ } ++ ++ if (dwc_otg_module_params.cont_on_bna != -1) { ++ retval += ++ dwc_otg_set_param_cont_on_bna(core_if, ++ dwc_otg_module_params.cont_on_bna); ++ } ++ ++ if (dwc_otg_module_params.ahb_single != -1) { ++ retval += ++ dwc_otg_set_param_ahb_single(core_if, ++ dwc_otg_module_params.ahb_single); ++ } ++ ++ if (dwc_otg_module_params.otg_ver != -1) { ++ retval += ++ dwc_otg_set_param_otg_ver(core_if, ++ dwc_otg_module_params.otg_ver); ++ } ++ if (dwc_otg_module_params.adp_enable != -1) { ++ retval += ++ dwc_otg_set_param_adp_enable(core_if, ++ dwc_otg_module_params. ++ adp_enable); ++ } ++ return retval; ++} ++ ++/** ++ * This function is the top level interrupt handler for the Common ++ * (Device and host modes) interrupts. ++ */ ++static irqreturn_t dwc_otg_common_irq(int irq, void *dev) ++{ ++ int32_t retval = IRQ_NONE; ++ ++ retval = dwc_otg_handle_common_intr(dev); ++ if (retval != 0) { ++ S3C2410X_CLEAR_EINTPEND(); ++ } ++ return IRQ_RETVAL(retval); ++} ++ ++/** ++ * This function is called when a lm_device is unregistered with the ++ * dwc_otg_driver. This happens, for example, when the rmmod command is ++ * executed. The device may or may not be electrically present. If it is ++ * present, the driver stops device processing. Any resources used on behalf ++ * of this device are freed. ++ * ++ * @param _dev ++ */ ++#ifdef LM_INTERFACE ++#define REM_RETVAL(n) ++static void dwc_otg_driver_remove( struct lm_device *_dev ) ++{ dwc_otg_device_t *otg_dev = lm_get_drvdata(_dev); ++#elif defined(PCI_INTERFACE) ++#define REM_RETVAL(n) ++static void dwc_otg_driver_remove( struct pci_dev *_dev ) ++{ dwc_otg_device_t *otg_dev = pci_get_drvdata(_dev); ++#elif defined(PLATFORM_INTERFACE) ++#define REM_RETVAL(n) n ++static int dwc_otg_driver_remove( struct platform_device *_dev ) ++{ dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev); ++#endif ++ ++ DWC_DEBUGPL(DBG_ANY, "%s(%p) otg_dev %p\n", __func__, _dev, otg_dev); ++ ++ if (!otg_dev) { ++ /* Memory allocation for the dwc_otg_device failed. */ ++ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__); ++ return REM_RETVAL(-ENOMEM); ++ } ++#ifndef DWC_DEVICE_ONLY ++ if (otg_dev->hcd) { ++ hcd_remove(_dev); ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__); ++ return REM_RETVAL(-EINVAL); ++ } ++#endif ++ ++#ifndef DWC_HOST_ONLY ++ if (otg_dev->pcd) { ++ pcd_remove(_dev); ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->pcd NULL!\n", __func__); ++ return REM_RETVAL(-EINVAL); ++ } ++#endif ++ /* ++ * Free the IRQ ++ */ ++ if (otg_dev->common_irq_installed) { ++#ifdef PLATFORM_INTERFACE ++ free_irq(platform_get_irq(_dev, 0), otg_dev); ++#else ++ free_irq(_dev->irq, otg_dev); ++#endif ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "%s: There is no installed irq!\n", __func__); ++ return REM_RETVAL(-ENXIO); ++ } ++ ++ if (otg_dev->core_if) { ++ dwc_otg_cil_remove(otg_dev->core_if); ++ } else { ++ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->core_if NULL!\n", __func__); ++ return REM_RETVAL(-ENXIO); ++ } ++ ++ /* ++ * Remove the device attributes ++ */ ++ dwc_otg_attr_remove(_dev); ++ ++ /* ++ * Return the memory. ++ */ ++ if (otg_dev->os_dep.base) { ++ iounmap(otg_dev->os_dep.base); ++ } ++ DWC_FREE(otg_dev); ++ ++ /* ++ * Clear the drvdata pointer. ++ */ ++#ifdef LM_INTERFACE ++ lm_set_drvdata(_dev, 0); ++#elif defined(PCI_INTERFACE) ++ release_mem_region(otg_dev->os_dep.rsrc_start, ++ otg_dev->os_dep.rsrc_len); ++ pci_set_drvdata(_dev, 0); ++#elif defined(PLATFORM_INTERFACE) ++ platform_set_drvdata(_dev, 0); ++#endif ++ return REM_RETVAL(0); ++} ++ ++/** ++ * This function is called when an lm_device is bound to a ++ * dwc_otg_driver. It creates the driver components required to ++ * control the device (CIL, HCD, and PCD) and it initializes the ++ * device. The driver components are stored in a dwc_otg_device ++ * structure. A reference to the dwc_otg_device is saved in the ++ * lm_device. This allows the driver to access the dwc_otg_device ++ * structure on subsequent calls to driver methods for this device. ++ * ++ * @param _dev Bus device ++ */ ++static int dwc_otg_driver_probe( ++#ifdef LM_INTERFACE ++ struct lm_device *_dev ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *_dev, ++ const struct pci_device_id *id ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *_dev ++#endif ++ ) ++{ ++ int retval = 0; ++ dwc_otg_device_t *dwc_otg_device; ++ int devirq; ++ ++ dev_dbg(&_dev->dev, "dwc_otg_driver_probe(%p)\n", _dev); ++#ifdef LM_INTERFACE ++ dev_dbg(&_dev->dev, "start=0x%08x\n", (unsigned)_dev->resource.start); ++#elif defined(PCI_INTERFACE) ++ if (!id) { ++ DWC_ERROR("Invalid pci_device_id %p", id); ++ return -EINVAL; ++ } ++ ++ if (!_dev || (pci_enable_device(_dev) < 0)) { ++ DWC_ERROR("Invalid pci_device %p", _dev); ++ return -ENODEV; ++ } ++ dev_dbg(&_dev->dev, "start=0x%08x\n", (unsigned)pci_resource_start(_dev,0)); ++ /* other stuff needed as well? */ ++ ++#elif defined(PLATFORM_INTERFACE) ++ dev_dbg(&_dev->dev, "start=0x%08x (len 0x%x)\n", ++ (unsigned)_dev->resource->start, ++ (unsigned)(_dev->resource->end - _dev->resource->start)); ++#endif ++ ++ dwc_otg_device = DWC_ALLOC(sizeof(dwc_otg_device_t)); ++ ++ if (!dwc_otg_device) { ++ dev_err(&_dev->dev, "kmalloc of dwc_otg_device failed\n"); ++ return -ENOMEM; ++ } ++ ++ memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); ++ dwc_otg_device->os_dep.reg_offset = 0xFFFFFFFF; ++ ++ /* ++ * Map the DWC_otg Core memory into virtual address space. ++ */ ++#ifdef LM_INTERFACE ++ dwc_otg_device->os_dep.base = ioremap(_dev->resource.start, SZ_256K); ++ ++ if (!dwc_otg_device->os_dep.base) { ++ dev_err(&_dev->dev, "ioremap() failed\n"); ++ DWC_FREE(dwc_otg_device); ++ return -ENOMEM; ++ } ++ dev_dbg(&_dev->dev, "base=0x%08x\n", ++ (unsigned)dwc_otg_device->os_dep.base); ++#elif defined(PCI_INTERFACE) ++ _dev->current_state = PCI_D0; ++ _dev->dev.power.power_state = PMSG_ON; ++ ++ if (!_dev->irq) { ++ DWC_ERROR("Found HC with no IRQ. Check BIOS/PCI %s setup!", ++ pci_name(_dev)); ++ iounmap(dwc_otg_device->os_dep.base); ++ DWC_FREE(dwc_otg_device); ++ return -ENODEV; ++ } ++ ++ dwc_otg_device->os_dep.rsrc_start = pci_resource_start(_dev, 0); ++ dwc_otg_device->os_dep.rsrc_len = pci_resource_len(_dev, 0); ++ DWC_DEBUGPL(DBG_ANY, "PCI resource: start=%08x, len=%08x\n", ++ (unsigned)dwc_otg_device->os_dep.rsrc_start, ++ (unsigned)dwc_otg_device->os_dep.rsrc_len); ++ if (!request_mem_region ++ (dwc_otg_device->os_dep.rsrc_start, dwc_otg_device->os_dep.rsrc_len, ++ "dwc_otg")) { ++ dev_dbg(&_dev->dev, "error requesting memory\n"); ++ iounmap(dwc_otg_device->os_dep.base); ++ DWC_FREE(dwc_otg_device); ++ return -EFAULT; ++ } ++ ++ dwc_otg_device->os_dep.base = ++ ioremap_nocache(dwc_otg_device->os_dep.rsrc_start, ++ dwc_otg_device->os_dep.rsrc_len); ++ if (dwc_otg_device->os_dep.base == NULL) { ++ dev_dbg(&_dev->dev, "error mapping memory\n"); ++ release_mem_region(dwc_otg_device->os_dep.rsrc_start, ++ dwc_otg_device->os_dep.rsrc_len); ++ iounmap(dwc_otg_device->os_dep.base); ++ DWC_FREE(dwc_otg_device); ++ return -EFAULT; ++ } ++ dev_dbg(&_dev->dev, "base=0x%p (before adjust) \n", ++ dwc_otg_device->os_dep.base); ++ dwc_otg_device->os_dep.base = (char *)dwc_otg_device->os_dep.base; ++ dev_dbg(&_dev->dev, "base=0x%p (after adjust) \n", ++ dwc_otg_device->os_dep.base); ++ dev_dbg(&_dev->dev, "%s: mapped PA 0x%x to VA 0x%p\n", __func__, ++ (unsigned)dwc_otg_device->os_dep.rsrc_start, ++ dwc_otg_device->os_dep.base); ++ ++ pci_set_master(_dev); ++ pci_set_drvdata(_dev, dwc_otg_device); ++#elif defined(PLATFORM_INTERFACE) ++ DWC_DEBUGPL(DBG_ANY,"Platform resource: start=%08x, len=%08x\n", ++ _dev->resource->start, ++ _dev->resource->end - _dev->resource->start + 1); ++#if 1 ++ if (!request_mem_region(_dev->resource->start, ++ _dev->resource->end - _dev->resource->start + 1, ++ "dwc_otg")) { ++ dev_dbg(&_dev->dev, "error reserving mapped memory\n"); ++ retval = -EFAULT; ++ goto fail; ++ } ++ ++ dwc_otg_device->os_dep.base = ioremap_nocache(_dev->resource->start, ++ _dev->resource->end - ++ _dev->resource->start+1); ++#else ++ { ++ struct map_desc desc = { ++ .virtual = IO_ADDRESS((unsigned)_dev->resource->start), ++ .pfn = __phys_to_pfn((unsigned)_dev->resource->start), ++ .length = SZ_128K, ++ .type = MT_DEVICE ++ }; ++ iotable_init(&desc, 1); ++ dwc_otg_device->os_dep.base = (void *)desc.virtual; ++ } ++#endif ++ if (!dwc_otg_device->os_dep.base) { ++ dev_err(&_dev->dev, "ioremap() failed\n"); ++ retval = -ENOMEM; ++ goto fail; ++ } ++ dev_dbg(&_dev->dev, "base=0x%08x\n", ++ (unsigned)dwc_otg_device->os_dep.base); ++#endif ++ ++ /* ++ * Initialize driver data to point to the global DWC_otg ++ * Device structure. ++ */ ++#ifdef LM_INTERFACE ++ lm_set_drvdata(_dev, dwc_otg_device); ++#elif defined(PLATFORM_INTERFACE) ++ platform_set_drvdata(_dev, dwc_otg_device); ++#endif ++ dev_dbg(&_dev->dev, "dwc_otg_device=0x%p\n", dwc_otg_device); ++ ++ dwc_otg_device->core_if = dwc_otg_cil_init(dwc_otg_device->os_dep.base); ++ DWC_DEBUGPL(DBG_HCDV, "probe of device %p given core_if %p\n", ++ dwc_otg_device, dwc_otg_device->core_if);//GRAYG ++ ++ if (!dwc_otg_device->core_if) { ++ dev_err(&_dev->dev, "CIL initialization failed!\n"); ++ retval = -ENOMEM; ++ goto fail; ++ } ++ ++ dev_dbg(&_dev->dev, "Calling get_gsnpsid\n"); ++ /* ++ * Attempt to ensure this device is really a DWC_otg Controller. ++ * Read and verify the SNPSID register contents. The value should be ++ * 0x45F42XXX or 0x45F42XXX, which corresponds to either "OT2" or "OTG3", ++ * as in "OTG version 2.XX" or "OTG version 3.XX". ++ */ ++ ++ if (((dwc_otg_get_gsnpsid(dwc_otg_device->core_if) & 0xFFFFF000) != 0x4F542000) && ++ ((dwc_otg_get_gsnpsid(dwc_otg_device->core_if) & 0xFFFFF000) != 0x4F543000)) { ++ dev_err(&_dev->dev, "Bad value for SNPSID: 0x%08x\n", ++ dwc_otg_get_gsnpsid(dwc_otg_device->core_if)); ++ retval = -EINVAL; ++ goto fail; ++ } ++ ++ /* ++ * Validate parameter values. ++ */ ++ dev_dbg(&_dev->dev, "Calling set_parameters\n"); ++ if (set_parameters(dwc_otg_device->core_if)) { ++ retval = -EINVAL; ++ goto fail; ++ } ++ ++ /* ++ * Create Device Attributes in sysfs ++ */ ++ dev_dbg(&_dev->dev, "Calling attr_create\n"); ++ dwc_otg_attr_create(_dev); ++ ++ /* ++ * Disable the global interrupt until all the interrupt ++ * handlers are installed. ++ */ ++ dev_dbg(&_dev->dev, "Calling disable_global_interrupts\n"); ++ dwc_otg_disable_global_interrupts(dwc_otg_device->core_if); ++ ++ /* ++ * Install the interrupt handler for the common interrupts before ++ * enabling common interrupts in core_init below. ++ */ ++ ++#if defined(PLATFORM_INTERFACE) ++ devirq = platform_get_irq(_dev, 0); ++#else ++ devirq = _dev->irq; ++#endif ++ DWC_DEBUGPL(DBG_CIL, "registering (common) handler for irq%d\n", ++ devirq); ++ dev_dbg(&_dev->dev, "Calling request_irq(%d)\n", devirq); ++ retval = request_irq(devirq, dwc_otg_common_irq, ++ IRQF_SHARED, ++ "dwc_otg", dwc_otg_device); ++ if (retval) { ++ DWC_ERROR("request of irq%d failed\n", devirq); ++ retval = -EBUSY; ++ goto fail; ++ } else { ++ dwc_otg_device->common_irq_installed = 1; ++ } ++ ++#ifndef IRQF_TRIGGER_LOW ++#if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE) ++ dev_dbg(&_dev->dev, "Calling set_irq_type\n"); ++ set_irq_type(devirq, ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) ++ IRQT_LOW ++#else ++ IRQ_TYPE_LEVEL_LOW ++#endif ++ ); ++#endif ++#endif /*IRQF_TRIGGER_LOW*/ ++ ++ /* ++ * Initialize the DWC_otg core. ++ */ ++ dev_dbg(&_dev->dev, "Calling dwc_otg_core_init\n"); ++ dwc_otg_core_init(dwc_otg_device->core_if); ++ ++#ifndef DWC_HOST_ONLY ++ /* ++ * Initialize the PCD ++ */ ++ dev_dbg(&_dev->dev, "Calling pcd_init\n"); ++ retval = pcd_init(_dev); ++ if (retval != 0) { ++ DWC_ERROR("pcd_init failed\n"); ++ dwc_otg_device->pcd = NULL; ++ goto fail; ++ } ++#endif ++#ifndef DWC_DEVICE_ONLY ++ /* ++ * Initialize the HCD ++ */ ++ dev_dbg(&_dev->dev, "Calling hcd_init\n"); ++ retval = hcd_init(_dev); ++ if (retval != 0) { ++ DWC_ERROR("hcd_init failed\n"); ++ dwc_otg_device->hcd = NULL; ++ goto fail; ++ } ++#endif ++ /* Recover from drvdata having been overwritten by hcd_init() */ ++#ifdef LM_INTERFACE ++ lm_set_drvdata(_dev, dwc_otg_device); ++#elif defined(PLATFORM_INTERFACE) ++ platform_set_drvdata(_dev, dwc_otg_device); ++#elif defined(PCI_INTERFACE) ++ pci_set_drvdata(_dev, dwc_otg_device); ++ dwc_otg_device->os_dep.pcidev = _dev; ++#endif ++ ++ /* ++ * Enable the global interrupt after all the interrupt ++ * handlers are installed if there is no ADP support else ++ * perform initial actions required for Internal ADP logic. ++ */ ++ if (!dwc_otg_get_param_adp_enable(dwc_otg_device->core_if)) { ++ dev_dbg(&_dev->dev, "Calling enable_global_interrupts\n"); ++ dwc_otg_enable_global_interrupts(dwc_otg_device->core_if); ++ dev_dbg(&_dev->dev, "Done\n"); ++ } else ++ dwc_otg_adp_start(dwc_otg_device->core_if, ++ dwc_otg_is_host_mode(dwc_otg_device->core_if)); ++ ++ return 0; ++ ++fail: ++ dwc_otg_driver_remove(_dev); ++ return retval; ++} ++ ++/** ++ * This structure defines the methods to be called by a bus driver ++ * during the lifecycle of a device on that bus. Both drivers and ++ * devices are registered with a bus driver. The bus driver matches ++ * devices to drivers based on information in the device and driver ++ * structures. ++ * ++ * The probe function is called when the bus driver matches a device ++ * to this driver. The remove function is called when a device is ++ * unregistered with the bus driver. ++ */ ++#ifdef LM_INTERFACE ++static struct lm_driver dwc_otg_driver = { ++ .drv = {.name = (char *)dwc_driver_name,}, ++ .probe = dwc_otg_driver_probe, ++ .remove = dwc_otg_driver_remove, ++ // 'suspend' and 'resume' absent ++}; ++#elif defined(PCI_INTERFACE) ++static const struct pci_device_id pci_ids[] = { { ++ PCI_DEVICE(0x16c3, 0xabcd), ++ .driver_data = ++ (unsigned long)0xdeadbeef, ++ }, { /* end: all zeroes */ } ++}; ++ ++MODULE_DEVICE_TABLE(pci, pci_ids); ++ ++/* pci driver glue; this is a "new style" PCI driver module */ ++static struct pci_driver dwc_otg_driver = { ++ .name = "dwc_otg", ++ .id_table = pci_ids, ++ ++ .probe = dwc_otg_driver_probe, ++ .remove = dwc_otg_driver_remove, ++ ++ .driver = { ++ .name = (char *)dwc_driver_name, ++ }, ++}; ++#elif defined(PLATFORM_INTERFACE) ++static struct platform_device_id platform_ids[] = { ++ { ++ .name = "bcm2708_usb", ++ .driver_data = (kernel_ulong_t) 0xdeadbeef, ++ }, ++ { /* end: all zeroes */ } ++}; ++MODULE_DEVICE_TABLE(platform, platform_ids); ++ ++static struct platform_driver dwc_otg_driver = { ++ .driver = { ++ .name = (char *)dwc_driver_name, ++ }, ++ .id_table = platform_ids, ++ ++ .probe = dwc_otg_driver_probe, ++ .remove = dwc_otg_driver_remove, ++ // no 'shutdown', 'suspend', 'resume', 'suspend_late' or 'resume_early' ++}; ++#endif ++ ++/** ++ * This function is called when the dwc_otg_driver is installed with the ++ * insmod command. It registers the dwc_otg_driver structure with the ++ * appropriate bus driver. This will cause the dwc_otg_driver_probe function ++ * to be called. In addition, the bus driver will automatically expose ++ * attributes defined for the device and driver in the special sysfs file ++ * system. ++ * ++ * @return ++ */ ++static int __init dwc_otg_driver_init(void) ++{ ++ int retval = 0; ++ int error; ++ struct device_driver *drv; ++ printk(KERN_INFO "%s: version %s (%s bus)\n", dwc_driver_name, ++ DWC_DRIVER_VERSION, ++#ifdef LM_INTERFACE ++ "logicmodule"); ++ retval = lm_driver_register(&dwc_otg_driver); ++ drv = &dwc_otg_driver.drv; ++#elif defined(PCI_INTERFACE) ++ "pci"); ++ retval = pci_register_driver(&dwc_otg_driver); ++ drv = &dwc_otg_driver.driver; ++#elif defined(PLATFORM_INTERFACE) ++ "platform"); ++ retval = platform_driver_register(&dwc_otg_driver); ++ drv = &dwc_otg_driver.driver; ++#endif ++ if (retval < 0) { ++ printk(KERN_ERR "%s retval=%d\n", __func__, retval); ++ return retval; ++ } ++ ++ error = driver_create_file(drv, &driver_attr_version); ++#ifdef DEBUG ++ error = driver_create_file(drv, &driver_attr_debuglevel); ++#endif ++ return retval; ++} ++ ++module_init(dwc_otg_driver_init); ++ ++/** ++ * This function is called when the driver is removed from the kernel ++ * with the rmmod command. The driver unregisters itself with its bus ++ * driver. ++ * ++ */ ++static void __exit dwc_otg_driver_cleanup(void) ++{ ++ printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n"); ++ ++#ifdef LM_INTERFACE ++ driver_remove_file(&dwc_otg_driver.drv, &driver_attr_debuglevel); ++ driver_remove_file(&dwc_otg_driver.drv, &driver_attr_version); ++ lm_driver_unregister(&dwc_otg_driver); ++#elif defined(PCI_INTERFACE) ++ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel); ++ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version); ++ pci_unregister_driver(&dwc_otg_driver); ++#elif defined(PLATFORM_INTERFACE) ++ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel); ++ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version); ++ platform_driver_unregister(&dwc_otg_driver); ++#endif ++ ++ printk(KERN_INFO "%s module removed\n", dwc_driver_name); ++} ++ ++module_exit(dwc_otg_driver_cleanup); ++ ++MODULE_DESCRIPTION(DWC_DRIVER_DESC); ++MODULE_AUTHOR("Synopsys Inc."); ++MODULE_LICENSE("GPL"); ++ ++module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444); ++MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None"); ++module_param_named(opt, dwc_otg_module_params.opt, int, 0444); ++MODULE_PARM_DESC(opt, "OPT Mode"); ++module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444); ++MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled"); ++ ++module_param_named(dma_desc_enable, dwc_otg_module_params.dma_desc_enable, int, ++ 0444); ++MODULE_PARM_DESC(dma_desc_enable, ++ "DMA Desc Mode 0=Address DMA 1=DMA Descriptor enabled"); ++ ++module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int, ++ 0444); ++MODULE_PARM_DESC(dma_burst_size, ++ "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256"); ++module_param_named(speed, dwc_otg_module_params.speed, int, 0444); ++MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed"); ++module_param_named(host_support_fs_ls_low_power, ++ dwc_otg_module_params.host_support_fs_ls_low_power, int, ++ 0444); ++MODULE_PARM_DESC(host_support_fs_ls_low_power, ++ "Support Low Power w/FS or LS 0=Support 1=Don't Support"); ++module_param_named(host_ls_low_power_phy_clk, ++ dwc_otg_module_params.host_ls_low_power_phy_clk, int, 0444); ++MODULE_PARM_DESC(host_ls_low_power_phy_clk, ++ "Low Speed Low Power Clock 0=48Mhz 1=6Mhz"); ++module_param_named(enable_dynamic_fifo, ++ dwc_otg_module_params.enable_dynamic_fifo, int, 0444); ++MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing"); ++module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int, ++ 0444); ++MODULE_PARM_DESC(data_fifo_size, ++ "Total number of words in the data FIFO memory 32-32768"); ++module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size, ++ int, 0444); ++MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768"); ++module_param_named(dev_nperio_tx_fifo_size, ++ dwc_otg_module_params.dev_nperio_tx_fifo_size, int, 0444); ++MODULE_PARM_DESC(dev_nperio_tx_fifo_size, ++ "Number of words in the non-periodic Tx FIFO 16-32768"); ++module_param_named(dev_perio_tx_fifo_size_1, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[0], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_1, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_2, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[1], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_2, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_3, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[2], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_3, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_4, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[3], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_4, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_5, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[4], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_5, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_6, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[5], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_6, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_7, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[6], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_7, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_8, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[7], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_8, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_9, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[8], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_9, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_10, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[9], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_10, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_11, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[10], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_11, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_12, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[11], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_12, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_13, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[12], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_13, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_14, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[13], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_14, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(dev_perio_tx_fifo_size_15, ++ dwc_otg_module_params.dev_perio_tx_fifo_size[14], int, 0444); ++MODULE_PARM_DESC(dev_perio_tx_fifo_size_15, ++ "Number of words in the periodic Tx FIFO 4-768"); ++module_param_named(host_rx_fifo_size, dwc_otg_module_params.host_rx_fifo_size, ++ int, 0444); ++MODULE_PARM_DESC(host_rx_fifo_size, "Number of words in the Rx FIFO 16-32768"); ++module_param_named(host_nperio_tx_fifo_size, ++ dwc_otg_module_params.host_nperio_tx_fifo_size, int, 0444); ++MODULE_PARM_DESC(host_nperio_tx_fifo_size, ++ "Number of words in the non-periodic Tx FIFO 16-32768"); ++module_param_named(host_perio_tx_fifo_size, ++ dwc_otg_module_params.host_perio_tx_fifo_size, int, 0444); ++MODULE_PARM_DESC(host_perio_tx_fifo_size, ++ "Number of words in the host periodic Tx FIFO 16-32768"); ++module_param_named(max_transfer_size, dwc_otg_module_params.max_transfer_size, ++ int, 0444); ++/** @todo Set the max to 512K, modify checks */ ++MODULE_PARM_DESC(max_transfer_size, ++ "The maximum transfer size supported in bytes 2047-65535"); ++module_param_named(max_packet_count, dwc_otg_module_params.max_packet_count, ++ int, 0444); ++MODULE_PARM_DESC(max_packet_count, ++ "The maximum number of packets in a transfer 15-511"); ++module_param_named(host_channels, dwc_otg_module_params.host_channels, int, ++ 0444); ++MODULE_PARM_DESC(host_channels, ++ "The number of host channel registers to use 1-16"); ++module_param_named(dev_endpoints, dwc_otg_module_params.dev_endpoints, int, ++ 0444); ++MODULE_PARM_DESC(dev_endpoints, ++ "The number of endpoints in addition to EP0 available for device mode 1-15"); ++module_param_named(phy_type, dwc_otg_module_params.phy_type, int, 0444); ++MODULE_PARM_DESC(phy_type, "0=Reserved 1=UTMI+ 2=ULPI"); ++module_param_named(phy_utmi_width, dwc_otg_module_params.phy_utmi_width, int, ++ 0444); ++MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits"); ++module_param_named(phy_ulpi_ddr, dwc_otg_module_params.phy_ulpi_ddr, int, 0444); ++MODULE_PARM_DESC(phy_ulpi_ddr, ++ "ULPI at double or single data rate 0=Single 1=Double"); ++module_param_named(phy_ulpi_ext_vbus, dwc_otg_module_params.phy_ulpi_ext_vbus, ++ int, 0444); ++MODULE_PARM_DESC(phy_ulpi_ext_vbus, ++ "ULPI PHY using internal or external vbus 0=Internal"); ++module_param_named(i2c_enable, dwc_otg_module_params.i2c_enable, int, 0444); ++MODULE_PARM_DESC(i2c_enable, "FS PHY Interface"); ++module_param_named(ulpi_fs_ls, dwc_otg_module_params.ulpi_fs_ls, int, 0444); ++MODULE_PARM_DESC(ulpi_fs_ls, "ULPI PHY FS/LS mode only"); ++module_param_named(ts_dline, dwc_otg_module_params.ts_dline, int, 0444); ++MODULE_PARM_DESC(ts_dline, "Term select Dline pulsing for all PHYs"); ++module_param_named(debug, g_dbg_lvl, int, 0444); ++MODULE_PARM_DESC(debug, ""); ++ ++module_param_named(en_multiple_tx_fifo, ++ dwc_otg_module_params.en_multiple_tx_fifo, int, 0444); ++MODULE_PARM_DESC(en_multiple_tx_fifo, ++ "Dedicated Non Periodic Tx FIFOs 0=disabled 1=enabled"); ++module_param_named(dev_tx_fifo_size_1, ++ dwc_otg_module_params.dev_tx_fifo_size[0], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_1, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_2, ++ dwc_otg_module_params.dev_tx_fifo_size[1], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_2, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_3, ++ dwc_otg_module_params.dev_tx_fifo_size[2], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_3, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_4, ++ dwc_otg_module_params.dev_tx_fifo_size[3], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_4, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_5, ++ dwc_otg_module_params.dev_tx_fifo_size[4], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_5, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_6, ++ dwc_otg_module_params.dev_tx_fifo_size[5], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_6, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_7, ++ dwc_otg_module_params.dev_tx_fifo_size[6], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_7, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_8, ++ dwc_otg_module_params.dev_tx_fifo_size[7], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_8, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_9, ++ dwc_otg_module_params.dev_tx_fifo_size[8], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_9, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_10, ++ dwc_otg_module_params.dev_tx_fifo_size[9], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_10, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_11, ++ dwc_otg_module_params.dev_tx_fifo_size[10], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_11, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_12, ++ dwc_otg_module_params.dev_tx_fifo_size[11], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_12, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_13, ++ dwc_otg_module_params.dev_tx_fifo_size[12], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_13, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_14, ++ dwc_otg_module_params.dev_tx_fifo_size[13], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_14, "Number of words in the Tx FIFO 4-768"); ++module_param_named(dev_tx_fifo_size_15, ++ dwc_otg_module_params.dev_tx_fifo_size[14], int, 0444); ++MODULE_PARM_DESC(dev_tx_fifo_size_15, "Number of words in the Tx FIFO 4-768"); ++ ++module_param_named(thr_ctl, dwc_otg_module_params.thr_ctl, int, 0444); ++MODULE_PARM_DESC(thr_ctl, ++ "Thresholding enable flag bit 0 - non ISO Tx thr., 1 - ISO Tx thr., 2 - Rx thr.- bit 0=disabled 1=enabled"); ++module_param_named(tx_thr_length, dwc_otg_module_params.tx_thr_length, int, ++ 0444); ++MODULE_PARM_DESC(tx_thr_length, "Tx Threshold length in 32 bit DWORDs"); ++module_param_named(rx_thr_length, dwc_otg_module_params.rx_thr_length, int, ++ 0444); ++MODULE_PARM_DESC(rx_thr_length, "Rx Threshold length in 32 bit DWORDs"); ++ ++module_param_named(pti_enable, dwc_otg_module_params.pti_enable, int, 0444); ++module_param_named(mpi_enable, dwc_otg_module_params.mpi_enable, int, 0444); ++module_param_named(lpm_enable, dwc_otg_module_params.lpm_enable, int, 0444); ++MODULE_PARM_DESC(lpm_enable, "LPM Enable 0=LPM Disabled 1=LPM Enabled"); ++module_param_named(ic_usb_cap, dwc_otg_module_params.ic_usb_cap, int, 0444); ++MODULE_PARM_DESC(ic_usb_cap, ++ "IC_USB Capability 0=IC_USB Disabled 1=IC_USB Enabled"); ++module_param_named(ahb_thr_ratio, dwc_otg_module_params.ahb_thr_ratio, int, ++ 0444); ++MODULE_PARM_DESC(ahb_thr_ratio, "AHB Threshold Ratio"); ++module_param_named(power_down, dwc_otg_module_params.power_down, int, 0444); ++MODULE_PARM_DESC(power_down, "Power Down Mode"); ++module_param_named(reload_ctl, dwc_otg_module_params.reload_ctl, int, 0444); ++MODULE_PARM_DESC(reload_ctl, "HFIR Reload Control"); ++module_param_named(dev_out_nak, dwc_otg_module_params.dev_out_nak, int, 0444); ++MODULE_PARM_DESC(dev_out_nak, "Enable Device OUT NAK"); ++module_param_named(cont_on_bna, dwc_otg_module_params.cont_on_bna, int, 0444); ++MODULE_PARM_DESC(cont_on_bna, "Enable Enable Continue on BNA"); ++module_param_named(ahb_single, dwc_otg_module_params.ahb_single, int, 0444); ++MODULE_PARM_DESC(ahb_single, "Enable AHB Single Support"); ++module_param_named(adp_enable, dwc_otg_module_params.adp_enable, int, 0444); ++MODULE_PARM_DESC(adp_enable, "ADP Enable 0=ADP Disabled 1=ADP Enabled"); ++module_param_named(otg_ver, dwc_otg_module_params.otg_ver, int, 0444); ++MODULE_PARM_DESC(otg_ver, "OTG revision supported 0=OTG 1.3 1=OTG 2.0"); ++module_param(microframe_schedule, bool, 0444); ++MODULE_PARM_DESC(microframe_schedule, "Enable the microframe scheduler"); ++ ++/** @page "Module Parameters" ++ * ++ * The following parameters may be specified when starting the module. ++ * These parameters define how the DWC_otg controller should be ++ * configured. Parameter values are passed to the CIL initialization ++ * function dwc_otg_cil_init ++ * ++ * Example: modprobe dwc_otg speed=1 otg_cap=1 ++ * ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++*/ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_driver.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_driver.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,86 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.h $ ++ * $Revision: #19 $ ++ * $Date: 2010/11/15 $ ++ * $Change: 1627671 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#ifndef __DWC_OTG_DRIVER_H__ ++#define __DWC_OTG_DRIVER_H__ ++ ++/** @file ++ * This file contains the interface to the Linux driver. ++ */ ++#include "dwc_otg_os_dep.h" ++#include "dwc_otg_core_if.h" ++ ++/* Type declarations */ ++struct dwc_otg_pcd; ++struct dwc_otg_hcd; ++ ++/** ++ * This structure is a wrapper that encapsulates the driver components used to ++ * manage a single DWC_otg controller. ++ */ ++typedef struct dwc_otg_device { ++ /** Structure containing OS-dependent stuff. KEEP THIS STRUCT AT THE ++ * VERY BEGINNING OF THE DEVICE STRUCT. OSes such as FreeBSD and NetBSD ++ * require this. */ ++ struct os_dependent os_dep; ++ ++ /** Pointer to the core interface structure. */ ++ dwc_otg_core_if_t *core_if; ++ ++ /** Pointer to the PCD structure. */ ++ struct dwc_otg_pcd *pcd; ++ ++ /** Pointer to the HCD structure. */ ++ struct dwc_otg_hcd *hcd; ++ ++ /** Flag to indicate whether the common IRQ handler is installed. */ ++ uint8_t common_irq_installed; ++ ++} dwc_otg_device_t; ++ ++/*We must clear S3C24XX_EINTPEND external interrupt register ++ * because after clearing in this register trigerred IRQ from ++ * H/W core in kernel interrupt can be occured again before OTG ++ * handlers clear all IRQ sources of Core registers because of ++ * timing latencies and Low Level IRQ Type. ++ */ ++#ifdef CONFIG_MACH_IPMATE ++#define S3C2410X_CLEAR_EINTPEND() \ ++do { \ ++ __raw_writel(1UL << 11,S3C24XX_EINTPEND); \ ++} while (0) ++#else ++#define S3C2410X_CLEAR_EINTPEND() do { } while (0) ++#endif ++ ++#endif +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,3473 @@ ++ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $ ++ * $Revision: #104 $ ++ * $Date: 2011/10/24 $ ++ * $Change: 1871159 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_DEVICE_ONLY ++ ++/** @file ++ * This file implements HCD Core. All code in this file is portable and doesn't ++ * use any OS specific functions. ++ * Interface provided by HCD Core is defined in ++ * header file. ++ */ ++ ++#include "dwc_otg_hcd.h" ++#include "dwc_otg_regs.h" ++ ++extern bool microframe_schedule; ++ ++//#define DEBUG_HOST_CHANNELS ++#ifdef DEBUG_HOST_CHANNELS ++static int last_sel_trans_num_per_scheduled = 0; ++static int last_sel_trans_num_nonper_scheduled = 0; ++static int last_sel_trans_num_avail_hc_at_start = 0; ++static int last_sel_trans_num_avail_hc_at_end = 0; ++#endif /* DEBUG_HOST_CHANNELS */ ++ ++dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void) ++{ ++ return DWC_ALLOC(sizeof(dwc_otg_hcd_t)); ++} ++ ++/** ++ * Connection timeout function. An OTG host is required to display a ++ * message if the device does not connect within 10 seconds. ++ */ ++void dwc_otg_hcd_connect_timeout(void *ptr) ++{ ++ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, ptr); ++ DWC_PRINTF("Connect Timeout\n"); ++ __DWC_ERROR("Device Not Connected/Responding\n"); ++} ++ ++#if defined(DEBUG) ++static void dump_channel_info(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ if (qh->channel != NULL) { ++ dwc_hc_t *hc = qh->channel; ++ dwc_list_link_t *item; ++ dwc_otg_qh_t *qh_item; ++ int num_channels = hcd->core_if->core_params->host_channels; ++ int i; ++ ++ dwc_otg_hc_regs_t *hc_regs; ++ hcchar_data_t hcchar; ++ hcsplt_data_t hcsplt; ++ hctsiz_data_t hctsiz; ++ uint32_t hcdma; ++ ++ hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num]; ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt); ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ hcdma = DWC_READ_REG32(&hc_regs->hcdma); ++ ++ DWC_PRINTF(" Assigned to channel %p:\n", hc); ++ DWC_PRINTF(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, ++ hcsplt.d32); ++ DWC_PRINTF(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, ++ hcdma); ++ DWC_PRINTF(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n", ++ hc->dev_addr, hc->ep_num, hc->ep_is_in); ++ DWC_PRINTF(" ep_type: %d\n", hc->ep_type); ++ DWC_PRINTF(" max_packet: %d\n", hc->max_packet); ++ DWC_PRINTF(" data_pid_start: %d\n", hc->data_pid_start); ++ DWC_PRINTF(" xfer_started: %d\n", hc->xfer_started); ++ DWC_PRINTF(" halt_status: %d\n", hc->halt_status); ++ DWC_PRINTF(" xfer_buff: %p\n", hc->xfer_buff); ++ DWC_PRINTF(" xfer_len: %d\n", hc->xfer_len); ++ DWC_PRINTF(" qh: %p\n", hc->qh); ++ DWC_PRINTF(" NP inactive sched:\n"); ++ DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_inactive) { ++ qh_item = ++ DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry); ++ DWC_PRINTF(" %p\n", qh_item); ++ } ++ DWC_PRINTF(" NP active sched:\n"); ++ DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_active) { ++ qh_item = ++ DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry); ++ DWC_PRINTF(" %p\n", qh_item); ++ } ++ DWC_PRINTF(" Channels: \n"); ++ for (i = 0; i < num_channels; i++) { ++ dwc_hc_t *hc = hcd->hc_ptr_array[i]; ++ DWC_PRINTF(" %2d: %p\n", i, hc); ++ } ++ } ++} ++#else ++#define dump_channel_info(hcd, qh) ++#endif /* DEBUG */ ++ ++/** ++ * Work queue function for starting the HCD when A-Cable is connected. ++ * The hcd_start() must be called in a process context. ++ */ ++static void hcd_start_func(void *_vp) ++{ ++ dwc_otg_hcd_t *hcd = (dwc_otg_hcd_t *) _vp; ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, hcd); ++ if (hcd) { ++ hcd->fops->start(hcd); ++ } ++} ++ ++static void del_xfer_timers(dwc_otg_hcd_t * hcd) ++{ ++#ifdef DEBUG ++ int i; ++ int num_channels = hcd->core_if->core_params->host_channels; ++ for (i = 0; i < num_channels; i++) { ++ DWC_TIMER_CANCEL(hcd->core_if->hc_xfer_timer[i]); ++ } ++#endif ++} ++ ++static void del_timers(dwc_otg_hcd_t * hcd) ++{ ++ del_xfer_timers(hcd); ++ DWC_TIMER_CANCEL(hcd->conn_timer); ++} ++ ++/** ++ * Processes all the URBs in a single list of QHs. Completes them with ++ * -ETIMEDOUT and frees the QTD. ++ */ ++static void kill_urbs_in_qh_list(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list) ++{ ++ dwc_list_link_t *qh_item; ++ dwc_otg_qh_t *qh; ++ dwc_otg_qtd_t *qtd, *qtd_tmp; ++ ++ DWC_LIST_FOREACH(qh_item, qh_list) { ++ qh = DWC_LIST_ENTRY(qh_item, dwc_otg_qh_t, qh_list_entry); ++ DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, ++ &qh->qtd_list, qtd_list_entry) { ++ qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list); ++ if (qtd->urb != NULL) { ++ hcd->fops->complete(hcd, qtd->urb->priv, ++ qtd->urb, -DWC_E_TIMEOUT); ++ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh); ++ } ++ ++ } ++ } ++} ++ ++/** ++ * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic ++ * and periodic schedules. The QTD associated with each URB is removed from ++ * the schedule and freed. This function may be called when a disconnect is ++ * detected or when the HCD is being stopped. ++ */ ++static void kill_all_urbs(dwc_otg_hcd_t * hcd) ++{ ++ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive); ++ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active); ++ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive); ++ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready); ++ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned); ++ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued); ++} ++ ++/** ++ * Start the connection timer. An OTG host is required to display a ++ * message if the device does not connect within 10 seconds. The ++ * timer is deleted if a port connect interrupt occurs before the ++ * timer expires. ++ */ ++static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t * hcd) ++{ ++ DWC_TIMER_SCHEDULE(hcd->conn_timer, 10000 /* 10 secs */ ); ++} ++ ++/** ++ * HCD Callback function for disconnect of the HCD. ++ * ++ * @param p void pointer to the struct usb_hcd ++ */ ++static int32_t dwc_otg_hcd_session_start_cb(void *p) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd; ++ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p); ++ dwc_otg_hcd = p; ++ dwc_otg_hcd_start_connect_timer(dwc_otg_hcd); ++ return 1; ++} ++ ++/** ++ * HCD Callback function for starting the HCD when A-Cable is ++ * connected. ++ * ++ * @param p void pointer to the struct usb_hcd ++ */ ++static int32_t dwc_otg_hcd_start_cb(void *p) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = p; ++ dwc_otg_core_if_t *core_if; ++ hprt0_data_t hprt0; ++ ++ core_if = dwc_otg_hcd->core_if; ++ ++ if (core_if->op_state == B_HOST) { ++ /* ++ * Reset the port. During a HNP mode switch the reset ++ * needs to occur within 1ms and have a duration of at ++ * least 50ms. ++ */ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtrst = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ } ++ DWC_WORKQ_SCHEDULE_DELAYED(core_if->wq_otg, ++ hcd_start_func, dwc_otg_hcd, 50, ++ "start hcd"); ++ ++ return 1; ++} ++ ++/** ++ * HCD Callback function for disconnect of the HCD. ++ * ++ * @param p void pointer to the struct usb_hcd ++ */ ++static int32_t dwc_otg_hcd_disconnect_cb(void *p) ++{ ++ gintsts_data_t intr; ++ dwc_otg_hcd_t *dwc_otg_hcd = p; ++ ++ /* ++ * Set status flags for the hub driver. ++ */ ++ dwc_otg_hcd->flags.b.port_connect_status_change = 1; ++ dwc_otg_hcd->flags.b.port_connect_status = 0; ++ ++ /* ++ * Shutdown any transfers in process by clearing the Tx FIFO Empty ++ * interrupt mask and status bits and disabling subsequent host ++ * channel interrupts. ++ */ ++ intr.d32 = 0; ++ intr.b.nptxfempty = 1; ++ intr.b.ptxfempty = 1; ++ intr.b.hcintr = 1; ++ DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, ++ intr.d32, 0); ++ DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintsts, ++ intr.d32, 0); ++ ++ del_timers(dwc_otg_hcd); ++ ++ /* ++ * Turn off the vbus power only if the core has transitioned to device ++ * mode. If still in host mode, need to keep power on to detect a ++ * reconnection. ++ */ ++ if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) { ++ if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) { ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++ DWC_PRINTF("Disconnect: PortPower off\n"); ++ hprt0.b.prtpwr = 0; ++ DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0, ++ hprt0.d32); ++ } ++ ++ dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if); ++ } ++ ++ /* Respond with an error status to all URBs in the schedule. */ ++ kill_all_urbs(dwc_otg_hcd); ++ ++ if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) { ++ /* Clean up any host channels that were in use. */ ++ int num_channels; ++ int i; ++ dwc_hc_t *channel; ++ dwc_otg_hc_regs_t *hc_regs; ++ hcchar_data_t hcchar; ++ ++ num_channels = dwc_otg_hcd->core_if->core_params->host_channels; ++ ++ if (!dwc_otg_hcd->core_if->dma_enable) { ++ /* Flush out any channel requests in slave mode. */ ++ for (i = 0; i < num_channels; i++) { ++ channel = dwc_otg_hcd->hc_ptr_array[i]; ++ if (DWC_CIRCLEQ_EMPTY_ENTRY ++ (channel, hc_list_entry)) { ++ hc_regs = ++ dwc_otg_hcd->core_if-> ++ host_if->hc_regs[i]; ++ hcchar.d32 = ++ DWC_READ_REG32(&hc_regs->hcchar); ++ if (hcchar.b.chen) { ++ hcchar.b.chen = 0; ++ hcchar.b.chdis = 1; ++ hcchar.b.epdir = 0; ++ DWC_WRITE_REG32 ++ (&hc_regs->hcchar, ++ hcchar.d32); ++ } ++ } ++ } ++ } ++ ++ for (i = 0; i < num_channels; i++) { ++ channel = dwc_otg_hcd->hc_ptr_array[i]; ++ if (DWC_CIRCLEQ_EMPTY_ENTRY(channel, hc_list_entry)) { ++ hc_regs = ++ dwc_otg_hcd->core_if->host_if->hc_regs[i]; ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ if (hcchar.b.chen) { ++ /* Halt the channel. */ ++ hcchar.b.chdis = 1; ++ DWC_WRITE_REG32(&hc_regs->hcchar, ++ hcchar.d32); ++ } ++ ++ dwc_otg_hc_cleanup(dwc_otg_hcd->core_if, ++ channel); ++ DWC_CIRCLEQ_INSERT_TAIL ++ (&dwc_otg_hcd->free_hc_list, channel, ++ hc_list_entry); ++ /* ++ * Added for Descriptor DMA to prevent channel double cleanup ++ * in release_channel_ddma(). Which called from ep_disable ++ * when device disconnect. ++ */ ++ channel->qh = NULL; ++ } ++ } ++ } ++ ++ if (dwc_otg_hcd->fops->disconnect) { ++ dwc_otg_hcd->fops->disconnect(dwc_otg_hcd); ++ } ++ ++ return 1; ++} ++ ++/** ++ * HCD Callback function for stopping the HCD. ++ * ++ * @param p void pointer to the struct usb_hcd ++ */ ++static int32_t dwc_otg_hcd_stop_cb(void *p) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = p; ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p); ++ dwc_otg_hcd_stop(dwc_otg_hcd); ++ return 1; ++} ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++/** ++ * HCD Callback function for sleep of HCD. ++ * ++ * @param p void pointer to the struct usb_hcd ++ */ ++static int dwc_otg_hcd_sleep_cb(void *p) ++{ ++ dwc_otg_hcd_t *hcd = p; ++ ++ dwc_otg_hcd_free_hc_from_lpm(hcd); ++ ++ return 0; ++} ++#endif ++ ++/** ++ * HCD Callback function for Remote Wakeup. ++ * ++ * @param p void pointer to the struct usb_hcd ++ */ ++static int dwc_otg_hcd_rem_wakeup_cb(void *p) ++{ ++ dwc_otg_hcd_t *hcd = p; ++ ++ if (hcd->core_if->lx_state == DWC_OTG_L2) { ++ hcd->flags.b.port_suspend_change = 1; ++ } ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ else { ++ hcd->flags.b.port_l1_change = 1; ++ } ++#endif ++ return 0; ++} ++ ++/** ++ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are ++ * stopped. ++ */ ++void dwc_otg_hcd_stop(dwc_otg_hcd_t * hcd) ++{ ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n"); ++ ++ /* ++ * The root hub should be disconnected before this function is called. ++ * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue) ++ * and the QH lists (via ..._hcd_endpoint_disable). ++ */ ++ ++ /* Turn off all host-specific interrupts. */ ++ dwc_otg_disable_host_interrupts(hcd->core_if); ++ ++ /* Turn off the vbus power */ ++ DWC_PRINTF("PortPower off\n"); ++ hprt0.b.prtpwr = 0; ++ DWC_WRITE_REG32(hcd->core_if->host_if->hprt0, hprt0.d32); ++ dwc_mdelay(1); ++} ++ ++int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t * hcd, ++ dwc_otg_hcd_urb_t * dwc_otg_urb, void **ep_handle, ++ int atomic_alloc) ++{ ++ dwc_irqflags_t flags; ++ int retval = 0; ++ dwc_otg_qtd_t *qtd; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++#ifdef DEBUG /* integrity checks (Broadcom) */ ++ if (NULL == hcd->core_if) { ++ DWC_ERROR("**** DWC OTG HCD URB Enqueue - HCD has NULL core_if\n"); ++ /* No longer connected. */ ++ return -DWC_E_INVALID; ++ } ++#endif ++ if (!hcd->flags.b.port_connect_status) { ++ /* No longer connected. */ ++ DWC_ERROR("Not connected\n"); ++ return -DWC_E_NO_DEVICE; ++ } ++ ++ qtd = dwc_otg_hcd_qtd_create(dwc_otg_urb, atomic_alloc); ++ if (qtd == NULL) { ++ DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n"); ++ return -DWC_E_NO_MEMORY; ++ } ++#ifdef DEBUG /* integrity checks (Broadcom) */ ++ if (qtd->urb == NULL) { ++ DWC_ERROR("**** DWC OTG HCD URB Enqueue created QTD with no URBs\n"); ++ return -DWC_E_NO_MEMORY; ++ } ++ if (qtd->urb->priv == NULL) { ++ DWC_ERROR("**** DWC OTG HCD URB Enqueue created QTD URB with no URB handle\n"); ++ return -DWC_E_NO_MEMORY; ++ } ++#endif ++ retval = ++ dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc); ++ // creates a new queue in ep_handle if it doesn't exist already ++ if (retval < 0) { ++ DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. " ++ "Error status %d\n", retval); ++ dwc_otg_hcd_qtd_free(qtd); ++ } else { ++ qtd->qh = *ep_handle; ++ } ++ intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk); ++ if (!intr_mask.b.sofintr && retval == 0) { ++ dwc_otg_transaction_type_e tr_type; ++ if ((qtd->qh->ep_type == UE_BULK) ++ && !(qtd->urb->flags & URB_GIVEBACK_ASAP)) { ++ /* Do not schedule SG transactions until qtd has URB_GIVEBACK_ASAP set */ ++ return 0; ++ } ++ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); ++ tr_type = dwc_otg_hcd_select_transactions(hcd); ++ if (tr_type != DWC_OTG_TRANSACTION_NONE) { ++ dwc_otg_hcd_queue_transactions(hcd, tr_type); ++ } ++ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ } ++ ++ return retval; ++} ++ ++int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_t * hcd, ++ dwc_otg_hcd_urb_t * dwc_otg_urb) ++{ ++ dwc_otg_qh_t *qh; ++ dwc_otg_qtd_t *urb_qtd; ++ ++#ifdef DEBUG /* integrity checks (Broadcom) */ ++ ++ if (hcd == NULL) { ++ DWC_ERROR("**** DWC OTG HCD URB Dequeue has NULL HCD\n"); ++ return -DWC_E_INVALID; ++ } ++ if (dwc_otg_urb == NULL) { ++ DWC_ERROR("**** DWC OTG HCD URB Dequeue has NULL URB\n"); ++ return -DWC_E_INVALID; ++ } ++ if (dwc_otg_urb->qtd == NULL) { ++ DWC_ERROR("**** DWC OTG HCD URB Dequeue with NULL QTD\n"); ++ return -DWC_E_INVALID; ++ } ++ urb_qtd = dwc_otg_urb->qtd; ++ if (urb_qtd->qh == NULL) { ++ DWC_ERROR("**** DWC OTG HCD URB Dequeue with QTD with NULL Q handler\n"); ++ return -DWC_E_INVALID; ++ } ++#else ++ urb_qtd = dwc_otg_urb->qtd; ++#endif ++ qh = urb_qtd->qh; ++ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { ++ if (urb_qtd->in_process) { ++ dump_channel_info(hcd, qh); ++ } ++ } ++#ifdef DEBUG /* integrity checks (Broadcom) */ ++ if (hcd->core_if == NULL) { ++ DWC_ERROR("**** DWC OTG HCD URB Dequeue HCD has NULL core_if\n"); ++ return -DWC_E_INVALID; ++ } ++#endif ++ if (urb_qtd->in_process && qh->channel) { ++ /* The QTD is in process (it has been assigned to a channel). */ ++ if (hcd->flags.b.port_connect_status) { ++ /* ++ * If still connected (i.e. in host mode), halt the ++ * channel so it can be used for other transfers. If ++ * no longer connected, the host registers can't be ++ * written to halt the channel since the core is in ++ * device mode. ++ */ ++ dwc_otg_hc_halt(hcd->core_if, qh->channel, ++ DWC_OTG_HC_XFER_URB_DEQUEUE); ++ } ++ } ++ ++ /* ++ * Free the QTD and clean up the associated QH. Leave the QH in the ++ * schedule if it has any remaining QTDs. ++ */ ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue - " ++ "delete %sQueue handler\n", ++ hcd->core_if->dma_desc_enable?"DMA ":""); ++ if (!hcd->core_if->dma_desc_enable) { ++ uint8_t b = urb_qtd->in_process; ++ dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh); ++ if (b) { ++ dwc_otg_hcd_qh_deactivate(hcd, qh, 0); ++ qh->channel = NULL; ++ } else if (DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) { ++ dwc_otg_hcd_qh_remove(hcd, qh); ++ } ++ } else { ++ dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh); ++ } ++ return 0; ++} ++ ++int dwc_otg_hcd_endpoint_disable(dwc_otg_hcd_t * hcd, void *ep_handle, ++ int retry) ++{ ++ dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle; ++ int retval = 0; ++ dwc_irqflags_t flags; ++ ++ if (retry < 0) { ++ retval = -DWC_E_INVALID; ++ goto done; ++ } ++ ++ if (!qh) { ++ retval = -DWC_E_INVALID; ++ goto done; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); ++ ++ while (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list) && retry) { ++ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ retry--; ++ dwc_msleep(5); ++ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); ++ } ++ ++ dwc_otg_hcd_qh_remove(hcd, qh); ++ ++ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ /* ++ * Split dwc_otg_hcd_qh_remove_and_free() into qh_remove ++ * and qh_free to prevent stack dump on DWC_DMA_FREE() with ++ * irq_disabled (spinlock_irqsave) in dwc_otg_hcd_desc_list_free() ++ * and dwc_otg_hcd_frame_list_alloc(). ++ */ ++ dwc_otg_hcd_qh_free(hcd, qh); ++ ++done: ++ return retval; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) ++int dwc_otg_hcd_endpoint_reset(dwc_otg_hcd_t * hcd, void *ep_handle) ++{ ++ int retval = 0; ++ dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle; ++ if (!qh) ++ return -DWC_E_INVALID; ++ ++ qh->data_toggle = DWC_OTG_HC_PID_DATA0; ++ return retval; ++} ++#endif ++ ++/** ++ * HCD Callback structure for handling mode switching. ++ */ ++static dwc_otg_cil_callbacks_t hcd_cil_callbacks = { ++ .start = dwc_otg_hcd_start_cb, ++ .stop = dwc_otg_hcd_stop_cb, ++ .disconnect = dwc_otg_hcd_disconnect_cb, ++ .session_start = dwc_otg_hcd_session_start_cb, ++ .resume_wakeup = dwc_otg_hcd_rem_wakeup_cb, ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ .sleep = dwc_otg_hcd_sleep_cb, ++#endif ++ .p = 0, ++}; ++ ++/** ++ * Reset tasklet function ++ */ ++static void reset_tasklet_func(void *data) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *) data; ++ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; ++ hprt0_data_t hprt0; ++ ++ DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n"); ++ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtrst = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ dwc_mdelay(60); ++ ++ hprt0.b.prtrst = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ dwc_otg_hcd->flags.b.port_reset_change = 1; ++} ++ ++static void qh_list_free(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list) ++{ ++ dwc_list_link_t *item; ++ dwc_otg_qh_t *qh; ++ dwc_irqflags_t flags; ++ ++ if (!qh_list->next) { ++ /* The list hasn't been initialized yet. */ ++ return; ++ } ++ /* ++ * Hold spinlock here. Not needed in that case if bellow ++ * function is being called from ISR ++ */ ++ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); ++ /* Ensure there are no QTDs or URBs left. */ ++ kill_urbs_in_qh_list(hcd, qh_list); ++ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ ++ DWC_LIST_FOREACH(item, qh_list) { ++ qh = DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry); ++ dwc_otg_hcd_qh_remove_and_free(hcd, qh); ++ } ++} ++ ++/** ++ * Exit from Hibernation if Host did not detect SRP from connected SRP capable ++ * Device during SRP time by host power up. ++ */ ++void dwc_otg_hcd_power_up(void *ptr) ++{ ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr; ++ ++ DWC_PRINTF("%s called\n", __FUNCTION__); ++ ++ if (!core_if->hibernation_suspend) { ++ DWC_PRINTF("Already exited from Hibernation\n"); ++ return; ++ } ++ ++ /* Switch on the voltage to the core */ ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Reset the core */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Disable power clamps */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ /* Remove reset the core signal */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnrstn = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Disable PMU interrupt */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ core_if->hibernation_suspend = 0; ++ ++ /* Disable PMU */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ dwc_udelay(10); ++ ++ /* Enable VBUS */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.dis_vbus = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0); ++ ++ core_if->op_state = A_HOST; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_hcd_start(core_if); ++} ++ ++/** ++ * Frees secondary storage associated with the dwc_otg_hcd structure contained ++ * in the struct usb_hcd field. ++ */ ++static void dwc_otg_hcd_free(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ int i; ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n"); ++ ++ del_timers(dwc_otg_hcd); ++ ++ /* Free memory for QH/QTD lists */ ++ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive); ++ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active); ++ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive); ++ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready); ++ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned); ++ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued); ++ ++ /* Free memory for the host channels. */ ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i]; ++ ++#ifdef DEBUG ++ if (dwc_otg_hcd->core_if->hc_xfer_timer[i]) { ++ DWC_TIMER_FREE(dwc_otg_hcd->core_if->hc_xfer_timer[i]); ++ } ++#endif ++ if (hc != NULL) { ++ DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", ++ i, hc); ++ DWC_FREE(hc); ++ } ++ } ++ ++ if (dwc_otg_hcd->core_if->dma_enable) { ++ if (dwc_otg_hcd->status_buf_dma) { ++ DWC_DMA_FREE(DWC_OTG_HCD_STATUS_BUF_SIZE, ++ dwc_otg_hcd->status_buf, ++ dwc_otg_hcd->status_buf_dma); ++ } ++ } else if (dwc_otg_hcd->status_buf != NULL) { ++ DWC_FREE(dwc_otg_hcd->status_buf); ++ } ++ DWC_SPINLOCK_FREE(dwc_otg_hcd->lock); ++ /* Set core_if's lock pointer to NULL */ ++ dwc_otg_hcd->core_if->lock = NULL; ++ ++ DWC_TIMER_FREE(dwc_otg_hcd->conn_timer); ++ DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet); ++ ++#ifdef DWC_DEV_SRPCAP ++ if (dwc_otg_hcd->core_if->power_down == 2 && ++ dwc_otg_hcd->core_if->pwron_timer) { ++ DWC_TIMER_FREE(dwc_otg_hcd->core_if->pwron_timer); ++ } ++#endif ++ DWC_FREE(dwc_otg_hcd); ++} ++ ++int init_hcd_usecs(dwc_otg_hcd_t *_hcd); ++ ++int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if) ++{ ++ int retval = 0; ++ int num_channels; ++ int i; ++ dwc_hc_t *channel; ++ ++ hcd->lock = DWC_SPINLOCK_ALLOC(); ++ DWC_DEBUGPL(DBG_HCDV, "init of HCD %p given core_if %p\n", ++ hcd, core_if); ++ if (!hcd->lock) { ++ DWC_ERROR("Could not allocate lock for pcd"); ++ DWC_FREE(hcd); ++ retval = -DWC_E_NO_MEMORY; ++ goto out; ++ } ++ hcd->core_if = core_if; ++ ++ /* Register the HCD CIL Callbacks */ ++ dwc_otg_cil_register_hcd_callbacks(hcd->core_if, ++ &hcd_cil_callbacks, hcd); ++ ++ /* Initialize the non-periodic schedule. */ ++ DWC_LIST_INIT(&hcd->non_periodic_sched_inactive); ++ DWC_LIST_INIT(&hcd->non_periodic_sched_active); ++ ++ /* Initialize the periodic schedule. */ ++ DWC_LIST_INIT(&hcd->periodic_sched_inactive); ++ DWC_LIST_INIT(&hcd->periodic_sched_ready); ++ DWC_LIST_INIT(&hcd->periodic_sched_assigned); ++ DWC_LIST_INIT(&hcd->periodic_sched_queued); ++ ++ /* ++ * Create a host channel descriptor for each host channel implemented ++ * in the controller. Initialize the channel descriptor array. ++ */ ++ DWC_CIRCLEQ_INIT(&hcd->free_hc_list); ++ num_channels = hcd->core_if->core_params->host_channels; ++ DWC_MEMSET(hcd->hc_ptr_array, 0, sizeof(hcd->hc_ptr_array)); ++ for (i = 0; i < num_channels; i++) { ++ channel = DWC_ALLOC(sizeof(dwc_hc_t)); ++ if (channel == NULL) { ++ retval = -DWC_E_NO_MEMORY; ++ DWC_ERROR("%s: host channel allocation failed\n", ++ __func__); ++ dwc_otg_hcd_free(hcd); ++ goto out; ++ } ++ channel->hc_num = i; ++ hcd->hc_ptr_array[i] = channel; ++#ifdef DEBUG ++ hcd->core_if->hc_xfer_timer[i] = ++ DWC_TIMER_ALLOC("hc timer", hc_xfer_timeout, ++ &hcd->core_if->hc_xfer_info[i]); ++#endif ++ DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, ++ channel); ++ } ++ ++ /* Initialize the Connection timeout timer. */ ++ hcd->conn_timer = DWC_TIMER_ALLOC("Connection timer", ++ dwc_otg_hcd_connect_timeout, 0); ++ ++ printk(KERN_DEBUG "dwc_otg: Microframe scheduler %s\n", microframe_schedule ? "enabled":"disabled"); ++ if (microframe_schedule) ++ init_hcd_usecs(hcd); ++ ++ /* Initialize reset tasklet. */ ++ hcd->reset_tasklet = DWC_TASK_ALLOC("reset_tasklet", reset_tasklet_func, hcd); ++#ifdef DWC_DEV_SRPCAP ++ if (hcd->core_if->power_down == 2) { ++ /* Initialize Power on timer for Host power up in case hibernation */ ++ hcd->core_if->pwron_timer = DWC_TIMER_ALLOC("PWRON TIMER", ++ dwc_otg_hcd_power_up, core_if); ++ } ++#endif ++ ++ /* ++ * Allocate space for storing data on status transactions. Normally no ++ * data is sent, but this space acts as a bit bucket. This must be ++ * done after usb_add_hcd since that function allocates the DMA buffer ++ * pool. ++ */ ++ if (hcd->core_if->dma_enable) { ++ hcd->status_buf = ++ DWC_DMA_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE, ++ &hcd->status_buf_dma); ++ } else { ++ hcd->status_buf = DWC_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE); ++ } ++ if (!hcd->status_buf) { ++ retval = -DWC_E_NO_MEMORY; ++ DWC_ERROR("%s: status_buf allocation failed\n", __func__); ++ dwc_otg_hcd_free(hcd); ++ goto out; ++ } ++ ++ hcd->otg_port = 1; ++ hcd->frame_list = NULL; ++ hcd->frame_list_dma = 0; ++ hcd->periodic_qh_count = 0; ++out: ++ return retval; ++} ++ ++void dwc_otg_hcd_remove(dwc_otg_hcd_t * hcd) ++{ ++ /* Turn off all host-specific interrupts. */ ++ dwc_otg_disable_host_interrupts(hcd->core_if); ++ ++ dwc_otg_hcd_free(hcd); ++} ++ ++/** ++ * Initializes dynamic portions of the DWC_otg HCD state. ++ */ ++static void dwc_otg_hcd_reinit(dwc_otg_hcd_t * hcd) ++{ ++ int num_channels; ++ int i; ++ dwc_hc_t *channel; ++ dwc_hc_t *channel_tmp; ++ ++ hcd->flags.d32 = 0; ++ ++ hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active; ++ if (!microframe_schedule) { ++ hcd->non_periodic_channels = 0; ++ hcd->periodic_channels = 0; ++ } else { ++ hcd->available_host_channels = hcd->core_if->core_params->host_channels; ++ } ++ /* ++ * Put all channels in the free channel list and clean up channel ++ * states. ++ */ ++ DWC_CIRCLEQ_FOREACH_SAFE(channel, channel_tmp, ++ &hcd->free_hc_list, hc_list_entry) { ++ DWC_CIRCLEQ_REMOVE(&hcd->free_hc_list, channel, hc_list_entry); ++ } ++ ++ num_channels = hcd->core_if->core_params->host_channels; ++ for (i = 0; i < num_channels; i++) { ++ channel = hcd->hc_ptr_array[i]; ++ DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, channel, ++ hc_list_entry); ++ dwc_otg_hc_cleanup(hcd->core_if, channel); ++ } ++ ++ /* Initialize the DWC core for host mode operation. */ ++ dwc_otg_core_host_init(hcd->core_if); ++ ++ /* Set core_if's lock pointer to the hcd->lock */ ++ hcd->core_if->lock = hcd->lock; ++} ++ ++/** ++ * Assigns transactions from a QTD to a free host channel and initializes the ++ * host channel to perform the transactions. The host channel is removed from ++ * the free list. ++ * ++ * @param hcd The HCD state structure. ++ * @param qh Transactions from the first QTD for this QH are selected and ++ * assigned to a free host channel. ++ */ ++static void assign_and_init_hc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ dwc_hc_t *hc; ++ dwc_otg_qtd_t *qtd; ++ dwc_otg_hcd_urb_t *urb; ++ void* ptr = NULL; ++ ++ qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list); ++ ++ urb = qtd->urb; ++ ++ DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p) - urb %x, actual_length %d\n", __func__, hcd, qh, (unsigned int)urb, urb->actual_length); ++ ++ if (((urb->actual_length < 0) || (urb->actual_length > urb->length)) && !dwc_otg_hcd_is_pipe_in(&urb->pipe_info)) ++ urb->actual_length = urb->length; ++ ++ ++ hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list); ++ ++ /* Remove the host channel from the free list. */ ++ DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry); ++ ++ qh->channel = hc; ++ ++ qtd->in_process = 1; ++ ++ /* ++ * Use usb_pipedevice to determine device address. This address is ++ * 0 before the SET_ADDRESS command and the correct address afterward. ++ */ ++ hc->dev_addr = dwc_otg_hcd_get_dev_addr(&urb->pipe_info); ++ hc->ep_num = dwc_otg_hcd_get_ep_num(&urb->pipe_info); ++ hc->speed = qh->dev_speed; ++ hc->max_packet = dwc_max_packet(qh->maxp); ++ ++ hc->xfer_started = 0; ++ hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS; ++ hc->error_state = (qtd->error_count > 0); ++ hc->halt_on_queue = 0; ++ hc->halt_pending = 0; ++ hc->requests = 0; ++ ++ /* ++ * The following values may be modified in the transfer type section ++ * below. The xfer_len value may be reduced when the transfer is ++ * started to accommodate the max widths of the XferSize and PktCnt ++ * fields in the HCTSIZn register. ++ */ ++ ++ hc->ep_is_in = (dwc_otg_hcd_is_pipe_in(&urb->pipe_info) != 0); ++ if (hc->ep_is_in) { ++ hc->do_ping = 0; ++ } else { ++ hc->do_ping = qh->ping_state; ++ } ++ ++ hc->data_pid_start = qh->data_toggle; ++ hc->multi_count = 1; ++ ++ if (hcd->core_if->dma_enable) { ++ hc->xfer_buff = (uint8_t *) urb->dma + urb->actual_length; ++ ++ /* For non-dword aligned case */ ++ if (((unsigned long)hc->xfer_buff & 0x3) ++ && !hcd->core_if->dma_desc_enable) { ++ ptr = (uint8_t *) urb->buf + urb->actual_length; ++ } ++ } else { ++ hc->xfer_buff = (uint8_t *) urb->buf + urb->actual_length; ++ } ++ hc->xfer_len = urb->length - urb->actual_length; ++ hc->xfer_count = 0; ++ ++ /* ++ * Set the split attributes ++ */ ++ hc->do_split = 0; ++ if (qh->do_split) { ++ uint32_t hub_addr, port_addr; ++ hc->do_split = 1; ++ hc->xact_pos = qtd->isoc_split_pos; ++ hc->complete_split = qtd->complete_split; ++ hcd->fops->hub_info(hcd, urb->priv, &hub_addr, &port_addr); ++ hc->hub_addr = (uint8_t) hub_addr; ++ hc->port_addr = (uint8_t) port_addr; ++ } ++ ++ switch (dwc_otg_hcd_get_pipe_type(&urb->pipe_info)) { ++ case UE_CONTROL: ++ hc->ep_type = DWC_OTG_EP_TYPE_CONTROL; ++ switch (qtd->control_phase) { ++ case DWC_OTG_CONTROL_SETUP: ++ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n"); ++ hc->do_ping = 0; ++ hc->ep_is_in = 0; ++ hc->data_pid_start = DWC_OTG_HC_PID_SETUP; ++ if (hcd->core_if->dma_enable) { ++ hc->xfer_buff = (uint8_t *) urb->setup_dma; ++ } else { ++ hc->xfer_buff = (uint8_t *) urb->setup_packet; ++ } ++ hc->xfer_len = 8; ++ ptr = NULL; ++ break; ++ case DWC_OTG_CONTROL_DATA: ++ DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n"); ++ hc->data_pid_start = qtd->data_toggle; ++ break; ++ case DWC_OTG_CONTROL_STATUS: ++ /* ++ * Direction is opposite of data direction or IN if no ++ * data. ++ */ ++ DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n"); ++ if (urb->length == 0) { ++ hc->ep_is_in = 1; ++ } else { ++ hc->ep_is_in = ++ dwc_otg_hcd_is_pipe_out(&urb->pipe_info); ++ } ++ if (hc->ep_is_in) { ++ hc->do_ping = 0; ++ } ++ ++ hc->data_pid_start = DWC_OTG_HC_PID_DATA1; ++ ++ hc->xfer_len = 0; ++ if (hcd->core_if->dma_enable) { ++ hc->xfer_buff = (uint8_t *) hcd->status_buf_dma; ++ } else { ++ hc->xfer_buff = (uint8_t *) hcd->status_buf; ++ } ++ ptr = NULL; ++ break; ++ } ++ break; ++ case UE_BULK: ++ hc->ep_type = DWC_OTG_EP_TYPE_BULK; ++ break; ++ case UE_INTERRUPT: ++ hc->ep_type = DWC_OTG_EP_TYPE_INTR; ++ break; ++ case UE_ISOCHRONOUS: ++ { ++ struct dwc_otg_hcd_iso_packet_desc *frame_desc; ++ ++ hc->ep_type = DWC_OTG_EP_TYPE_ISOC; ++ ++ if (hcd->core_if->dma_desc_enable) ++ break; ++ ++ frame_desc = &urb->iso_descs[qtd->isoc_frame_index]; ++ ++ frame_desc->status = 0; ++ ++ if (hcd->core_if->dma_enable) { ++ hc->xfer_buff = (uint8_t *) urb->dma; ++ } else { ++ hc->xfer_buff = (uint8_t *) urb->buf; ++ } ++ hc->xfer_buff += ++ frame_desc->offset + qtd->isoc_split_offset; ++ hc->xfer_len = ++ frame_desc->length - qtd->isoc_split_offset; ++ ++ /* For non-dword aligned buffers */ ++ if (((unsigned long)hc->xfer_buff & 0x3) ++ && hcd->core_if->dma_enable) { ++ ptr = ++ (uint8_t *) urb->buf + frame_desc->offset + ++ qtd->isoc_split_offset; ++ } else ++ ptr = NULL; ++ ++ if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) { ++ if (hc->xfer_len <= 188) { ++ hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL; ++ } else { ++ hc->xact_pos = ++ DWC_HCSPLIT_XACTPOS_BEGIN; ++ } ++ } ++ } ++ break; ++ } ++ /* non DWORD-aligned buffer case */ ++ if (ptr) { ++ uint32_t buf_size; ++ if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) { ++ buf_size = hcd->core_if->core_params->max_transfer_size; ++ } else { ++ buf_size = 4096; ++ } ++ if (!qh->dw_align_buf) { ++ qh->dw_align_buf = DWC_DMA_ALLOC_ATOMIC(buf_size, ++ &qh->dw_align_buf_dma); ++ if (!qh->dw_align_buf) { ++ DWC_ERROR ++ ("%s: Failed to allocate memory to handle " ++ "non-dword aligned buffer case\n", ++ __func__); ++ return; ++ } ++ } ++ if (!hc->ep_is_in) { ++ dwc_memcpy(qh->dw_align_buf, ptr, hc->xfer_len); ++ } ++ hc->align_buff = qh->dw_align_buf_dma; ++ } else { ++ hc->align_buff = 0; ++ } ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || ++ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ /* ++ * This value may be modified when the transfer is started to ++ * reflect the actual transfer length. ++ */ ++ hc->multi_count = dwc_hb_mult(qh->maxp); ++ } ++ ++ if (hcd->core_if->dma_desc_enable) ++ hc->desc_list_addr = qh->desc_list_dma; ++ ++ dwc_otg_hc_init(hcd->core_if, hc); ++ hc->qh = qh; ++} ++ ++/** ++ * This function selects transactions from the HCD transfer schedule and ++ * assigns them to available host channels. It is called from HCD interrupt ++ * handler functions. ++ * ++ * @param hcd The HCD state structure. ++ * ++ * @return The types of new transactions that were assigned to host channels. ++ */ ++dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t * hcd) ++{ ++ dwc_list_link_t *qh_ptr; ++ dwc_otg_qh_t *qh; ++ int num_channels; ++ dwc_irqflags_t flags; ++ dwc_spinlock_t *channel_lock = DWC_SPINLOCK_ALLOC(); ++ dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE; ++ ++#ifdef DEBUG_SOF ++ DWC_DEBUGPL(DBG_HCD, " Select Transactions\n"); ++#endif ++ ++#ifdef DEBUG_HOST_CHANNELS ++ last_sel_trans_num_per_scheduled = 0; ++ last_sel_trans_num_nonper_scheduled = 0; ++ last_sel_trans_num_avail_hc_at_start = hcd->available_host_channels; ++#endif /* DEBUG_HOST_CHANNELS */ ++ ++ /* Process entries in the periodic ready list. */ ++ qh_ptr = DWC_LIST_FIRST(&hcd->periodic_sched_ready); ++ ++ while (qh_ptr != &hcd->periodic_sched_ready && ++ !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) { ++ if (microframe_schedule) { ++ // Make sure we leave one channel for non periodic transactions. ++ DWC_SPINLOCK_IRQSAVE(channel_lock, &flags); ++ if (hcd->available_host_channels <= 1) { ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++ break; ++ } ++ hcd->available_host_channels--; ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++#ifdef DEBUG_HOST_CHANNELS ++ last_sel_trans_num_per_scheduled++; ++#endif /* DEBUG_HOST_CHANNELS */ ++ } ++ qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry); ++ assign_and_init_hc(hcd, qh); ++ ++ /* ++ * Move the QH from the periodic ready schedule to the ++ * periodic assigned schedule. ++ */ ++ qh_ptr = DWC_LIST_NEXT(qh_ptr); ++ DWC_SPINLOCK_IRQSAVE(channel_lock, &flags); ++ DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned, ++ &qh->qh_list_entry); ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++ ++ ret_val = DWC_OTG_TRANSACTION_PERIODIC; ++ } ++ ++ /* ++ * Process entries in the inactive portion of the non-periodic ++ * schedule. Some free host channels may not be used if they are ++ * reserved for periodic transfers. ++ */ ++ qh_ptr = hcd->non_periodic_sched_inactive.next; ++ num_channels = hcd->core_if->core_params->host_channels; ++ while (qh_ptr != &hcd->non_periodic_sched_inactive && ++ (microframe_schedule || hcd->non_periodic_channels < ++ num_channels - hcd->periodic_channels) && ++ !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) { ++ ++ if (microframe_schedule) { ++ DWC_SPINLOCK_IRQSAVE(channel_lock, &flags); ++ if (hcd->available_host_channels < 1) { ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++ break; ++ } ++ hcd->available_host_channels--; ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++#ifdef DEBUG_HOST_CHANNELS ++ last_sel_trans_num_nonper_scheduled++; ++#endif /* DEBUG_HOST_CHANNELS */ ++ } ++ qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry); ++ ++ assign_and_init_hc(hcd, qh); ++ ++ /* ++ * Move the QH from the non-periodic inactive schedule to the ++ * non-periodic active schedule. ++ */ ++ qh_ptr = DWC_LIST_NEXT(qh_ptr); ++ DWC_SPINLOCK_IRQSAVE(channel_lock, &flags); ++ DWC_LIST_MOVE_HEAD(&hcd->non_periodic_sched_active, ++ &qh->qh_list_entry); ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++ ++ if (ret_val == DWC_OTG_TRANSACTION_NONE) { ++ ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC; ++ } else { ++ ret_val = DWC_OTG_TRANSACTION_ALL; ++ } ++ ++ if (!microframe_schedule) ++ hcd->non_periodic_channels++; ++ } ++ ++#ifdef DEBUG_HOST_CHANNELS ++ last_sel_trans_num_avail_hc_at_end = hcd->available_host_channels; ++#endif /* DEBUG_HOST_CHANNELS */ ++ ++ DWC_SPINLOCK_FREE(channel_lock); ++ return ret_val; ++} ++ ++/** ++ * Attempts to queue a single transaction request for a host channel ++ * associated with either a periodic or non-periodic transfer. This function ++ * assumes that there is space available in the appropriate request queue. For ++ * an OUT transfer or SETUP transaction in Slave mode, it checks whether space ++ * is available in the appropriate Tx FIFO. ++ * ++ * @param hcd The HCD state structure. ++ * @param hc Host channel descriptor associated with either a periodic or ++ * non-periodic transfer. ++ * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx ++ * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic ++ * transfers. ++ * ++ * @return 1 if a request is queued and more requests may be needed to ++ * complete the transfer, 0 if no more requests are required for this ++ * transfer, -1 if there is insufficient space in the Tx FIFO. ++ */ ++static int queue_transaction(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, uint16_t fifo_dwords_avail) ++{ ++ int retval; ++ ++ if (hcd->core_if->dma_enable) { ++ if (hcd->core_if->dma_desc_enable) { ++ if (!hc->xfer_started ++ || (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) { ++ dwc_otg_hcd_start_xfer_ddma(hcd, hc->qh); ++ hc->qh->ping_state = 0; ++ } ++ } else if (!hc->xfer_started) { ++ dwc_otg_hc_start_transfer(hcd->core_if, hc); ++ hc->qh->ping_state = 0; ++ } ++ retval = 0; ++ } else if (hc->halt_pending) { ++ /* Don't queue a request if the channel has been halted. */ ++ retval = 0; ++ } else if (hc->halt_on_queue) { ++ dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status); ++ retval = 0; ++ } else if (hc->do_ping) { ++ if (!hc->xfer_started) { ++ dwc_otg_hc_start_transfer(hcd->core_if, hc); ++ } ++ retval = 0; ++ } else if (!hc->ep_is_in || hc->data_pid_start == DWC_OTG_HC_PID_SETUP) { ++ if ((fifo_dwords_avail * 4) >= hc->max_packet) { ++ if (!hc->xfer_started) { ++ dwc_otg_hc_start_transfer(hcd->core_if, hc); ++ retval = 1; ++ } else { ++ retval = ++ dwc_otg_hc_continue_transfer(hcd->core_if, ++ hc); ++ } ++ } else { ++ retval = -1; ++ } ++ } else { ++ if (!hc->xfer_started) { ++ dwc_otg_hc_start_transfer(hcd->core_if, hc); ++ retval = 1; ++ } else { ++ retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc); ++ } ++ } ++ ++ return retval; ++} ++ ++/** ++ * Processes periodic channels for the next frame and queues transactions for ++ * these channels to the DWC_otg controller. After queueing transactions, the ++ * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions ++ * to queue as Periodic Tx FIFO or request queue space becomes available. ++ * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled. ++ */ ++static void process_periodic_channels(dwc_otg_hcd_t * hcd) ++{ ++ hptxsts_data_t tx_status; ++ dwc_list_link_t *qh_ptr; ++ dwc_otg_qh_t *qh; ++ int status; ++ int no_queue_space = 0; ++ int no_fifo_space = 0; ++ ++ dwc_otg_host_global_regs_t *host_regs; ++ host_regs = hcd->core_if->host_if->host_global_regs; ++ ++ DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n"); ++#ifdef DEBUG ++ tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts); ++ DWC_DEBUGPL(DBG_HCDV, ++ " P Tx Req Queue Space Avail (before queue): %d\n", ++ tx_status.b.ptxqspcavail); ++ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n", ++ tx_status.b.ptxfspcavail); ++#endif ++ ++ qh_ptr = hcd->periodic_sched_assigned.next; ++ while (qh_ptr != &hcd->periodic_sched_assigned) { ++ tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts); ++ if (tx_status.b.ptxqspcavail == 0) { ++ no_queue_space = 1; ++ break; ++ } ++ ++ qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry); ++ ++ /* ++ * Set a flag if we're queuing high-bandwidth in slave mode. ++ * The flag prevents any halts to get into the request queue in ++ * the middle of multiple high-bandwidth packets getting queued. ++ */ ++ if (!hcd->core_if->dma_enable && qh->channel->multi_count > 1) { ++ hcd->core_if->queuing_high_bandwidth = 1; ++ } ++ status = ++ queue_transaction(hcd, qh->channel, ++ tx_status.b.ptxfspcavail); ++ if (status < 0) { ++ no_fifo_space = 1; ++ break; ++ } ++ ++ /* ++ * In Slave mode, stay on the current transfer until there is ++ * nothing more to do or the high-bandwidth request count is ++ * reached. In DMA mode, only need to queue one request. The ++ * controller automatically handles multiple packets for ++ * high-bandwidth transfers. ++ */ ++ if (hcd->core_if->dma_enable || status == 0 || ++ qh->channel->requests == qh->channel->multi_count) { ++ qh_ptr = qh_ptr->next; ++ /* ++ * Move the QH from the periodic assigned schedule to ++ * the periodic queued schedule. ++ */ ++ DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_queued, ++ &qh->qh_list_entry); ++ ++ /* done queuing high bandwidth */ ++ hcd->core_if->queuing_high_bandwidth = 0; ++ } ++ } ++ ++ if (!hcd->core_if->dma_enable) { ++ dwc_otg_core_global_regs_t *global_regs; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ global_regs = hcd->core_if->core_global_regs; ++ intr_mask.b.ptxfempty = 1; ++#ifdef DEBUG ++ tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts); ++ DWC_DEBUGPL(DBG_HCDV, ++ " P Tx Req Queue Space Avail (after queue): %d\n", ++ tx_status.b.ptxqspcavail); ++ DWC_DEBUGPL(DBG_HCDV, ++ " P Tx FIFO Space Avail (after queue): %d\n", ++ tx_status.b.ptxfspcavail); ++#endif ++ if (!DWC_LIST_EMPTY(&hcd->periodic_sched_assigned) || ++ no_queue_space || no_fifo_space) { ++ /* ++ * May need to queue more transactions as the request ++ * queue or Tx FIFO empties. Enable the periodic Tx ++ * FIFO empty interrupt. (Always use the half-empty ++ * level to ensure that new requests are loaded as ++ * soon as possible.) ++ */ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, 0, ++ intr_mask.d32); ++ } else { ++ /* ++ * Disable the Tx FIFO empty interrupt since there are ++ * no more transactions that need to be queued right ++ * now. This function is called from interrupt ++ * handlers to queue more transactions as transfer ++ * states change. ++ */ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, ++ 0); ++ } ++ } ++} ++ ++/** ++ * Processes active non-periodic channels and queues transactions for these ++ * channels to the DWC_otg controller. After queueing transactions, the NP Tx ++ * FIFO Empty interrupt is enabled if there are more transactions to queue as ++ * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx ++ * FIFO Empty interrupt is disabled. ++ */ ++static void process_non_periodic_channels(dwc_otg_hcd_t * hcd) ++{ ++ gnptxsts_data_t tx_status; ++ dwc_list_link_t *orig_qh_ptr; ++ dwc_otg_qh_t *qh; ++ int status; ++ int no_queue_space = 0; ++ int no_fifo_space = 0; ++ int more_to_do = 0; ++ ++ dwc_otg_core_global_regs_t *global_regs = ++ hcd->core_if->core_global_regs; ++ ++ DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n"); ++#ifdef DEBUG ++ tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts); ++ DWC_DEBUGPL(DBG_HCDV, ++ " NP Tx Req Queue Space Avail (before queue): %d\n", ++ tx_status.b.nptxqspcavail); ++ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n", ++ tx_status.b.nptxfspcavail); ++#endif ++ /* ++ * Keep track of the starting point. Skip over the start-of-list ++ * entry. ++ */ ++ if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) { ++ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next; ++ } ++ orig_qh_ptr = hcd->non_periodic_qh_ptr; ++ ++ /* ++ * Process once through the active list or until no more space is ++ * available in the request queue or the Tx FIFO. ++ */ ++ do { ++ tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts); ++ if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) { ++ no_queue_space = 1; ++ break; ++ } ++ ++ qh = DWC_LIST_ENTRY(hcd->non_periodic_qh_ptr, dwc_otg_qh_t, ++ qh_list_entry); ++ status = ++ queue_transaction(hcd, qh->channel, ++ tx_status.b.nptxfspcavail); ++ ++ if (status > 0) { ++ more_to_do = 1; ++ } else if (status < 0) { ++ no_fifo_space = 1; ++ break; ++ } ++ ++ /* Advance to next QH, skipping start-of-list entry. */ ++ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next; ++ if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) { ++ hcd->non_periodic_qh_ptr = ++ hcd->non_periodic_qh_ptr->next; ++ } ++ ++ } while (hcd->non_periodic_qh_ptr != orig_qh_ptr); ++ ++ if (!hcd->core_if->dma_enable) { ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ intr_mask.b.nptxfempty = 1; ++ ++#ifdef DEBUG ++ tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts); ++ DWC_DEBUGPL(DBG_HCDV, ++ " NP Tx Req Queue Space Avail (after queue): %d\n", ++ tx_status.b.nptxqspcavail); ++ DWC_DEBUGPL(DBG_HCDV, ++ " NP Tx FIFO Space Avail (after queue): %d\n", ++ tx_status.b.nptxfspcavail); ++#endif ++ if (more_to_do || no_queue_space || no_fifo_space) { ++ /* ++ * May need to queue more transactions as the request ++ * queue or Tx FIFO empties. Enable the non-periodic ++ * Tx FIFO empty interrupt. (Always use the half-empty ++ * level to ensure that new requests are loaded as ++ * soon as possible.) ++ */ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, 0, ++ intr_mask.d32); ++ } else { ++ /* ++ * Disable the Tx FIFO empty interrupt since there are ++ * no more transactions that need to be queued right ++ * now. This function is called from interrupt ++ * handlers to queue more transactions as transfer ++ * states change. ++ */ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, ++ 0); ++ } ++ } ++} ++ ++/** ++ * This function processes the currently active host channels and queues ++ * transactions for these channels to the DWC_otg controller. It is called ++ * from HCD interrupt handler functions. ++ * ++ * @param hcd The HCD state structure. ++ * @param tr_type The type(s) of transactions to queue (non-periodic, ++ * periodic, or both). ++ */ ++void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t * hcd, ++ dwc_otg_transaction_type_e tr_type) ++{ ++#ifdef DEBUG_SOF ++ DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n"); ++#endif ++ /* Process host channels associated with periodic transfers. */ ++ if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC || ++ tr_type == DWC_OTG_TRANSACTION_ALL) && ++ !DWC_LIST_EMPTY(&hcd->periodic_sched_assigned)) { ++ ++ process_periodic_channels(hcd); ++ } ++ ++ /* Process host channels associated with non-periodic transfers. */ ++ if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC || ++ tr_type == DWC_OTG_TRANSACTION_ALL) { ++ if (!DWC_LIST_EMPTY(&hcd->non_periodic_sched_active)) { ++ process_non_periodic_channels(hcd); ++ } else { ++ /* ++ * Ensure NP Tx FIFO empty interrupt is disabled when ++ * there are no non-periodic transfers to process. ++ */ ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ gintmsk.b.nptxfempty = 1; ++ DWC_MODIFY_REG32(&hcd->core_if-> ++ core_global_regs->gintmsk, gintmsk.d32, ++ 0); ++ } ++ } ++} ++ ++#ifdef DWC_HS_ELECT_TST ++/* ++ * Quick and dirty hack to implement the HS Electrical Test ++ * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature. ++ * ++ * This code was copied from our userspace app "hset". It sends a ++ * Get Device Descriptor control sequence in two parts, first the ++ * Setup packet by itself, followed some time later by the In and ++ * Ack packets. Rather than trying to figure out how to add this ++ * functionality to the normal driver code, we just hijack the ++ * hardware, using these two function to drive the hardware ++ * directly. ++ */ ++ ++static dwc_otg_core_global_regs_t *global_regs; ++static dwc_otg_host_global_regs_t *hc_global_regs; ++static dwc_otg_hc_regs_t *hc_regs; ++static uint32_t *data_fifo; ++ ++static void do_setup(void) ++{ ++ gintsts_data_t gintsts; ++ hctsiz_data_t hctsiz; ++ hcchar_data_t hcchar; ++ haint_data_t haint; ++ hcint_data_t hcint; ++ ++ /* Enable HAINTs */ ++ DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001); ++ ++ /* Enable HCINTs */ ++ DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* ++ * Send Setup packet (Get Device Descriptor) ++ */ ++ ++ /* Make sure channel is disabled */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ if (hcchar.b.chen) { ++ hcchar.b.chdis = 1; ++// hcchar.b.chen = 1; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ //sleep(1); ++ dwc_mdelay(1000); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ } ++ ++ /* Set HCTSIZ */ ++ hctsiz.d32 = 0; ++ hctsiz.b.xfersize = 8; ++ hctsiz.b.pktcnt = 1; ++ hctsiz.b.pid = DWC_OTG_HC_PID_SETUP; ++ DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32); ++ ++ /* Set HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; ++ hcchar.b.epdir = 0; ++ hcchar.b.epnum = 0; ++ hcchar.b.mps = 8; ++ hcchar.b.chen = 1; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ ++ /* Fill FIFO with Setup data for Get Device Descriptor */ ++ data_fifo = (uint32_t *) ((char *)global_regs + 0x1000); ++ DWC_WRITE_REG32(data_fifo++, 0x01000680); ++ DWC_WRITE_REG32(data_fifo++, 0x00080000); ++ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Wait for host channel interrupt */ ++ do { ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ } while (gintsts.b.hcintr == 0); ++ ++ /* Disable HCINTs */ ++ DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000); ++ ++ /* Disable HAINTs */ ++ DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++} ++ ++static void do_in_ack(void) ++{ ++ gintsts_data_t gintsts; ++ hctsiz_data_t hctsiz; ++ hcchar_data_t hcchar; ++ haint_data_t haint; ++ hcint_data_t hcint; ++ host_grxsts_data_t grxsts; ++ ++ /* Enable HAINTs */ ++ DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001); ++ ++ /* Enable HCINTs */ ++ DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* ++ * Receive Control In packet ++ */ ++ ++ /* Make sure channel is disabled */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ if (hcchar.b.chen) { ++ hcchar.b.chdis = 1; ++ hcchar.b.chen = 1; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ //sleep(1); ++ dwc_mdelay(1000); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ } ++ ++ /* Set HCTSIZ */ ++ hctsiz.d32 = 0; ++ hctsiz.b.xfersize = 8; ++ hctsiz.b.pktcnt = 1; ++ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1; ++ DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32); ++ ++ /* Set HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; ++ hcchar.b.epdir = 1; ++ hcchar.b.epnum = 0; ++ hcchar.b.mps = 8; ++ hcchar.b.chen = 1; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Wait for receive status queue interrupt */ ++ do { ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ } while (gintsts.b.rxstsqlvl == 0); ++ ++ /* Read RXSTS */ ++ grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp); ++ ++ /* Clear RXSTSQLVL in GINTSTS */ ++ gintsts.d32 = 0; ++ gintsts.b.rxstsqlvl = 1; ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ switch (grxsts.b.pktsts) { ++ case DWC_GRXSTS_PKTSTS_IN: ++ /* Read the data into the host buffer */ ++ if (grxsts.b.bcnt > 0) { ++ int i; ++ int word_count = (grxsts.b.bcnt + 3) / 4; ++ ++ data_fifo = (uint32_t *) ((char *)global_regs + 0x1000); ++ ++ for (i = 0; i < word_count; i++) { ++ (void)DWC_READ_REG32(data_fifo++); ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Wait for receive status queue interrupt */ ++ do { ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ } while (gintsts.b.rxstsqlvl == 0); ++ ++ /* Read RXSTS */ ++ grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp); ++ ++ /* Clear RXSTSQLVL in GINTSTS */ ++ gintsts.d32 = 0; ++ gintsts.b.rxstsqlvl = 1; ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ switch (grxsts.b.pktsts) { ++ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP: ++ break; ++ ++ default: ++ break; ++ } ++ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Wait for host channel interrupt */ ++ do { ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ } while (gintsts.b.hcintr == 0); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++// usleep(100000); ++// mdelay(100); ++ dwc_mdelay(1); ++ ++ /* ++ * Send handshake packet ++ */ ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Make sure channel is disabled */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ if (hcchar.b.chen) { ++ hcchar.b.chdis = 1; ++ hcchar.b.chen = 1; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ //sleep(1); ++ dwc_mdelay(1000); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ } ++ ++ /* Set HCTSIZ */ ++ hctsiz.d32 = 0; ++ hctsiz.b.xfersize = 0; ++ hctsiz.b.pktcnt = 1; ++ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1; ++ DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32); ++ ++ /* Set HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; ++ hcchar.b.epdir = 0; ++ hcchar.b.epnum = 0; ++ hcchar.b.mps = 8; ++ hcchar.b.chen = 1; ++ DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32); ++ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ ++ /* Wait for host channel interrupt */ ++ do { ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++ } while (gintsts.b.hcintr == 0); ++ ++ /* Disable HCINTs */ ++ DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000); ++ ++ /* Disable HAINTs */ ++ DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000); ++ ++ /* Read HAINT */ ++ haint.d32 = DWC_READ_REG32(&hc_global_regs->haint); ++ ++ /* Read HCINT */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ ++ /* Read HCCHAR */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ ++ /* Clear HCINT */ ++ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32); ++ ++ /* Clear HAINT */ ++ DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32); ++ ++ /* Clear GINTSTS */ ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ /* Read GINTSTS */ ++ gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts); ++} ++#endif ++ ++/** Handles hub class-specific requests. */ ++int dwc_otg_hcd_hub_control(dwc_otg_hcd_t * dwc_otg_hcd, ++ uint16_t typeReq, ++ uint16_t wValue, ++ uint16_t wIndex, uint8_t * buf, uint16_t wLength) ++{ ++ int retval = 0; ++ ++ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; ++ usb_hub_descriptor_t *hub_desc; ++ hprt0_data_t hprt0 = {.d32 = 0 }; ++ ++ uint32_t port_status; ++ ++ switch (typeReq) { ++ case UCR_CLEAR_HUB_FEATURE: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearHubFeature 0x%x\n", wValue); ++ switch (wValue) { ++ case UHF_C_HUB_LOCAL_POWER: ++ case UHF_C_HUB_OVER_CURRENT: ++ /* Nothing required here */ ++ break; ++ default: ++ retval = -DWC_E_INVALID; ++ DWC_ERROR("DWC OTG HCD - " ++ "ClearHubFeature request %xh unknown\n", ++ wValue); ++ } ++ break; ++ case UCR_CLEAR_PORT_FEATURE: ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ if (wValue != UHF_PORT_L1) ++#endif ++ if (!wIndex || wIndex > 1) ++ goto error; ++ ++ switch (wValue) { ++ case UHF_PORT_ENABLE: ++ DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_ENABLE\n"); ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtena = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ break; ++ case UHF_PORT_SUSPEND: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); ++ ++ if (core_if->power_down == 2) { ++ dwc_otg_host_hibernation_restore(core_if, 0, 0); ++ } else { ++ DWC_WRITE_REG32(core_if->pcgcctl, 0); ++ dwc_mdelay(5); ++ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtres = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ hprt0.b.prtsusp = 0; ++ /* Clear Resume bit */ ++ dwc_mdelay(100); ++ hprt0.b.prtres = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ } ++ break; ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ case UHF_PORT_L1: ++ { ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ glpmcfg_data_t lpmcfg = {.d32 = 0 }; ++ ++ lpmcfg.d32 = ++ DWC_READ_REG32(&core_if-> ++ core_global_regs->glpmcfg); ++ lpmcfg.b.en_utmi_sleep = 0; ++ lpmcfg.b.hird_thres &= (~(1 << 4)); ++ lpmcfg.b.prt_sleep_sts = 1; ++ DWC_WRITE_REG32(&core_if-> ++ core_global_regs->glpmcfg, ++ lpmcfg.d32); ++ ++ /* Clear Enbl_L1Gating bit. */ ++ pcgcctl.b.enbl_sleep_gating = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, ++ 0); ++ ++ dwc_mdelay(5); ++ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtres = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, ++ hprt0.d32); ++ /* This bit will be cleared in wakeup interrupt handle */ ++ break; ++ } ++#endif ++ case UHF_PORT_POWER: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_POWER\n"); ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtpwr = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ break; ++ case UHF_PORT_INDICATOR: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_INDICATOR\n"); ++ /* Port inidicator not supported */ ++ break; ++ case UHF_C_PORT_CONNECTION: ++ /* Clears drivers internal connect status change ++ * flag */ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n"); ++ dwc_otg_hcd->flags.b.port_connect_status_change = 0; ++ break; ++ case UHF_C_PORT_RESET: ++ /* Clears the driver's internal Port Reset Change ++ * flag */ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_C_RESET\n"); ++ dwc_otg_hcd->flags.b.port_reset_change = 0; ++ break; ++ case UHF_C_PORT_ENABLE: ++ /* Clears the driver's internal Port ++ * Enable/Disable Change flag */ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n"); ++ dwc_otg_hcd->flags.b.port_enable_change = 0; ++ break; ++ case UHF_C_PORT_SUSPEND: ++ /* Clears the driver's internal Port Suspend ++ * Change flag, which is set when resume signaling on ++ * the host port is complete */ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n"); ++ dwc_otg_hcd->flags.b.port_suspend_change = 0; ++ break; ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ case UHF_C_PORT_L1: ++ dwc_otg_hcd->flags.b.port_l1_change = 0; ++ break; ++#endif ++ case UHF_C_PORT_OVER_CURRENT: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n"); ++ dwc_otg_hcd->flags.b.port_over_current_change = 0; ++ break; ++ default: ++ retval = -DWC_E_INVALID; ++ DWC_ERROR("DWC OTG HCD - " ++ "ClearPortFeature request %xh " ++ "unknown or unsupported\n", wValue); ++ } ++ break; ++ case UCR_GET_HUB_DESCRIPTOR: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "GetHubDescriptor\n"); ++ hub_desc = (usb_hub_descriptor_t *) buf; ++ hub_desc->bDescLength = 9; ++ hub_desc->bDescriptorType = 0x29; ++ hub_desc->bNbrPorts = 1; ++ USETW(hub_desc->wHubCharacteristics, 0x08); ++ hub_desc->bPwrOn2PwrGood = 1; ++ hub_desc->bHubContrCurrent = 0; ++ hub_desc->DeviceRemovable[0] = 0; ++ hub_desc->DeviceRemovable[1] = 0xff; ++ break; ++ case UCR_GET_HUB_STATUS: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "GetHubStatus\n"); ++ DWC_MEMSET(buf, 0, 4); ++ break; ++ case UCR_GET_PORT_STATUS: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "GetPortStatus wIndex = 0x%04x FLAGS=0x%08x\n", ++ wIndex, dwc_otg_hcd->flags.d32); ++ if (!wIndex || wIndex > 1) ++ goto error; ++ ++ port_status = 0; ++ ++ if (dwc_otg_hcd->flags.b.port_connect_status_change) ++ port_status |= (1 << UHF_C_PORT_CONNECTION); ++ ++ if (dwc_otg_hcd->flags.b.port_enable_change) ++ port_status |= (1 << UHF_C_PORT_ENABLE); ++ ++ if (dwc_otg_hcd->flags.b.port_suspend_change) ++ port_status |= (1 << UHF_C_PORT_SUSPEND); ++ ++ if (dwc_otg_hcd->flags.b.port_l1_change) ++ port_status |= (1 << UHF_C_PORT_L1); ++ ++ if (dwc_otg_hcd->flags.b.port_reset_change) { ++ port_status |= (1 << UHF_C_PORT_RESET); ++ } ++ ++ if (dwc_otg_hcd->flags.b.port_over_current_change) { ++ DWC_WARN("Overcurrent change detected\n"); ++ port_status |= (1 << UHF_C_PORT_OVER_CURRENT); ++ } ++ ++ if (!dwc_otg_hcd->flags.b.port_connect_status) { ++ /* ++ * The port is disconnected, which means the core is ++ * either in device mode or it soon will be. Just ++ * return 0's for the remainder of the port status ++ * since the port register can't be read if the core ++ * is in device mode. ++ */ ++ *((__le32 *) buf) = dwc_cpu_to_le32(&port_status); ++ break; ++ } ++ ++ hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0); ++ DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32); ++ ++ if (hprt0.b.prtconnsts) ++ port_status |= (1 << UHF_PORT_CONNECTION); ++ ++ if (hprt0.b.prtena) ++ port_status |= (1 << UHF_PORT_ENABLE); ++ ++ if (hprt0.b.prtsusp) ++ port_status |= (1 << UHF_PORT_SUSPEND); ++ ++ if (hprt0.b.prtovrcurract) ++ port_status |= (1 << UHF_PORT_OVER_CURRENT); ++ ++ if (hprt0.b.prtrst) ++ port_status |= (1 << UHF_PORT_RESET); ++ ++ if (hprt0.b.prtpwr) ++ port_status |= (1 << UHF_PORT_POWER); ++ ++ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) ++ port_status |= (1 << UHF_PORT_HIGH_SPEED); ++ else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED) ++ port_status |= (1 << UHF_PORT_LOW_SPEED); ++ ++ if (hprt0.b.prttstctl) ++ port_status |= (1 << UHF_PORT_TEST); ++ if (dwc_otg_get_lpm_portsleepstatus(dwc_otg_hcd->core_if)) { ++ port_status |= (1 << UHF_PORT_L1); ++ } ++ /* ++ For Synopsys HW emulation of Power down wkup_control asserts the ++ hreset_n and prst_n on suspned. This causes the HPRT0 to be zero. ++ We intentionally tell the software that port is in L2Suspend state. ++ Only for STE. ++ */ ++ if ((core_if->power_down == 2) ++ && (core_if->hibernation_suspend == 1)) { ++ port_status |= (1 << UHF_PORT_SUSPEND); ++ } ++ /* USB_PORT_FEAT_INDICATOR unsupported always 0 */ ++ ++ *((__le32 *) buf) = dwc_cpu_to_le32(&port_status); ++ ++ break; ++ case UCR_SET_HUB_FEATURE: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "SetHubFeature\n"); ++ /* No HUB features supported */ ++ break; ++ case UCR_SET_PORT_FEATURE: ++ if (wValue != UHF_PORT_TEST && (!wIndex || wIndex > 1)) ++ goto error; ++ ++ if (!dwc_otg_hcd->flags.b.port_connect_status) { ++ /* ++ * The port is disconnected, which means the core is ++ * either in device mode or it soon will be. Just ++ * return without doing anything since the port ++ * register can't be written if the core is in device ++ * mode. ++ */ ++ break; ++ } ++ ++ switch (wValue) { ++ case UHF_PORT_SUSPEND: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "SetPortFeature - USB_PORT_FEAT_SUSPEND\n"); ++ if (dwc_otg_hcd_otg_port(dwc_otg_hcd) != wIndex) { ++ goto error; ++ } ++ if (core_if->power_down == 2) { ++ int timeout = 300; ++ dwc_irqflags_t flags; ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ gusbcfg_data_t gusbcfg = {.d32 = 0 }; ++#ifdef DWC_DEV_SRPCAP ++ int32_t otg_cap_param = core_if->core_params->otg_cap; ++#endif ++ DWC_PRINTF("Preparing for complete power-off\n"); ++ ++ /* Save registers before hibernation */ ++ dwc_otg_save_global_regs(core_if); ++ dwc_otg_save_host_regs(core_if); ++ ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtsusp = 1; ++ hprt0.b.prtena = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ /* Spin hprt0.b.prtsusp to became 1 */ ++ do { ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ if (hprt0.b.prtsusp) { ++ break; ++ } ++ dwc_mdelay(1); ++ } while (--timeout); ++ if (!timeout) { ++ DWC_WARN("Suspend wasn't genereted\n"); ++ } ++ dwc_udelay(10); ++ ++ /* ++ * We need to disable interrupts to prevent servicing of any IRQ ++ * during going to hibernation ++ */ ++ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags); ++ core_if->lx_state = DWC_OTG_L2; ++#ifdef DWC_DEV_SRPCAP ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtpwr = 0; ++ hprt0.b.prtena = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, ++ hprt0.d32); ++#endif ++ gusbcfg.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs-> ++ gusbcfg); ++ if (gusbcfg.b.ulpi_utmi_sel == 1) { ++ /* ULPI interface */ ++ /* Suspend the Phy Clock */ ++ pcgcctl.d32 = 0; ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, ++ pcgcctl.d32); ++ dwc_udelay(10); ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ } else { ++ /* UTMI+ Interface */ ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32); ++ dwc_udelay(10); ++ } ++#ifdef DWC_DEV_SRPCAP ++ gpwrdn.d32 = 0; ++ gpwrdn.b.dis_vbus = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++#endif ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ gpwrdn.d32 = 0; ++#ifdef DWC_DEV_SRPCAP ++ gpwrdn.b.srp_det_msk = 1; ++#endif ++ gpwrdn.b.disconn_det_msk = 1; ++ gpwrdn.b.lnstchng_msk = 1; ++ gpwrdn.b.sts_chngint_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Enable Power Down Clamp and all interrupts in GPWRDN */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnclmp = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ dwc_udelay(10); ++ ++ /* Switch off VDD */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ ++#ifdef DWC_DEV_SRPCAP ++ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) ++ { ++ core_if->pwron_timer_started = 1; ++ DWC_TIMER_SCHEDULE(core_if->pwron_timer, 6000 /* 6 secs */ ); ++ } ++#endif ++ /* Save gpwrdn register for further usage if stschng interrupt */ ++ core_if->gr_backup->gpwrdn_local = ++ DWC_READ_REG32(&core_if->core_global_regs->gpwrdn); ++ ++ /* Set flag to indicate that we are in hibernation */ ++ core_if->hibernation_suspend = 1; ++ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock,flags); ++ ++ DWC_PRINTF("Host hibernation completed\n"); ++ // Exit from case statement ++ break; ++ ++ } ++ if (dwc_otg_hcd_otg_port(dwc_otg_hcd) == wIndex && ++ dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) { ++ gotgctl_data_t gotgctl = {.d32 = 0 }; ++ gotgctl.b.hstsethnpen = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gotgctl, 0, gotgctl.d32); ++ core_if->op_state = A_SUSPEND; ++ } ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtsusp = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ { ++ dwc_irqflags_t flags; ++ /* Update lx_state */ ++ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags); ++ core_if->lx_state = DWC_OTG_L2; ++ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags); ++ } ++ /* Suspend the Phy Clock */ ++ { ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, 0, ++ pcgcctl.d32); ++ dwc_udelay(10); ++ } ++ ++ /* For HNP the bus must be suspended for at least 200ms. */ ++ if (dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) { ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0); ++ dwc_mdelay(200); ++ } ++ ++ /** @todo - check how sw can wait for 1 sec to check asesvld??? */ ++#if 0 //vahrama !!!!!!!!!!!!!!!!!! ++ if (core_if->adp_enable) { ++ gotgctl_data_t gotgctl = {.d32 = 0 }; ++ gpwrdn_data_t gpwrdn; ++ ++ while (gotgctl.b.asesvld == 1) { ++ gotgctl.d32 = ++ DWC_READ_REG32(&core_if-> ++ core_global_regs-> ++ gotgctl); ++ dwc_mdelay(100); ++ } ++ ++ /* Enable Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ ++ /* Unmask SRP detected interrupt from Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.srp_det_msk = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs-> ++ gpwrdn, 0, gpwrdn.d32); ++ ++ dwc_otg_adp_probe_start(core_if); ++ } ++#endif ++ break; ++ case UHF_PORT_POWER: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "SetPortFeature - USB_PORT_FEAT_POWER\n"); ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtpwr = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ break; ++ case UHF_PORT_RESET: ++ if ((core_if->power_down == 2) ++ && (core_if->hibernation_suspend == 1)) { ++ /* If we are going to exit from Hibernated ++ * state via USB RESET. ++ */ ++ dwc_otg_host_hibernation_restore(core_if, 0, 1); ++ } else { ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ ++ DWC_DEBUGPL(DBG_HCD, ++ "DWC OTG HCD HUB CONTROL - " ++ "SetPortFeature - USB_PORT_FEAT_RESET\n"); ++ { ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ pcgcctl.b.enbl_sleep_gating = 1; ++ pcgcctl.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0); ++ DWC_WRITE_REG32(core_if->pcgcctl, 0); ++ } ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ { ++ glpmcfg_data_t lpmcfg; ++ lpmcfg.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ if (lpmcfg.b.prt_sleep_sts) { ++ lpmcfg.b.en_utmi_sleep = 0; ++ lpmcfg.b.hird_thres &= (~(1 << 4)); ++ DWC_WRITE_REG32 ++ (&core_if->core_global_regs->glpmcfg, ++ lpmcfg.d32); ++ dwc_mdelay(1); ++ } ++ } ++#endif ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ /* Clear suspend bit if resetting from suspended state. */ ++ hprt0.b.prtsusp = 0; ++ /* When B-Host the Port reset bit is set in ++ * the Start HCD Callback function, so that ++ * the reset is started within 1ms of the HNP ++ * success interrupt. */ ++ if (!dwc_otg_hcd_is_b_host(dwc_otg_hcd)) { ++ hprt0.b.prtpwr = 1; ++ hprt0.b.prtrst = 1; ++ DWC_PRINTF("Indeed it is in host mode hprt0 = %08x\n",hprt0.d32); ++ DWC_WRITE_REG32(core_if->host_if->hprt0, ++ hprt0.d32); ++ } ++ /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */ ++ dwc_mdelay(60); ++ hprt0.b.prtrst = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ core_if->lx_state = DWC_OTG_L0; /* Now back to the on state */ ++ } ++ break; ++#ifdef DWC_HS_ELECT_TST ++ case UHF_PORT_TEST: ++ { ++ uint32_t t; ++ gintmsk_data_t gintmsk; ++ ++ t = (wIndex >> 8); /* MSB wIndex USB */ ++ DWC_DEBUGPL(DBG_HCD, ++ "DWC OTG HCD HUB CONTROL - " ++ "SetPortFeature - USB_PORT_FEAT_TEST %d\n", ++ t); ++ DWC_WARN("USB_PORT_FEAT_TEST %d\n", t); ++ if (t < 6) { ++ hprt0.d32 = dwc_otg_read_hprt0(core_if); ++ hprt0.b.prttstctl = t; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, ++ hprt0.d32); ++ } else { ++ /* Setup global vars with reg addresses (quick and ++ * dirty hack, should be cleaned up) ++ */ ++ global_regs = core_if->core_global_regs; ++ hc_global_regs = ++ core_if->host_if->host_global_regs; ++ hc_regs = ++ (dwc_otg_hc_regs_t *) ((char *) ++ global_regs + ++ 0x500); ++ data_fifo = ++ (uint32_t *) ((char *)global_regs + ++ 0x1000); ++ ++ if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */ ++ /* Save current interrupt mask */ ++ gintmsk.d32 = ++ DWC_READ_REG32 ++ (&global_regs->gintmsk); ++ ++ /* Disable all interrupts while we muck with ++ * the hardware directly ++ */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, 0); ++ ++ /* 15 second delay per the test spec */ ++ dwc_mdelay(15000); ++ ++ /* Drive suspend on the root port */ ++ hprt0.d32 = ++ dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtsusp = 1; ++ hprt0.b.prtres = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ /* 15 second delay per the test spec */ ++ dwc_mdelay(15000); ++ ++ /* Drive resume on the root port */ ++ hprt0.d32 = ++ dwc_otg_read_hprt0(core_if); ++ hprt0.b.prtsusp = 0; ++ hprt0.b.prtres = 1; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ dwc_mdelay(100); ++ ++ /* Clear the resume bit */ ++ hprt0.b.prtres = 0; ++ DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32); ++ ++ /* Restore interrupts */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32); ++ } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */ ++ /* Save current interrupt mask */ ++ gintmsk.d32 = ++ DWC_READ_REG32 ++ (&global_regs->gintmsk); ++ ++ /* Disable all interrupts while we muck with ++ * the hardware directly ++ */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, 0); ++ ++ /* 15 second delay per the test spec */ ++ dwc_mdelay(15000); ++ ++ /* Send the Setup packet */ ++ do_setup(); ++ ++ /* 15 second delay so nothing else happens for awhile */ ++ dwc_mdelay(15000); ++ ++ /* Restore interrupts */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32); ++ } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */ ++ /* Save current interrupt mask */ ++ gintmsk.d32 = ++ DWC_READ_REG32 ++ (&global_regs->gintmsk); ++ ++ /* Disable all interrupts while we muck with ++ * the hardware directly ++ */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, 0); ++ ++ /* Send the Setup packet */ ++ do_setup(); ++ ++ /* 15 second delay so nothing else happens for awhile */ ++ dwc_mdelay(15000); ++ ++ /* Send the In and Ack packets */ ++ do_in_ack(); ++ ++ /* 15 second delay so nothing else happens for awhile */ ++ dwc_mdelay(15000); ++ ++ /* Restore interrupts */ ++ DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32); ++ } ++ } ++ break; ++ } ++#endif /* DWC_HS_ELECT_TST */ ++ ++ case UHF_PORT_INDICATOR: ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " ++ "SetPortFeature - USB_PORT_FEAT_INDICATOR\n"); ++ /* Not supported */ ++ break; ++ default: ++ retval = -DWC_E_INVALID; ++ DWC_ERROR("DWC OTG HCD - " ++ "SetPortFeature request %xh " ++ "unknown or unsupported\n", wValue); ++ break; ++ } ++ break; ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ case UCR_SET_AND_TEST_PORT_FEATURE: ++ if (wValue != UHF_PORT_L1) { ++ goto error; ++ } ++ { ++ int portnum, hird, devaddr, remwake; ++ glpmcfg_data_t lpmcfg; ++ uint32_t time_usecs; ++ gintsts_data_t gintsts; ++ gintmsk_data_t gintmsk; ++ ++ if (!dwc_otg_get_param_lpm_enable(core_if)) { ++ goto error; ++ } ++ if (wValue != UHF_PORT_L1 || wLength != 1) { ++ goto error; ++ } ++ /* Check if the port currently is in SLEEP state */ ++ lpmcfg.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ if (lpmcfg.b.prt_sleep_sts) { ++ DWC_INFO("Port is already in sleep mode\n"); ++ buf[0] = 0; /* Return success */ ++ break; ++ } ++ ++ portnum = wIndex & 0xf; ++ hird = (wIndex >> 4) & 0xf; ++ devaddr = (wIndex >> 8) & 0x7f; ++ remwake = (wIndex >> 15); ++ ++ if (portnum != 1) { ++ retval = -DWC_E_INVALID; ++ DWC_WARN ++ ("Wrong port number(%d) in SetandTestPortFeature request\n", ++ portnum); ++ break; ++ } ++ ++ DWC_PRINTF ++ ("SetandTestPortFeature request: portnum = %d, hird = %d, devaddr = %d, rewake = %d\n", ++ portnum, hird, devaddr, remwake); ++ /* Disable LPM interrupt */ ++ gintmsk.d32 = 0; ++ gintmsk.b.lpmtranrcvd = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, ++ gintmsk.d32, 0); ++ ++ if (dwc_otg_hcd_send_lpm ++ (dwc_otg_hcd, devaddr, hird, remwake)) { ++ retval = -DWC_E_INVALID; ++ break; ++ } ++ ++ time_usecs = 10 * (lpmcfg.b.retry_count + 1); ++ /* We will consider timeout if time_usecs microseconds pass, ++ * and we don't receive LPM transaction status. ++ * After receiving non-error responce(ACK/NYET/STALL) from device, ++ * core will set lpmtranrcvd bit. ++ */ ++ do { ++ gintsts.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ if (gintsts.b.lpmtranrcvd) { ++ break; ++ } ++ dwc_udelay(1); ++ } while (--time_usecs); ++ /* lpm_int bit will be cleared in LPM interrupt handler */ ++ ++ /* Now fill status ++ * 0x00 - Success ++ * 0x10 - NYET ++ * 0x11 - Timeout ++ */ ++ if (!gintsts.b.lpmtranrcvd) { ++ buf[0] = 0x3; /* Completion code is Timeout */ ++ dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd); ++ } else { ++ lpmcfg.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ if (lpmcfg.b.lpm_resp == 0x3) { ++ /* ACK responce from the device */ ++ buf[0] = 0x00; /* Success */ ++ } else if (lpmcfg.b.lpm_resp == 0x2) { ++ /* NYET responce from the device */ ++ buf[0] = 0x2; ++ } else { ++ /* Otherwise responce with Timeout */ ++ buf[0] = 0x3; ++ } ++ } ++ DWC_PRINTF("Device responce to LPM trans is %x\n", ++ lpmcfg.b.lpm_resp); ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, ++ gintmsk.d32); ++ ++ break; ++ } ++#endif /* CONFIG_USB_DWC_OTG_LPM */ ++ default: ++error: ++ retval = -DWC_E_INVALID; ++ DWC_WARN("DWC OTG HCD - " ++ "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n", ++ typeReq, wIndex, wValue); ++ break; ++ } ++ ++ return retval; ++} ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++/** Returns index of host channel to perform LPM transaction. */ ++int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t * hcd, uint8_t devaddr) ++{ ++ dwc_otg_core_if_t *core_if = hcd->core_if; ++ dwc_hc_t *hc; ++ hcchar_data_t hcchar; ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ ++ if (DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) { ++ DWC_PRINTF("No free channel to select for LPM transaction\n"); ++ return -1; ++ } ++ ++ hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list); ++ ++ /* Mask host channel interrupts. */ ++ gintmsk.b.hcintr = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0); ++ ++ /* Fill fields that core needs for LPM transaction */ ++ hcchar.b.devaddr = devaddr; ++ hcchar.b.epnum = 0; ++ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; ++ hcchar.b.mps = 64; ++ hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW); ++ hcchar.b.epdir = 0; /* OUT */ ++ DWC_WRITE_REG32(&core_if->host_if->hc_regs[hc->hc_num]->hcchar, ++ hcchar.d32); ++ ++ /* Remove the host channel from the free list. */ ++ DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry); ++ ++ DWC_PRINTF("hcnum = %d devaddr = %d\n", hc->hc_num, devaddr); ++ ++ return hc->hc_num; ++} ++ ++/** Release hc after performing LPM transaction */ ++void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t * hcd) ++{ ++ dwc_hc_t *hc; ++ glpmcfg_data_t lpmcfg; ++ uint8_t hc_num; ++ ++ lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg); ++ hc_num = lpmcfg.b.lpm_chan_index; ++ ++ hc = hcd->hc_ptr_array[hc_num]; ++ ++ DWC_PRINTF("Freeing channel %d after LPM\n", hc_num); ++ /* Return host channel to free list */ ++ DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry); ++} ++ ++int dwc_otg_hcd_send_lpm(dwc_otg_hcd_t * hcd, uint8_t devaddr, uint8_t hird, ++ uint8_t bRemoteWake) ++{ ++ glpmcfg_data_t lpmcfg; ++ pcgcctl_data_t pcgcctl = {.d32 = 0 }; ++ int channel; ++ ++ channel = dwc_otg_hcd_get_hc_for_lpm_tran(hcd, devaddr); ++ if (channel < 0) { ++ return channel; ++ } ++ ++ pcgcctl.b.enbl_sleep_gating = 1; ++ DWC_MODIFY_REG32(hcd->core_if->pcgcctl, 0, pcgcctl.d32); ++ ++ /* Read LPM config register */ ++ lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg); ++ ++ /* Program LPM transaction fields */ ++ lpmcfg.b.rem_wkup_en = bRemoteWake; ++ lpmcfg.b.hird = hird; ++ lpmcfg.b.hird_thres = 0x1c; ++ lpmcfg.b.lpm_chan_index = channel; ++ lpmcfg.b.en_utmi_sleep = 1; ++ /* Program LPM config register */ ++ DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32); ++ ++ /* Send LPM transaction */ ++ lpmcfg.b.send_lpm = 1; ++ DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32); ++ ++ return 0; ++} ++ ++#endif /* CONFIG_USB_DWC_OTG_LPM */ ++ ++int dwc_otg_hcd_is_status_changed(dwc_otg_hcd_t * hcd, int port) ++{ ++ int retval; ++ ++ if (port != 1) { ++ return -DWC_E_INVALID; ++ } ++ ++ retval = (hcd->flags.b.port_connect_status_change || ++ hcd->flags.b.port_reset_change || ++ hcd->flags.b.port_enable_change || ++ hcd->flags.b.port_suspend_change || ++ hcd->flags.b.port_over_current_change); ++#ifdef DEBUG ++ if (retval) { ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:" ++ " Root port status changed\n"); ++ DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n", ++ hcd->flags.b.port_connect_status_change); ++ DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n", ++ hcd->flags.b.port_reset_change); ++ DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n", ++ hcd->flags.b.port_enable_change); ++ DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n", ++ hcd->flags.b.port_suspend_change); ++ DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n", ++ hcd->flags.b.port_over_current_change); ++ } ++#endif ++ return retval; ++} ++ ++int dwc_otg_hcd_get_frame_number(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ hfnum_data_t hfnum; ++ hfnum.d32 = ++ DWC_READ_REG32(&dwc_otg_hcd->core_if->host_if->host_global_regs-> ++ hfnum); ++ ++#ifdef DEBUG_SOF ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", ++ hfnum.b.frnum); ++#endif ++ return hfnum.b.frnum; ++} ++ ++int dwc_otg_hcd_start(dwc_otg_hcd_t * hcd, ++ struct dwc_otg_hcd_function_ops *fops) ++{ ++ int retval = 0; ++ ++ hcd->fops = fops; ++ if (!dwc_otg_is_device_mode(hcd->core_if) && ++ (!hcd->core_if->adp_enable || hcd->core_if->adp.adp_started)) { ++ dwc_otg_hcd_reinit(hcd); ++ } else { ++ retval = -DWC_E_NO_DEVICE; ++ } ++ ++ return retval; ++} ++ ++void *dwc_otg_hcd_get_priv_data(dwc_otg_hcd_t * hcd) ++{ ++ return hcd->priv; ++} ++ ++void dwc_otg_hcd_set_priv_data(dwc_otg_hcd_t * hcd, void *priv_data) ++{ ++ hcd->priv = priv_data; ++} ++ ++uint32_t dwc_otg_hcd_otg_port(dwc_otg_hcd_t * hcd) ++{ ++ return hcd->otg_port; ++} ++ ++uint32_t dwc_otg_hcd_is_b_host(dwc_otg_hcd_t * hcd) ++{ ++ uint32_t is_b_host; ++ if (hcd->core_if->op_state == B_HOST) { ++ is_b_host = 1; ++ } else { ++ is_b_host = 0; ++ } ++ ++ return is_b_host; ++} ++ ++dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc(dwc_otg_hcd_t * hcd, ++ int iso_desc_count, int atomic_alloc) ++{ ++ dwc_otg_hcd_urb_t *dwc_otg_urb; ++ uint32_t size; ++ ++ size = ++ sizeof(*dwc_otg_urb) + ++ iso_desc_count * sizeof(struct dwc_otg_hcd_iso_packet_desc); ++ if (atomic_alloc) ++ dwc_otg_urb = DWC_ALLOC_ATOMIC(size); ++ else ++ dwc_otg_urb = DWC_ALLOC(size); ++ ++ if (NULL != dwc_otg_urb) ++ dwc_otg_urb->packet_count = iso_desc_count; ++ else { ++ dwc_otg_urb->packet_count = 0; ++ if (size != 0) { ++ DWC_ERROR("**** DWC OTG HCD URB alloc - " ++ "%salloc of %db failed\n", ++ atomic_alloc?"atomic ":"", size); ++ } ++ } ++ ++ return dwc_otg_urb; ++} ++ ++void dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_hcd_urb_t * dwc_otg_urb, ++ uint8_t dev_addr, uint8_t ep_num, ++ uint8_t ep_type, uint8_t ep_dir, uint16_t mps) ++{ ++ dwc_otg_hcd_fill_pipe(&dwc_otg_urb->pipe_info, dev_addr, ep_num, ++ ep_type, ep_dir, mps); ++#if 0 ++ DWC_PRINTF ++ ("addr = %d, ep_num = %d, ep_dir = 0x%x, ep_type = 0x%x, mps = %d\n", ++ dev_addr, ep_num, ep_dir, ep_type, mps); ++#endif ++} ++ ++void dwc_otg_hcd_urb_set_params(dwc_otg_hcd_urb_t * dwc_otg_urb, ++ void *urb_handle, void *buf, dwc_dma_t dma, ++ uint32_t buflen, void *setup_packet, ++ dwc_dma_t setup_dma, uint32_t flags, ++ uint16_t interval) ++{ ++ dwc_otg_urb->priv = urb_handle; ++ dwc_otg_urb->buf = buf; ++ dwc_otg_urb->dma = dma; ++ dwc_otg_urb->length = buflen; ++ dwc_otg_urb->setup_packet = setup_packet; ++ dwc_otg_urb->setup_dma = setup_dma; ++ dwc_otg_urb->flags = flags; ++ dwc_otg_urb->interval = interval; ++ dwc_otg_urb->status = -DWC_E_IN_PROGRESS; ++} ++ ++uint32_t dwc_otg_hcd_urb_get_status(dwc_otg_hcd_urb_t * dwc_otg_urb) ++{ ++ return dwc_otg_urb->status; ++} ++ ++uint32_t dwc_otg_hcd_urb_get_actual_length(dwc_otg_hcd_urb_t * dwc_otg_urb) ++{ ++ return dwc_otg_urb->actual_length; ++} ++ ++uint32_t dwc_otg_hcd_urb_get_error_count(dwc_otg_hcd_urb_t * dwc_otg_urb) ++{ ++ return dwc_otg_urb->error_count; ++} ++ ++void dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_hcd_urb_t * dwc_otg_urb, ++ int desc_num, uint32_t offset, ++ uint32_t length) ++{ ++ dwc_otg_urb->iso_descs[desc_num].offset = offset; ++ dwc_otg_urb->iso_descs[desc_num].length = length; ++} ++ ++uint32_t dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_hcd_urb_t * dwc_otg_urb, ++ int desc_num) ++{ ++ return dwc_otg_urb->iso_descs[desc_num].status; ++} ++ ++uint32_t dwc_otg_hcd_urb_get_iso_desc_actual_length(dwc_otg_hcd_urb_t * ++ dwc_otg_urb, int desc_num) ++{ ++ return dwc_otg_urb->iso_descs[desc_num].actual_length; ++} ++ ++int dwc_otg_hcd_is_bandwidth_allocated(dwc_otg_hcd_t * hcd, void *ep_handle) ++{ ++ int allocated = 0; ++ dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle; ++ ++ if (qh) { ++ if (!DWC_LIST_EMPTY(&qh->qh_list_entry)) { ++ allocated = 1; ++ } ++ } ++ return allocated; ++} ++ ++int dwc_otg_hcd_is_bandwidth_freed(dwc_otg_hcd_t * hcd, void *ep_handle) ++{ ++ dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle; ++ int freed = 0; ++ DWC_ASSERT(qh, "qh is not allocated\n"); ++ ++ if (DWC_LIST_EMPTY(&qh->qh_list_entry)) { ++ freed = 1; ++ } ++ ++ return freed; ++} ++ ++uint8_t dwc_otg_hcd_get_ep_bandwidth(dwc_otg_hcd_t * hcd, void *ep_handle) ++{ ++ dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle; ++ DWC_ASSERT(qh, "qh is not allocated\n"); ++ return qh->usecs; ++} ++ ++void dwc_otg_hcd_dump_state(dwc_otg_hcd_t * hcd) ++{ ++#ifdef DEBUG ++ int num_channels; ++ int i; ++ gnptxsts_data_t np_tx_status; ++ hptxsts_data_t p_tx_status; ++ ++ num_channels = hcd->core_if->core_params->host_channels; ++ DWC_PRINTF("\n"); ++ DWC_PRINTF ++ ("************************************************************\n"); ++ DWC_PRINTF("HCD State:\n"); ++ DWC_PRINTF(" Num channels: %d\n", num_channels); ++ for (i = 0; i < num_channels; i++) { ++ dwc_hc_t *hc = hcd->hc_ptr_array[i]; ++ DWC_PRINTF(" Channel %d:\n", i); ++ DWC_PRINTF(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n", ++ hc->dev_addr, hc->ep_num, hc->ep_is_in); ++ DWC_PRINTF(" speed: %d\n", hc->speed); ++ DWC_PRINTF(" ep_type: %d\n", hc->ep_type); ++ DWC_PRINTF(" max_packet: %d\n", hc->max_packet); ++ DWC_PRINTF(" data_pid_start: %d\n", hc->data_pid_start); ++ DWC_PRINTF(" multi_count: %d\n", hc->multi_count); ++ DWC_PRINTF(" xfer_started: %d\n", hc->xfer_started); ++ DWC_PRINTF(" xfer_buff: %p\n", hc->xfer_buff); ++ DWC_PRINTF(" xfer_len: %d\n", hc->xfer_len); ++ DWC_PRINTF(" xfer_count: %d\n", hc->xfer_count); ++ DWC_PRINTF(" halt_on_queue: %d\n", hc->halt_on_queue); ++ DWC_PRINTF(" halt_pending: %d\n", hc->halt_pending); ++ DWC_PRINTF(" halt_status: %d\n", hc->halt_status); ++ DWC_PRINTF(" do_split: %d\n", hc->do_split); ++ DWC_PRINTF(" complete_split: %d\n", hc->complete_split); ++ DWC_PRINTF(" hub_addr: %d\n", hc->hub_addr); ++ DWC_PRINTF(" port_addr: %d\n", hc->port_addr); ++ DWC_PRINTF(" xact_pos: %d\n", hc->xact_pos); ++ DWC_PRINTF(" requests: %d\n", hc->requests); ++ DWC_PRINTF(" qh: %p\n", hc->qh); ++ if (hc->xfer_started) { ++ hfnum_data_t hfnum; ++ hcchar_data_t hcchar; ++ hctsiz_data_t hctsiz; ++ hcint_data_t hcint; ++ hcintmsk_data_t hcintmsk; ++ hfnum.d32 = ++ DWC_READ_REG32(&hcd->core_if-> ++ host_if->host_global_regs->hfnum); ++ hcchar.d32 = ++ DWC_READ_REG32(&hcd->core_if->host_if-> ++ hc_regs[i]->hcchar); ++ hctsiz.d32 = ++ DWC_READ_REG32(&hcd->core_if->host_if-> ++ hc_regs[i]->hctsiz); ++ hcint.d32 = ++ DWC_READ_REG32(&hcd->core_if->host_if-> ++ hc_regs[i]->hcint); ++ hcintmsk.d32 = ++ DWC_READ_REG32(&hcd->core_if->host_if-> ++ hc_regs[i]->hcintmsk); ++ DWC_PRINTF(" hfnum: 0x%08x\n", hfnum.d32); ++ DWC_PRINTF(" hcchar: 0x%08x\n", hcchar.d32); ++ DWC_PRINTF(" hctsiz: 0x%08x\n", hctsiz.d32); ++ DWC_PRINTF(" hcint: 0x%08x\n", hcint.d32); ++ DWC_PRINTF(" hcintmsk: 0x%08x\n", hcintmsk.d32); ++ } ++ if (hc->xfer_started && hc->qh) { ++ dwc_otg_qtd_t *qtd; ++ dwc_otg_hcd_urb_t *urb; ++ ++ DWC_CIRCLEQ_FOREACH(qtd, &hc->qh->qtd_list, qtd_list_entry) { ++ if (!qtd->in_process) ++ break; ++ ++ urb = qtd->urb; ++ DWC_PRINTF(" URB Info:\n"); ++ DWC_PRINTF(" qtd: %p, urb: %p\n", qtd, urb); ++ if (urb) { ++ DWC_PRINTF(" Dev: %d, EP: %d %s\n", ++ dwc_otg_hcd_get_dev_addr(&urb-> ++ pipe_info), ++ dwc_otg_hcd_get_ep_num(&urb-> ++ pipe_info), ++ dwc_otg_hcd_is_pipe_in(&urb-> ++ pipe_info) ? ++ "IN" : "OUT"); ++ DWC_PRINTF(" Max packet size: %d\n", ++ dwc_otg_hcd_get_mps(&urb-> ++ pipe_info)); ++ DWC_PRINTF(" transfer_buffer: %p\n", ++ urb->buf); ++ DWC_PRINTF(" transfer_dma: %p\n", ++ (void *)urb->dma); ++ DWC_PRINTF(" transfer_buffer_length: %d\n", ++ urb->length); ++ DWC_PRINTF(" actual_length: %d\n", ++ urb->actual_length); ++ } ++ } ++ } ++ } ++ DWC_PRINTF(" non_periodic_channels: %d\n", hcd->non_periodic_channels); ++ DWC_PRINTF(" periodic_channels: %d\n", hcd->periodic_channels); ++ DWC_PRINTF(" periodic_usecs: %d\n", hcd->periodic_usecs); ++ np_tx_status.d32 = ++ DWC_READ_REG32(&hcd->core_if->core_global_regs->gnptxsts); ++ DWC_PRINTF(" NP Tx Req Queue Space Avail: %d\n", ++ np_tx_status.b.nptxqspcavail); ++ DWC_PRINTF(" NP Tx FIFO Space Avail: %d\n", ++ np_tx_status.b.nptxfspcavail); ++ p_tx_status.d32 = ++ DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hptxsts); ++ DWC_PRINTF(" P Tx Req Queue Space Avail: %d\n", ++ p_tx_status.b.ptxqspcavail); ++ DWC_PRINTF(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail); ++ dwc_otg_hcd_dump_frrem(hcd); ++ dwc_otg_dump_global_registers(hcd->core_if); ++ dwc_otg_dump_host_registers(hcd->core_if); ++ DWC_PRINTF ++ ("************************************************************\n"); ++ DWC_PRINTF("\n"); ++#endif ++} ++ ++#ifdef DEBUG ++void dwc_print_setup_data(uint8_t * setup) ++{ ++ int i; ++ if (CHK_DEBUG_LEVEL(DBG_HCD)) { ++ DWC_PRINTF("Setup Data = MSB "); ++ for (i = 7; i >= 0; i--) ++ DWC_PRINTF("%02x ", setup[i]); ++ DWC_PRINTF("\n"); ++ DWC_PRINTF(" bmRequestType Tranfer = %s\n", ++ (setup[0] & 0x80) ? "Device-to-Host" : ++ "Host-to-Device"); ++ DWC_PRINTF(" bmRequestType Type = "); ++ switch ((setup[0] & 0x60) >> 5) { ++ case 0: ++ DWC_PRINTF("Standard\n"); ++ break; ++ case 1: ++ DWC_PRINTF("Class\n"); ++ break; ++ case 2: ++ DWC_PRINTF("Vendor\n"); ++ break; ++ case 3: ++ DWC_PRINTF("Reserved\n"); ++ break; ++ } ++ DWC_PRINTF(" bmRequestType Recipient = "); ++ switch (setup[0] & 0x1f) { ++ case 0: ++ DWC_PRINTF("Device\n"); ++ break; ++ case 1: ++ DWC_PRINTF("Interface\n"); ++ break; ++ case 2: ++ DWC_PRINTF("Endpoint\n"); ++ break; ++ case 3: ++ DWC_PRINTF("Other\n"); ++ break; ++ default: ++ DWC_PRINTF("Reserved\n"); ++ break; ++ } ++ DWC_PRINTF(" bRequest = 0x%0x\n", setup[1]); ++ DWC_PRINTF(" wValue = 0x%0x\n", *((uint16_t *) & setup[2])); ++ DWC_PRINTF(" wIndex = 0x%0x\n", *((uint16_t *) & setup[4])); ++ DWC_PRINTF(" wLength = 0x%0x\n\n", *((uint16_t *) & setup[6])); ++ } ++} ++#endif ++ ++void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t * hcd) ++{ ++#if 0 ++ DWC_PRINTF("Frame remaining at SOF:\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->frrem_samples, hcd->frrem_accum, ++ (hcd->frrem_samples > 0) ? ++ hcd->frrem_accum / hcd->frrem_samples : 0); ++ ++ DWC_PRINTF("\n"); ++ DWC_PRINTF("Frame remaining at start_transfer (uframe 7):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->core_if->hfnum_7_samples, ++ hcd->core_if->hfnum_7_frrem_accum, ++ (hcd->core_if->hfnum_7_samples > ++ 0) ? hcd->core_if->hfnum_7_frrem_accum / ++ hcd->core_if->hfnum_7_samples : 0); ++ DWC_PRINTF("Frame remaining at start_transfer (uframe 0):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->core_if->hfnum_0_samples, ++ hcd->core_if->hfnum_0_frrem_accum, ++ (hcd->core_if->hfnum_0_samples > ++ 0) ? hcd->core_if->hfnum_0_frrem_accum / ++ hcd->core_if->hfnum_0_samples : 0); ++ DWC_PRINTF("Frame remaining at start_transfer (uframe 1-6):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->core_if->hfnum_other_samples, ++ hcd->core_if->hfnum_other_frrem_accum, ++ (hcd->core_if->hfnum_other_samples > ++ 0) ? hcd->core_if->hfnum_other_frrem_accum / ++ hcd->core_if->hfnum_other_samples : 0); ++ ++ DWC_PRINTF("\n"); ++ DWC_PRINTF("Frame remaining at sample point A (uframe 7):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a, ++ (hcd->hfnum_7_samples_a > 0) ? ++ hcd->hfnum_7_frrem_accum_a / hcd->hfnum_7_samples_a : 0); ++ DWC_PRINTF("Frame remaining at sample point A (uframe 0):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a, ++ (hcd->hfnum_0_samples_a > 0) ? ++ hcd->hfnum_0_frrem_accum_a / hcd->hfnum_0_samples_a : 0); ++ DWC_PRINTF("Frame remaining at sample point A (uframe 1-6):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a, ++ (hcd->hfnum_other_samples_a > 0) ? ++ hcd->hfnum_other_frrem_accum_a / ++ hcd->hfnum_other_samples_a : 0); ++ ++ DWC_PRINTF("\n"); ++ DWC_PRINTF("Frame remaining at sample point B (uframe 7):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b, ++ (hcd->hfnum_7_samples_b > 0) ? ++ hcd->hfnum_7_frrem_accum_b / hcd->hfnum_7_samples_b : 0); ++ DWC_PRINTF("Frame remaining at sample point B (uframe 0):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b, ++ (hcd->hfnum_0_samples_b > 0) ? ++ hcd->hfnum_0_frrem_accum_b / hcd->hfnum_0_samples_b : 0); ++ DWC_PRINTF("Frame remaining at sample point B (uframe 1-6):\n"); ++ DWC_PRINTF(" samples %u, accum %llu, avg %llu\n", ++ hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b, ++ (hcd->hfnum_other_samples_b > 0) ? ++ hcd->hfnum_other_frrem_accum_b / ++ hcd->hfnum_other_samples_b : 0); ++#endif ++} ++ ++#endif /* DWC_DEVICE_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,824 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.h $ ++ * $Revision: #58 $ ++ * $Date: 2011/09/15 $ ++ * $Change: 1846647 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_DEVICE_ONLY ++#ifndef __DWC_HCD_H__ ++#define __DWC_HCD_H__ ++ ++#include "dwc_otg_os_dep.h" ++#include "usb.h" ++#include "dwc_otg_hcd_if.h" ++#include "dwc_otg_core_if.h" ++#include "dwc_list.h" ++#include "dwc_otg_cil.h" ++ ++/** ++ * @file ++ * ++ * This file contains the structures, constants, and interfaces for ++ * the Host Contoller Driver (HCD). ++ * ++ * The Host Controller Driver (HCD) is responsible for translating requests ++ * from the USB Driver into the appropriate actions on the DWC_otg controller. ++ * It isolates the USBD from the specifics of the controller by providing an ++ * API to the USBD. ++ */ ++ ++struct dwc_otg_hcd_pipe_info { ++ uint8_t dev_addr; ++ uint8_t ep_num; ++ uint8_t pipe_type; ++ uint8_t pipe_dir; ++ uint16_t mps; ++}; ++ ++struct dwc_otg_hcd_iso_packet_desc { ++ uint32_t offset; ++ uint32_t length; ++ uint32_t actual_length; ++ uint32_t status; ++}; ++ ++struct dwc_otg_qtd; ++ ++struct dwc_otg_hcd_urb { ++ void *priv; ++ struct dwc_otg_qtd *qtd; ++ void *buf; ++ dwc_dma_t dma; ++ void *setup_packet; ++ dwc_dma_t setup_dma; ++ uint32_t length; ++ uint32_t actual_length; ++ uint32_t status; ++ uint32_t error_count; ++ uint32_t packet_count; ++ uint32_t flags; ++ uint16_t interval; ++ struct dwc_otg_hcd_pipe_info pipe_info; ++ struct dwc_otg_hcd_iso_packet_desc iso_descs[0]; ++}; ++ ++static inline uint8_t dwc_otg_hcd_get_ep_num(struct dwc_otg_hcd_pipe_info *pipe) ++{ ++ return pipe->ep_num; ++} ++ ++static inline uint8_t dwc_otg_hcd_get_pipe_type(struct dwc_otg_hcd_pipe_info ++ *pipe) ++{ ++ return pipe->pipe_type; ++} ++ ++static inline uint16_t dwc_otg_hcd_get_mps(struct dwc_otg_hcd_pipe_info *pipe) ++{ ++ return pipe->mps; ++} ++ ++static inline uint8_t dwc_otg_hcd_get_dev_addr(struct dwc_otg_hcd_pipe_info ++ *pipe) ++{ ++ return pipe->dev_addr; ++} ++ ++static inline uint8_t dwc_otg_hcd_is_pipe_isoc(struct dwc_otg_hcd_pipe_info ++ *pipe) ++{ ++ return (pipe->pipe_type == UE_ISOCHRONOUS); ++} ++ ++static inline uint8_t dwc_otg_hcd_is_pipe_int(struct dwc_otg_hcd_pipe_info ++ *pipe) ++{ ++ return (pipe->pipe_type == UE_INTERRUPT); ++} ++ ++static inline uint8_t dwc_otg_hcd_is_pipe_bulk(struct dwc_otg_hcd_pipe_info ++ *pipe) ++{ ++ return (pipe->pipe_type == UE_BULK); ++} ++ ++static inline uint8_t dwc_otg_hcd_is_pipe_control(struct dwc_otg_hcd_pipe_info ++ *pipe) ++{ ++ return (pipe->pipe_type == UE_CONTROL); ++} ++ ++static inline uint8_t dwc_otg_hcd_is_pipe_in(struct dwc_otg_hcd_pipe_info *pipe) ++{ ++ return (pipe->pipe_dir == UE_DIR_IN); ++} ++ ++static inline uint8_t dwc_otg_hcd_is_pipe_out(struct dwc_otg_hcd_pipe_info ++ *pipe) ++{ ++ return (!dwc_otg_hcd_is_pipe_in(pipe)); ++} ++ ++static inline void dwc_otg_hcd_fill_pipe(struct dwc_otg_hcd_pipe_info *pipe, ++ uint8_t devaddr, uint8_t ep_num, ++ uint8_t pipe_type, uint8_t pipe_dir, ++ uint16_t mps) ++{ ++ pipe->dev_addr = devaddr; ++ pipe->ep_num = ep_num; ++ pipe->pipe_type = pipe_type; ++ pipe->pipe_dir = pipe_dir; ++ pipe->mps = mps; ++} ++ ++/** ++ * Phases for control transfers. ++ */ ++typedef enum dwc_otg_control_phase { ++ DWC_OTG_CONTROL_SETUP, ++ DWC_OTG_CONTROL_DATA, ++ DWC_OTG_CONTROL_STATUS ++} dwc_otg_control_phase_e; ++ ++/** Transaction types. */ ++typedef enum dwc_otg_transaction_type { ++ DWC_OTG_TRANSACTION_NONE, ++ DWC_OTG_TRANSACTION_PERIODIC, ++ DWC_OTG_TRANSACTION_NON_PERIODIC, ++ DWC_OTG_TRANSACTION_ALL ++} dwc_otg_transaction_type_e; ++ ++struct dwc_otg_qh; ++ ++/** ++ * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control, ++ * interrupt, or isochronous transfer. A single QTD is created for each URB ++ * (of one of these types) submitted to the HCD. The transfer associated with ++ * a QTD may require one or multiple transactions. ++ * ++ * A QTD is linked to a Queue Head, which is entered in either the ++ * non-periodic or periodic schedule for execution. When a QTD is chosen for ++ * execution, some or all of its transactions may be executed. After ++ * execution, the state of the QTD is updated. The QTD may be retired if all ++ * its transactions are complete or if an error occurred. Otherwise, it ++ * remains in the schedule so more transactions can be executed later. ++ */ ++typedef struct dwc_otg_qtd { ++ /** ++ * Determines the PID of the next data packet for the data phase of ++ * control transfers. Ignored for other transfer types.
++ * One of the following values: ++ * - DWC_OTG_HC_PID_DATA0 ++ * - DWC_OTG_HC_PID_DATA1 ++ */ ++ uint8_t data_toggle; ++ ++ /** Current phase for control transfers (Setup, Data, or Status). */ ++ dwc_otg_control_phase_e control_phase; ++ ++ /** Keep track of the current split type ++ * for FS/LS endpoints on a HS Hub */ ++ uint8_t complete_split; ++ ++ /** How many bytes transferred during SSPLIT OUT */ ++ uint32_t ssplit_out_xfer_count; ++ ++ /** ++ * Holds the number of bus errors that have occurred for a transaction ++ * within this transfer. ++ */ ++ uint8_t error_count; ++ ++ /** ++ * Index of the next frame descriptor for an isochronous transfer. A ++ * frame descriptor describes the buffer position and length of the ++ * data to be transferred in the next scheduled (micro)frame of an ++ * isochronous transfer. It also holds status for that transaction. ++ * The frame index starts at 0. ++ */ ++ uint16_t isoc_frame_index; ++ ++ /** Position of the ISOC split on full/low speed */ ++ uint8_t isoc_split_pos; ++ ++ /** Position of the ISOC split in the buffer for the current frame */ ++ uint16_t isoc_split_offset; ++ ++ /** URB for this transfer */ ++ struct dwc_otg_hcd_urb *urb; ++ ++ struct dwc_otg_qh *qh; ++ ++ /** This list of QTDs */ ++ DWC_CIRCLEQ_ENTRY(dwc_otg_qtd) qtd_list_entry; ++ ++ /** Indicates if this QTD is currently processed by HW. */ ++ uint8_t in_process; ++ ++ /** Number of DMA descriptors for this QTD */ ++ uint8_t n_desc; ++ ++ /** ++ * Last activated frame(packet) index. ++ * Used in Descriptor DMA mode only. ++ */ ++ uint16_t isoc_frame_index_last; ++ ++} dwc_otg_qtd_t; ++ ++DWC_CIRCLEQ_HEAD(dwc_otg_qtd_list, dwc_otg_qtd); ++ ++/** ++ * A Queue Head (QH) holds the static characteristics of an endpoint and ++ * maintains a list of transfers (QTDs) for that endpoint. A QH structure may ++ * be entered in either the non-periodic or periodic schedule. ++ */ ++typedef struct dwc_otg_qh { ++ /** ++ * Endpoint type. ++ * One of the following values: ++ * - UE_CONTROL ++ * - UE_BULK ++ * - UE_INTERRUPT ++ * - UE_ISOCHRONOUS ++ */ ++ uint8_t ep_type; ++ uint8_t ep_is_in; ++ ++ /** wMaxPacketSize Field of Endpoint Descriptor. */ ++ uint16_t maxp; ++ ++ /** ++ * Device speed. ++ * One of the following values: ++ * - DWC_OTG_EP_SPEED_LOW ++ * - DWC_OTG_EP_SPEED_FULL ++ * - DWC_OTG_EP_SPEED_HIGH ++ */ ++ uint8_t dev_speed; ++ ++ /** ++ * Determines the PID of the next data packet for non-control ++ * transfers. Ignored for control transfers.
++ * One of the following values: ++ * - DWC_OTG_HC_PID_DATA0 ++ * - DWC_OTG_HC_PID_DATA1 ++ */ ++ uint8_t data_toggle; ++ ++ /** Ping state if 1. */ ++ uint8_t ping_state; ++ ++ /** ++ * List of QTDs for this QH. ++ */ ++ struct dwc_otg_qtd_list qtd_list; ++ ++ /** Host channel currently processing transfers for this QH. */ ++ struct dwc_hc *channel; ++ ++ /** Full/low speed endpoint on high-speed hub requires split. */ ++ uint8_t do_split; ++ ++ /** @name Periodic schedule information */ ++ /** @{ */ ++ ++ /** Bandwidth in microseconds per (micro)frame. */ ++ uint16_t usecs; ++ ++ /** Interval between transfers in (micro)frames. */ ++ uint16_t interval; ++ ++ /** ++ * (micro)frame to initialize a periodic transfer. The transfer ++ * executes in the following (micro)frame. ++ */ ++ uint16_t sched_frame; ++ ++ /** (micro)frame at which last start split was initialized. */ ++ uint16_t start_split_frame; ++ ++ /** @} */ ++ ++ /** ++ * Used instead of original buffer if ++ * it(physical address) is not dword-aligned. ++ */ ++ uint8_t *dw_align_buf; ++ dwc_dma_t dw_align_buf_dma; ++ ++ /** Entry for QH in either the periodic or non-periodic schedule. */ ++ dwc_list_link_t qh_list_entry; ++ ++ /** @name Descriptor DMA support */ ++ /** @{ */ ++ ++ /** Descriptor List. */ ++ dwc_otg_host_dma_desc_t *desc_list; ++ ++ /** Descriptor List physical address. */ ++ dwc_dma_t desc_list_dma; ++ ++ /** ++ * Xfer Bytes array. ++ * Each element corresponds to a descriptor and indicates ++ * original XferSize size value for the descriptor. ++ */ ++ uint32_t *n_bytes; ++ ++ /** Actual number of transfer descriptors in a list. */ ++ uint16_t ntd; ++ ++ /** First activated isochronous transfer descriptor index. */ ++ uint8_t td_first; ++ /** Last activated isochronous transfer descriptor index. */ ++ uint8_t td_last; ++ ++ /** @} */ ++ ++ ++ uint16_t speed; ++ uint16_t frame_usecs[8]; ++} dwc_otg_qh_t; ++ ++DWC_CIRCLEQ_HEAD(hc_list, dwc_hc); ++ ++/** ++ * This structure holds the state of the HCD, including the non-periodic and ++ * periodic schedules. ++ */ ++struct dwc_otg_hcd { ++ /** The DWC otg device pointer */ ++ struct dwc_otg_device *otg_dev; ++ /** DWC OTG Core Interface Layer */ ++ dwc_otg_core_if_t *core_if; ++ ++ /** Function HCD driver callbacks */ ++ struct dwc_otg_hcd_function_ops *fops; ++ ++ /** Internal DWC HCD Flags */ ++ volatile union dwc_otg_hcd_internal_flags { ++ uint32_t d32; ++ struct { ++ unsigned port_connect_status_change:1; ++ unsigned port_connect_status:1; ++ unsigned port_reset_change:1; ++ unsigned port_enable_change:1; ++ unsigned port_suspend_change:1; ++ unsigned port_over_current_change:1; ++ unsigned port_l1_change:1; ++ unsigned reserved:26; ++ } b; ++ } flags; ++ ++ /** ++ * Inactive items in the non-periodic schedule. This is a list of ++ * Queue Heads. Transfers associated with these Queue Heads are not ++ * currently assigned to a host channel. ++ */ ++ dwc_list_link_t non_periodic_sched_inactive; ++ ++ /** ++ * Active items in the non-periodic schedule. This is a list of ++ * Queue Heads. Transfers associated with these Queue Heads are ++ * currently assigned to a host channel. ++ */ ++ dwc_list_link_t non_periodic_sched_active; ++ ++ /** ++ * Pointer to the next Queue Head to process in the active ++ * non-periodic schedule. ++ */ ++ dwc_list_link_t *non_periodic_qh_ptr; ++ ++ /** ++ * Inactive items in the periodic schedule. This is a list of QHs for ++ * periodic transfers that are _not_ scheduled for the next frame. ++ * Each QH in the list has an interval counter that determines when it ++ * needs to be scheduled for execution. This scheduling mechanism ++ * allows only a simple calculation for periodic bandwidth used (i.e. ++ * must assume that all periodic transfers may need to execute in the ++ * same frame). However, it greatly simplifies scheduling and should ++ * be sufficient for the vast majority of OTG hosts, which need to ++ * connect to a small number of peripherals at one time. ++ * ++ * Items move from this list to periodic_sched_ready when the QH ++ * interval counter is 0 at SOF. ++ */ ++ dwc_list_link_t periodic_sched_inactive; ++ ++ /** ++ * List of periodic QHs that are ready for execution in the next ++ * frame, but have not yet been assigned to host channels. ++ * ++ * Items move from this list to periodic_sched_assigned as host ++ * channels become available during the current frame. ++ */ ++ dwc_list_link_t periodic_sched_ready; ++ ++ /** ++ * List of periodic QHs to be executed in the next frame that are ++ * assigned to host channels. ++ * ++ * Items move from this list to periodic_sched_queued as the ++ * transactions for the QH are queued to the DWC_otg controller. ++ */ ++ dwc_list_link_t periodic_sched_assigned; ++ ++ /** ++ * List of periodic QHs that have been queued for execution. ++ * ++ * Items move from this list to either periodic_sched_inactive or ++ * periodic_sched_ready when the channel associated with the transfer ++ * is released. If the interval for the QH is 1, the item moves to ++ * periodic_sched_ready because it must be rescheduled for the next ++ * frame. Otherwise, the item moves to periodic_sched_inactive. ++ */ ++ dwc_list_link_t periodic_sched_queued; ++ ++ /** ++ * Total bandwidth claimed so far for periodic transfers. This value ++ * is in microseconds per (micro)frame. The assumption is that all ++ * periodic transfers may occur in the same (micro)frame. ++ */ ++ uint16_t periodic_usecs; ++ ++ /** ++ * Total bandwidth claimed so far for all periodic transfers ++ * in a frame. ++ * This will include a mixture of HS and FS transfers. ++ * Units are microseconds per (micro)frame. ++ * We have a budget per frame and have to schedule ++ * transactions accordingly. ++ * Watch out for the fact that things are actually scheduled for the ++ * "next frame". ++ */ ++ uint16_t frame_usecs[8]; ++ ++ ++ /** ++ * Frame number read from the core at SOF. The value ranges from 0 to ++ * DWC_HFNUM_MAX_FRNUM. ++ */ ++ uint16_t frame_number; ++ ++ /** ++ * Count of periodic QHs, if using several eps. For SOF enable/disable. ++ */ ++ uint16_t periodic_qh_count; ++ ++ /** ++ * Free host channels in the controller. This is a list of ++ * dwc_hc_t items. ++ */ ++ struct hc_list free_hc_list; ++ /** ++ * Number of host channels assigned to periodic transfers. Currently ++ * assuming that there is a dedicated host channel for each periodic ++ * transaction and at least one host channel available for ++ * non-periodic transactions. ++ */ ++ int periodic_channels; /* microframe_schedule==0 */ ++ ++ /** ++ * Number of host channels assigned to non-periodic transfers. ++ */ ++ int non_periodic_channels; /* microframe_schedule==0 */ ++ ++ /** ++ * Number of host channels assigned to non-periodic transfers. ++ */ ++ int available_host_channels; ++ ++ /** ++ * Array of pointers to the host channel descriptors. Allows accessing ++ * a host channel descriptor given the host channel number. This is ++ * useful in interrupt handlers. ++ */ ++ struct dwc_hc *hc_ptr_array[MAX_EPS_CHANNELS]; ++ ++ /** ++ * Buffer to use for any data received during the status phase of a ++ * control transfer. Normally no data is transferred during the status ++ * phase. This buffer is used as a bit bucket. ++ */ ++ uint8_t *status_buf; ++ ++ /** ++ * DMA address for status_buf. ++ */ ++ dma_addr_t status_buf_dma; ++#define DWC_OTG_HCD_STATUS_BUF_SIZE 64 ++ ++ /** ++ * Connection timer. An OTG host must display a message if the device ++ * does not connect. Started when the VBus power is turned on via ++ * sysfs attribute "buspower". ++ */ ++ dwc_timer_t *conn_timer; ++ ++ /* Tasket to do a reset */ ++ dwc_tasklet_t *reset_tasklet; ++ ++ /* */ ++ dwc_spinlock_t *lock; ++ ++ /** ++ * Private data that could be used by OS wrapper. ++ */ ++ void *priv; ++ ++ uint8_t otg_port; ++ ++ /** Frame List */ ++ uint32_t *frame_list; ++ ++ /** Frame List DMA address */ ++ dma_addr_t frame_list_dma; ++ ++#ifdef DEBUG ++ uint32_t frrem_samples; ++ uint64_t frrem_accum; ++ ++ uint32_t hfnum_7_samples_a; ++ uint64_t hfnum_7_frrem_accum_a; ++ uint32_t hfnum_0_samples_a; ++ uint64_t hfnum_0_frrem_accum_a; ++ uint32_t hfnum_other_samples_a; ++ uint64_t hfnum_other_frrem_accum_a; ++ ++ uint32_t hfnum_7_samples_b; ++ uint64_t hfnum_7_frrem_accum_b; ++ uint32_t hfnum_0_samples_b; ++ uint64_t hfnum_0_frrem_accum_b; ++ uint32_t hfnum_other_samples_b; ++ uint64_t hfnum_other_frrem_accum_b; ++#endif ++}; ++ ++/** @name Transaction Execution Functions */ ++/** @{ */ ++extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t ++ * hcd); ++extern void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t * hcd, ++ dwc_otg_transaction_type_e tr_type); ++ ++/** @} */ ++ ++/** @name Interrupt Handler Functions */ ++/** @{ */ ++extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t * ++ dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t * ++ dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t * ++ dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t * ++ dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t * dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(dwc_otg_hcd_t * ++ dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_disconnect_intr(dwc_otg_hcd_t * dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t * dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd, ++ uint32_t num); ++extern int32_t dwc_otg_hcd_handle_session_req_intr(dwc_otg_hcd_t * dwc_otg_hcd); ++extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(dwc_otg_hcd_t * ++ dwc_otg_hcd); ++/** @} */ ++ ++/** @name Schedule Queue Functions */ ++/** @{ */ ++ ++/* Implemented in dwc_otg_hcd_queue.c */ ++extern dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t * hcd, ++ dwc_otg_hcd_urb_t * urb, int atomic_alloc); ++extern void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); ++extern int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); ++extern void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); ++extern void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, ++ int sched_csplit); ++ ++/** Remove and free a QH */ ++static inline void dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd_t * hcd, ++ dwc_otg_qh_t * qh) ++{ ++ dwc_irqflags_t flags; ++ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); ++ dwc_otg_hcd_qh_remove(hcd, qh); ++ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ dwc_otg_hcd_qh_free(hcd, qh); ++} ++ ++/** Allocates memory for a QH structure. ++ * @return Returns the memory allocate or NULL on error. */ ++static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc(int atomic_alloc) ++{ ++ if (atomic_alloc) ++ return (dwc_otg_qh_t *) DWC_ALLOC_ATOMIC(sizeof(dwc_otg_qh_t)); ++ else ++ return (dwc_otg_qh_t *) DWC_ALLOC(sizeof(dwc_otg_qh_t)); ++} ++ ++extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(dwc_otg_hcd_urb_t * urb, ++ int atomic_alloc); ++extern void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t * qtd, dwc_otg_hcd_urb_t * urb); ++extern int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * qtd, dwc_otg_hcd_t * dwc_otg_hcd, ++ dwc_otg_qh_t ** qh, int atomic_alloc); ++ ++/** Allocates memory for a QTD structure. ++ * @return Returns the memory allocate or NULL on error. */ ++static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc(int atomic_alloc) ++{ ++ if (atomic_alloc) ++ return (dwc_otg_qtd_t *) DWC_ALLOC_ATOMIC(sizeof(dwc_otg_qtd_t)); ++ else ++ return (dwc_otg_qtd_t *) DWC_ALLOC(sizeof(dwc_otg_qtd_t)); ++} ++ ++/** Frees the memory for a QTD structure. QTD should already be removed from ++ * list. ++ * @param qtd QTD to free.*/ ++static inline void dwc_otg_hcd_qtd_free(dwc_otg_qtd_t * qtd) ++{ ++ DWC_FREE(qtd); ++} ++ ++/** Removes a QTD from list. ++ * @param hcd HCD instance. ++ * @param qtd QTD to remove from list. ++ * @param qh QTD belongs to. ++ */ ++static inline void dwc_otg_hcd_qtd_remove(dwc_otg_hcd_t * hcd, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_qh_t * qh) ++{ ++ DWC_CIRCLEQ_REMOVE(&qh->qtd_list, qtd, qtd_list_entry); ++} ++ ++/** Remove and free a QTD ++ * Need to disable IRQ and hold hcd lock while calling this function out of ++ * interrupt servicing chain */ ++static inline void dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd_t * hcd, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_qh_t * qh) ++{ ++ dwc_otg_hcd_qtd_remove(hcd, qtd, qh); ++ dwc_otg_hcd_qtd_free(qtd); ++} ++ ++/** @} */ ++ ++/** @name Descriptor DMA Supporting Functions */ ++/** @{ */ ++ ++extern void dwc_otg_hcd_start_xfer_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); ++extern void dwc_otg_hcd_complete_xfer_ddma(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_halt_status_e halt_status); ++ ++extern int dwc_otg_hcd_qh_init_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); ++extern void dwc_otg_hcd_qh_free_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); ++ ++/** @} */ ++ ++/** @name Internal Functions */ ++/** @{ */ ++dwc_otg_qh_t *dwc_urb_to_qh(dwc_otg_hcd_urb_t * urb); ++/** @} */ ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++extern int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t * hcd, ++ uint8_t devaddr); ++extern void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t * hcd); ++#endif ++ ++/** Gets the QH that contains the list_head */ ++#define dwc_list_to_qh(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qh_t, qh_list_entry) ++ ++/** Gets the QTD that contains the list_head */ ++#define dwc_list_to_qtd(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qtd_t, qtd_list_entry) ++ ++/** Check if QH is non-periodic */ ++#define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == UE_BULK) || \ ++ (_qh_ptr_->ep_type == UE_CONTROL)) ++ ++/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */ ++#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) ++ ++/** Packet size for any kind of endpoint descriptor */ ++#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) ++ ++/** ++ * Returns true if _frame1 is less than or equal to _frame2. The comparison is ++ * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the ++ * frame number when the max frame number is reached. ++ */ ++static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2) ++{ ++ return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <= ++ (DWC_HFNUM_MAX_FRNUM >> 1); ++} ++ ++/** ++ * Returns true if _frame1 is greater than _frame2. The comparison is done ++ * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame ++ * number when the max frame number is reached. ++ */ ++static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2) ++{ ++ return (frame1 != frame2) && ++ (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) < ++ (DWC_HFNUM_MAX_FRNUM >> 1)); ++} ++ ++/** ++ * Increments _frame by the amount specified by _inc. The addition is done ++ * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value. ++ */ ++static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc) ++{ ++ return (frame + inc) & DWC_HFNUM_MAX_FRNUM; ++} ++ ++static inline uint16_t dwc_full_frame_num(uint16_t frame) ++{ ++ return (frame & DWC_HFNUM_MAX_FRNUM) >> 3; ++} ++ ++static inline uint16_t dwc_micro_frame_num(uint16_t frame) ++{ ++ return frame & 0x7; ++} ++ ++void dwc_otg_hcd_save_data_toggle(dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd); ++ ++#ifdef DEBUG ++/** ++ * Macro to sample the remaining PHY clocks left in the current frame. This ++ * may be used during debugging to determine the average time it takes to ++ * execute sections of code. There are two possible sample points, "a" and ++ * "b", so the _letter argument must be one of these values. ++ * ++ * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For ++ * example, "cat /sys/devices/lm0/hcd_frrem". ++ */ ++#define dwc_sample_frrem(_hcd, _qh, _letter) \ ++{ \ ++ hfnum_data_t hfnum; \ ++ dwc_otg_qtd_t *qtd; \ ++ qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \ ++ if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \ ++ hfnum.d32 = DWC_READ_REG32(&_hcd->core_if->host_if->host_global_regs->hfnum); \ ++ switch (hfnum.b.frnum & 0x7) { \ ++ case 7: \ ++ _hcd->hfnum_7_samples_##_letter++; \ ++ _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \ ++ break; \ ++ case 0: \ ++ _hcd->hfnum_0_samples_##_letter++; \ ++ _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \ ++ break; \ ++ default: \ ++ _hcd->hfnum_other_samples_##_letter++; \ ++ _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \ ++ break; \ ++ } \ ++ } \ ++} ++#else ++#define dwc_sample_frrem(_hcd, _qh, _letter) ++#endif ++#endif ++#endif /* DWC_DEVICE_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1133 @@ ++/*========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_ddma.c $ ++ * $Revision: #10 $ ++ * $Date: 2011/10/20 $ ++ * $Change: 1869464 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_DEVICE_ONLY ++ ++/** @file ++ * This file contains Descriptor DMA support implementation for host mode. ++ */ ++ ++#include "dwc_otg_hcd.h" ++#include "dwc_otg_regs.h" ++ ++extern bool microframe_schedule; ++ ++static inline uint8_t frame_list_idx(uint16_t frame) ++{ ++ return (frame & (MAX_FRLIST_EN_NUM - 1)); ++} ++ ++static inline uint16_t desclist_idx_inc(uint16_t idx, uint16_t inc, uint8_t speed) ++{ ++ return (idx + inc) & ++ (((speed == ++ DWC_OTG_EP_SPEED_HIGH) ? MAX_DMA_DESC_NUM_HS_ISOC : ++ MAX_DMA_DESC_NUM_GENERIC) - 1); ++} ++ ++static inline uint16_t desclist_idx_dec(uint16_t idx, uint16_t inc, uint8_t speed) ++{ ++ return (idx - inc) & ++ (((speed == ++ DWC_OTG_EP_SPEED_HIGH) ? MAX_DMA_DESC_NUM_HS_ISOC : ++ MAX_DMA_DESC_NUM_GENERIC) - 1); ++} ++ ++static inline uint16_t max_desc_num(dwc_otg_qh_t * qh) ++{ ++ return (((qh->ep_type == UE_ISOCHRONOUS) ++ && (qh->dev_speed == DWC_OTG_EP_SPEED_HIGH)) ++ ? MAX_DMA_DESC_NUM_HS_ISOC : MAX_DMA_DESC_NUM_GENERIC); ++} ++static inline uint16_t frame_incr_val(dwc_otg_qh_t * qh) ++{ ++ return ((qh->dev_speed == DWC_OTG_EP_SPEED_HIGH) ++ ? ((qh->interval + 8 - 1) / 8) ++ : qh->interval); ++} ++ ++static int desc_list_alloc(dwc_otg_qh_t * qh) ++{ ++ int retval = 0; ++ ++ qh->desc_list = (dwc_otg_host_dma_desc_t *) ++ DWC_DMA_ALLOC(sizeof(dwc_otg_host_dma_desc_t) * max_desc_num(qh), ++ &qh->desc_list_dma); ++ ++ if (!qh->desc_list) { ++ retval = -DWC_E_NO_MEMORY; ++ DWC_ERROR("%s: DMA descriptor list allocation failed\n", __func__); ++ ++ } ++ ++ dwc_memset(qh->desc_list, 0x00, ++ sizeof(dwc_otg_host_dma_desc_t) * max_desc_num(qh)); ++ ++ qh->n_bytes = ++ (uint32_t *) DWC_ALLOC(sizeof(uint32_t) * max_desc_num(qh)); ++ ++ if (!qh->n_bytes) { ++ retval = -DWC_E_NO_MEMORY; ++ DWC_ERROR ++ ("%s: Failed to allocate array for descriptors' size actual values\n", ++ __func__); ++ ++ } ++ return retval; ++ ++} ++ ++static void desc_list_free(dwc_otg_qh_t * qh) ++{ ++ if (qh->desc_list) { ++ DWC_DMA_FREE(max_desc_num(qh), qh->desc_list, ++ qh->desc_list_dma); ++ qh->desc_list = NULL; ++ } ++ ++ if (qh->n_bytes) { ++ DWC_FREE(qh->n_bytes); ++ qh->n_bytes = NULL; ++ } ++} ++ ++static int frame_list_alloc(dwc_otg_hcd_t * hcd) ++{ ++ int retval = 0; ++ if (hcd->frame_list) ++ return 0; ++ ++ hcd->frame_list = DWC_DMA_ALLOC(4 * MAX_FRLIST_EN_NUM, ++ &hcd->frame_list_dma); ++ if (!hcd->frame_list) { ++ retval = -DWC_E_NO_MEMORY; ++ DWC_ERROR("%s: Frame List allocation failed\n", __func__); ++ } ++ ++ dwc_memset(hcd->frame_list, 0x00, 4 * MAX_FRLIST_EN_NUM); ++ ++ return retval; ++} ++ ++static void frame_list_free(dwc_otg_hcd_t * hcd) ++{ ++ if (!hcd->frame_list) ++ return; ++ ++ DWC_DMA_FREE(4 * MAX_FRLIST_EN_NUM, hcd->frame_list, hcd->frame_list_dma); ++ hcd->frame_list = NULL; ++} ++ ++static void per_sched_enable(dwc_otg_hcd_t * hcd, uint16_t fr_list_en) ++{ ++ ++ hcfg_data_t hcfg; ++ ++ hcfg.d32 = DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hcfg); ++ ++ if (hcfg.b.perschedena) { ++ /* already enabled */ ++ return; ++ } ++ ++ DWC_WRITE_REG32(&hcd->core_if->host_if->host_global_regs->hflbaddr, ++ hcd->frame_list_dma); ++ ++ switch (fr_list_en) { ++ case 64: ++ hcfg.b.frlisten = 3; ++ break; ++ case 32: ++ hcfg.b.frlisten = 2; ++ break; ++ case 16: ++ hcfg.b.frlisten = 1; ++ break; ++ case 8: ++ hcfg.b.frlisten = 0; ++ break; ++ default: ++ break; ++ } ++ ++ hcfg.b.perschedena = 1; ++ ++ DWC_DEBUGPL(DBG_HCD, "Enabling Periodic schedule\n"); ++ DWC_WRITE_REG32(&hcd->core_if->host_if->host_global_regs->hcfg, hcfg.d32); ++ ++} ++ ++static void per_sched_disable(dwc_otg_hcd_t * hcd) ++{ ++ hcfg_data_t hcfg; ++ ++ hcfg.d32 = DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hcfg); ++ ++ if (!hcfg.b.perschedena) { ++ /* already disabled */ ++ return; ++ } ++ hcfg.b.perschedena = 0; ++ ++ DWC_DEBUGPL(DBG_HCD, "Disabling Periodic schedule\n"); ++ DWC_WRITE_REG32(&hcd->core_if->host_if->host_global_regs->hcfg, hcfg.d32); ++} ++ ++/* ++ * Activates/Deactivates FrameList entries for the channel ++ * based on endpoint servicing period. ++ */ ++void update_frame_list(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, uint8_t enable) ++{ ++ uint16_t i, j, inc; ++ dwc_hc_t *hc = NULL; ++ ++ if (!qh->channel) { ++ DWC_ERROR("qh->channel = %p", qh->channel); ++ return; ++ } ++ ++ if (!hcd) { ++ DWC_ERROR("------hcd = %p", hcd); ++ return; ++ } ++ ++ if (!hcd->frame_list) { ++ DWC_ERROR("-------hcd->frame_list = %p", hcd->frame_list); ++ return; ++ } ++ ++ hc = qh->channel; ++ inc = frame_incr_val(qh); ++ if (qh->ep_type == UE_ISOCHRONOUS) ++ i = frame_list_idx(qh->sched_frame); ++ else ++ i = 0; ++ ++ j = i; ++ do { ++ if (enable) ++ hcd->frame_list[j] |= (1 << hc->hc_num); ++ else ++ hcd->frame_list[j] &= ~(1 << hc->hc_num); ++ j = (j + inc) & (MAX_FRLIST_EN_NUM - 1); ++ } ++ while (j != i); ++ if (!enable) ++ return; ++ hc->schinfo = 0; ++ if (qh->channel->speed == DWC_OTG_EP_SPEED_HIGH) { ++ j = 1; ++ /* TODO - check this */ ++ inc = (8 + qh->interval - 1) / qh->interval; ++ for (i = 0; i < inc; i++) { ++ hc->schinfo |= j; ++ j = j << qh->interval; ++ } ++ } else { ++ hc->schinfo = 0xff; ++ } ++} ++ ++#if 1 ++void dump_frame_list(dwc_otg_hcd_t * hcd) ++{ ++ int i = 0; ++ DWC_PRINTF("--FRAME LIST (hex) --\n"); ++ for (i = 0; i < MAX_FRLIST_EN_NUM; i++) { ++ DWC_PRINTF("%x\t", hcd->frame_list[i]); ++ if (!(i % 8) && i) ++ DWC_PRINTF("\n"); ++ } ++ DWC_PRINTF("\n----\n"); ++ ++} ++#endif ++ ++static void release_channel_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ dwc_irqflags_t flags; ++ dwc_spinlock_t *channel_lock = DWC_SPINLOCK_ALLOC(); ++ ++ dwc_hc_t *hc = qh->channel; ++ if (dwc_qh_is_non_per(qh)) { ++ DWC_SPINLOCK_IRQSAVE(channel_lock, &flags); ++ if (!microframe_schedule) ++ hcd->non_periodic_channels--; ++ else ++ hcd->available_host_channels++; ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++ } else ++ update_frame_list(hcd, qh, 0); ++ ++ /* ++ * The condition is added to prevent double cleanup try in case of device ++ * disconnect. See channel cleanup in dwc_otg_hcd_disconnect_cb(). ++ */ ++ if (hc->qh) { ++ dwc_otg_hc_cleanup(hcd->core_if, hc); ++ DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry); ++ hc->qh = NULL; ++ } ++ ++ qh->channel = NULL; ++ qh->ntd = 0; ++ ++ if (qh->desc_list) { ++ dwc_memset(qh->desc_list, 0x00, ++ sizeof(dwc_otg_host_dma_desc_t) * max_desc_num(qh)); ++ } ++ DWC_SPINLOCK_FREE(channel_lock); ++} ++ ++/** ++ * Initializes a QH structure's Descriptor DMA related members. ++ * Allocates memory for descriptor list. ++ * On first periodic QH, allocates memory for FrameList ++ * and enables periodic scheduling. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh The QH to init. ++ * ++ * @return 0 if successful, negative error code otherwise. ++ */ ++int dwc_otg_hcd_qh_init_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ int retval = 0; ++ ++ if (qh->do_split) { ++ DWC_ERROR("SPLIT Transfers are not supported in Descriptor DMA.\n"); ++ return -1; ++ } ++ ++ retval = desc_list_alloc(qh); ++ ++ if ((retval == 0) ++ && (qh->ep_type == UE_ISOCHRONOUS || qh->ep_type == UE_INTERRUPT)) { ++ if (!hcd->frame_list) { ++ retval = frame_list_alloc(hcd); ++ /* Enable periodic schedule on first periodic QH */ ++ if (retval == 0) ++ per_sched_enable(hcd, MAX_FRLIST_EN_NUM); ++ } ++ } ++ ++ qh->ntd = 0; ++ ++ return retval; ++} ++ ++/** ++ * Frees descriptor list memory associated with the QH. ++ * If QH is periodic and the last, frees FrameList memory ++ * and disables periodic scheduling. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh The QH to init. ++ */ ++void dwc_otg_hcd_qh_free_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ desc_list_free(qh); ++ ++ /* ++ * Channel still assigned due to some reasons. ++ * Seen on Isoc URB dequeue. Channel halted but no subsequent ++ * ChHalted interrupt to release the channel. Afterwards ++ * when it comes here from endpoint disable routine ++ * channel remains assigned. ++ */ ++ if (qh->channel) ++ release_channel_ddma(hcd, qh); ++ ++ if ((qh->ep_type == UE_ISOCHRONOUS || qh->ep_type == UE_INTERRUPT) ++ && (microframe_schedule || !hcd->periodic_channels) && hcd->frame_list) { ++ ++ per_sched_disable(hcd); ++ frame_list_free(hcd); ++ } ++} ++ ++static uint8_t frame_to_desc_idx(dwc_otg_qh_t * qh, uint16_t frame_idx) ++{ ++ if (qh->dev_speed == DWC_OTG_EP_SPEED_HIGH) { ++ /* ++ * Descriptor set(8 descriptors) index ++ * which is 8-aligned. ++ */ ++ return (frame_idx & ((MAX_DMA_DESC_NUM_HS_ISOC / 8) - 1)) * 8; ++ } else { ++ return (frame_idx & (MAX_DMA_DESC_NUM_GENERIC - 1)); ++ } ++} ++ ++/* ++ * Determine starting frame for Isochronous transfer. ++ * Few frames skipped to prevent race condition with HC. ++ */ ++static uint8_t calc_starting_frame(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, ++ uint8_t * skip_frames) ++{ ++ uint16_t frame = 0; ++ hcd->frame_number = dwc_otg_hcd_get_frame_number(hcd); ++ ++ /* sched_frame is always frame number(not uFrame) both in FS and HS !! */ ++ ++ /* ++ * skip_frames is used to limit activated descriptors number ++ * to avoid the situation when HC services the last activated ++ * descriptor firstly. ++ * Example for FS: ++ * Current frame is 1, scheduled frame is 3. Since HC always fetches the descriptor ++ * corresponding to curr_frame+1, the descriptor corresponding to frame 2 ++ * will be fetched. If the number of descriptors is max=64 (or greather) the ++ * list will be fully programmed with Active descriptors and it is possible ++ * case(rare) that the latest descriptor(considering rollback) corresponding ++ * to frame 2 will be serviced first. HS case is more probable because, in fact, ++ * up to 11 uframes(16 in the code) may be skipped. ++ */ ++ if (qh->dev_speed == DWC_OTG_EP_SPEED_HIGH) { ++ /* ++ * Consider uframe counter also, to start xfer asap. ++ * If half of the frame elapsed skip 2 frames otherwise ++ * just 1 frame. ++ * Starting descriptor index must be 8-aligned, so ++ * if the current frame is near to complete the next one ++ * is skipped as well. ++ */ ++ ++ if (dwc_micro_frame_num(hcd->frame_number) >= 5) { ++ *skip_frames = 2 * 8; ++ frame = dwc_frame_num_inc(hcd->frame_number, *skip_frames); ++ } else { ++ *skip_frames = 1 * 8; ++ frame = dwc_frame_num_inc(hcd->frame_number, *skip_frames); ++ } ++ ++ frame = dwc_full_frame_num(frame); ++ } else { ++ /* ++ * Two frames are skipped for FS - the current and the next. ++ * But for descriptor programming, 1 frame(descriptor) is enough, ++ * see example above. ++ */ ++ *skip_frames = 1; ++ frame = dwc_frame_num_inc(hcd->frame_number, 2); ++ } ++ ++ return frame; ++} ++ ++/* ++ * Calculate initial descriptor index for isochronous transfer ++ * based on scheduled frame. ++ */ ++static uint8_t recalc_initial_desc_idx(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ uint16_t frame = 0, fr_idx, fr_idx_tmp; ++ uint8_t skip_frames = 0; ++ /* ++ * With current ISOC processing algorithm the channel is being ++ * released when no more QTDs in the list(qh->ntd == 0). ++ * Thus this function is called only when qh->ntd == 0 and qh->channel == 0. ++ * ++ * So qh->channel != NULL branch is not used and just not removed from the ++ * source file. It is required for another possible approach which is, ++ * do not disable and release the channel when ISOC session completed, ++ * just move QH to inactive schedule until new QTD arrives. ++ * On new QTD, the QH moved back to 'ready' schedule, ++ * starting frame and therefore starting desc_index are recalculated. ++ * In this case channel is released only on ep_disable. ++ */ ++ ++ /* Calculate starting descriptor index. For INTERRUPT endpoint it is always 0. */ ++ if (qh->channel) { ++ frame = calc_starting_frame(hcd, qh, &skip_frames); ++ /* ++ * Calculate initial descriptor index based on FrameList current bitmap ++ * and servicing period. ++ */ ++ fr_idx_tmp = frame_list_idx(frame); ++ fr_idx = ++ (MAX_FRLIST_EN_NUM + frame_list_idx(qh->sched_frame) - ++ fr_idx_tmp) ++ % frame_incr_val(qh); ++ fr_idx = (fr_idx + fr_idx_tmp) % MAX_FRLIST_EN_NUM; ++ } else { ++ qh->sched_frame = calc_starting_frame(hcd, qh, &skip_frames); ++ fr_idx = frame_list_idx(qh->sched_frame); ++ } ++ ++ qh->td_first = qh->td_last = frame_to_desc_idx(qh, fr_idx); ++ ++ return skip_frames; ++} ++ ++#define ISOC_URB_GIVEBACK_ASAP ++ ++#define MAX_ISOC_XFER_SIZE_FS 1023 ++#define MAX_ISOC_XFER_SIZE_HS 3072 ++#define DESCNUM_THRESHOLD 4 ++ ++static void init_isoc_dma_desc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, ++ uint8_t skip_frames) ++{ ++ struct dwc_otg_hcd_iso_packet_desc *frame_desc; ++ dwc_otg_qtd_t *qtd; ++ dwc_otg_host_dma_desc_t *dma_desc; ++ uint16_t idx, inc, n_desc, ntd_max, max_xfer_size; ++ ++ idx = qh->td_last; ++ inc = qh->interval; ++ n_desc = 0; ++ ++ ntd_max = (max_desc_num(qh) + qh->interval - 1) / qh->interval; ++ if (skip_frames && !qh->channel) ++ ntd_max = ntd_max - skip_frames / qh->interval; ++ ++ max_xfer_size = ++ (qh->dev_speed == ++ DWC_OTG_EP_SPEED_HIGH) ? MAX_ISOC_XFER_SIZE_HS : ++ MAX_ISOC_XFER_SIZE_FS; ++ ++ DWC_CIRCLEQ_FOREACH(qtd, &qh->qtd_list, qtd_list_entry) { ++ while ((qh->ntd < ntd_max) ++ && (qtd->isoc_frame_index_last < ++ qtd->urb->packet_count)) { ++ ++ dma_desc = &qh->desc_list[idx]; ++ dwc_memset(dma_desc, 0x00, sizeof(dwc_otg_host_dma_desc_t)); ++ ++ frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index_last]; ++ ++ if (frame_desc->length > max_xfer_size) ++ qh->n_bytes[idx] = max_xfer_size; ++ else ++ qh->n_bytes[idx] = frame_desc->length; ++ dma_desc->status.b_isoc.n_bytes = qh->n_bytes[idx]; ++ dma_desc->status.b_isoc.a = 1; ++ dma_desc->status.b_isoc.sts = 0; ++ ++ dma_desc->buf = qtd->urb->dma + frame_desc->offset; ++ ++ qh->ntd++; ++ ++ qtd->isoc_frame_index_last++; ++ ++#ifdef ISOC_URB_GIVEBACK_ASAP ++ /* ++ * Set IOC for each descriptor corresponding to the ++ * last frame of the URB. ++ */ ++ if (qtd->isoc_frame_index_last == ++ qtd->urb->packet_count) ++ dma_desc->status.b_isoc.ioc = 1; ++ ++#endif ++ idx = desclist_idx_inc(idx, inc, qh->dev_speed); ++ n_desc++; ++ ++ } ++ qtd->in_process = 1; ++ } ++ ++ qh->td_last = idx; ++ ++#ifdef ISOC_URB_GIVEBACK_ASAP ++ /* Set IOC for the last descriptor if descriptor list is full */ ++ if (qh->ntd == ntd_max) { ++ idx = desclist_idx_dec(qh->td_last, inc, qh->dev_speed); ++ qh->desc_list[idx].status.b_isoc.ioc = 1; ++ } ++#else ++ /* ++ * Set IOC bit only for one descriptor. ++ * Always try to be ahead of HW processing, ++ * i.e. on IOC generation driver activates next descriptors but ++ * core continues to process descriptors followed the one with IOC set. ++ */ ++ ++ if (n_desc > DESCNUM_THRESHOLD) { ++ /* ++ * Move IOC "up". Required even if there is only one QTD ++ * in the list, cause QTDs migth continue to be queued, ++ * but during the activation it was only one queued. ++ * Actually more than one QTD might be in the list if this function called ++ * from XferCompletion - QTDs was queued during HW processing of the previous ++ * descriptor chunk. ++ */ ++ idx = dwc_desclist_idx_dec(idx, inc * ((qh->ntd + 1) / 2), qh->dev_speed); ++ } else { ++ /* ++ * Set the IOC for the latest descriptor ++ * if either number of descriptor is not greather than threshold ++ * or no more new descriptors activated. ++ */ ++ idx = dwc_desclist_idx_dec(qh->td_last, inc, qh->dev_speed); ++ } ++ ++ qh->desc_list[idx].status.b_isoc.ioc = 1; ++#endif ++} ++ ++static void init_non_isoc_dma_desc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ ++ dwc_hc_t *hc; ++ dwc_otg_host_dma_desc_t *dma_desc; ++ dwc_otg_qtd_t *qtd; ++ int num_packets, len, n_desc = 0; ++ ++ hc = qh->channel; ++ ++ /* ++ * Start with hc->xfer_buff initialized in ++ * assign_and_init_hc(), then if SG transfer consists of multiple URBs, ++ * this pointer re-assigned to the buffer of the currently processed QTD. ++ * For non-SG request there is always one QTD active. ++ */ ++ ++ DWC_CIRCLEQ_FOREACH(qtd, &qh->qtd_list, qtd_list_entry) { ++ ++ if (n_desc) { ++ /* SG request - more than 1 QTDs */ ++ hc->xfer_buff = (uint8_t *)qtd->urb->dma + qtd->urb->actual_length; ++ hc->xfer_len = qtd->urb->length - qtd->urb->actual_length; ++ } ++ ++ qtd->n_desc = 0; ++ ++ do { ++ dma_desc = &qh->desc_list[n_desc]; ++ len = hc->xfer_len; ++ ++ if (len > MAX_DMA_DESC_SIZE) ++ len = MAX_DMA_DESC_SIZE - hc->max_packet + 1; ++ ++ if (hc->ep_is_in) { ++ if (len > 0) { ++ num_packets = (len + hc->max_packet - 1) / hc->max_packet; ++ } else { ++ /* Need 1 packet for transfer length of 0. */ ++ num_packets = 1; ++ } ++ /* Always program an integral # of max packets for IN transfers. */ ++ len = num_packets * hc->max_packet; ++ } ++ ++ dma_desc->status.b.n_bytes = len; ++ ++ qh->n_bytes[n_desc] = len; ++ ++ if ((qh->ep_type == UE_CONTROL) ++ && (qtd->control_phase == DWC_OTG_CONTROL_SETUP)) ++ dma_desc->status.b.sup = 1; /* Setup Packet */ ++ ++ dma_desc->status.b.a = 1; /* Active descriptor */ ++ dma_desc->status.b.sts = 0; ++ ++ dma_desc->buf = ++ ((unsigned long)hc->xfer_buff & 0xffffffff); ++ ++ /* ++ * Last descriptor(or single) of IN transfer ++ * with actual size less than MaxPacket. ++ */ ++ if (len > hc->xfer_len) { ++ hc->xfer_len = 0; ++ } else { ++ hc->xfer_buff += len; ++ hc->xfer_len -= len; ++ } ++ ++ qtd->n_desc++; ++ n_desc++; ++ } ++ while ((hc->xfer_len > 0) && (n_desc != MAX_DMA_DESC_NUM_GENERIC)); ++ ++ ++ qtd->in_process = 1; ++ ++ if (qh->ep_type == UE_CONTROL) ++ break; ++ ++ if (n_desc == MAX_DMA_DESC_NUM_GENERIC) ++ break; ++ } ++ ++ if (n_desc) { ++ /* Request Transfer Complete interrupt for the last descriptor */ ++ qh->desc_list[n_desc - 1].status.b.ioc = 1; ++ /* End of List indicator */ ++ qh->desc_list[n_desc - 1].status.b.eol = 1; ++ ++ hc->ntd = n_desc; ++ } ++} ++ ++/** ++ * For Control and Bulk endpoints initializes descriptor list ++ * and starts the transfer. ++ * ++ * For Interrupt and Isochronous endpoints initializes descriptor list ++ * then updates FrameList, marking appropriate entries as active. ++ * In case of Isochronous, the starting descriptor index is calculated based ++ * on the scheduled frame, but only on the first transfer descriptor within a session. ++ * Then starts the transfer via enabling the channel. ++ * For Isochronous endpoint the channel is not halted on XferComplete ++ * interrupt so remains assigned to the endpoint(QH) until session is done. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh The QH to init. ++ * ++ * @return 0 if successful, negative error code otherwise. ++ */ ++void dwc_otg_hcd_start_xfer_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ /* Channel is already assigned */ ++ dwc_hc_t *hc = qh->channel; ++ uint8_t skip_frames = 0; ++ ++ switch (hc->ep_type) { ++ case DWC_OTG_EP_TYPE_CONTROL: ++ case DWC_OTG_EP_TYPE_BULK: ++ init_non_isoc_dma_desc(hcd, qh); ++ ++ dwc_otg_hc_start_transfer_ddma(hcd->core_if, hc); ++ break; ++ case DWC_OTG_EP_TYPE_INTR: ++ init_non_isoc_dma_desc(hcd, qh); ++ ++ update_frame_list(hcd, qh, 1); ++ ++ dwc_otg_hc_start_transfer_ddma(hcd->core_if, hc); ++ break; ++ case DWC_OTG_EP_TYPE_ISOC: ++ ++ if (!qh->ntd) ++ skip_frames = recalc_initial_desc_idx(hcd, qh); ++ ++ init_isoc_dma_desc(hcd, qh, skip_frames); ++ ++ if (!hc->xfer_started) { ++ ++ update_frame_list(hcd, qh, 1); ++ ++ /* ++ * Always set to max, instead of actual size. ++ * Otherwise ntd will be changed with ++ * channel being enabled. Not recommended. ++ * ++ */ ++ hc->ntd = max_desc_num(qh); ++ /* Enable channel only once for ISOC */ ++ dwc_otg_hc_start_transfer_ddma(hcd->core_if, hc); ++ } ++ ++ break; ++ default: ++ ++ break; ++ } ++} ++ ++static void complete_isoc_xfer_ddma(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_halt_status_e halt_status) ++{ ++ struct dwc_otg_hcd_iso_packet_desc *frame_desc; ++ dwc_otg_qtd_t *qtd, *qtd_tmp; ++ dwc_otg_qh_t *qh; ++ dwc_otg_host_dma_desc_t *dma_desc; ++ uint16_t idx, remain; ++ uint8_t urb_compl; ++ ++ qh = hc->qh; ++ idx = qh->td_first; ++ ++ if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE) { ++ DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &hc->qh->qtd_list, qtd_list_entry) ++ qtd->in_process = 0; ++ return; ++ } else if ((halt_status == DWC_OTG_HC_XFER_AHB_ERR) || ++ (halt_status == DWC_OTG_HC_XFER_BABBLE_ERR)) { ++ /* ++ * Channel is halted in these error cases. ++ * Considered as serious issues. ++ * Complete all URBs marking all frames as failed, ++ * irrespective whether some of the descriptors(frames) succeeded or no. ++ * Pass error code to completion routine as well, to ++ * update urb->status, some of class drivers might use it to stop ++ * queing transfer requests. ++ */ ++ int err = (halt_status == DWC_OTG_HC_XFER_AHB_ERR) ++ ? (-DWC_E_IO) ++ : (-DWC_E_OVERFLOW); ++ ++ DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &hc->qh->qtd_list, qtd_list_entry) { ++ for (idx = 0; idx < qtd->urb->packet_count; idx++) { ++ frame_desc = &qtd->urb->iso_descs[idx]; ++ frame_desc->status = err; ++ } ++ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, err); ++ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh); ++ } ++ return; ++ } ++ ++ DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &hc->qh->qtd_list, qtd_list_entry) { ++ ++ if (!qtd->in_process) ++ break; ++ ++ urb_compl = 0; ++ ++ do { ++ ++ dma_desc = &qh->desc_list[idx]; ++ ++ frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index]; ++ remain = hc->ep_is_in ? dma_desc->status.b_isoc.n_bytes : 0; ++ ++ if (dma_desc->status.b_isoc.sts == DMA_DESC_STS_PKTERR) { ++ /* ++ * XactError or, unable to complete all the transactions ++ * in the scheduled micro-frame/frame, ++ * both indicated by DMA_DESC_STS_PKTERR. ++ */ ++ qtd->urb->error_count++; ++ frame_desc->actual_length = qh->n_bytes[idx] - remain; ++ frame_desc->status = -DWC_E_PROTOCOL; ++ } else { ++ /* Success */ ++ ++ frame_desc->actual_length = qh->n_bytes[idx] - remain; ++ frame_desc->status = 0; ++ } ++ ++ if (++qtd->isoc_frame_index == qtd->urb->packet_count) { ++ /* ++ * urb->status is not used for isoc transfers here. ++ * The individual frame_desc status are used instead. ++ */ ++ ++ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0); ++ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh); ++ ++ /* ++ * This check is necessary because urb_dequeue can be called ++ * from urb complete callback(sound driver example). ++ * All pending URBs are dequeued there, so no need for ++ * further processing. ++ */ ++ if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE) { ++ return; ++ } ++ ++ urb_compl = 1; ++ ++ } ++ ++ qh->ntd--; ++ ++ /* Stop if IOC requested descriptor reached */ ++ if (dma_desc->status.b_isoc.ioc) { ++ idx = desclist_idx_inc(idx, qh->interval, hc->speed); ++ goto stop_scan; ++ } ++ ++ idx = desclist_idx_inc(idx, qh->interval, hc->speed); ++ ++ if (urb_compl) ++ break; ++ } ++ while (idx != qh->td_first); ++ } ++stop_scan: ++ qh->td_first = idx; ++} ++ ++uint8_t update_non_isoc_urb_state_ddma(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_host_dma_desc_t * dma_desc, ++ dwc_otg_halt_status_e halt_status, ++ uint32_t n_bytes, uint8_t * xfer_done) ++{ ++ ++ uint16_t remain = hc->ep_is_in ? dma_desc->status.b.n_bytes : 0; ++ dwc_otg_hcd_urb_t *urb = qtd->urb; ++ ++ if (halt_status == DWC_OTG_HC_XFER_AHB_ERR) { ++ urb->status = -DWC_E_IO; ++ return 1; ++ } ++ if (dma_desc->status.b.sts == DMA_DESC_STS_PKTERR) { ++ switch (halt_status) { ++ case DWC_OTG_HC_XFER_STALL: ++ urb->status = -DWC_E_PIPE; ++ break; ++ case DWC_OTG_HC_XFER_BABBLE_ERR: ++ urb->status = -DWC_E_OVERFLOW; ++ break; ++ case DWC_OTG_HC_XFER_XACT_ERR: ++ urb->status = -DWC_E_PROTOCOL; ++ break; ++ default: ++ DWC_ERROR("%s: Unhandled descriptor error status (%d)\n", __func__, ++ halt_status); ++ break; ++ } ++ return 1; ++ } ++ ++ if (dma_desc->status.b.a == 1) { ++ DWC_DEBUGPL(DBG_HCDV, ++ "Active descriptor encountered on channel %d\n", ++ hc->hc_num); ++ return 0; ++ } ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL) { ++ if (qtd->control_phase == DWC_OTG_CONTROL_DATA) { ++ urb->actual_length += n_bytes - remain; ++ if (remain || urb->actual_length == urb->length) { ++ /* ++ * For Control Data stage do not set urb->status=0 to prevent ++ * URB callback. Set it when Status phase done. See below. ++ */ ++ *xfer_done = 1; ++ } ++ ++ } else if (qtd->control_phase == DWC_OTG_CONTROL_STATUS) { ++ urb->status = 0; ++ *xfer_done = 1; ++ } ++ /* No handling for SETUP stage */ ++ } else { ++ /* BULK and INTR */ ++ urb->actual_length += n_bytes - remain; ++ if (remain || urb->actual_length == urb->length) { ++ urb->status = 0; ++ *xfer_done = 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static void complete_non_isoc_xfer_ddma(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_halt_status_e halt_status) ++{ ++ dwc_otg_hcd_urb_t *urb = NULL; ++ dwc_otg_qtd_t *qtd, *qtd_tmp; ++ dwc_otg_qh_t *qh; ++ dwc_otg_host_dma_desc_t *dma_desc; ++ uint32_t n_bytes, n_desc, i; ++ uint8_t failed = 0, xfer_done; ++ ++ n_desc = 0; ++ ++ qh = hc->qh; ++ ++ if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE) { ++ DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &hc->qh->qtd_list, qtd_list_entry) { ++ qtd->in_process = 0; ++ } ++ return; ++ } ++ ++ DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { ++ ++ urb = qtd->urb; ++ ++ n_bytes = 0; ++ xfer_done = 0; ++ ++ for (i = 0; i < qtd->n_desc; i++) { ++ dma_desc = &qh->desc_list[n_desc]; ++ ++ n_bytes = qh->n_bytes[n_desc]; ++ ++ failed = ++ update_non_isoc_urb_state_ddma(hcd, hc, qtd, ++ dma_desc, ++ halt_status, n_bytes, ++ &xfer_done); ++ ++ if (failed ++ || (xfer_done ++ && (urb->status != -DWC_E_IN_PROGRESS))) { ++ ++ hcd->fops->complete(hcd, urb->priv, urb, ++ urb->status); ++ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh); ++ ++ if (failed) ++ goto stop_scan; ++ } else if (qh->ep_type == UE_CONTROL) { ++ if (qtd->control_phase == DWC_OTG_CONTROL_SETUP) { ++ if (urb->length > 0) { ++ qtd->control_phase = DWC_OTG_CONTROL_DATA; ++ } else { ++ qtd->control_phase = DWC_OTG_CONTROL_STATUS; ++ } ++ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction done\n"); ++ } else if (qtd->control_phase == DWC_OTG_CONTROL_DATA) { ++ if (xfer_done) { ++ qtd->control_phase = DWC_OTG_CONTROL_STATUS; ++ DWC_DEBUGPL(DBG_HCDV, " Control data transfer done\n"); ++ } else if (i + 1 == qtd->n_desc) { ++ /* ++ * Last descriptor for Control data stage which is ++ * not completed yet. ++ */ ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ } ++ } ++ } ++ ++ n_desc++; ++ } ++ ++ } ++ ++stop_scan: ++ ++ if (qh->ep_type != UE_CONTROL) { ++ /* ++ * Resetting the data toggle for bulk ++ * and interrupt endpoints in case of stall. See handle_hc_stall_intr() ++ */ ++ if (halt_status == DWC_OTG_HC_XFER_STALL) ++ qh->data_toggle = DWC_OTG_HC_PID_DATA0; ++ else ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ } ++ ++ if (halt_status == DWC_OTG_HC_XFER_COMPLETE) { ++ hcint_data_t hcint; ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ if (hcint.b.nyet) { ++ /* ++ * Got a NYET on the last transaction of the transfer. It ++ * means that the endpoint should be in the PING state at the ++ * beginning of the next transfer. ++ */ ++ qh->ping_state = 1; ++ clear_hc_int(hc_regs, nyet); ++ } ++ ++ } ++ ++} ++ ++/** ++ * This function is called from interrupt handlers. ++ * Scans the descriptor list, updates URB's status and ++ * calls completion routine for the URB if it's done. ++ * Releases the channel to be used by other transfers. ++ * In case of Isochronous endpoint the channel is not halted until ++ * the end of the session, i.e. QTD list is empty. ++ * If periodic channel released the FrameList is updated accordingly. ++ * ++ * Calls transaction selection routines to activate pending transfers. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param hc Host channel, the transfer is completed on. ++ * @param hc_regs Host channel registers. ++ * @param halt_status Reason the channel is being halted, ++ * or just XferComplete for isochronous transfer ++ */ ++void dwc_otg_hcd_complete_xfer_ddma(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_halt_status_e halt_status) ++{ ++ uint8_t continue_isoc_xfer = 0; ++ dwc_otg_transaction_type_e tr_type; ++ dwc_otg_qh_t *qh = hc->qh; ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ ++ complete_isoc_xfer_ddma(hcd, hc, hc_regs, halt_status); ++ ++ /* Release the channel if halted or session completed */ ++ if (halt_status != DWC_OTG_HC_XFER_COMPLETE || ++ DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) { ++ ++ /* Halt the channel if session completed */ ++ if (halt_status == DWC_OTG_HC_XFER_COMPLETE) { ++ dwc_otg_hc_halt(hcd->core_if, hc, halt_status); ++ } ++ ++ release_channel_ddma(hcd, qh); ++ dwc_otg_hcd_qh_remove(hcd, qh); ++ } else { ++ /* Keep in assigned schedule to continue transfer */ ++ DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned, ++ &qh->qh_list_entry); ++ continue_isoc_xfer = 1; ++ ++ } ++ /** @todo Consider the case when period exceeds FrameList size. ++ * Frame Rollover interrupt should be used. ++ */ ++ } else { ++ /* Scan descriptor list to complete the URB(s), then release the channel */ ++ complete_non_isoc_xfer_ddma(hcd, hc, hc_regs, halt_status); ++ ++ release_channel_ddma(hcd, qh); ++ dwc_otg_hcd_qh_remove(hcd, qh); ++ ++ if (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) { ++ /* Add back to inactive non-periodic schedule on normal completion */ ++ dwc_otg_hcd_qh_add(hcd, qh); ++ } ++ ++ } ++ tr_type = dwc_otg_hcd_select_transactions(hcd); ++ if (tr_type != DWC_OTG_TRANSACTION_NONE || continue_isoc_xfer) { ++ if (continue_isoc_xfer) { ++ if (tr_type == DWC_OTG_TRANSACTION_NONE) { ++ tr_type = DWC_OTG_TRANSACTION_PERIODIC; ++ } else if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC) { ++ tr_type = DWC_OTG_TRANSACTION_ALL; ++ } ++ } ++ dwc_otg_hcd_queue_transactions(hcd, tr_type); ++ } ++} ++ ++#endif /* DWC_DEVICE_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,412 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_if.h $ ++ * $Revision: #12 $ ++ * $Date: 2011/10/26 $ ++ * $Change: 1873028 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_DEVICE_ONLY ++#ifndef __DWC_HCD_IF_H__ ++#define __DWC_HCD_IF_H__ ++ ++#include "dwc_otg_core_if.h" ++ ++/** @file ++ * This file defines DWC_OTG HCD Core API. ++ */ ++ ++struct dwc_otg_hcd; ++typedef struct dwc_otg_hcd dwc_otg_hcd_t; ++ ++struct dwc_otg_hcd_urb; ++typedef struct dwc_otg_hcd_urb dwc_otg_hcd_urb_t; ++ ++/** @name HCD Function Driver Callbacks */ ++/** @{ */ ++ ++/** This function is called whenever core switches to host mode. */ ++typedef int (*dwc_otg_hcd_start_cb_t) (dwc_otg_hcd_t * hcd); ++ ++/** This function is called when device has been disconnected */ ++typedef int (*dwc_otg_hcd_disconnect_cb_t) (dwc_otg_hcd_t * hcd); ++ ++/** Wrapper provides this function to HCD to core, so it can get hub information to which device is connected */ ++typedef int (*dwc_otg_hcd_hub_info_from_urb_cb_t) (dwc_otg_hcd_t * hcd, ++ void *urb_handle, ++ uint32_t * hub_addr, ++ uint32_t * port_addr); ++/** Via this function HCD core gets device speed */ ++typedef int (*dwc_otg_hcd_speed_from_urb_cb_t) (dwc_otg_hcd_t * hcd, ++ void *urb_handle); ++ ++/** This function is called when urb is completed */ ++typedef int (*dwc_otg_hcd_complete_urb_cb_t) (dwc_otg_hcd_t * hcd, ++ void *urb_handle, ++ dwc_otg_hcd_urb_t * dwc_otg_urb, ++ int32_t status); ++ ++/** Via this function HCD core gets b_hnp_enable parameter */ ++typedef int (*dwc_otg_hcd_get_b_hnp_enable) (dwc_otg_hcd_t * hcd); ++ ++struct dwc_otg_hcd_function_ops { ++ dwc_otg_hcd_start_cb_t start; ++ dwc_otg_hcd_disconnect_cb_t disconnect; ++ dwc_otg_hcd_hub_info_from_urb_cb_t hub_info; ++ dwc_otg_hcd_speed_from_urb_cb_t speed; ++ dwc_otg_hcd_complete_urb_cb_t complete; ++ dwc_otg_hcd_get_b_hnp_enable get_b_hnp_enable; ++}; ++/** @} */ ++ ++/** @name HCD Core API */ ++/** @{ */ ++/** This function allocates dwc_otg_hcd structure and returns pointer on it. */ ++extern dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void); ++ ++/** This function should be called to initiate HCD Core. ++ * ++ * @param hcd The HCD ++ * @param core_if The DWC_OTG Core ++ * ++ * Returns -DWC_E_NO_MEMORY if no enough memory. ++ * Returns 0 on success ++ */ ++extern int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if); ++ ++/** Frees HCD ++ * ++ * @param hcd The HCD ++ */ ++extern void dwc_otg_hcd_remove(dwc_otg_hcd_t * hcd); ++ ++/** This function should be called on every hardware interrupt. ++ * ++ * @param dwc_otg_hcd The HCD ++ * ++ * Returns non zero if interrupt is handled ++ * Return 0 if interrupt is not handled ++ */ ++extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd); ++ ++/** ++ * Returns private data set by ++ * dwc_otg_hcd_set_priv_data function. ++ * ++ * @param hcd The HCD ++ */ ++extern void *dwc_otg_hcd_get_priv_data(dwc_otg_hcd_t * hcd); ++ ++/** ++ * Set private data. ++ * ++ * @param hcd The HCD ++ * @param priv_data pointer to be stored in private data ++ */ ++extern void dwc_otg_hcd_set_priv_data(dwc_otg_hcd_t * hcd, void *priv_data); ++ ++/** ++ * This function initializes the HCD Core. ++ * ++ * @param hcd The HCD ++ * @param fops The Function Driver Operations data structure containing pointers to all callbacks. ++ * ++ * Returns -DWC_E_NO_DEVICE if Core is currently is in device mode. ++ * Returns 0 on success ++ */ ++extern int dwc_otg_hcd_start(dwc_otg_hcd_t * hcd, ++ struct dwc_otg_hcd_function_ops *fops); ++ ++/** ++ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are ++ * stopped. ++ * ++ * @param hcd The HCD ++ */ ++extern void dwc_otg_hcd_stop(dwc_otg_hcd_t * hcd); ++ ++/** ++ * Handles hub class-specific requests. ++ * ++ * @param dwc_otg_hcd The HCD ++ * @param typeReq Request Type ++ * @param wValue wValue from control request ++ * @param wIndex wIndex from control request ++ * @param buf data buffer ++ * @param wLength data buffer length ++ * ++ * Returns -DWC_E_INVALID if invalid argument is passed ++ * Returns 0 on success ++ */ ++extern int dwc_otg_hcd_hub_control(dwc_otg_hcd_t * dwc_otg_hcd, ++ uint16_t typeReq, uint16_t wValue, ++ uint16_t wIndex, uint8_t * buf, ++ uint16_t wLength); ++ ++/** ++ * Returns otg port number. ++ * ++ * @param hcd The HCD ++ */ ++extern uint32_t dwc_otg_hcd_otg_port(dwc_otg_hcd_t * hcd); ++ ++/** ++ * Returns OTG version - either 1.3 or 2.0. ++ * ++ * @param core_if The core_if structure pointer ++ */ ++extern uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if); ++ ++/** ++ * Returns 1 if currently core is acting as B host, and 0 otherwise. ++ * ++ * @param hcd The HCD ++ */ ++extern uint32_t dwc_otg_hcd_is_b_host(dwc_otg_hcd_t * hcd); ++ ++/** ++ * Returns current frame number. ++ * ++ * @param hcd The HCD ++ */ ++extern int dwc_otg_hcd_get_frame_number(dwc_otg_hcd_t * hcd); ++ ++/** ++ * Dumps hcd state. ++ * ++ * @param hcd The HCD ++ */ ++extern void dwc_otg_hcd_dump_state(dwc_otg_hcd_t * hcd); ++ ++/** ++ * Dump the average frame remaining at SOF. This can be used to ++ * determine average interrupt latency. Frame remaining is also shown for ++ * start transfer and two additional sample points. ++ * Currently this function is not implemented. ++ * ++ * @param hcd The HCD ++ */ ++extern void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t * hcd); ++ ++/** ++ * Sends LPM transaction to the local device. ++ * ++ * @param hcd The HCD ++ * @param devaddr Device Address ++ * @param hird Host initiated resume duration ++ * @param bRemoteWake Value of bRemoteWake field in LPM transaction ++ * ++ * Returns negative value if sending LPM transaction was not succeeded. ++ * Returns 0 on success. ++ */ ++extern int dwc_otg_hcd_send_lpm(dwc_otg_hcd_t * hcd, uint8_t devaddr, ++ uint8_t hird, uint8_t bRemoteWake); ++ ++/* URB interface */ ++ ++/** ++ * Allocates memory for dwc_otg_hcd_urb structure. ++ * Allocated memory should be freed by call of DWC_FREE. ++ * ++ * @param hcd The HCD ++ * @param iso_desc_count Count of ISOC descriptors ++ * @param atomic_alloc Specefies whether to perform atomic allocation. ++ */ ++extern dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc(dwc_otg_hcd_t * hcd, ++ int iso_desc_count, ++ int atomic_alloc); ++ ++/** ++ * Set pipe information in URB. ++ * ++ * @param hcd_urb DWC_OTG URB ++ * @param devaddr Device Address ++ * @param ep_num Endpoint Number ++ * @param ep_type Endpoint Type ++ * @param ep_dir Endpoint Direction ++ * @param mps Max Packet Size ++ */ ++extern void dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_hcd_urb_t * hcd_urb, ++ uint8_t devaddr, uint8_t ep_num, ++ uint8_t ep_type, uint8_t ep_dir, ++ uint16_t mps); ++ ++/* Transfer flags */ ++#define URB_GIVEBACK_ASAP 0x1 ++#define URB_SEND_ZERO_PACKET 0x2 ++ ++/** ++ * Sets dwc_otg_hcd_urb parameters. ++ * ++ * @param urb DWC_OTG URB allocated by dwc_otg_hcd_urb_alloc function. ++ * @param urb_handle Unique handle for request, this will be passed back ++ * to function driver in completion callback. ++ * @param buf The buffer for the data ++ * @param dma The DMA buffer for the data ++ * @param buflen Transfer length ++ * @param sp Buffer for setup data ++ * @param sp_dma DMA address of setup data buffer ++ * @param flags Transfer flags ++ * @param interval Polling interval for interrupt or isochronous transfers. ++ */ ++extern void dwc_otg_hcd_urb_set_params(dwc_otg_hcd_urb_t * urb, ++ void *urb_handle, void *buf, ++ dwc_dma_t dma, uint32_t buflen, void *sp, ++ dwc_dma_t sp_dma, uint32_t flags, ++ uint16_t interval); ++ ++/** Gets status from dwc_otg_hcd_urb ++ * ++ * @param dwc_otg_urb DWC_OTG URB ++ */ ++extern uint32_t dwc_otg_hcd_urb_get_status(dwc_otg_hcd_urb_t * dwc_otg_urb); ++ ++/** Gets actual length from dwc_otg_hcd_urb ++ * ++ * @param dwc_otg_urb DWC_OTG URB ++ */ ++extern uint32_t dwc_otg_hcd_urb_get_actual_length(dwc_otg_hcd_urb_t * ++ dwc_otg_urb); ++ ++/** Gets error count from dwc_otg_hcd_urb. Only for ISOC URBs ++ * ++ * @param dwc_otg_urb DWC_OTG URB ++ */ ++extern uint32_t dwc_otg_hcd_urb_get_error_count(dwc_otg_hcd_urb_t * ++ dwc_otg_urb); ++ ++/** Set ISOC descriptor offset and length ++ * ++ * @param dwc_otg_urb DWC_OTG URB ++ * @param desc_num ISOC descriptor number ++ * @param offset Offset from beginig of buffer. ++ * @param length Transaction length ++ */ ++extern void dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_hcd_urb_t * dwc_otg_urb, ++ int desc_num, uint32_t offset, ++ uint32_t length); ++ ++/** Get status of ISOC descriptor, specified by desc_num ++ * ++ * @param dwc_otg_urb DWC_OTG URB ++ * @param desc_num ISOC descriptor number ++ */ ++extern uint32_t dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_hcd_urb_t * ++ dwc_otg_urb, int desc_num); ++ ++/** Get actual length of ISOC descriptor, specified by desc_num ++ * ++ * @param dwc_otg_urb DWC_OTG URB ++ * @param desc_num ISOC descriptor number ++ */ ++extern uint32_t dwc_otg_hcd_urb_get_iso_desc_actual_length(dwc_otg_hcd_urb_t * ++ dwc_otg_urb, ++ int desc_num); ++ ++/** Queue URB. After transfer is completes, the complete callback will be called with the URB status ++ * ++ * @param dwc_otg_hcd The HCD ++ * @param dwc_otg_urb DWC_OTG URB ++ * @param ep_handle Out parameter for returning endpoint handle ++ * @param atomic_alloc Flag to do atomic allocation if needed ++ * ++ * Returns -DWC_E_NO_DEVICE if no device is connected. ++ * Returns -DWC_E_NO_MEMORY if there is no enough memory. ++ * Returns 0 on success. ++ */ ++extern int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t * dwc_otg_hcd, ++ dwc_otg_hcd_urb_t * dwc_otg_urb, ++ void **ep_handle, int atomic_alloc); ++ ++/** De-queue the specified URB ++ * ++ * @param dwc_otg_hcd The HCD ++ * @param dwc_otg_urb DWC_OTG URB ++ */ ++extern int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_t * dwc_otg_hcd, ++ dwc_otg_hcd_urb_t * dwc_otg_urb); ++ ++/** Frees resources in the DWC_otg controller related to a given endpoint. ++ * Any URBs for the endpoint must already be dequeued. ++ * ++ * @param hcd The HCD ++ * @param ep_handle Endpoint handle, returned by dwc_otg_hcd_urb_enqueue function ++ * @param retry Number of retries if there are queued transfers. ++ * ++ * Returns -DWC_E_INVALID if invalid arguments are passed. ++ * Returns 0 on success ++ */ ++extern int dwc_otg_hcd_endpoint_disable(dwc_otg_hcd_t * hcd, void *ep_handle, ++ int retry); ++ ++/* Resets the data toggle in qh structure. This function can be called from ++ * usb_clear_halt routine. ++ * ++ * @param hcd The HCD ++ * @param ep_handle Endpoint handle, returned by dwc_otg_hcd_urb_enqueue function ++ * ++ * Returns -DWC_E_INVALID if invalid arguments are passed. ++ * Returns 0 on success ++ */ ++extern int dwc_otg_hcd_endpoint_reset(dwc_otg_hcd_t * hcd, void *ep_handle); ++ ++/** Returns 1 if status of specified port is changed and 0 otherwise. ++ * ++ * @param hcd The HCD ++ * @param port Port number ++ */ ++extern int dwc_otg_hcd_is_status_changed(dwc_otg_hcd_t * hcd, int port); ++ ++/** Call this function to check if bandwidth was allocated for specified endpoint. ++ * Only for ISOC and INTERRUPT endpoints. ++ * ++ * @param hcd The HCD ++ * @param ep_handle Endpoint handle ++ */ ++extern int dwc_otg_hcd_is_bandwidth_allocated(dwc_otg_hcd_t * hcd, ++ void *ep_handle); ++ ++/** Call this function to check if bandwidth was freed for specified endpoint. ++ * ++ * @param hcd The HCD ++ * @param ep_handle Endpoint handle ++ */ ++extern int dwc_otg_hcd_is_bandwidth_freed(dwc_otg_hcd_t * hcd, void *ep_handle); ++ ++/** Returns bandwidth allocated for specified endpoint in microseconds. ++ * Only for ISOC and INTERRUPT endpoints. ++ * ++ * @param hcd The HCD ++ * @param ep_handle Endpoint handle ++ */ ++extern uint8_t dwc_otg_hcd_get_ep_bandwidth(dwc_otg_hcd_t * hcd, ++ void *ep_handle); ++ ++/** @} */ ++ ++#endif /* __DWC_HCD_IF_H__ */ ++#endif /* DWC_DEVICE_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,2106 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_intr.c $ ++ * $Revision: #89 $ ++ * $Date: 2011/10/20 $ ++ * $Change: 1869487 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_DEVICE_ONLY ++ ++#include "dwc_otg_hcd.h" ++#include "dwc_otg_regs.h" ++ ++extern bool microframe_schedule; ++ ++/** @file ++ * This file contains the implementation of the HCD Interrupt handlers. ++ */ ++ ++/** This function handles interrupts for the HCD. */ ++int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ int retval = 0; ++ ++ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; ++ gintsts_data_t gintsts; ++#ifdef DEBUG ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ ++ //GRAYG: debugging ++ if (NULL == global_regs) { ++ DWC_DEBUGPL(DBG_HCD, "**** NULL regs: dwc_otg_hcd=%p " ++ "core_if=%p\n", ++ dwc_otg_hcd, global_regs); ++ return retval; ++ } ++#endif ++ ++ /* Exit from ISR if core is hibernated */ ++ if (core_if->hibernation_suspend == 1) { ++ return retval; ++ } ++ DWC_SPINLOCK(dwc_otg_hcd->lock); ++ /* Check if HOST Mode */ ++ if (dwc_otg_is_host_mode(core_if)) { ++ gintsts.d32 = dwc_otg_read_core_intr(core_if); ++ if (!gintsts.d32) { ++ DWC_SPINUNLOCK(dwc_otg_hcd->lock); ++ return 0; ++ } ++#ifdef DEBUG ++ /* Don't print debug message in the interrupt handler on SOF */ ++#ifndef DEBUG_SOF ++ if (gintsts.d32 != DWC_SOF_INTR_MASK) ++#endif ++ DWC_DEBUGPL(DBG_HCDI, "\n"); ++#endif ++ ++#ifdef DEBUG ++#ifndef DEBUG_SOF ++ if (gintsts.d32 != DWC_SOF_INTR_MASK) ++#endif ++ DWC_DEBUGPL(DBG_HCDI, ++ "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x core_if=%p\n", ++ gintsts.d32, core_if); ++#endif ++ ++ if (gintsts.b.sofintr) { ++ retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd); ++ } ++ if (gintsts.b.rxstsqlvl) { ++ retval |= ++ dwc_otg_hcd_handle_rx_status_q_level_intr ++ (dwc_otg_hcd); ++ } ++ if (gintsts.b.nptxfempty) { ++ retval |= ++ dwc_otg_hcd_handle_np_tx_fifo_empty_intr ++ (dwc_otg_hcd); ++ } ++ if (gintsts.b.i2cintr) { ++ /** @todo Implement i2cintr handler. */ ++ } ++ if (gintsts.b.portintr) { ++ retval |= dwc_otg_hcd_handle_port_intr(dwc_otg_hcd); ++ } ++ if (gintsts.b.hcintr) { ++ retval |= dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd); ++ } ++ if (gintsts.b.ptxfempty) { ++ retval |= ++ dwc_otg_hcd_handle_perio_tx_fifo_empty_intr ++ (dwc_otg_hcd); ++ } ++#ifdef DEBUG ++#ifndef DEBUG_SOF ++ if (gintsts.d32 != DWC_SOF_INTR_MASK) ++#endif ++ { ++ DWC_DEBUGPL(DBG_HCDI, ++ "DWC OTG HCD Finished Servicing Interrupts\n"); ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n", ++ DWC_READ_REG32(&global_regs->gintsts)); ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n", ++ DWC_READ_REG32(&global_regs->gintmsk)); ++ } ++#endif ++ ++#ifdef DEBUG ++#ifndef DEBUG_SOF ++ if (gintsts.d32 != DWC_SOF_INTR_MASK) ++#endif ++ DWC_DEBUGPL(DBG_HCDI, "\n"); ++#endif ++ ++ } ++ DWC_SPINUNLOCK(dwc_otg_hcd->lock); ++ return retval; ++} ++ ++#ifdef DWC_TRACK_MISSED_SOFS ++#warning Compiling code to track missed SOFs ++#define FRAME_NUM_ARRAY_SIZE 1000 ++/** ++ * This function is for debug only. ++ */ ++static inline void track_missed_sofs(uint16_t curr_frame_number) ++{ ++ static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE]; ++ static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE]; ++ static int frame_num_idx = 0; ++ static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM; ++ static int dumped_frame_num_array = 0; ++ ++ if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) { ++ if (((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) != ++ curr_frame_number) { ++ frame_num_array[frame_num_idx] = curr_frame_number; ++ last_frame_num_array[frame_num_idx++] = last_frame_num; ++ } ++ } else if (!dumped_frame_num_array) { ++ int i; ++ DWC_PRINTF("Frame Last Frame\n"); ++ DWC_PRINTF("----- ----------\n"); ++ for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) { ++ DWC_PRINTF("0x%04x 0x%04x\n", ++ frame_num_array[i], last_frame_num_array[i]); ++ } ++ dumped_frame_num_array = 1; ++ } ++ last_frame_num = curr_frame_number; ++} ++#endif ++ ++/** ++ * Handles the start-of-frame interrupt in host mode. Non-periodic ++ * transactions may be queued to the DWC_otg controller for the current ++ * (micro)frame. Periodic transactions may be queued to the controller for the ++ * next (micro)frame. ++ */ ++int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * hcd) ++{ ++ hfnum_data_t hfnum; ++ dwc_list_link_t *qh_entry; ++ dwc_otg_qh_t *qh; ++ dwc_otg_transaction_type_e tr_type; ++ gintsts_data_t gintsts = {.d32 = 0 }; ++ ++ hfnum.d32 = ++ DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hfnum); ++ ++#ifdef DEBUG_SOF ++ DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n"); ++#endif ++ hcd->frame_number = hfnum.b.frnum; ++ ++#ifdef DEBUG ++ hcd->frrem_accum += hfnum.b.frrem; ++ hcd->frrem_samples++; ++#endif ++ ++#ifdef DWC_TRACK_MISSED_SOFS ++ track_missed_sofs(hcd->frame_number); ++#endif ++ /* Determine whether any periodic QHs should be executed. */ ++ qh_entry = DWC_LIST_FIRST(&hcd->periodic_sched_inactive); ++ while (qh_entry != &hcd->periodic_sched_inactive) { ++ qh = DWC_LIST_ENTRY(qh_entry, dwc_otg_qh_t, qh_list_entry); ++ qh_entry = qh_entry->next; ++ if (dwc_frame_num_le(qh->sched_frame, hcd->frame_number)) { ++ /* ++ * Move QH to the ready list to be executed next ++ * (micro)frame. ++ */ ++ DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_ready, ++ &qh->qh_list_entry); ++ } ++ } ++ tr_type = dwc_otg_hcd_select_transactions(hcd); ++ if (tr_type != DWC_OTG_TRANSACTION_NONE) { ++ dwc_otg_hcd_queue_transactions(hcd, tr_type); ++ } ++ ++ /* Clear interrupt */ ++ gintsts.b.sofintr = 1; ++ DWC_WRITE_REG32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++/** Handles the Rx Status Queue Level Interrupt, which indicates that there is at ++ * least one packet in the Rx FIFO. The packets are moved from the FIFO to ++ * memory if the DWC_otg controller is operating in Slave mode. */ ++int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ host_grxsts_data_t grxsts; ++ dwc_hc_t *hc = NULL; ++ ++ DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n"); ++ ++ grxsts.d32 = ++ DWC_READ_REG32(&dwc_otg_hcd->core_if->core_global_regs->grxstsp); ++ ++ hc = dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum]; ++ if (!hc) { ++ DWC_ERROR("Unable to get corresponding channel\n"); ++ return 0; ++ } ++ ++ /* Packet Status */ ++ DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum); ++ DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt); ++ DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid, ++ hc->data_pid_start); ++ DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts); ++ ++ switch (grxsts.b.pktsts) { ++ case DWC_GRXSTS_PKTSTS_IN: ++ /* Read the data into the host buffer. */ ++ if (grxsts.b.bcnt > 0) { ++ dwc_otg_read_packet(dwc_otg_hcd->core_if, ++ hc->xfer_buff, grxsts.b.bcnt); ++ ++ /* Update the HC fields for the next packet received. */ ++ hc->xfer_count += grxsts.b.bcnt; ++ hc->xfer_buff += grxsts.b.bcnt; ++ } ++ ++ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP: ++ case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR: ++ case DWC_GRXSTS_PKTSTS_CH_HALTED: ++ /* Handled in interrupt, just ignore data */ ++ break; ++ default: ++ DWC_ERROR("RX_STS_Q Interrupt: Unknown status %d\n", ++ grxsts.b.pktsts); ++ break; ++ } ++ ++ return 1; ++} ++ ++/** This interrupt occurs when the non-periodic Tx FIFO is half-empty. More ++ * data packets may be written to the FIFO for OUT transfers. More requests ++ * may be written to the non-periodic request queue for IN transfers. This ++ * interrupt is enabled only in Slave mode. */ ++int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n"); ++ dwc_otg_hcd_queue_transactions(dwc_otg_hcd, ++ DWC_OTG_TRANSACTION_NON_PERIODIC); ++ return 1; ++} ++ ++/** This interrupt occurs when the periodic Tx FIFO is half-empty. More data ++ * packets may be written to the FIFO for OUT transfers. More requests may be ++ * written to the periodic request queue for IN transfers. This interrupt is ++ * enabled only in Slave mode. */ ++int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n"); ++ dwc_otg_hcd_queue_transactions(dwc_otg_hcd, ++ DWC_OTG_TRANSACTION_PERIODIC); ++ return 1; ++} ++ ++/** There are multiple conditions that can cause a port interrupt. This function ++ * determines which interrupt conditions have occurred and handles them ++ * appropriately. */ ++int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ int retval = 0; ++ hprt0_data_t hprt0; ++ hprt0_data_t hprt0_modify; ++ ++ hprt0.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0); ++ hprt0_modify.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0); ++ ++ /* Clear appropriate bits in HPRT0 to clear the interrupt bit in ++ * GINTSTS */ ++ ++ hprt0_modify.b.prtena = 0; ++ hprt0_modify.b.prtconndet = 0; ++ hprt0_modify.b.prtenchng = 0; ++ hprt0_modify.b.prtovrcurrchng = 0; ++ ++ /* Port Connect Detected ++ * Set flag and clear if detected */ ++ if (dwc_otg_hcd->core_if->hibernation_suspend == 1) { ++ // Dont modify port status if we are in hibernation state ++ hprt0_modify.b.prtconndet = 1; ++ hprt0_modify.b.prtenchng = 1; ++ DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32); ++ hprt0.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0); ++ return retval; ++ } ++ ++ if (hprt0.b.prtconndet) { ++ /** @todo - check if steps performed in 'else' block should be perfromed regardles adp */ ++ if (dwc_otg_hcd->core_if->adp_enable && ++ dwc_otg_hcd->core_if->adp.vbuson_timer_started == 1) { ++ DWC_PRINTF("PORT CONNECT DETECTED ----------------\n"); ++ DWC_TIMER_CANCEL(dwc_otg_hcd->core_if->adp.vbuson_timer); ++ dwc_otg_hcd->core_if->adp.vbuson_timer_started = 0; ++ /* TODO - check if this is required, as ++ * host initialization was already performed ++ * after initial ADP probing ++ */ ++ /*dwc_otg_hcd->core_if->adp.vbuson_timer_started = 0; ++ dwc_otg_core_init(dwc_otg_hcd->core_if); ++ dwc_otg_enable_global_interrupts(dwc_otg_hcd->core_if); ++ cil_hcd_start(dwc_otg_hcd->core_if);*/ ++ } else { ++ ++ DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x " ++ "Port Connect Detected--\n", hprt0.d32); ++ dwc_otg_hcd->flags.b.port_connect_status_change = 1; ++ dwc_otg_hcd->flags.b.port_connect_status = 1; ++ hprt0_modify.b.prtconndet = 1; ++ ++ /* B-Device has connected, Delete the connection timer. */ ++ DWC_TIMER_CANCEL(dwc_otg_hcd->conn_timer); ++ } ++ /* The Hub driver asserts a reset when it sees port connect ++ * status change flag */ ++ retval |= 1; ++ } ++ ++ /* Port Enable Changed ++ * Clear if detected - Set internal flag if disabled */ ++ if (hprt0.b.prtenchng) { ++ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x " ++ "Port Enable Changed--\n", hprt0.d32); ++ hprt0_modify.b.prtenchng = 1; ++ if (hprt0.b.prtena == 1) { ++ hfir_data_t hfir; ++ int do_reset = 0; ++ dwc_otg_core_params_t *params = ++ dwc_otg_hcd->core_if->core_params; ++ dwc_otg_core_global_regs_t *global_regs = ++ dwc_otg_hcd->core_if->core_global_regs; ++ dwc_otg_host_if_t *host_if = ++ dwc_otg_hcd->core_if->host_if; ++ ++ /* Every time when port enables calculate ++ * HFIR.FrInterval ++ */ ++ hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir); ++ hfir.b.frint = calc_frame_interval(dwc_otg_hcd->core_if); ++ DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32); ++ ++ /* Check if we need to adjust the PHY clock speed for ++ * low power and adjust it */ ++ if (params->host_support_fs_ls_low_power) { ++ gusbcfg_data_t usbcfg; ++ ++ usbcfg.d32 = ++ DWC_READ_REG32(&global_regs->gusbcfg); ++ ++ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED ++ || hprt0.b.prtspd == ++ DWC_HPRT0_PRTSPD_FULL_SPEED) { ++ /* ++ * Low power ++ */ ++ hcfg_data_t hcfg; ++ if (usbcfg.b.phylpwrclksel == 0) { ++ /* Set PHY low power clock select for FS/LS devices */ ++ usbcfg.b.phylpwrclksel = 1; ++ DWC_WRITE_REG32 ++ (&global_regs->gusbcfg, ++ usbcfg.d32); ++ do_reset = 1; ++ } ++ ++ hcfg.d32 = ++ DWC_READ_REG32 ++ (&host_if->host_global_regs->hcfg); ++ ++ if (hprt0.b.prtspd == ++ DWC_HPRT0_PRTSPD_LOW_SPEED ++ && params->host_ls_low_power_phy_clk ++ == ++ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ) ++ { ++ /* 6 MHZ */ ++ DWC_DEBUGPL(DBG_CIL, ++ "FS_PHY programming HCFG to 6 MHz (Low Power)\n"); ++ if (hcfg.b.fslspclksel != ++ DWC_HCFG_6_MHZ) { ++ hcfg.b.fslspclksel = ++ DWC_HCFG_6_MHZ; ++ DWC_WRITE_REG32 ++ (&host_if->host_global_regs->hcfg, ++ hcfg.d32); ++ do_reset = 1; ++ } ++ } else { ++ /* 48 MHZ */ ++ DWC_DEBUGPL(DBG_CIL, ++ "FS_PHY programming HCFG to 48 MHz ()\n"); ++ if (hcfg.b.fslspclksel != ++ DWC_HCFG_48_MHZ) { ++ hcfg.b.fslspclksel = ++ DWC_HCFG_48_MHZ; ++ DWC_WRITE_REG32 ++ (&host_if->host_global_regs->hcfg, ++ hcfg.d32); ++ do_reset = 1; ++ } ++ } ++ } else { ++ /* ++ * Not low power ++ */ ++ if (usbcfg.b.phylpwrclksel == 1) { ++ usbcfg.b.phylpwrclksel = 0; ++ DWC_WRITE_REG32 ++ (&global_regs->gusbcfg, ++ usbcfg.d32); ++ do_reset = 1; ++ } ++ } ++ ++ if (do_reset) { ++ DWC_TASK_SCHEDULE(dwc_otg_hcd->reset_tasklet); ++ } ++ } ++ ++ if (!do_reset) { ++ /* Port has been enabled set the reset change flag */ ++ dwc_otg_hcd->flags.b.port_reset_change = 1; ++ } ++ } else { ++ dwc_otg_hcd->flags.b.port_enable_change = 1; ++ } ++ retval |= 1; ++ } ++ ++ /** Overcurrent Change Interrupt */ ++ if (hprt0.b.prtovrcurrchng) { ++ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x " ++ "Port Overcurrent Changed--\n", hprt0.d32); ++ dwc_otg_hcd->flags.b.port_over_current_change = 1; ++ hprt0_modify.b.prtovrcurrchng = 1; ++ retval |= 1; ++ } ++ ++ /* Clear Port Interrupts */ ++ DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32); ++ ++ return retval; ++} ++ ++/** This interrupt indicates that one or more host channels has a pending ++ * interrupt. There are multiple conditions that can cause each host channel ++ * interrupt. This function determines which conditions have occurred for each ++ * host channel interrupt and handles them appropriately. */ ++int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ int i; ++ int retval = 0; ++ haint_data_t haint; ++ ++ /* Clear appropriate bits in HCINTn to clear the interrupt bit in ++ * GINTSTS */ ++ ++ haint.d32 = dwc_otg_read_host_all_channels_intr(dwc_otg_hcd->core_if); ++ ++ for (i = 0; i < dwc_otg_hcd->core_if->core_params->host_channels; i++) { ++ if (haint.b2.chint & (1 << i)) { ++ retval |= dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd, i); ++ } ++ } ++ ++ return retval; ++} ++ ++/** ++ * Gets the actual length of a transfer after the transfer halts. _halt_status ++ * holds the reason for the halt. ++ * ++ * For IN transfers where halt_status is DWC_OTG_HC_XFER_COMPLETE, ++ * *short_read is set to 1 upon return if less than the requested ++ * number of bytes were transferred. Otherwise, *short_read is set to 0 upon ++ * return. short_read may also be NULL on entry, in which case it remains ++ * unchanged. ++ */ ++static uint32_t get_actual_xfer_length(dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_halt_status_e halt_status, ++ int *short_read) ++{ ++ hctsiz_data_t hctsiz; ++ uint32_t length; ++ ++ if (short_read != NULL) { ++ *short_read = 0; ++ } ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ ++ if (halt_status == DWC_OTG_HC_XFER_COMPLETE) { ++ if (hc->ep_is_in) { ++ length = hc->xfer_len - hctsiz.b.xfersize; ++ if (short_read != NULL) { ++ *short_read = (hctsiz.b.xfersize != 0); ++ } ++ } else if (hc->qh->do_split) { ++ length = qtd->ssplit_out_xfer_count; ++ } else { ++ length = hc->xfer_len; ++ } ++ } else { ++ /* ++ * Must use the hctsiz.pktcnt field to determine how much data ++ * has been transferred. This field reflects the number of ++ * packets that have been transferred via the USB. This is ++ * always an integral number of packets if the transfer was ++ * halted before its normal completion. (Can't use the ++ * hctsiz.xfersize field because that reflects the number of ++ * bytes transferred via the AHB, not the USB). ++ */ ++ length = ++ (hc->start_pkt_count - hctsiz.b.pktcnt) * hc->max_packet; ++ } ++ ++ return length; ++} ++ ++/** ++ * Updates the state of the URB after a Transfer Complete interrupt on the ++ * host channel. Updates the actual_length field of the URB based on the ++ * number of bytes transferred via the host channel. Sets the URB status ++ * if the data transfer is finished. ++ * ++ * @return 1 if the data transfer specified by the URB is completely finished, ++ * 0 otherwise. ++ */ ++static int update_urb_state_xfer_comp(dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_hcd_urb_t * urb, ++ dwc_otg_qtd_t * qtd) ++{ ++ int xfer_done = 0; ++ int short_read = 0; ++ ++ int xfer_length; ++ ++ xfer_length = get_actual_xfer_length(hc, hc_regs, qtd, ++ DWC_OTG_HC_XFER_COMPLETE, ++ &short_read); ++ ++ ++ /* non DWORD-aligned buffer case handling. */ ++ if (hc->align_buff && xfer_length && hc->ep_is_in) { ++ dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, ++ xfer_length); ++ } ++ ++ urb->actual_length += xfer_length; ++ ++ if (xfer_length && (hc->ep_type == DWC_OTG_EP_TYPE_BULK) && ++ (urb->flags & URB_SEND_ZERO_PACKET) ++ && (urb->actual_length == urb->length) ++ && !(urb->length % hc->max_packet)) { ++ xfer_done = 0; ++ } else if (short_read || urb->actual_length >= urb->length) { ++ xfer_done = 1; ++ urb->status = 0; ++ } ++ ++#ifdef DEBUG ++ { ++ hctsiz_data_t hctsiz; ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n", ++ __func__, (hc->ep_is_in ? "IN" : "OUT"), ++ hc->hc_num); ++ DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", hc->xfer_len); ++ DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", ++ hctsiz.b.xfersize); ++ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n", ++ urb->length); ++ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", ++ urb->actual_length); ++ DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n", ++ short_read, xfer_done); ++ } ++#endif ++ ++ return xfer_done; ++} ++ ++/* ++ * Save the starting data toggle for the next transfer. The data toggle is ++ * saved in the QH for non-control transfers and it's saved in the QTD for ++ * control transfers. ++ */ ++void dwc_otg_hcd_save_data_toggle(dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, dwc_otg_qtd_t * qtd) ++{ ++ hctsiz_data_t hctsiz; ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ ++ if (hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) { ++ dwc_otg_qh_t *qh = hc->qh; ++ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) { ++ qh->data_toggle = DWC_OTG_HC_PID_DATA0; ++ } else { ++ qh->data_toggle = DWC_OTG_HC_PID_DATA1; ++ } ++ } else { ++ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) { ++ qtd->data_toggle = DWC_OTG_HC_PID_DATA0; ++ } else { ++ qtd->data_toggle = DWC_OTG_HC_PID_DATA1; ++ } ++ } ++} ++ ++/** ++ * Updates the state of an Isochronous URB when the transfer is stopped for ++ * any reason. The fields of the current entry in the frame descriptor array ++ * are set based on the transfer state and the input _halt_status. Completes ++ * the Isochronous URB if all the URB frames have been completed. ++ * ++ * @return DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be ++ * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE. ++ */ ++static dwc_otg_halt_status_e ++update_isoc_urb_state(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd, dwc_otg_halt_status_e halt_status) ++{ ++ dwc_otg_hcd_urb_t *urb = qtd->urb; ++ dwc_otg_halt_status_e ret_val = halt_status; ++ struct dwc_otg_hcd_iso_packet_desc *frame_desc; ++ ++ frame_desc = &urb->iso_descs[qtd->isoc_frame_index]; ++ switch (halt_status) { ++ case DWC_OTG_HC_XFER_COMPLETE: ++ frame_desc->status = 0; ++ frame_desc->actual_length = ++ get_actual_xfer_length(hc, hc_regs, qtd, halt_status, NULL); ++ ++ /* non DWORD-aligned buffer case handling. */ ++ if (hc->align_buff && frame_desc->actual_length && hc->ep_is_in) { ++ dwc_memcpy(urb->buf + frame_desc->offset + qtd->isoc_split_offset, ++ hc->qh->dw_align_buf, frame_desc->actual_length); ++ } ++ ++ break; ++ case DWC_OTG_HC_XFER_FRAME_OVERRUN: ++ urb->error_count++; ++ if (hc->ep_is_in) { ++ frame_desc->status = -DWC_E_NO_STREAM_RES; ++ } else { ++ frame_desc->status = -DWC_E_COMMUNICATION; ++ } ++ frame_desc->actual_length = 0; ++ break; ++ case DWC_OTG_HC_XFER_BABBLE_ERR: ++ urb->error_count++; ++ frame_desc->status = -DWC_E_OVERFLOW; ++ /* Don't need to update actual_length in this case. */ ++ break; ++ case DWC_OTG_HC_XFER_XACT_ERR: ++ urb->error_count++; ++ frame_desc->status = -DWC_E_PROTOCOL; ++ frame_desc->actual_length = ++ get_actual_xfer_length(hc, hc_regs, qtd, halt_status, NULL); ++ ++ /* non DWORD-aligned buffer case handling. */ ++ if (hc->align_buff && frame_desc->actual_length && hc->ep_is_in) { ++ dwc_memcpy(urb->buf + frame_desc->offset + qtd->isoc_split_offset, ++ hc->qh->dw_align_buf, frame_desc->actual_length); ++ } ++ /* Skip whole frame */ ++ if (hc->qh->do_split && (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && ++ hc->ep_is_in && hcd->core_if->dma_enable) { ++ qtd->complete_split = 0; ++ qtd->isoc_split_offset = 0; ++ } ++ ++ break; ++ default: ++ DWC_ASSERT(1, "Unhandled _halt_status (%d)\n", halt_status); ++ break; ++ } ++ if (++qtd->isoc_frame_index == urb->packet_count) { ++ /* ++ * urb->status is not used for isoc transfers. ++ * The individual frame_desc statuses are used instead. ++ */ ++ hcd->fops->complete(hcd, urb->priv, urb, 0); ++ ret_val = DWC_OTG_HC_XFER_URB_COMPLETE; ++ } else { ++ ret_val = DWC_OTG_HC_XFER_COMPLETE; ++ } ++ return ret_val; ++} ++ ++/** ++ * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic ++ * QHs, removes the QH from the active non-periodic schedule. If any QTDs are ++ * still linked to the QH, the QH is added to the end of the inactive ++ * non-periodic schedule. For periodic QHs, removes the QH from the periodic ++ * schedule if no more QTDs are linked to the QH. ++ */ ++static void deactivate_qh(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, int free_qtd) ++{ ++ int continue_split = 0; ++ dwc_otg_qtd_t *qtd; ++ ++ DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, hcd, qh, free_qtd); ++ ++ qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list); ++ ++ if (qtd->complete_split) { ++ continue_split = 1; ++ } else if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID || ++ qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END) { ++ continue_split = 1; ++ } ++ ++ if (free_qtd) { ++ dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh); ++ continue_split = 0; ++ } ++ ++ qh->channel = NULL; ++ dwc_otg_hcd_qh_deactivate(hcd, qh, continue_split); ++} ++ ++/** ++ * Releases a host channel for use by other transfers. Attempts to select and ++ * queue more transactions since at least one host channel is available. ++ * ++ * @param hcd The HCD state structure. ++ * @param hc The host channel to release. ++ * @param qtd The QTD associated with the host channel. This QTD may be freed ++ * if the transfer is complete or an error has occurred. ++ * @param halt_status Reason the channel is being released. This status ++ * determines the actions taken by this function. ++ */ ++static void release_channel(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_halt_status_e halt_status) ++{ ++ dwc_otg_transaction_type_e tr_type; ++ int free_qtd; ++ dwc_irqflags_t flags; ++ dwc_spinlock_t *channel_lock = DWC_SPINLOCK_ALLOC(); ++ ++ DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d, xfer_len %d\n", ++ __func__, hc->hc_num, halt_status, hc->xfer_len); ++ ++ switch (halt_status) { ++ case DWC_OTG_HC_XFER_URB_COMPLETE: ++ free_qtd = 1; ++ break; ++ case DWC_OTG_HC_XFER_AHB_ERR: ++ case DWC_OTG_HC_XFER_STALL: ++ case DWC_OTG_HC_XFER_BABBLE_ERR: ++ free_qtd = 1; ++ break; ++ case DWC_OTG_HC_XFER_XACT_ERR: ++ if (qtd->error_count >= 3) { ++ DWC_DEBUGPL(DBG_HCDV, ++ " Complete URB with transaction error\n"); ++ free_qtd = 1; ++ qtd->urb->status = -DWC_E_PROTOCOL; ++ hcd->fops->complete(hcd, qtd->urb->priv, ++ qtd->urb, -DWC_E_PROTOCOL); ++ } else { ++ free_qtd = 0; ++ } ++ break; ++ case DWC_OTG_HC_XFER_URB_DEQUEUE: ++ /* ++ * The QTD has already been removed and the QH has been ++ * deactivated. Don't want to do anything except release the ++ * host channel and try to queue more transfers. ++ */ ++ goto cleanup; ++ case DWC_OTG_HC_XFER_NO_HALT_STATUS: ++ free_qtd = 0; ++ break; ++ case DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE: ++ DWC_DEBUGPL(DBG_HCDV, ++ " Complete URB with I/O error\n"); ++ free_qtd = 1; ++ qtd->urb->status = -DWC_E_IO; ++ hcd->fops->complete(hcd, qtd->urb->priv, ++ qtd->urb, -DWC_E_IO); ++ break; ++ default: ++ free_qtd = 0; ++ break; ++ } ++ ++ deactivate_qh(hcd, hc->qh, free_qtd); ++ ++cleanup: ++ /* ++ * Release the host channel for use by other transfers. The cleanup ++ * function clears the channel interrupt enables and conditions, so ++ * there's no need to clear the Channel Halted interrupt separately. ++ */ ++ dwc_otg_hc_cleanup(hcd->core_if, hc); ++ DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry); ++ ++ if (!microframe_schedule) { ++ switch (hc->ep_type) { ++ case DWC_OTG_EP_TYPE_CONTROL: ++ case DWC_OTG_EP_TYPE_BULK: ++ hcd->non_periodic_channels--; ++ break; ++ ++ default: ++ /* ++ * Don't release reservations for periodic channels here. ++ * That's done when a periodic transfer is descheduled (i.e. ++ * when the QH is removed from the periodic schedule). ++ */ ++ break; ++ } ++ } else { ++ ++ DWC_SPINLOCK_IRQSAVE(channel_lock, &flags); ++ hcd->available_host_channels++; ++ DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags); ++ } ++ ++ /* Try to queue more transfers now that there's a free channel. */ ++ tr_type = dwc_otg_hcd_select_transactions(hcd); ++ if (tr_type != DWC_OTG_TRANSACTION_NONE) { ++ dwc_otg_hcd_queue_transactions(hcd, tr_type); ++ } ++ DWC_SPINLOCK_FREE(channel_lock); ++} ++ ++/** ++ * Halts a host channel. If the channel cannot be halted immediately because ++ * the request queue is full, this function ensures that the FIFO empty ++ * interrupt for the appropriate queue is enabled so that the halt request can ++ * be queued when there is space in the request queue. ++ * ++ * This function may also be called in DMA mode. In that case, the channel is ++ * simply released since the core always halts the channel automatically in ++ * DMA mode. ++ */ ++static void halt_channel(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_qtd_t * qtd, dwc_otg_halt_status_e halt_status) ++{ ++ if (hcd->core_if->dma_enable) { ++ release_channel(hcd, hc, qtd, halt_status); ++ return; ++ } ++ ++ /* Slave mode processing... */ ++ dwc_otg_hc_halt(hcd->core_if, hc, halt_status); ++ ++ if (hc->halt_on_queue) { ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ dwc_otg_core_global_regs_t *global_regs; ++ global_regs = hcd->core_if->core_global_regs; ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL || ++ hc->ep_type == DWC_OTG_EP_TYPE_BULK) { ++ /* ++ * Make sure the Non-periodic Tx FIFO empty interrupt ++ * is enabled so that the non-periodic schedule will ++ * be processed. ++ */ ++ gintmsk.b.nptxfempty = 1; ++ DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmsk.d32); ++ } else { ++ /* ++ * Move the QH from the periodic queued schedule to ++ * the periodic assigned schedule. This allows the ++ * halt to be queued when the periodic schedule is ++ * processed. ++ */ ++ DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned, ++ &hc->qh->qh_list_entry); ++ ++ /* ++ * Make sure the Periodic Tx FIFO Empty interrupt is ++ * enabled so that the periodic schedule will be ++ * processed. ++ */ ++ gintmsk.b.ptxfempty = 1; ++ DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmsk.d32); ++ } ++ } ++} ++ ++/** ++ * Performs common cleanup for non-periodic transfers after a Transfer ++ * Complete interrupt. This function should be called after any endpoint type ++ * specific handling is finished to release the host channel. ++ */ ++static void complete_non_periodic_xfer(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_halt_status_e halt_status) ++{ ++ hcint_data_t hcint; ++ ++ qtd->error_count = 0; ++ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ if (hcint.b.nyet) { ++ /* ++ * Got a NYET on the last transaction of the transfer. This ++ * means that the endpoint should be in the PING state at the ++ * beginning of the next transfer. ++ */ ++ hc->qh->ping_state = 1; ++ clear_hc_int(hc_regs, nyet); ++ } ++ ++ /* ++ * Always halt and release the host channel to make it available for ++ * more transfers. There may still be more phases for a control ++ * transfer or more data packets for a bulk transfer at this point, ++ * but the host channel is still halted. A channel will be reassigned ++ * to the transfer when the non-periodic schedule is processed after ++ * the channel is released. This allows transactions to be queued ++ * properly via dwc_otg_hcd_queue_transactions, which also enables the ++ * Tx FIFO Empty interrupt if necessary. ++ */ ++ if (hc->ep_is_in) { ++ /* ++ * IN transfers in Slave mode require an explicit disable to ++ * halt the channel. (In DMA mode, this call simply releases ++ * the channel.) ++ */ ++ halt_channel(hcd, hc, qtd, halt_status); ++ } else { ++ /* ++ * The channel is automatically disabled by the core for OUT ++ * transfers in Slave mode. ++ */ ++ release_channel(hcd, hc, qtd, halt_status); ++ } ++} ++ ++/** ++ * Performs common cleanup for periodic transfers after a Transfer Complete ++ * interrupt. This function should be called after any endpoint type specific ++ * handling is finished to release the host channel. ++ */ ++static void complete_periodic_xfer(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_halt_status_e halt_status) ++{ ++ hctsiz_data_t hctsiz; ++ qtd->error_count = 0; ++ ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ if (!hc->ep_is_in || hctsiz.b.pktcnt == 0) { ++ /* Core halts channel in these cases. */ ++ release_channel(hcd, hc, qtd, halt_status); ++ } else { ++ /* Flush any outstanding requests from the Tx queue. */ ++ halt_channel(hcd, hc, qtd, halt_status); ++ } ++} ++ ++static int32_t handle_xfercomp_isoc_split_in(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ uint32_t len; ++ struct dwc_otg_hcd_iso_packet_desc *frame_desc; ++ frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index]; ++ ++ len = get_actual_xfer_length(hc, hc_regs, qtd, ++ DWC_OTG_HC_XFER_COMPLETE, NULL); ++ ++ if (!len) { ++ qtd->complete_split = 0; ++ qtd->isoc_split_offset = 0; ++ return 0; ++ } ++ frame_desc->actual_length += len; ++ ++ if (hc->align_buff && len) ++ dwc_memcpy(qtd->urb->buf + frame_desc->offset + ++ qtd->isoc_split_offset, hc->qh->dw_align_buf, len); ++ qtd->isoc_split_offset += len; ++ ++ if (frame_desc->length == frame_desc->actual_length) { ++ frame_desc->status = 0; ++ qtd->isoc_frame_index++; ++ qtd->complete_split = 0; ++ qtd->isoc_split_offset = 0; ++ } ++ ++ if (qtd->isoc_frame_index == qtd->urb->packet_count) { ++ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0); ++ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); ++ } else { ++ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NO_HALT_STATUS); ++ } ++ ++ return 1; /* Indicates that channel released */ ++} ++ ++/** ++ * Handles a host channel Transfer Complete interrupt. This handler may be ++ * called in either DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_xfercomp_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ int urb_xfer_done; ++ dwc_otg_halt_status_e halt_status = DWC_OTG_HC_XFER_COMPLETE; ++ dwc_otg_hcd_urb_t *urb = qtd->urb; ++ int pipe_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info); ++ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "Transfer Complete--\n", hc->hc_num); ++ ++ if (hcd->core_if->dma_desc_enable) { ++ dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, halt_status); ++ if (pipe_type == UE_ISOCHRONOUS) { ++ /* Do not disable the interrupt, just clear it */ ++ clear_hc_int(hc_regs, xfercomp); ++ return 1; ++ } ++ goto handle_xfercomp_done; ++ } ++ ++ /* ++ * Handle xfer complete on CSPLIT. ++ */ ++ ++ if (hc->qh->do_split) { ++ if ((hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && hc->ep_is_in ++ && hcd->core_if->dma_enable) { ++ if (qtd->complete_split ++ && handle_xfercomp_isoc_split_in(hcd, hc, hc_regs, ++ qtd)) ++ goto handle_xfercomp_done; ++ } else { ++ qtd->complete_split = 0; ++ } ++ } ++ ++ /* Update the QTD and URB states. */ ++ switch (pipe_type) { ++ case UE_CONTROL: ++ switch (qtd->control_phase) { ++ case DWC_OTG_CONTROL_SETUP: ++ if (urb->length > 0) { ++ qtd->control_phase = DWC_OTG_CONTROL_DATA; ++ } else { ++ qtd->control_phase = DWC_OTG_CONTROL_STATUS; ++ } ++ DWC_DEBUGPL(DBG_HCDV, ++ " Control setup transaction done\n"); ++ halt_status = DWC_OTG_HC_XFER_COMPLETE; ++ break; ++ case DWC_OTG_CONTROL_DATA:{ ++ urb_xfer_done = ++ update_urb_state_xfer_comp(hc, hc_regs, urb, ++ qtd); ++ if (urb_xfer_done) { ++ qtd->control_phase = ++ DWC_OTG_CONTROL_STATUS; ++ DWC_DEBUGPL(DBG_HCDV, ++ " Control data transfer done\n"); ++ } else { ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ } ++ halt_status = DWC_OTG_HC_XFER_COMPLETE; ++ break; ++ } ++ case DWC_OTG_CONTROL_STATUS: ++ DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n"); ++ if (urb->status == -DWC_E_IN_PROGRESS) { ++ urb->status = 0; ++ } ++ hcd->fops->complete(hcd, urb->priv, urb, urb->status); ++ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE; ++ break; ++ } ++ ++ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status); ++ break; ++ case UE_BULK: ++ DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n"); ++ urb_xfer_done = ++ update_urb_state_xfer_comp(hc, hc_regs, urb, qtd); ++ if (urb_xfer_done) { ++ hcd->fops->complete(hcd, urb->priv, urb, urb->status); ++ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE; ++ } else { ++ halt_status = DWC_OTG_HC_XFER_COMPLETE; ++ } ++ ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status); ++ break; ++ case UE_INTERRUPT: ++ DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n"); ++ urb_xfer_done = ++ update_urb_state_xfer_comp(hc, hc_regs, urb, qtd); ++ ++ /* ++ * Interrupt URB is done on the first transfer complete ++ * interrupt. ++ */ ++ if (urb_xfer_done) { ++ hcd->fops->complete(hcd, urb->priv, urb, urb->status); ++ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE; ++ } else { ++ halt_status = DWC_OTG_HC_XFER_COMPLETE; ++ } ++ ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status); ++ break; ++ case UE_ISOCHRONOUS: ++ DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n"); ++ if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL) { ++ halt_status = ++ update_isoc_urb_state(hcd, hc, hc_regs, qtd, ++ DWC_OTG_HC_XFER_COMPLETE); ++ } ++ complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status); ++ break; ++ } ++ ++handle_xfercomp_done: ++ disable_hc_int(hc_regs, xfercompl); ++ ++ return 1; ++} ++ ++/** ++ * Handles a host channel STALL interrupt. This handler may be called in ++ * either DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_stall_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ dwc_otg_hcd_urb_t *urb = qtd->urb; ++ int pipe_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info); ++ ++ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " ++ "STALL Received--\n", hc->hc_num); ++ ++ if (hcd->core_if->dma_desc_enable) { ++ dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, DWC_OTG_HC_XFER_STALL); ++ goto handle_stall_done; ++ } ++ ++ if (pipe_type == UE_CONTROL) { ++ hcd->fops->complete(hcd, urb->priv, urb, -DWC_E_PIPE); ++ } ++ ++ if (pipe_type == UE_BULK || pipe_type == UE_INTERRUPT) { ++ hcd->fops->complete(hcd, urb->priv, urb, -DWC_E_PIPE); ++ /* ++ * USB protocol requires resetting the data toggle for bulk ++ * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT) ++ * setup command is issued to the endpoint. Anticipate the ++ * CLEAR_FEATURE command since a STALL has occurred and reset ++ * the data toggle now. ++ */ ++ hc->qh->data_toggle = 0; ++ } ++ ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_STALL); ++ ++handle_stall_done: ++ disable_hc_int(hc_regs, stall); ++ ++ return 1; ++} ++ ++/* ++ * Updates the state of the URB when a transfer has been stopped due to an ++ * abnormal condition before the transfer completes. Modifies the ++ * actual_length field of the URB to reflect the number of bytes that have ++ * actually been transferred via the host channel. ++ */ ++static void update_urb_state_xfer_intr(dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_hcd_urb_t * urb, ++ dwc_otg_qtd_t * qtd, ++ dwc_otg_halt_status_e halt_status) ++{ ++ uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd, ++ halt_status, NULL); ++ /* non DWORD-aligned buffer case handling. */ ++ if (hc->align_buff && bytes_transferred && hc->ep_is_in) { ++ dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, ++ bytes_transferred); ++ } ++ ++ urb->actual_length += bytes_transferred; ++ ++#ifdef DEBUG ++ { ++ hctsiz_data_t hctsiz; ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n", ++ __func__, (hc->ep_is_in ? "IN" : "OUT"), ++ hc->hc_num); ++ DWC_DEBUGPL(DBG_HCDV, " hc->start_pkt_count %d\n", ++ hc->start_pkt_count); ++ DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt); ++ DWC_DEBUGPL(DBG_HCDV, " hc->max_packet %d\n", hc->max_packet); ++ DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n", ++ bytes_transferred); ++ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", ++ urb->actual_length); ++ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n", ++ urb->length); ++ } ++#endif ++} ++ ++/** ++ * Handles a host channel NAK interrupt. This handler may be called in either ++ * DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_nak_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "NAK Received--\n", hc->hc_num); ++ ++ /* ++ * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and ++ * interrupt. Re-start the SSPLIT transfer. ++ */ ++ if (hc->do_split) { ++ if (hc->complete_split) { ++ qtd->error_count = 0; ++ } ++ qtd->complete_split = 0; ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK); ++ goto handle_nak_done; ++ } ++ ++ switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) { ++ case UE_CONTROL: ++ case UE_BULK: ++ if (hcd->core_if->dma_enable && hc->ep_is_in) { ++ /* ++ * NAK interrupts are enabled on bulk/control IN ++ * transfers in DMA mode for the sole purpose of ++ * resetting the error count after a transaction error ++ * occurs. The core will continue transferring data. ++ */ ++ qtd->error_count = 0; ++ goto handle_nak_done; ++ } ++ ++ /* ++ * NAK interrupts normally occur during OUT transfers in DMA ++ * or Slave mode. For IN transfers, more requests will be ++ * queued as request queue space is available. ++ */ ++ qtd->error_count = 0; ++ ++ if (!hc->qh->ping_state) { ++ update_urb_state_xfer_intr(hc, hc_regs, ++ qtd->urb, qtd, ++ DWC_OTG_HC_XFER_NAK); ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ ++ if (hc->speed == DWC_OTG_EP_SPEED_HIGH) ++ hc->qh->ping_state = 1; ++ } ++ ++ /* ++ * Halt the channel so the transfer can be re-started from ++ * the appropriate point or the PING protocol will ++ * start/continue. ++ */ ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK); ++ break; ++ case UE_INTERRUPT: ++ qtd->error_count = 0; ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK); ++ break; ++ case UE_ISOCHRONOUS: ++ /* Should never get called for isochronous transfers. */ ++ DWC_ASSERT(1, "NACK interrupt for ISOC transfer\n"); ++ break; ++ } ++ ++handle_nak_done: ++ disable_hc_int(hc_regs, nak); ++ ++ return 1; ++} ++ ++/** ++ * Handles a host channel ACK interrupt. This interrupt is enabled when ++ * performing the PING protocol in Slave mode, when errors occur during ++ * either Slave mode or DMA mode, and during Start Split transactions. ++ */ ++static int32_t handle_hc_ack_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "ACK Received--\n", hc->hc_num); ++ ++ if (hc->do_split) { ++ /* ++ * Handle ACK on SSPLIT. ++ * ACK should not occur in CSPLIT. ++ */ ++ if (!hc->ep_is_in && hc->data_pid_start != DWC_OTG_HC_PID_SETUP) { ++ qtd->ssplit_out_xfer_count = hc->xfer_len; ++ } ++ if (!(hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in)) { ++ /* Don't need complete for isochronous out transfers. */ ++ qtd->complete_split = 1; ++ } ++ ++ /* ISOC OUT */ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) { ++ switch (hc->xact_pos) { ++ case DWC_HCSPLIT_XACTPOS_ALL: ++ break; ++ case DWC_HCSPLIT_XACTPOS_END: ++ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL; ++ qtd->isoc_split_offset = 0; ++ break; ++ case DWC_HCSPLIT_XACTPOS_BEGIN: ++ case DWC_HCSPLIT_XACTPOS_MID: ++ /* ++ * For BEGIN or MID, calculate the length for ++ * the next microframe to determine the correct ++ * SSPLIT token, either MID or END. ++ */ ++ { ++ struct dwc_otg_hcd_iso_packet_desc ++ *frame_desc; ++ ++ frame_desc = ++ &qtd->urb-> ++ iso_descs[qtd->isoc_frame_index]; ++ qtd->isoc_split_offset += 188; ++ ++ if ((frame_desc->length - ++ qtd->isoc_split_offset) <= 188) { ++ qtd->isoc_split_pos = ++ DWC_HCSPLIT_XACTPOS_END; ++ } else { ++ qtd->isoc_split_pos = ++ DWC_HCSPLIT_XACTPOS_MID; ++ } ++ ++ } ++ break; ++ } ++ } else { ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK); ++ } ++ } else { ++ qtd->error_count = 0; ++ ++ if (hc->qh->ping_state) { ++ hc->qh->ping_state = 0; ++ /* ++ * Halt the channel so the transfer can be re-started ++ * from the appropriate point. This only happens in ++ * Slave mode. In DMA mode, the ping_state is cleared ++ * when the transfer is started because the core ++ * automatically executes the PING, then the transfer. ++ */ ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK); ++ } ++ } ++ ++ /* ++ * If the ACK occurred when _not_ in the PING state, let the channel ++ * continue transferring data after clearing the error count. ++ */ ++ ++ disable_hc_int(hc_regs, ack); ++ ++ return 1; ++} ++ ++/** ++ * Handles a host channel NYET interrupt. This interrupt should only occur on ++ * Bulk and Control OUT endpoints and for complete split transactions. If a ++ * NYET occurs at the same time as a Transfer Complete interrupt, it is ++ * handled in the xfercomp interrupt handler, not here. This handler may be ++ * called in either DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_nyet_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "NYET Received--\n", hc->hc_num); ++ ++ /* ++ * NYET on CSPLIT ++ * re-do the CSPLIT immediately on non-periodic ++ */ ++ if (hc->do_split && hc->complete_split) { ++ if (hc->ep_is_in && (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) ++ && hcd->core_if->dma_enable) { ++ qtd->complete_split = 0; ++ qtd->isoc_split_offset = 0; ++ if (++qtd->isoc_frame_index == qtd->urb->packet_count) { ++ hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0); ++ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE); ++ } ++ else ++ release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NO_HALT_STATUS); ++ goto handle_nyet_done; ++ } ++ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || ++ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ int frnum = dwc_otg_hcd_get_frame_number(hcd); ++ ++ if (dwc_full_frame_num(frnum) != ++ dwc_full_frame_num(hc->qh->sched_frame)) { ++ /* ++ * No longer in the same full speed frame. ++ * Treat this as a transaction error. ++ */ ++#if 0 ++ /** @todo Fix system performance so this can ++ * be treated as an error. Right now complete ++ * splits cannot be scheduled precisely enough ++ * due to other system activity, so this error ++ * occurs regularly in Slave mode. ++ */ ++ qtd->error_count++; ++#endif ++ qtd->complete_split = 0; ++ halt_channel(hcd, hc, qtd, ++ DWC_OTG_HC_XFER_XACT_ERR); ++ /** @todo add support for isoc release */ ++ goto handle_nyet_done; ++ } ++ } ++ ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET); ++ goto handle_nyet_done; ++ } ++ ++ hc->qh->ping_state = 1; ++ qtd->error_count = 0; ++ ++ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, qtd, ++ DWC_OTG_HC_XFER_NYET); ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ ++ /* ++ * Halt the channel and re-start the transfer so the PING ++ * protocol will start. ++ */ ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET); ++ ++handle_nyet_done: ++ disable_hc_int(hc_regs, nyet); ++ return 1; ++} ++ ++/** ++ * Handles a host channel babble interrupt. This handler may be called in ++ * either DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_babble_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "Babble Error--\n", hc->hc_num); ++ ++ if (hcd->core_if->dma_desc_enable) { ++ dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, ++ DWC_OTG_HC_XFER_BABBLE_ERR); ++ goto handle_babble_done; ++ } ++ ++ if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) { ++ hcd->fops->complete(hcd, qtd->urb->priv, ++ qtd->urb, -DWC_E_OVERFLOW); ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_BABBLE_ERR); ++ } else { ++ dwc_otg_halt_status_e halt_status; ++ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd, ++ DWC_OTG_HC_XFER_BABBLE_ERR); ++ halt_channel(hcd, hc, qtd, halt_status); ++ } ++ ++handle_babble_done: ++ disable_hc_int(hc_regs, bblerr); ++ return 1; ++} ++ ++/** ++ * Handles a host channel AHB error interrupt. This handler is only called in ++ * DMA mode. ++ */ ++static int32_t handle_hc_ahberr_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ hcchar_data_t hcchar; ++ hcsplt_data_t hcsplt; ++ hctsiz_data_t hctsiz; ++ uint32_t hcdma; ++ char *pipetype, *speed; ++ ++ dwc_otg_hcd_urb_t *urb = qtd->urb; ++ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "AHB Error--\n", hc->hc_num); ++ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt); ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ hcdma = DWC_READ_REG32(&hc_regs->hcdma); ++ ++ DWC_ERROR("AHB ERROR, Channel %d\n", hc->hc_num); ++ DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32); ++ DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma); ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n"); ++ DWC_ERROR(" Device address: %d\n", ++ dwc_otg_hcd_get_dev_addr(&urb->pipe_info)); ++ DWC_ERROR(" Endpoint: %d, %s\n", ++ dwc_otg_hcd_get_ep_num(&urb->pipe_info), ++ (dwc_otg_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT")); ++ ++ switch (dwc_otg_hcd_get_pipe_type(&urb->pipe_info)) { ++ case UE_CONTROL: ++ pipetype = "CONTROL"; ++ break; ++ case UE_BULK: ++ pipetype = "BULK"; ++ break; ++ case UE_INTERRUPT: ++ pipetype = "INTERRUPT"; ++ break; ++ case UE_ISOCHRONOUS: ++ pipetype = "ISOCHRONOUS"; ++ break; ++ default: ++ pipetype = "UNKNOWN"; ++ break; ++ } ++ ++ DWC_ERROR(" Endpoint type: %s\n", pipetype); ++ ++ switch (hc->speed) { ++ case DWC_OTG_EP_SPEED_HIGH: ++ speed = "HIGH"; ++ break; ++ case DWC_OTG_EP_SPEED_FULL: ++ speed = "FULL"; ++ break; ++ case DWC_OTG_EP_SPEED_LOW: ++ speed = "LOW"; ++ break; ++ default: ++ speed = "UNKNOWN"; ++ break; ++ }; ++ ++ DWC_ERROR(" Speed: %s\n", speed); ++ ++ DWC_ERROR(" Max packet size: %d\n", ++ dwc_otg_hcd_get_mps(&urb->pipe_info)); ++ DWC_ERROR(" Data buffer length: %d\n", urb->length); ++ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n", ++ urb->buf, (void *)urb->dma); ++ DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n", ++ urb->setup_packet, (void *)urb->setup_dma); ++ DWC_ERROR(" Interval: %d\n", urb->interval); ++ ++ /* Core haltes the channel for Descriptor DMA mode */ ++ if (hcd->core_if->dma_desc_enable) { ++ dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, ++ DWC_OTG_HC_XFER_AHB_ERR); ++ goto handle_ahberr_done; ++ } ++ ++ hcd->fops->complete(hcd, urb->priv, urb, -DWC_E_IO); ++ ++ /* ++ * Force a channel halt. Don't call halt_channel because that won't ++ * write to the HCCHARn register in DMA mode to force the halt. ++ */ ++ dwc_otg_hc_halt(hcd->core_if, hc, DWC_OTG_HC_XFER_AHB_ERR); ++handle_ahberr_done: ++ disable_hc_int(hc_regs, ahberr); ++ return 1; ++} ++ ++/** ++ * Handles a host channel transaction error interrupt. This handler may be ++ * called in either DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_xacterr_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "Transaction Error--\n", hc->hc_num); ++ ++ if (hcd->core_if->dma_desc_enable) { ++ dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, ++ DWC_OTG_HC_XFER_XACT_ERR); ++ goto handle_xacterr_done; ++ } ++ ++ switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) { ++ case UE_CONTROL: ++ case UE_BULK: ++ qtd->error_count++; ++ if (!hc->qh->ping_state) { ++ ++ update_urb_state_xfer_intr(hc, hc_regs, ++ qtd->urb, qtd, ++ DWC_OTG_HC_XFER_XACT_ERR); ++ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd); ++ if (!hc->ep_is_in && hc->speed == DWC_OTG_EP_SPEED_HIGH) { ++ hc->qh->ping_state = 1; ++ } ++ } ++ ++ /* ++ * Halt the channel so the transfer can be re-started from ++ * the appropriate point or the PING protocol will start. ++ */ ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR); ++ break; ++ case UE_INTERRUPT: ++ qtd->error_count++; ++ if (hc->do_split && hc->complete_split) { ++ qtd->complete_split = 0; ++ } ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR); ++ break; ++ case UE_ISOCHRONOUS: ++ { ++ dwc_otg_halt_status_e halt_status; ++ halt_status = ++ update_isoc_urb_state(hcd, hc, hc_regs, qtd, ++ DWC_OTG_HC_XFER_XACT_ERR); ++ ++ halt_channel(hcd, hc, qtd, halt_status); ++ } ++ break; ++ } ++handle_xacterr_done: ++ disable_hc_int(hc_regs, xacterr); ++ ++ return 1; ++} ++ ++/** ++ * Handles a host channel frame overrun interrupt. This handler may be called ++ * in either DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_frmovrun_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "Frame Overrun--\n", hc->hc_num); ++ ++ switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) { ++ case UE_CONTROL: ++ case UE_BULK: ++ break; ++ case UE_INTERRUPT: ++ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN); ++ break; ++ case UE_ISOCHRONOUS: ++ { ++ dwc_otg_halt_status_e halt_status; ++ halt_status = ++ update_isoc_urb_state(hcd, hc, hc_regs, qtd, ++ DWC_OTG_HC_XFER_FRAME_OVERRUN); ++ ++ halt_channel(hcd, hc, qtd, halt_status); ++ } ++ break; ++ } ++ ++ disable_hc_int(hc_regs, frmovrun); ++ ++ return 1; ++} ++ ++/** ++ * Handles a host channel data toggle error interrupt. This handler may be ++ * called in either DMA mode or Slave mode. ++ */ ++static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "Data Toggle Error--\n", hc->hc_num); ++ ++ if (hc->ep_is_in) { ++ qtd->error_count = 0; ++ } else { ++ DWC_ERROR("Data Toggle Error on OUT transfer," ++ "channel %d\n", hc->hc_num); ++ } ++ ++ disable_hc_int(hc_regs, datatglerr); ++ ++ return 1; ++} ++ ++#ifdef DEBUG ++/** ++ * This function is for debug only. It checks that a valid halt status is set ++ * and that HCCHARn.chdis is clear. If there's a problem, corrective action is ++ * taken and a warning is issued. ++ * @return 1 if halt status is ok, 0 otherwise. ++ */ ++static inline int halt_status_ok(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ hcchar_data_t hcchar; ++ hctsiz_data_t hctsiz; ++ hcint_data_t hcint; ++ hcintmsk_data_t hcintmsk; ++ hcsplt_data_t hcsplt; ++ ++ if (hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) { ++ /* ++ * This code is here only as a check. This condition should ++ * never happen. Ignore the halt if it does occur. ++ */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz); ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ hcintmsk.d32 = DWC_READ_REG32(&hc_regs->hcintmsk); ++ hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt); ++ DWC_WARN ++ ("%s: hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, " ++ "channel %d, hcchar 0x%08x, hctsiz 0x%08x, " ++ "hcint 0x%08x, hcintmsk 0x%08x, " ++ "hcsplt 0x%08x, qtd->complete_split %d\n", __func__, ++ hc->hc_num, hcchar.d32, hctsiz.d32, hcint.d32, ++ hcintmsk.d32, hcsplt.d32, qtd->complete_split); ++ ++ DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n", ++ __func__, hc->hc_num); ++ DWC_WARN("\n"); ++ clear_hc_int(hc_regs, chhltd); ++ return 0; ++ } ++ ++ /* ++ * This code is here only as a check. hcchar.chdis should ++ * never be set when the halt interrupt occurs. Halt the ++ * channel again if it does occur. ++ */ ++ hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar); ++ if (hcchar.b.chdis) { ++ DWC_WARN("%s: hcchar.chdis set unexpectedly, " ++ "hcchar 0x%08x, trying to halt again\n", ++ __func__, hcchar.d32); ++ clear_hc_int(hc_regs, chhltd); ++ hc->halt_pending = 0; ++ halt_channel(hcd, hc, qtd, hc->halt_status); ++ return 0; ++ } ++ ++ return 1; ++} ++#endif ++ ++/** ++ * Handles a host Channel Halted interrupt in DMA mode. This handler ++ * determines the reason the channel halted and proceeds accordingly. ++ */ ++static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ hcint_data_t hcint; ++ hcintmsk_data_t hcintmsk; ++ int out_nak_enh = 0; ++ ++ /* For core with OUT NAK enhancement, the flow for high- ++ * speed CONTROL/BULK OUT is handled a little differently. ++ */ ++ if (hcd->core_if->snpsid >= OTG_CORE_REV_2_71a) { ++ if (hc->speed == DWC_OTG_EP_SPEED_HIGH && !hc->ep_is_in && ++ (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL || ++ hc->ep_type == DWC_OTG_EP_TYPE_BULK)) { ++ out_nak_enh = 1; ++ } ++ } ++ ++ if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE || ++ (hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR ++ && !hcd->core_if->dma_desc_enable)) { ++ /* ++ * Just release the channel. A dequeue can happen on a ++ * transfer timeout. In the case of an AHB Error, the channel ++ * was forced to halt because there's no way to gracefully ++ * recover. ++ */ ++ if (hcd->core_if->dma_desc_enable) ++ dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, ++ hc->halt_status); ++ else ++ release_channel(hcd, hc, qtd, hc->halt_status); ++ return; ++ } ++ ++ /* Read the HCINTn register to determine the cause for the halt. */ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ hcintmsk.d32 = DWC_READ_REG32(&hc_regs->hcintmsk); ++ ++ if (hcint.b.xfercomp) { ++ /** @todo This is here because of a possible hardware bug. Spec ++ * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT ++ * interrupt w/ACK bit set should occur, but I only see the ++ * XFERCOMP bit, even with it masked out. This is a workaround ++ * for that behavior. Should fix this when hardware is fixed. ++ */ ++ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) { ++ handle_hc_ack_intr(hcd, hc, hc_regs, qtd); ++ } ++ handle_hc_xfercomp_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.stall) { ++ handle_hc_stall_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.xacterr && !hcd->core_if->dma_desc_enable) { ++ if (out_nak_enh) { ++ if (hcint.b.nyet || hcint.b.nak || hcint.b.ack) { ++ DWC_DEBUGPL(DBG_HCD, "XactErr with NYET/NAK/ACK\n"); ++ qtd->error_count = 0; ++ } else { ++ DWC_DEBUGPL(DBG_HCD, "XactErr without NYET/NAK/ACK\n"); ++ } ++ } ++ ++ /* ++ * Must handle xacterr before nak or ack. Could get a xacterr ++ * at the same time as either of these on a BULK/CONTROL OUT ++ * that started with a PING. The xacterr takes precedence. ++ */ ++ handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.xcs_xact && hcd->core_if->dma_desc_enable) { ++ handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.ahberr && hcd->core_if->dma_desc_enable) { ++ handle_hc_ahberr_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.bblerr) { ++ handle_hc_babble_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.frmovrun) { ++ handle_hc_frmovrun_intr(hcd, hc, hc_regs, qtd); ++ } else if (!out_nak_enh) { ++ if (hcint.b.nyet) { ++ /* ++ * Must handle nyet before nak or ack. Could get a nyet at the ++ * same time as either of those on a BULK/CONTROL OUT that ++ * started with a PING. The nyet takes precedence. ++ */ ++ handle_hc_nyet_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.nak && !hcintmsk.b.nak) { ++ /* ++ * If nak is not masked, it's because a non-split IN transfer ++ * is in an error state. In that case, the nak is handled by ++ * the nak interrupt handler, not here. Handle nak here for ++ * BULK/CONTROL OUT transfers, which halt on a NAK to allow ++ * rewinding the buffer pointer. ++ */ ++ handle_hc_nak_intr(hcd, hc, hc_regs, qtd); ++ } else if (hcint.b.ack && !hcintmsk.b.ack) { ++ /* ++ * If ack is not masked, it's because a non-split IN transfer ++ * is in an error state. In that case, the ack is handled by ++ * the ack interrupt handler, not here. Handle ack here for ++ * split transfers. Start splits halt on ACK. ++ */ ++ handle_hc_ack_intr(hcd, hc, hc_regs, qtd); ++ } else { ++ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || ++ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { ++ /* ++ * A periodic transfer halted with no other channel ++ * interrupts set. Assume it was halted by the core ++ * because it could not be completed in its scheduled ++ * (micro)frame. ++ */ ++#ifdef DEBUG ++ DWC_PRINTF ++ ("%s: Halt channel %d (assume incomplete periodic transfer)\n", ++ __func__, hc->hc_num); ++#endif ++ halt_channel(hcd, hc, qtd, ++ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE); ++ } else { ++ DWC_ERROR ++ ("%s: Channel %d, DMA Mode -- ChHltd set, but reason " ++ "for halting is unknown, hcint 0x%08x, intsts 0x%08x\n", ++ __func__, hc->hc_num, hcint.d32, ++ DWC_READ_REG32(&hcd-> ++ core_if->core_global_regs-> ++ gintsts)); ++ } ++ ++ } ++ } else { ++ DWC_PRINTF("NYET/NAK/ACK/other in non-error case, 0x%08x\n", ++ hcint.d32); ++ } ++} ++ ++/** ++ * Handles a host channel Channel Halted interrupt. ++ * ++ * In slave mode, this handler is called only when the driver specifically ++ * requests a halt. This occurs during handling other host channel interrupts ++ * (e.g. nak, xacterr, stall, nyet, etc.). ++ * ++ * In DMA mode, this is the interrupt that occurs when the core has finished ++ * processing a transfer on a channel. Other host channel interrupts (except ++ * ahberr) are disabled in DMA mode. ++ */ ++static int32_t handle_hc_chhltd_intr(dwc_otg_hcd_t * hcd, ++ dwc_hc_t * hc, ++ dwc_otg_hc_regs_t * hc_regs, ++ dwc_otg_qtd_t * qtd) ++{ ++ DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: " ++ "Channel Halted--\n", hc->hc_num); ++ ++ if (hcd->core_if->dma_enable) { ++ handle_hc_chhltd_intr_dma(hcd, hc, hc_regs, qtd); ++ } else { ++#ifdef DEBUG ++ if (!halt_status_ok(hcd, hc, hc_regs, qtd)) { ++ return 1; ++ } ++#endif ++ release_channel(hcd, hc, qtd, hc->halt_status); ++ } ++ ++ return 1; ++} ++ ++/** Handles interrupt for a specific Host Channel */ ++int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd, uint32_t num) ++{ ++ int retval = 0; ++ hcint_data_t hcint; ++ hcintmsk_data_t hcintmsk; ++ dwc_hc_t *hc; ++ dwc_otg_hc_regs_t *hc_regs; ++ dwc_otg_qtd_t *qtd; ++ ++ DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", num); ++ ++ hc = dwc_otg_hcd->hc_ptr_array[num]; ++ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[num]; ++ qtd = DWC_CIRCLEQ_FIRST(&hc->qh->qtd_list); ++ ++ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint); ++ hcintmsk.d32 = DWC_READ_REG32(&hc_regs->hcintmsk); ++ DWC_DEBUGPL(DBG_HCDV, ++ " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n", ++ hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32)); ++ hcint.d32 = hcint.d32 & hcintmsk.d32; ++ ++ if (!dwc_otg_hcd->core_if->dma_enable) { ++ if (hcint.b.chhltd && hcint.d32 != 0x2) { ++ hcint.b.chhltd = 0; ++ } ++ } ++ ++ if (hcint.b.xfercomp) { ++ retval |= ++ handle_hc_xfercomp_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ /* ++ * If NYET occurred at same time as Xfer Complete, the NYET is ++ * handled by the Xfer Complete interrupt handler. Don't want ++ * to call the NYET interrupt handler in this case. ++ */ ++ hcint.b.nyet = 0; ++ } ++ if (hcint.b.chhltd) { ++ retval |= handle_hc_chhltd_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.ahberr) { ++ retval |= handle_hc_ahberr_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.stall) { ++ retval |= handle_hc_stall_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.nak) { ++ retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.ack) { ++ retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.nyet) { ++ retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.xacterr) { ++ retval |= handle_hc_xacterr_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.bblerr) { ++ retval |= handle_hc_babble_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.frmovrun) { ++ retval |= ++ handle_hc_frmovrun_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ if (hcint.b.datatglerr) { ++ retval |= ++ handle_hc_datatglerr_intr(dwc_otg_hcd, hc, hc_regs, qtd); ++ } ++ ++ return retval; ++} ++ ++#endif /* DWC_DEVICE_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,893 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $ ++ * $Revision: #20 $ ++ * $Date: 2011/10/26 $ ++ * $Change: 1872981 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_DEVICE_ONLY ++ ++/** ++ * @file ++ * ++ * This file contains the implementation of the HCD. In Linux, the HCD ++ * implements the hc_driver API. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++#include <../drivers/usb/core/hcd.h> ++#else ++#include ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) ++#define USB_URB_EP_LINKING 1 ++#else ++#define USB_URB_EP_LINKING 0 ++#endif ++ ++#include "dwc_otg_hcd_if.h" ++#include "dwc_otg_dbg.h" ++#include "dwc_otg_driver.h" ++#include "dwc_otg_hcd.h" ++/** ++ * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is ++ * qualified with its direction (possible 32 endpoints per device). ++ */ ++#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \ ++ ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4) ++ ++static const char dwc_otg_hcd_name[] = "dwc_otg_hcd"; ++ ++/** @name Linux HC Driver API Functions */ ++/** @{ */ ++/* manage i/o requests, device state */ ++static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++ struct usb_host_endpoint *ep, ++#endif ++ struct urb *urb, gfp_t mem_flags); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++static int dwc_otg_urb_dequeue(struct usb_hcd *hcd, struct urb *urb); ++#endif ++#else /* kernels at or post 2.6.30 */ ++static int dwc_otg_urb_dequeue(struct usb_hcd *hcd, ++ struct urb *urb, int status); ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) */ ++ ++static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) ++static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); ++#endif ++static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd); ++extern int hcd_start(struct usb_hcd *hcd); ++extern void hcd_stop(struct usb_hcd *hcd); ++static int get_frame_number(struct usb_hcd *hcd); ++extern int hub_status_data(struct usb_hcd *hcd, char *buf); ++extern int hub_control(struct usb_hcd *hcd, ++ u16 typeReq, ++ u16 wValue, u16 wIndex, char *buf, u16 wLength); ++ ++struct wrapper_priv_data { ++ dwc_otg_hcd_t *dwc_otg_hcd; ++}; ++ ++/** @} */ ++ ++static struct hc_driver dwc_otg_hc_driver = { ++ ++ .description = dwc_otg_hcd_name, ++ .product_desc = "DWC OTG Controller", ++ .hcd_priv_size = sizeof(struct wrapper_priv_data), ++ ++ .irq = dwc_otg_hcd_irq, ++ ++ .flags = HCD_MEMORY | HCD_USB2, ++ ++ //.reset = ++ .start = hcd_start, ++ //.suspend = ++ //.resume = ++ .stop = hcd_stop, ++ ++ .urb_enqueue = dwc_otg_urb_enqueue, ++ .urb_dequeue = dwc_otg_urb_dequeue, ++ .endpoint_disable = endpoint_disable, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) ++ .endpoint_reset = endpoint_reset, ++#endif ++ .get_frame_number = get_frame_number, ++ ++ .hub_status_data = hub_status_data, ++ .hub_control = hub_control, ++ //.bus_suspend = ++ //.bus_resume = ++}; ++ ++/** Gets the dwc_otg_hcd from a struct usb_hcd */ ++static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd) ++{ ++ struct wrapper_priv_data *p; ++ p = (struct wrapper_priv_data *)(hcd->hcd_priv); ++ return p->dwc_otg_hcd; ++} ++ ++/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */ ++static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd) ++{ ++ return dwc_otg_hcd_get_priv_data(dwc_otg_hcd); ++} ++ ++/** Gets the usb_host_endpoint associated with an URB. */ ++inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb) ++{ ++ struct usb_device *dev = urb->dev; ++ int ep_num = usb_pipeendpoint(urb->pipe); ++ ++ if (usb_pipein(urb->pipe)) ++ return dev->ep_in[ep_num]; ++ else ++ return dev->ep_out[ep_num]; ++} ++ ++static int _disconnect(dwc_otg_hcd_t * hcd) ++{ ++ struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd); ++ ++ usb_hcd->self.is_b_host = 0; ++ return 0; ++} ++ ++static int _start(dwc_otg_hcd_t * hcd) ++{ ++ struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd); ++ ++ usb_hcd->self.is_b_host = dwc_otg_hcd_is_b_host(hcd); ++ hcd_start(usb_hcd); ++ ++ return 0; ++} ++ ++static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr, ++ uint32_t * port_addr) ++{ ++ struct urb *urb = (struct urb *)urb_handle; ++ struct usb_bus *bus; ++#if 1 //GRAYG - temporary ++ if (NULL == urb_handle) ++ DWC_ERROR("**** %s - NULL URB handle\n", __func__);//GRAYG ++ if (NULL == urb->dev) ++ DWC_ERROR("**** %s - URB has no device\n", __func__);//GRAYG ++ if (NULL == port_addr) ++ DWC_ERROR("**** %s - NULL port_address\n", __func__);//GRAYG ++#endif ++ if (urb->dev->tt) { ++ if (NULL == urb->dev->tt->hub) { ++ DWC_ERROR("**** %s - (URB's transactor has no TT - giving no hub)\n", ++ __func__); //GRAYG ++ //*hub_addr = (u8)usb_pipedevice(urb->pipe); //GRAYG ++ *hub_addr = 0; //GRAYG ++ // we probably shouldn't have a transaction translator if ++ // there's no associated hub? ++ } else { ++ bus = hcd_to_bus(dwc_otg_hcd_to_hcd(hcd)); ++ if (urb->dev->tt->hub == bus->root_hub) ++ *hub_addr = 0; ++ else ++ *hub_addr = urb->dev->tt->hub->devnum; ++ } ++ *port_addr = urb->dev->tt->multi ? urb->dev->ttport : 1; ++ } else { ++ *hub_addr = 0; ++ *port_addr = urb->dev->ttport; ++ } ++ return 0; ++} ++ ++static int _speed(dwc_otg_hcd_t * hcd, void *urb_handle) ++{ ++ struct urb *urb = (struct urb *)urb_handle; ++ return urb->dev->speed; ++} ++ ++static int _get_b_hnp_enable(dwc_otg_hcd_t * hcd) ++{ ++ struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd); ++ return usb_hcd->self.b_hnp_enable; ++} ++ ++static void allocate_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw, ++ struct urb *urb) ++{ ++ hcd_to_bus(hcd)->bandwidth_allocated += bw / urb->interval; ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ hcd_to_bus(hcd)->bandwidth_isoc_reqs++; ++ } else { ++ hcd_to_bus(hcd)->bandwidth_int_reqs++; ++ } ++} ++ ++static void free_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw, ++ struct urb *urb) ++{ ++ hcd_to_bus(hcd)->bandwidth_allocated -= bw / urb->interval; ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ hcd_to_bus(hcd)->bandwidth_isoc_reqs--; ++ } else { ++ hcd_to_bus(hcd)->bandwidth_int_reqs--; ++ } ++} ++ ++/** ++ * Sets the final status of an URB and returns it to the device driver. Any ++ * required cleanup of the URB is performed. ++ */ ++static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle, ++ dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status) ++{ ++ struct urb *urb = (struct urb *)urb_handle; ++ ++ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { ++ DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n", ++ __func__, urb, usb_pipedevice(urb->pipe), ++ usb_pipeendpoint(urb->pipe), ++ usb_pipein(urb->pipe) ? "IN" : "OUT", status); ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ int i; ++ for (i = 0; i < urb->number_of_packets; i++) { ++ DWC_PRINTF(" ISO Desc %d status: %d\n", ++ i, urb->iso_frame_desc[i].status); ++ } ++ } ++ } ++ ++ urb->actual_length = dwc_otg_hcd_urb_get_actual_length(dwc_otg_urb); ++ /* Convert status value. */ ++ switch (status) { ++ case -DWC_E_PROTOCOL: ++ status = -EPROTO; ++ break; ++ case -DWC_E_IN_PROGRESS: ++ status = -EINPROGRESS; ++ break; ++ case -DWC_E_PIPE: ++ status = -EPIPE; ++ break; ++ case -DWC_E_IO: ++ status = -EIO; ++ break; ++ case -DWC_E_TIMEOUT: ++ status = -ETIMEDOUT; ++ break; ++ case -DWC_E_OVERFLOW: ++ status = -EOVERFLOW; ++ break; ++ default: ++ if (status) { ++ DWC_PRINTF("Uknown urb status %d\n", status); ++ ++ } ++ } ++ ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ int i; ++ ++ urb->error_count = dwc_otg_hcd_urb_get_error_count(dwc_otg_urb); ++ for (i = 0; i < urb->number_of_packets; ++i) { ++ urb->iso_frame_desc[i].actual_length = ++ dwc_otg_hcd_urb_get_iso_desc_actual_length ++ (dwc_otg_urb, i); ++ urb->iso_frame_desc[i].status = ++ dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i); ++ } ++ } ++ ++ urb->status = status; ++ urb->hcpriv = NULL; ++ if (!status) { ++ if ((urb->transfer_flags & URB_SHORT_NOT_OK) && ++ (urb->actual_length < urb->transfer_buffer_length)) { ++ urb->status = -EREMOTEIO; ++ } ++ } ++ ++ if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) || ++ (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) { ++ struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb); ++ if (ep) { ++ free_bus_bandwidth(dwc_otg_hcd_to_hcd(hcd), ++ dwc_otg_hcd_get_ep_bandwidth(hcd, ++ ep->hcpriv), ++ urb); ++ } ++ } ++ ++ DWC_FREE(dwc_otg_urb); ++ ++#if USB_URB_EP_LINKING ++ usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb); ++#endif ++ DWC_SPINUNLOCK(hcd->lock); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb); ++#else ++ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status); ++#endif ++ DWC_SPINLOCK(hcd->lock); ++ ++ return 0; ++} ++ ++static struct dwc_otg_hcd_function_ops hcd_fops = { ++ .start = _start, ++ .disconnect = _disconnect, ++ .hub_info = _hub_info, ++ .speed = _speed, ++ .complete = _complete, ++ .get_b_hnp_enable = _get_b_hnp_enable, ++}; ++ ++/** ++ * Initializes the HCD. This function allocates memory for and initializes the ++ * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the ++ * USB bus with the core and calls the hc_driver->start() function. It returns ++ * a negative error on failure. ++ */ ++int hcd_init(dwc_bus_dev_t *_dev) ++{ ++ struct usb_hcd *hcd = NULL; ++ dwc_otg_hcd_t *dwc_otg_hcd = NULL; ++ dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev); ++ int retval = 0; ++ u64 dmamask; ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev); ++ ++ /* Set device flags indicating whether the HCD supports DMA. */ ++ if (dwc_otg_is_dma_enable(otg_dev->core_if)) ++ dmamask = DMA_BIT_MASK(32); ++ else ++ dmamask = 0; ++ ++#if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE) ++ dma_set_mask(&_dev->dev, dmamask); ++ dma_set_coherent_mask(&_dev->dev, dmamask); ++#elif defined(PCI_INTERFACE) ++ pci_set_dma_mask(_dev, dmamask); ++ pci_set_consistent_dma_mask(_dev, dmamask); ++#endif ++ ++ /* ++ * Allocate memory for the base HCD plus the DWC OTG HCD. ++ * Initialize the base HCD. ++ */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) ++ hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, _dev->dev.bus_id); ++#else ++ hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, dev_name(&_dev->dev)); ++ hcd->has_tt = 1; ++// hcd->uses_new_polling = 1; ++// hcd->poll_rh = 0; ++#endif ++ if (!hcd) { ++ retval = -ENOMEM; ++ goto error1; ++ } ++ ++ hcd->regs = otg_dev->os_dep.base; ++ ++ /* Initialize the DWC OTG HCD. */ ++ dwc_otg_hcd = dwc_otg_hcd_alloc_hcd(); ++ if (!dwc_otg_hcd) { ++ goto error2; ++ } ++ ((struct wrapper_priv_data *)(hcd->hcd_priv))->dwc_otg_hcd = ++ dwc_otg_hcd; ++ otg_dev->hcd = dwc_otg_hcd; ++ ++ if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) { ++ goto error2; ++ } ++ ++ otg_dev->hcd->otg_dev = otg_dev; ++ hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) //version field absent later ++ hcd->self.otg_version = dwc_otg_get_otg_version(otg_dev->core_if); ++#endif ++ /* Don't support SG list at this point */ ++ hcd->self.sg_tablesize = 0; ++#endif ++ /* ++ * Finish generic HCD initialization and start the HCD. This function ++ * allocates the DMA buffer pool, registers the USB bus, requests the ++ * IRQ line, and calls hcd_start method. ++ */ ++#ifdef PLATFORM_INTERFACE ++ retval = usb_add_hcd(hcd, platform_get_irq(_dev, 0), IRQF_SHARED | IRQF_DISABLED); ++#else ++ retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED | IRQF_DISABLED); ++#endif ++ if (retval < 0) { ++ goto error2; ++ } ++ ++ dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd); ++ return 0; ++ ++error2: ++ usb_put_hcd(hcd); ++error1: ++ return retval; ++} ++ ++/** ++ * Removes the HCD. ++ * Frees memory and resources associated with the HCD and deregisters the bus. ++ */ ++void hcd_remove(dwc_bus_dev_t *_dev) ++{ ++ dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev); ++ dwc_otg_hcd_t *dwc_otg_hcd; ++ struct usb_hcd *hcd; ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE otg_dev=%p\n", otg_dev); ++ ++ if (!otg_dev) { ++ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__); ++ return; ++ } ++ ++ dwc_otg_hcd = otg_dev->hcd; ++ ++ if (!dwc_otg_hcd) { ++ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__); ++ return; ++ } ++ ++ hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd); ++ ++ if (!hcd) { ++ DWC_DEBUGPL(DBG_ANY, ++ "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n", ++ __func__); ++ return; ++ } ++ usb_remove_hcd(hcd); ++ dwc_otg_hcd_set_priv_data(dwc_otg_hcd, NULL); ++ dwc_otg_hcd_remove(dwc_otg_hcd); ++ usb_put_hcd(hcd); ++} ++ ++/* ========================================================================= ++ * Linux HC Driver Functions ++ * ========================================================================= */ ++ ++/** Initializes the DWC_otg controller and its root hub and prepares it for host ++ * mode operation. Activates the root port. Returns 0 on success and a negative ++ * error code on failure. */ ++int hcd_start(struct usb_hcd *hcd) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ struct usb_bus *bus; ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n"); ++ bus = hcd_to_bus(hcd); ++ ++ hcd->state = HC_STATE_RUNNING; ++ if (dwc_otg_hcd_start(dwc_otg_hcd, &hcd_fops)) { ++ return 0; ++ } ++ ++ /* Initialize and connect root hub if one is not already attached */ ++ if (bus->root_hub) { ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n"); ++ /* Inform the HUB driver to resume. */ ++ usb_hcd_resume_root_hub(hcd); ++ } ++ ++ return 0; ++} ++ ++/** ++ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are ++ * stopped. ++ */ ++void hcd_stop(struct usb_hcd *hcd) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ ++ dwc_otg_hcd_stop(dwc_otg_hcd); ++} ++ ++/** Returns the current frame number. */ ++static int get_frame_number(struct usb_hcd *hcd) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ ++ return dwc_otg_hcd_get_frame_number(dwc_otg_hcd); ++} ++ ++#ifdef DEBUG ++static void dump_urb_info(struct urb *urb, char *fn_name) ++{ ++ DWC_PRINTF("%s, urb %p\n", fn_name, urb); ++ DWC_PRINTF(" Device address: %d\n", usb_pipedevice(urb->pipe)); ++ DWC_PRINTF(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe), ++ (usb_pipein(urb->pipe) ? "IN" : "OUT")); ++ DWC_PRINTF(" Endpoint type: %s\n", ( { ++ char *pipetype; ++ switch (usb_pipetype(urb->pipe)) { ++case PIPE_CONTROL: ++pipetype = "CONTROL"; break; case PIPE_BULK: ++pipetype = "BULK"; break; case PIPE_INTERRUPT: ++pipetype = "INTERRUPT"; break; case PIPE_ISOCHRONOUS: ++pipetype = "ISOCHRONOUS"; break; default: ++ pipetype = "UNKNOWN"; break;}; ++ pipetype;} ++ )) ; ++ DWC_PRINTF(" Speed: %s\n", ( { ++ char *speed; switch (urb->dev->speed) { ++case USB_SPEED_HIGH: ++speed = "HIGH"; break; case USB_SPEED_FULL: ++speed = "FULL"; break; case USB_SPEED_LOW: ++speed = "LOW"; break; default: ++ speed = "UNKNOWN"; break;}; ++ speed;} ++ )) ; ++ DWC_PRINTF(" Max packet size: %d\n", ++ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))); ++ DWC_PRINTF(" Data buffer length: %d\n", urb->transfer_buffer_length); ++ DWC_PRINTF(" Transfer buffer: %p, Transfer DMA: %p\n", ++ urb->transfer_buffer, (void *)urb->transfer_dma); ++ DWC_PRINTF(" Setup buffer: %p, Setup DMA: %p\n", ++ urb->setup_packet, (void *)urb->setup_dma); ++ DWC_PRINTF(" Interval: %d\n", urb->interval); ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ int i; ++ for (i = 0; i < urb->number_of_packets; i++) { ++ DWC_PRINTF(" ISO Desc %d:\n", i); ++ DWC_PRINTF(" offset: %d, length %d\n", ++ urb->iso_frame_desc[i].offset, ++ urb->iso_frame_desc[i].length); ++ } ++ } ++} ++#endif ++ ++/** Starts processing a USB transfer request specified by a USB Request Block ++ * (URB). mem_flags indicates the type of memory allocation to use while ++ * processing this URB. */ ++static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++ struct usb_host_endpoint *ep, ++#endif ++ struct urb *urb, gfp_t mem_flags) ++{ ++ int retval = 0; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) ++ struct usb_host_endpoint *ep = urb->ep; ++#endif ++#if USB_URB_EP_LINKING ++ dwc_irqflags_t irqflags; ++#endif ++ void **ref_ep_hcpriv = &ep->hcpriv; ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ dwc_otg_hcd_urb_t *dwc_otg_urb; ++ int i; ++ int alloc_bandwidth = 0; ++ uint8_t ep_type = 0; ++ uint32_t flags = 0; ++ void *buf; ++ ++#ifdef DEBUG ++ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { ++ dump_urb_info(urb, "dwc_otg_urb_enqueue"); ++ } ++#endif ++ ++ if (!urb->transfer_buffer && urb->transfer_buffer_length) ++ return -EINVAL; ++ ++ if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ++ || (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) { ++ if (!dwc_otg_hcd_is_bandwidth_allocated ++ (dwc_otg_hcd, ref_ep_hcpriv)) { ++ alloc_bandwidth = 1; ++ } ++ } ++ ++ switch (usb_pipetype(urb->pipe)) { ++ case PIPE_CONTROL: ++ ep_type = USB_ENDPOINT_XFER_CONTROL; ++ break; ++ case PIPE_ISOCHRONOUS: ++ ep_type = USB_ENDPOINT_XFER_ISOC; ++ break; ++ case PIPE_BULK: ++ ep_type = USB_ENDPOINT_XFER_BULK; ++ break; ++ case PIPE_INTERRUPT: ++ ep_type = USB_ENDPOINT_XFER_INT; ++ break; ++ default: ++ DWC_WARN("Wrong EP type - %d\n", usb_pipetype(urb->pipe)); ++ } ++ ++ /* # of packets is often 0 - do we really need to call this then? */ ++ dwc_otg_urb = dwc_otg_hcd_urb_alloc(dwc_otg_hcd, ++ urb->number_of_packets, ++ mem_flags == GFP_ATOMIC ? 1 : 0); ++ ++ if(dwc_otg_urb == NULL) ++ return -ENOMEM; ++ ++ urb->hcpriv = dwc_otg_urb; ++ if (!dwc_otg_urb && urb->number_of_packets) ++ return -ENOMEM; ++ ++ dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_urb, usb_pipedevice(urb->pipe), ++ usb_pipeendpoint(urb->pipe), ep_type, ++ usb_pipein(urb->pipe), ++ usb_maxpacket(urb->dev, urb->pipe, ++ !(usb_pipein(urb->pipe)))); ++ ++ buf = urb->transfer_buffer; ++ if (hcd->self.uses_dma) { ++ /* ++ * Calculate virtual address from physical address, ++ * because some class driver may not fill transfer_buffer. ++ * In Buffer DMA mode virual address is used, ++ * when handling non DWORD aligned buffers. ++ */ ++ //buf = phys_to_virt(urb->transfer_dma); ++ // DMA addresses are bus addresses not physical addresses! ++ buf = dma_to_virt(&urb->dev->dev, urb->transfer_dma); ++ } ++ ++ if (!(urb->transfer_flags & URB_NO_INTERRUPT)) ++ flags |= URB_GIVEBACK_ASAP; ++ if (urb->transfer_flags & URB_ZERO_PACKET) ++ flags |= URB_SEND_ZERO_PACKET; ++ ++ dwc_otg_hcd_urb_set_params(dwc_otg_urb, urb, buf, ++ urb->transfer_dma, ++ urb->transfer_buffer_length, ++ urb->setup_packet, ++ urb->setup_dma, flags, urb->interval); ++ ++ for (i = 0; i < urb->number_of_packets; ++i) { ++ dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_urb, i, ++ urb-> ++ iso_frame_desc[i].offset, ++ urb-> ++ iso_frame_desc[i].length); ++ } ++ ++#if USB_URB_EP_LINKING ++ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags); ++ retval = usb_hcd_link_urb_to_ep(hcd, urb); ++ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags); ++ if (0 == retval) ++#endif ++ { ++ retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb, ++ /*(dwc_otg_qh_t **)*/ ++ ref_ep_hcpriv, ++ mem_flags == GFP_ATOMIC ? 1 : 0); ++ if (0 == retval) { ++ if (alloc_bandwidth) { ++ allocate_bus_bandwidth(hcd, ++ dwc_otg_hcd_get_ep_bandwidth( ++ dwc_otg_hcd, *ref_ep_hcpriv), ++ urb); ++ } ++ } else { ++#if USB_URB_EP_LINKING ++ dwc_irqflags_t irqflags; ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG dwc_otg_hcd_urb_enqueue failed rc %d\n", retval); ++ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags); ++ usb_hcd_unlink_urb_from_ep(hcd, urb); ++ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags); ++#endif ++ if (retval == -DWC_E_NO_DEVICE) { ++ retval = -ENODEV; ++ } ++ } ++ } ++ return retval; ++} ++ ++/** Aborts/cancels a USB transfer request. Always returns 0 to indicate ++ * success. */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++static int dwc_otg_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) ++#else ++static int dwc_otg_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ++#endif ++{ ++ dwc_irqflags_t flags; ++ dwc_otg_hcd_t *dwc_otg_hcd; ++ int rc; ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n"); ++ ++ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ ++#ifdef DEBUG ++ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { ++ dump_urb_info(urb, "dwc_otg_urb_dequeue"); ++ } ++#endif ++ ++ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags); ++ rc = usb_hcd_check_unlink_urb(hcd, urb, status); ++ if (0 == rc) { ++ if(urb->hcpriv != NULL) { ++ dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, ++ (dwc_otg_hcd_urb_t *)urb->hcpriv); ++ ++ DWC_FREE(urb->hcpriv); ++ urb->hcpriv = NULL; ++ } ++ } ++ ++ if (0 == rc) { ++ /* Higher layer software sets URB status. */ ++#if USB_URB_EP_LINKING ++ usb_hcd_unlink_urb_from_ep(hcd, urb); ++#endif ++ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++ usb_hcd_giveback_urb(hcd, urb); ++#else ++ usb_hcd_giveback_urb(hcd, urb, status); ++#endif ++ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { ++ DWC_PRINTF("Called usb_hcd_giveback_urb() \n"); ++ DWC_PRINTF(" 1urb->status = %d\n", urb->status); ++ } ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue OK\n"); ++ } else { ++ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags); ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue failed - rc %d\n", ++ rc); ++ } ++ ++ return rc; ++} ++ ++/* Frees resources in the DWC_otg controller related to a given endpoint. Also ++ * clears state in the HCD related to the endpoint. Any URBs for the endpoint ++ * must already be dequeued. */ ++static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ ++ DWC_DEBUGPL(DBG_HCD, ++ "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, " ++ "endpoint=%d\n", ep->desc.bEndpointAddress, ++ dwc_ep_addr_to_endpoint(ep->desc.bEndpointAddress)); ++ dwc_otg_hcd_endpoint_disable(dwc_otg_hcd, ep->hcpriv, 250); ++ ep->hcpriv = NULL; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) ++/* Resets endpoint specific parameter values, in current version used to reset ++ * the data toggle(as a WA). This function can be called from usb_clear_halt routine */ ++static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) ++{ ++ dwc_irqflags_t flags; ++ struct usb_device *udev = NULL; ++ int epnum = usb_endpoint_num(&ep->desc); ++ int is_out = usb_endpoint_dir_out(&ep->desc); ++ int is_control = usb_endpoint_xfer_control(&ep->desc); ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ struct device *dev = DWC_OTG_OS_GETDEV(dwc_otg_hcd->otg_dev->os_dep); ++ ++ if (dev) ++ udev = to_usb_device(dev); ++ else ++ return; ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", epnum); ++ ++ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags); ++ usb_settoggle(udev, epnum, is_out, 0); ++ if (is_control) ++ usb_settoggle(udev, epnum, !is_out, 0); ++ ++ if (ep->hcpriv) { ++ dwc_otg_hcd_endpoint_reset(dwc_otg_hcd, ep->hcpriv); ++ } ++ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags); ++} ++#endif ++ ++/** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if ++ * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid ++ * interrupt. ++ * ++ * This function is called by the USB core when an interrupt occurs */ ++static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ int32_t retval = dwc_otg_hcd_handle_intr(dwc_otg_hcd); ++ if (retval != 0) { ++ S3C2410X_CLEAR_EINTPEND(); ++ } ++ return IRQ_RETVAL(retval); ++} ++ ++/** Creates Status Change bitmap for the root hub and root port. The bitmap is ++ * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1 ++ * is the status change indicator for the single root port. Returns 1 if either ++ * change indicator is 1, otherwise returns 0. */ ++int hub_status_data(struct usb_hcd *hcd, char *buf) ++{ ++ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); ++ ++ buf[0] = 0; ++ buf[0] |= (dwc_otg_hcd_is_status_changed(dwc_otg_hcd, 1)) << 1; ++ ++ return (buf[0] != 0); ++} ++ ++/** Handles hub class-specific requests. */ ++int hub_control(struct usb_hcd *hcd, ++ u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) ++{ ++ int retval; ++ ++ retval = dwc_otg_hcd_hub_control(hcd_to_dwc_otg_hcd(hcd), ++ typeReq, wValue, wIndex, buf, wLength); ++ ++ switch (retval) { ++ case -DWC_E_INVALID: ++ retval = -EINVAL; ++ break; ++ } ++ ++ return retval; ++} ++ ++#endif /* DWC_DEVICE_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,922 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_queue.c $ ++ * $Revision: #44 $ ++ * $Date: 2011/10/26 $ ++ * $Change: 1873028 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_DEVICE_ONLY ++ ++/** ++ * @file ++ * ++ * This file contains the functions to manage Queue Heads and Queue ++ * Transfer Descriptors. ++ */ ++ ++#include "dwc_otg_hcd.h" ++#include "dwc_otg_regs.h" ++ ++extern bool microframe_schedule; ++ ++/** ++ * Free each QTD in the QH's QTD-list then free the QH. QH should already be ++ * removed from a list. QTD list should already be empty if called from URB ++ * Dequeue. ++ * ++ * @param hcd HCD instance. ++ * @param qh The QH to free. ++ */ ++void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ dwc_otg_qtd_t *qtd, *qtd_tmp; ++ ++ /* Free each QTD in the QTD list */ ++ DWC_SPINLOCK(hcd->lock); ++ DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { ++ DWC_CIRCLEQ_REMOVE(&qh->qtd_list, qtd, qtd_list_entry); ++ dwc_otg_hcd_qtd_free(qtd); ++ } ++ ++ if (hcd->core_if->dma_desc_enable) { ++ dwc_otg_hcd_qh_free_ddma(hcd, qh); ++ } else if (qh->dw_align_buf) { ++ uint32_t buf_size; ++ if (qh->ep_type == UE_ISOCHRONOUS) { ++ buf_size = 4096; ++ } else { ++ buf_size = hcd->core_if->core_params->max_transfer_size; ++ } ++ DWC_DMA_FREE(buf_size, qh->dw_align_buf, qh->dw_align_buf_dma); ++ } ++ ++ DWC_FREE(qh); ++ DWC_SPINUNLOCK(hcd->lock); ++ return; ++} ++ ++#define BitStuffTime(bytecount) ((8 * 7* bytecount) / 6) ++#define HS_HOST_DELAY 5 /* nanoseconds */ ++#define FS_LS_HOST_DELAY 1000 /* nanoseconds */ ++#define HUB_LS_SETUP 333 /* nanoseconds */ ++#define NS_TO_US(ns) ((ns + 500) / 1000) ++ /* convert & round nanoseconds to microseconds */ ++ ++static uint32_t calc_bus_time(int speed, int is_in, int is_isoc, int bytecount) ++{ ++ unsigned long retval; ++ ++ switch (speed) { ++ case USB_SPEED_HIGH: ++ if (is_isoc) { ++ retval = ++ ((38 * 8 * 2083) + ++ (2083 * (3 + BitStuffTime(bytecount)))) / 1000 + ++ HS_HOST_DELAY; ++ } else { ++ retval = ++ ((55 * 8 * 2083) + ++ (2083 * (3 + BitStuffTime(bytecount)))) / 1000 + ++ HS_HOST_DELAY; ++ } ++ break; ++ case USB_SPEED_FULL: ++ if (is_isoc) { ++ retval = ++ (8354 * (31 + 10 * BitStuffTime(bytecount))) / 1000; ++ if (is_in) { ++ retval = 7268 + FS_LS_HOST_DELAY + retval; ++ } else { ++ retval = 6265 + FS_LS_HOST_DELAY + retval; ++ } ++ } else { ++ retval = ++ (8354 * (31 + 10 * BitStuffTime(bytecount))) / 1000; ++ retval = 9107 + FS_LS_HOST_DELAY + retval; ++ } ++ break; ++ case USB_SPEED_LOW: ++ if (is_in) { ++ retval = ++ (67667 * (31 + 10 * BitStuffTime(bytecount))) / ++ 1000; ++ retval = ++ 64060 + (2 * HUB_LS_SETUP) + FS_LS_HOST_DELAY + ++ retval; ++ } else { ++ retval = ++ (66700 * (31 + 10 * BitStuffTime(bytecount))) / ++ 1000; ++ retval = ++ 64107 + (2 * HUB_LS_SETUP) + FS_LS_HOST_DELAY + ++ retval; ++ } ++ break; ++ default: ++ DWC_WARN("Unknown device speed\n"); ++ retval = -1; ++ } ++ ++ return NS_TO_US(retval); ++} ++ ++/** ++ * Initializes a QH structure. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh The QH to init. ++ * @param urb Holds the information about the device/endpoint that we need ++ * to initialize the QH. ++ */ ++#define SCHEDULE_SLOP 10 ++void qh_init(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, dwc_otg_hcd_urb_t * urb) ++{ ++ char *speed, *type; ++ int dev_speed; ++ uint32_t hub_addr, hub_port; ++ ++ dwc_memset(qh, 0, sizeof(dwc_otg_qh_t)); ++ ++ /* Initialize QH */ ++ qh->ep_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info); ++ qh->ep_is_in = dwc_otg_hcd_is_pipe_in(&urb->pipe_info) ? 1 : 0; ++ ++ qh->data_toggle = DWC_OTG_HC_PID_DATA0; ++ qh->maxp = dwc_otg_hcd_get_mps(&urb->pipe_info); ++ DWC_CIRCLEQ_INIT(&qh->qtd_list); ++ DWC_LIST_INIT(&qh->qh_list_entry); ++ qh->channel = NULL; ++ ++ /* FS/LS Enpoint on HS Hub ++ * NOT virtual root hub */ ++ dev_speed = hcd->fops->speed(hcd, urb->priv); ++ ++ hcd->fops->hub_info(hcd, urb->priv, &hub_addr, &hub_port); ++ qh->do_split = 0; ++ if (microframe_schedule) ++ qh->speed = dev_speed; ++ ++ ++ if (((dev_speed == USB_SPEED_LOW) || ++ (dev_speed == USB_SPEED_FULL)) && ++ (hub_addr != 0 && hub_addr != 1)) { ++ DWC_DEBUGPL(DBG_HCD, ++ "QH init: EP %d: TT found at hub addr %d, for port %d\n", ++ dwc_otg_hcd_get_ep_num(&urb->pipe_info), hub_addr, ++ hub_port); ++ qh->do_split = 1; ++ } ++ ++ if (qh->ep_type == UE_INTERRUPT || qh->ep_type == UE_ISOCHRONOUS) { ++ /* Compute scheduling parameters once and save them. */ ++ hprt0_data_t hprt; ++ ++ /** @todo Account for split transfers in the bus time. */ ++ int bytecount = ++ dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp); ++ ++ qh->usecs = ++ calc_bus_time((qh->do_split ? USB_SPEED_HIGH : dev_speed), ++ qh->ep_is_in, (qh->ep_type == UE_ISOCHRONOUS), ++ bytecount); ++ /* Start in a slightly future (micro)frame. */ ++ qh->sched_frame = dwc_frame_num_inc(hcd->frame_number, ++ SCHEDULE_SLOP); ++ qh->interval = urb->interval; ++ ++#if 0 ++ /* Increase interrupt polling rate for debugging. */ ++ if (qh->ep_type == UE_INTERRUPT) { ++ qh->interval = 8; ++ } ++#endif ++ hprt.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0); ++ if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) && ++ ((dev_speed == USB_SPEED_LOW) || ++ (dev_speed == USB_SPEED_FULL))) { ++ qh->interval *= 8; ++ qh->sched_frame |= 0x7; ++ qh->start_split_frame = qh->sched_frame; ++ } ++ ++ } ++ ++ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n"); ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", qh); ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n", ++ dwc_otg_hcd_get_dev_addr(&urb->pipe_info)); ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n", ++ dwc_otg_hcd_get_ep_num(&urb->pipe_info), ++ dwc_otg_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT"); ++ switch (dev_speed) { ++ case USB_SPEED_LOW: ++ qh->dev_speed = DWC_OTG_EP_SPEED_LOW; ++ speed = "low"; ++ break; ++ case USB_SPEED_FULL: ++ qh->dev_speed = DWC_OTG_EP_SPEED_FULL; ++ speed = "full"; ++ break; ++ case USB_SPEED_HIGH: ++ qh->dev_speed = DWC_OTG_EP_SPEED_HIGH; ++ speed = "high"; ++ break; ++ default: ++ speed = "?"; ++ break; ++ } ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n", speed); ++ ++ switch (qh->ep_type) { ++ case UE_ISOCHRONOUS: ++ type = "isochronous"; ++ break; ++ case UE_INTERRUPT: ++ type = "interrupt"; ++ break; ++ case UE_CONTROL: ++ type = "control"; ++ break; ++ case UE_BULK: ++ type = "bulk"; ++ break; ++ default: ++ type = "?"; ++ break; ++ } ++ ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n", type); ++ ++#ifdef DEBUG ++ if (qh->ep_type == UE_INTERRUPT) { ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n", ++ qh->usecs); ++ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n", ++ qh->interval); ++ } ++#endif ++ ++} ++ ++/** ++ * This function allocates and initializes a QH. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param urb Holds the information about the device/endpoint that we need ++ * to initialize the QH. ++ * @param atomic_alloc Flag to do atomic allocation if needed ++ * ++ * @return Returns pointer to the newly allocated QH, or NULL on error. */ ++dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t * hcd, ++ dwc_otg_hcd_urb_t * urb, int atomic_alloc) ++{ ++ dwc_otg_qh_t *qh; ++ ++ /* Allocate memory */ ++ /** @todo add memflags argument */ ++ qh = dwc_otg_hcd_qh_alloc(atomic_alloc); ++ if (qh == NULL) { ++ DWC_ERROR("qh allocation failed"); ++ return NULL; ++ } ++ ++ qh_init(hcd, qh, urb); ++ ++ if (hcd->core_if->dma_desc_enable ++ && (dwc_otg_hcd_qh_init_ddma(hcd, qh) < 0)) { ++ dwc_otg_hcd_qh_free(hcd, qh); ++ return NULL; ++ } ++ ++ return qh; ++} ++ ++/* microframe_schedule=0 start */ ++ ++/** ++ * Checks that a channel is available for a periodic transfer. ++ * ++ * @return 0 if successful, negative error code otherise. ++ */ ++static int periodic_channel_available(dwc_otg_hcd_t * hcd) ++{ ++ /* ++ * Currently assuming that there is a dedicated host channnel for each ++ * periodic transaction plus at least one host channel for ++ * non-periodic transactions. ++ */ ++ int status; ++ int num_channels; ++ ++ num_channels = hcd->core_if->core_params->host_channels; ++ if ((hcd->periodic_channels + hcd->non_periodic_channels < num_channels) ++ && (hcd->periodic_channels < num_channels - 1)) { ++ status = 0; ++ } else { ++ DWC_INFO("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n", ++ __func__, num_channels, hcd->periodic_channels, hcd->non_periodic_channels); //NOTICE ++ status = -DWC_E_NO_SPACE; ++ } ++ ++ return status; ++} ++ ++/** ++ * Checks that there is sufficient bandwidth for the specified QH in the ++ * periodic schedule. For simplicity, this calculation assumes that all the ++ * transfers in the periodic schedule may occur in the same (micro)frame. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh QH containing periodic bandwidth required. ++ * ++ * @return 0 if successful, negative error code otherwise. ++ */ ++static int check_periodic_bandwidth(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ int status; ++ int16_t max_claimed_usecs; ++ ++ status = 0; ++ ++ if ((qh->dev_speed == DWC_OTG_EP_SPEED_HIGH) || qh->do_split) { ++ /* ++ * High speed mode. ++ * Max periodic usecs is 80% x 125 usec = 100 usec. ++ */ ++ ++ max_claimed_usecs = 100 - qh->usecs; ++ } else { ++ /* ++ * Full speed mode. ++ * Max periodic usecs is 90% x 1000 usec = 900 usec. ++ */ ++ max_claimed_usecs = 900 - qh->usecs; ++ } ++ ++ if (hcd->periodic_usecs > max_claimed_usecs) { ++ DWC_INFO("%s: already claimed usecs %d, required usecs %d\n", __func__, hcd->periodic_usecs, qh->usecs); //NOTICE ++ status = -DWC_E_NO_SPACE; ++ } ++ ++ return status; ++} ++ ++/* microframe_schedule=0 end */ ++ ++/** ++ * Microframe scheduler ++ * track the total use in hcd->frame_usecs ++ * keep each qh use in qh->frame_usecs ++ * when surrendering the qh then donate the time back ++ */ ++const unsigned short max_uframe_usecs[]={ 100, 100, 100, 100, 100, 100, 30, 0 }; ++ ++/* ++ * called from dwc_otg_hcd.c:dwc_otg_hcd_init ++ */ ++int init_hcd_usecs(dwc_otg_hcd_t *_hcd) ++{ ++ int i; ++ for (i=0; i<8; i++) { ++ _hcd->frame_usecs[i] = max_uframe_usecs[i]; ++ } ++ return 0; ++} ++ ++static int find_single_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh) ++{ ++ int i; ++ unsigned short utime; ++ int t_left; ++ int ret; ++ int done; ++ ++ ret = -1; ++ utime = _qh->usecs; ++ t_left = utime; ++ i = 0; ++ done = 0; ++ while (done == 0) { ++ /* At the start _hcd->frame_usecs[i] = max_uframe_usecs[i]; */ ++ if (utime <= _hcd->frame_usecs[i]) { ++ _hcd->frame_usecs[i] -= utime; ++ _qh->frame_usecs[i] += utime; ++ t_left -= utime; ++ ret = i; ++ done = 1; ++ return ret; ++ } else { ++ i++; ++ if (i == 8) { ++ done = 1; ++ ret = -1; ++ } ++ } ++ } ++ return ret; ++ } ++ ++/* ++ * use this for FS apps that can span multiple uframes ++ */ ++static int find_multi_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh) ++{ ++ int i; ++ int j; ++ unsigned short utime; ++ int t_left; ++ int ret; ++ int done; ++ unsigned short xtime; ++ ++ ret = -1; ++ utime = _qh->usecs; ++ t_left = utime; ++ i = 0; ++ done = 0; ++loop: ++ while (done == 0) { ++ if(_hcd->frame_usecs[i] <= 0) { ++ i++; ++ if (i == 8) { ++ done = 1; ++ ret = -1; ++ } ++ goto loop; ++ } ++ ++ /* ++ * we need n consecutive slots ++ * so use j as a start slot j plus j+1 must be enough time (for now) ++ */ ++ xtime= _hcd->frame_usecs[i]; ++ for (j = i+1 ; j < 8 ; j++ ) { ++ /* ++ * if we add this frame remaining time to xtime we may ++ * be OK, if not we need to test j for a complete frame ++ */ ++ if ((xtime+_hcd->frame_usecs[j]) < utime) { ++ if (_hcd->frame_usecs[j] < max_uframe_usecs[j]) { ++ j = 8; ++ ret = -1; ++ continue; ++ } ++ } ++ if (xtime >= utime) { ++ ret = i; ++ j = 8; /* stop loop with a good value ret */ ++ continue; ++ } ++ /* add the frame time to x time */ ++ xtime += _hcd->frame_usecs[j]; ++ /* we must have a fully available next frame or break */ ++ if ((xtime < utime) ++ && (_hcd->frame_usecs[j] == max_uframe_usecs[j])) { ++ ret = -1; ++ j = 8; /* stop loop with a bad value ret */ ++ continue; ++ } ++ } ++ if (ret >= 0) { ++ t_left = utime; ++ for (j = i; (t_left>0) && (j < 8); j++ ) { ++ t_left -= _hcd->frame_usecs[j]; ++ if ( t_left <= 0 ) { ++ _qh->frame_usecs[j] += _hcd->frame_usecs[j] + t_left; ++ _hcd->frame_usecs[j]= -t_left; ++ ret = i; ++ done = 1; ++ } else { ++ _qh->frame_usecs[j] += _hcd->frame_usecs[j]; ++ _hcd->frame_usecs[j] = 0; ++ } ++ } ++ } else { ++ i++; ++ if (i == 8) { ++ done = 1; ++ ret = -1; ++ } ++ } ++ } ++ return ret; ++} ++ ++static int find_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh) ++{ ++ int ret; ++ ret = -1; ++ ++ if (_qh->speed == USB_SPEED_HIGH) { ++ /* if this is a hs transaction we need a full frame */ ++ ret = find_single_uframe(_hcd, _qh); ++ } else { ++ /* if this is a fs transaction we may need a sequence of frames */ ++ ret = find_multi_uframe(_hcd, _qh); ++ } ++ return ret; ++} ++ ++/** ++ * Checks that the max transfer size allowed in a host channel is large enough ++ * to handle the maximum data transfer in a single (micro)frame for a periodic ++ * transfer. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh QH for a periodic endpoint. ++ * ++ * @return 0 if successful, negative error code otherwise. ++ */ ++static int check_max_xfer_size(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ int status; ++ uint32_t max_xfer_size; ++ uint32_t max_channel_xfer_size; ++ ++ status = 0; ++ ++ max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp); ++ max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size; ++ ++ if (max_xfer_size > max_channel_xfer_size) { ++ DWC_INFO("%s: Periodic xfer length %d > " "max xfer length for channel %d\n", ++ __func__, max_xfer_size, max_channel_xfer_size); //NOTICE ++ status = -DWC_E_NO_SPACE; ++ } ++ ++ return status; ++} ++ ++/** ++ * Schedules an interrupt or isochronous transfer in the periodic schedule. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh QH for the periodic transfer. The QH should already contain the ++ * scheduling information. ++ * ++ * @return 0 if successful, negative error code otherwise. ++ */ ++static int schedule_periodic(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ int status = 0; ++ ++ if (microframe_schedule) { ++ int frame; ++ status = find_uframe(hcd, qh); ++ frame = -1; ++ if (status == 0) { ++ frame = 7; ++ } else { ++ if (status > 0 ) ++ frame = status-1; ++ } ++ ++ /* Set the new frame up */ ++ if (frame > -1) { ++ qh->sched_frame &= ~0x7; ++ qh->sched_frame |= (frame & 7); ++ } ++ ++ if (status != -1) ++ status = 0; ++ } else { ++ status = periodic_channel_available(hcd); ++ if (status) { ++ DWC_INFO("%s: No host channel available for periodic " "transfer.\n", __func__); //NOTICE ++ return status; ++ } ++ ++ status = check_periodic_bandwidth(hcd, qh); ++ } ++ if (status) { ++ DWC_INFO("%s: Insufficient periodic bandwidth for " ++ "periodic transfer.\n", __func__); ++ return status; ++ } ++ status = check_max_xfer_size(hcd, qh); ++ if (status) { ++ DWC_INFO("%s: Channel max transfer size too small " ++ "for periodic transfer.\n", __func__); ++ return status; ++ } ++ ++ if (hcd->core_if->dma_desc_enable) { ++ /* Don't rely on SOF and start in ready schedule */ ++ DWC_LIST_INSERT_TAIL(&hcd->periodic_sched_ready, &qh->qh_list_entry); ++ } ++ else { ++ /* Always start in the inactive schedule. */ ++ DWC_LIST_INSERT_TAIL(&hcd->periodic_sched_inactive, &qh->qh_list_entry); ++ } ++ ++ if (!microframe_schedule) { ++ /* Reserve the periodic channel. */ ++ hcd->periodic_channels++; ++ } ++ ++ /* Update claimed usecs per (micro)frame. */ ++ hcd->periodic_usecs += qh->usecs; ++ ++ return status; ++} ++ ++/** ++ * This function adds a QH to either the non periodic or periodic schedule if ++ * it is not already in the schedule. If the QH is already in the schedule, no ++ * action is taken. ++ * ++ * @return 0 if successful, negative error code otherwise. ++ */ ++int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ int status = 0; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ if (!DWC_LIST_EMPTY(&qh->qh_list_entry)) { ++ /* QH already in a schedule. */ ++ return status; ++ } ++ ++ /* Add the new QH to the appropriate schedule */ ++ if (dwc_qh_is_non_per(qh)) { ++ /* Always start in the inactive schedule. */ ++ DWC_LIST_INSERT_TAIL(&hcd->non_periodic_sched_inactive, ++ &qh->qh_list_entry); ++ } else { ++ status = schedule_periodic(hcd, qh); ++ if ( !hcd->periodic_qh_count ) { ++ intr_mask.b.sofintr = 1; ++ DWC_MODIFY_REG32(&hcd->core_if->core_global_regs->gintmsk, ++ intr_mask.d32, intr_mask.d32); ++ } ++ hcd->periodic_qh_count++; ++ } ++ ++ return status; ++} ++ ++/** ++ * Removes an interrupt or isochronous transfer from the periodic schedule. ++ * ++ * @param hcd The HCD state structure for the DWC OTG controller. ++ * @param qh QH for the periodic transfer. ++ */ ++static void deschedule_periodic(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ int i; ++ DWC_LIST_REMOVE_INIT(&qh->qh_list_entry); ++ ++ /* Update claimed usecs per (micro)frame. */ ++ hcd->periodic_usecs -= qh->usecs; ++ ++ if (!microframe_schedule) { ++ /* Release the periodic channel reservation. */ ++ hcd->periodic_channels--; ++ } else { ++ for (i = 0; i < 8; i++) { ++ hcd->frame_usecs[i] += qh->frame_usecs[i]; ++ qh->frame_usecs[i] = 0; ++ } ++ } ++} ++ ++/** ++ * Removes a QH from either the non-periodic or periodic schedule. Memory is ++ * not freed. ++ * ++ * @param hcd The HCD state structure. ++ * @param qh QH to remove from schedule. */ ++void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) ++{ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ if (DWC_LIST_EMPTY(&qh->qh_list_entry)) { ++ /* QH is not in a schedule. */ ++ return; ++ } ++ ++ if (dwc_qh_is_non_per(qh)) { ++ if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry) { ++ hcd->non_periodic_qh_ptr = ++ hcd->non_periodic_qh_ptr->next; ++ } ++ DWC_LIST_REMOVE_INIT(&qh->qh_list_entry); ++ } else { ++ deschedule_periodic(hcd, qh); ++ hcd->periodic_qh_count--; ++ if( !hcd->periodic_qh_count ) { ++ intr_mask.b.sofintr = 1; ++ DWC_MODIFY_REG32(&hcd->core_if->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ } ++ } ++} ++ ++/** ++ * Deactivates a QH. For non-periodic QHs, removes the QH from the active ++ * non-periodic schedule. The QH is added to the inactive non-periodic ++ * schedule if any QTDs are still attached to the QH. ++ * ++ * For periodic QHs, the QH is removed from the periodic queued schedule. If ++ * there are any QTDs still attached to the QH, the QH is added to either the ++ * periodic inactive schedule or the periodic ready schedule and its next ++ * scheduled frame is calculated. The QH is placed in the ready schedule if ++ * the scheduled frame has been reached already. Otherwise it's placed in the ++ * inactive schedule. If there are no QTDs attached to the QH, the QH is ++ * completely removed from the periodic schedule. ++ */ ++void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, ++ int sched_next_periodic_split) ++{ ++ if (dwc_qh_is_non_per(qh)) { ++ dwc_otg_hcd_qh_remove(hcd, qh); ++ if (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) { ++ /* Add back to inactive non-periodic schedule. */ ++ dwc_otg_hcd_qh_add(hcd, qh); ++ } ++ } else { ++ uint16_t frame_number = dwc_otg_hcd_get_frame_number(hcd); ++ ++ if (qh->do_split) { ++ /* Schedule the next continuing periodic split transfer */ ++ if (sched_next_periodic_split) { ++ ++ qh->sched_frame = frame_number; ++ if (dwc_frame_num_le(frame_number, ++ dwc_frame_num_inc ++ (qh->start_split_frame, ++ 1))) { ++ /* ++ * Allow one frame to elapse after start ++ * split microframe before scheduling ++ * complete split, but DONT if we are ++ * doing the next start split in the ++ * same frame for an ISOC out. ++ */ ++ if ((qh->ep_type != UE_ISOCHRONOUS) || ++ (qh->ep_is_in != 0)) { ++ qh->sched_frame = ++ dwc_frame_num_inc(qh->sched_frame, 1); ++ } ++ } ++ } else { ++ qh->sched_frame = ++ dwc_frame_num_inc(qh->start_split_frame, ++ qh->interval); ++ if (dwc_frame_num_le ++ (qh->sched_frame, frame_number)) { ++ qh->sched_frame = frame_number; ++ } ++ qh->sched_frame |= 0x7; ++ qh->start_split_frame = qh->sched_frame; ++ } ++ } else { ++ qh->sched_frame = ++ dwc_frame_num_inc(qh->sched_frame, qh->interval); ++ if (dwc_frame_num_le(qh->sched_frame, frame_number)) { ++ qh->sched_frame = frame_number; ++ } ++ } ++ ++ if (DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) { ++ dwc_otg_hcd_qh_remove(hcd, qh); ++ } else { ++ /* ++ * Remove from periodic_sched_queued and move to ++ * appropriate queue. ++ */ ++ if ((microframe_schedule && dwc_frame_num_le(qh->sched_frame, frame_number)) || ++ (!microframe_schedule && qh->sched_frame == frame_number)) { ++ DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_ready, ++ &qh->qh_list_entry); ++ } else { ++ DWC_LIST_MOVE_HEAD ++ (&hcd->periodic_sched_inactive, ++ &qh->qh_list_entry); ++ } ++ } ++ } ++} ++ ++/** ++ * This function allocates and initializes a QTD. ++ * ++ * @param urb The URB to create a QTD from. Each URB-QTD pair will end up ++ * pointing to each other so each pair should have a unique correlation. ++ * @param atomic_alloc Flag to do atomic alloc if needed ++ * ++ * @return Returns pointer to the newly allocated QTD, or NULL on error. */ ++dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(dwc_otg_hcd_urb_t * urb, int atomic_alloc) ++{ ++ dwc_otg_qtd_t *qtd; ++ ++ qtd = dwc_otg_hcd_qtd_alloc(atomic_alloc); ++ if (qtd == NULL) { ++ return NULL; ++ } ++ ++ dwc_otg_hcd_qtd_init(qtd, urb); ++ return qtd; ++} ++ ++/** ++ * Initializes a QTD structure. ++ * ++ * @param qtd The QTD to initialize. ++ * @param urb The URB to use for initialization. */ ++void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t * qtd, dwc_otg_hcd_urb_t * urb) ++{ ++ dwc_memset(qtd, 0, sizeof(dwc_otg_qtd_t)); ++ qtd->urb = urb; ++ if (dwc_otg_hcd_get_pipe_type(&urb->pipe_info) == UE_CONTROL) { ++ /* ++ * The only time the QTD data toggle is used is on the data ++ * phase of control transfers. This phase always starts with ++ * DATA1. ++ */ ++ qtd->data_toggle = DWC_OTG_HC_PID_DATA1; ++ qtd->control_phase = DWC_OTG_CONTROL_SETUP; ++ } ++ ++ /* start split */ ++ qtd->complete_split = 0; ++ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL; ++ qtd->isoc_split_offset = 0; ++ qtd->in_process = 0; ++ ++ /* Store the qtd ptr in the urb to reference what QTD. */ ++ urb->qtd = qtd; ++ return; ++} ++ ++/** ++ * This function adds a QTD to the QTD-list of a QH. It will find the correct ++ * QH to place the QTD into. If it does not find a QH, then it will create a ++ * new QH. If the QH to which the QTD is added is not currently scheduled, it ++ * is placed into the proper schedule based on its EP type. ++ * ++ * @param[in] qtd The QTD to add ++ * @param[in] hcd The DWC HCD structure ++ * @param[out] qh out parameter to return queue head ++ * @param atomic_alloc Flag to do atomic alloc if needed ++ * ++ * @return 0 if successful, negative error code otherwise. ++ */ ++int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * qtd, ++ dwc_otg_hcd_t * hcd, dwc_otg_qh_t ** qh, int atomic_alloc) ++{ ++ int retval = 0; ++ dwc_irqflags_t flags; ++ ++ dwc_otg_hcd_urb_t *urb = qtd->urb; ++ ++ /* ++ * Get the QH which holds the QTD-list to insert to. Create QH if it ++ * doesn't exist. ++ */ ++ if (*qh == NULL) { ++ *qh = dwc_otg_hcd_qh_create(hcd, urb, atomic_alloc); ++ if (*qh == NULL) { ++ retval = -1; ++ goto done; ++ } ++ } ++ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); ++ retval = dwc_otg_hcd_qh_add(hcd, *qh); ++ if (retval == 0) { ++ DWC_CIRCLEQ_INSERT_TAIL(&((*qh)->qtd_list), qtd, ++ qtd_list_entry); ++ } ++ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ ++done: ++ ++ return retval; ++} ++ ++#endif /* DWC_DEVICE_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,185 @@ ++#ifndef _DWC_OS_DEP_H_ ++#define _DWC_OS_DEP_H_ ++ ++/** ++ * @file ++ * ++ * This file contains OS dependent structures. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) ++# include ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++# include ++#else ++# include ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++# include ++#else ++# include ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++# include ++#endif ++ ++#ifdef PCI_INTERFACE ++# include ++#endif ++ ++#ifdef LM_INTERFACE ++# include ++# include ++# include ++# include ++# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) ++# include ++# include ++# include ++# include ++# else ++/* in 2.6.31, at least, we seem to have lost the generic LM infrastructure - ++ here we assume that the machine architecture provides definitions ++ in its own header ++*/ ++# include ++# include ++# endif ++#endif ++ ++#ifdef PLATFORM_INTERFACE ++#include ++#include ++#endif ++ ++/** The OS page size */ ++#define DWC_OS_PAGE_SIZE PAGE_SIZE ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) ++typedef int gfp_t; ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ++# define IRQF_SHARED SA_SHIRQ ++#endif ++ ++typedef struct os_dependent { ++ /** Base address returned from ioremap() */ ++ void *base; ++ ++ /** Register offset for Diagnostic API */ ++ uint32_t reg_offset; ++ ++#ifdef LM_INTERFACE ++ struct lm_device *lmdev; ++#elif defined(PCI_INTERFACE) ++ struct pci_dev *pcidev; ++ ++ /** Start address of a PCI region */ ++ resource_size_t rsrc_start; ++ ++ /** Length address of a PCI region */ ++ resource_size_t rsrc_len; ++#elif defined(PLATFORM_INTERFACE) ++ struct platform_device *platformdev; ++#endif ++ ++} os_dependent_t; ++ ++#ifdef __cplusplus ++} ++#endif ++ ++ ++ ++/* Type for the our device on the chosen bus */ ++#if defined(LM_INTERFACE) ++typedef struct lm_device dwc_bus_dev_t; ++#elif defined(PCI_INTERFACE) ++typedef struct pci_dev dwc_bus_dev_t; ++#elif defined(PLATFORM_INTERFACE) ++typedef struct platform_device dwc_bus_dev_t; ++#endif ++ ++/* Helper macro to retrieve drvdata from the device on the chosen bus */ ++#if defined(LM_INTERFACE) ++#define DWC_OTG_BUSDRVDATA(_dev) lm_get_drvdata(_dev) ++#elif defined(PCI_INTERFACE) ++#define DWC_OTG_BUSDRVDATA(_dev) pci_get_drvdata(_dev) ++#elif defined(PLATFORM_INTERFACE) ++#define DWC_OTG_BUSDRVDATA(_dev) platform_get_drvdata(_dev) ++#endif ++ ++/** ++ * Helper macro returning the otg_device structure of a given struct device ++ * ++ * c.f. static dwc_otg_device_t *dwc_otg_drvdev(struct device *_dev) ++ */ ++#ifdef LM_INTERFACE ++#define DWC_OTG_GETDRVDEV(_var, _dev) do { \ ++ struct lm_device *lm_dev = \ ++ container_of(_dev, struct lm_device, dev); \ ++ _var = lm_get_drvdata(lm_dev); \ ++ } while (0) ++ ++#elif defined(PCI_INTERFACE) ++#define DWC_OTG_GETDRVDEV(_var, _dev) do { \ ++ _var = dev_get_drvdata(_dev); \ ++ } while (0) ++ ++#elif defined(PLATFORM_INTERFACE) ++#define DWC_OTG_GETDRVDEV(_var, _dev) do { \ ++ struct platform_device *platform_dev = \ ++ container_of(_dev, struct platform_device, dev); \ ++ _var = platform_get_drvdata(platform_dev); \ ++ } while (0) ++#endif ++ ++ ++/** ++ * Helper macro returning the struct dev of the given struct os_dependent ++ * ++ * c.f. static struct device *dwc_otg_getdev(struct os_dependent *osdep) ++ */ ++#ifdef LM_INTERFACE ++#define DWC_OTG_OS_GETDEV(_osdep) \ ++ ((_osdep).lmdev == NULL? NULL: &(_osdep).lmdev->dev) ++#elif defined(PCI_INTERFACE) ++#define DWC_OTG_OS_GETDEV(_osdep) \ ++ ((_osdep).pci_dev == NULL? NULL: &(_osdep).pci_dev->dev) ++#elif defined(PLATFORM_INTERFACE) ++#define DWC_OTG_OS_GETDEV(_osdep) \ ++ ((_osdep).platformdev == NULL? NULL: &(_osdep).platformdev->dev) ++#endif ++ ++ ++ ++ ++#endif /* _DWC_OS_DEP_H_ */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,2708 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $ ++ * $Revision: #101 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_HOST_ONLY ++ ++/** @file ++ * This file implements PCD Core. All code in this file is portable and doesn't ++ * use any OS specific functions. ++ * PCD Core provides Interface, defined in ++ * header file, which can be used to implement OS specific PCD interface. ++ * ++ * An important function of the PCD is managing interrupts generated ++ * by the DWC_otg controller. The implementation of the DWC_otg device ++ * mode interrupt service routines is in dwc_otg_pcd_intr.c. ++ * ++ * @todo Add Device Mode test modes (Test J mode, Test K mode, etc). ++ * @todo Does it work when the request size is greater than DEPTSIZ ++ * transfer size ++ * ++ */ ++ ++#include "dwc_otg_pcd.h" ++ ++#ifdef DWC_UTE_CFI ++#include "dwc_otg_cfi.h" ++ ++extern int init_cfi(cfiobject_t * cfiobj); ++#endif ++ ++/** ++ * Choose endpoint from ep arrays using usb_ep structure. ++ */ ++static dwc_otg_pcd_ep_t *get_ep_from_handle(dwc_otg_pcd_t * pcd, void *handle) ++{ ++ int i; ++ if (pcd->ep0.priv == handle) { ++ return &pcd->ep0; ++ } ++ for (i = 0; i < MAX_EPS_CHANNELS - 1; i++) { ++ if (pcd->in_ep[i].priv == handle) ++ return &pcd->in_ep[i]; ++ if (pcd->out_ep[i].priv == handle) ++ return &pcd->out_ep[i]; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * This function completes a request. It call's the request call back. ++ */ ++void dwc_otg_request_done(dwc_otg_pcd_ep_t * ep, dwc_otg_pcd_request_t * req, ++ int32_t status) ++{ ++ unsigned stopped = ep->stopped; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(ep %p req %p)\n", __func__, ep, req); ++ DWC_CIRCLEQ_REMOVE_INIT(&ep->queue, req, queue_entry); ++ ++ /* don't modify queue heads during completion callback */ ++ ep->stopped = 1; ++ /* spin_unlock/spin_lock now done in fops->complete() */ ++ ep->pcd->fops->complete(ep->pcd, ep->priv, req->priv, status, ++ req->actual); ++ ++ if (ep->pcd->request_pending > 0) { ++ --ep->pcd->request_pending; ++ } ++ ++ ep->stopped = stopped; ++ DWC_FREE(req); ++} ++ ++/** ++ * This function terminates all the requsts in the EP request queue. ++ */ ++void dwc_otg_request_nuke(dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_otg_pcd_request_t *req; ++ ++ ep->stopped = 1; ++ ++ /* called with irqs blocked?? */ ++ while (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ dwc_otg_request_done(ep, req, -DWC_E_SHUTDOWN); ++ } ++} ++ ++void dwc_otg_pcd_start(dwc_otg_pcd_t * pcd, ++ const struct dwc_otg_pcd_function_ops *fops) ++{ ++ pcd->fops = fops; ++} ++ ++/** ++ * PCD Callback function for initializing the PCD when switching to ++ * device mode. ++ * ++ * @param p void pointer to the dwc_otg_pcd_t ++ */ ++static int32_t dwc_otg_pcd_start_cb(void *p) ++{ ++ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ ++ /* ++ * Initialized the Core for Device mode. ++ */ ++ if (dwc_otg_is_device_mode(core_if)) { ++ dwc_otg_core_dev_init(core_if); ++ /* Set core_if's lock pointer to the pcd->lock */ ++ core_if->lock = pcd->lock; ++ } ++ return 1; ++} ++ ++/** CFI-specific buffer allocation function for EP */ ++#ifdef DWC_UTE_CFI ++uint8_t *cfiw_ep_alloc_buffer(dwc_otg_pcd_t * pcd, void *pep, dwc_dma_t * addr, ++ size_t buflen, int flags) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ ep = get_ep_from_handle(pcd, pep); ++ if (!ep) { ++ DWC_WARN("bad ep\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ return pcd->cfi->ops.ep_alloc_buf(pcd->cfi, pcd, ep, addr, buflen, ++ flags); ++} ++#else ++uint8_t *cfiw_ep_alloc_buffer(dwc_otg_pcd_t * pcd, void *pep, dwc_dma_t * addr, ++ size_t buflen, int flags); ++#endif ++ ++/** ++ * PCD Callback function for notifying the PCD when resuming from ++ * suspend. ++ * ++ * @param p void pointer to the dwc_otg_pcd_t ++ */ ++static int32_t dwc_otg_pcd_resume_cb(void *p) ++{ ++ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p; ++ ++ if (pcd->fops->resume) { ++ pcd->fops->resume(pcd); ++ } ++ ++ /* Stop the SRP timeout timer. */ ++ if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS) ++ || (!GET_CORE_IF(pcd)->core_params->i2c_enable)) { ++ if (GET_CORE_IF(pcd)->srp_timer_started) { ++ GET_CORE_IF(pcd)->srp_timer_started = 0; ++ DWC_TIMER_CANCEL(GET_CORE_IF(pcd)->srp_timer); ++ } ++ } ++ return 1; ++} ++ ++/** ++ * PCD Callback function for notifying the PCD device is suspended. ++ * ++ * @param p void pointer to the dwc_otg_pcd_t ++ */ ++static int32_t dwc_otg_pcd_suspend_cb(void *p) ++{ ++ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p; ++ ++ if (pcd->fops->suspend) { ++ DWC_SPINUNLOCK(pcd->lock); ++ pcd->fops->suspend(pcd); ++ DWC_SPINLOCK(pcd->lock); ++ } ++ ++ return 1; ++} ++ ++/** ++ * PCD Callback function for stopping the PCD when switching to Host ++ * mode. ++ * ++ * @param p void pointer to the dwc_otg_pcd_t ++ */ ++static int32_t dwc_otg_pcd_stop_cb(void *p) ++{ ++ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p; ++ extern void dwc_otg_pcd_stop(dwc_otg_pcd_t * _pcd); ++ ++ dwc_otg_pcd_stop(pcd); ++ return 1; ++} ++ ++/** ++ * PCD Callback structure for handling mode switching. ++ */ ++static dwc_otg_cil_callbacks_t pcd_callbacks = { ++ .start = dwc_otg_pcd_start_cb, ++ .stop = dwc_otg_pcd_stop_cb, ++ .suspend = dwc_otg_pcd_suspend_cb, ++ .resume_wakeup = dwc_otg_pcd_resume_cb, ++ .p = 0, /* Set at registration */ ++}; ++ ++/** ++ * This function allocates a DMA Descriptor chain for the Endpoint ++ * buffer to be used for a transfer to/from the specified endpoint. ++ */ ++dwc_otg_dev_dma_desc_t *dwc_otg_ep_alloc_desc_chain(dwc_dma_t * dma_desc_addr, ++ uint32_t count) ++{ ++ return DWC_DMA_ALLOC_ATOMIC(count * sizeof(dwc_otg_dev_dma_desc_t), ++ dma_desc_addr); ++} ++ ++/** ++ * This function frees a DMA Descriptor chain that was allocated by ep_alloc_desc. ++ */ ++void dwc_otg_ep_free_desc_chain(dwc_otg_dev_dma_desc_t * desc_addr, ++ uint32_t dma_desc_addr, uint32_t count) ++{ ++ DWC_DMA_FREE(count * sizeof(dwc_otg_dev_dma_desc_t), desc_addr, ++ dma_desc_addr); ++} ++ ++#ifdef DWC_EN_ISOC ++ ++/** ++ * This function initializes a descriptor chain for Isochronous transfer ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param dwc_ep The EP to start the transfer on. ++ * ++ */ ++void dwc_otg_iso_ep_start_ddma_transfer(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * dwc_ep) ++{ ++ ++ dsts_data_t dsts = {.d32 = 0 }; ++ depctl_data_t depctl = {.d32 = 0 }; ++ volatile uint32_t *addr; ++ int i, j; ++ uint32_t len; ++ ++ if (dwc_ep->is_in) ++ dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl / dwc_ep->bInterval; ++ else ++ dwc_ep->desc_cnt = ++ dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / ++ dwc_ep->bInterval; ++ ++ /** Allocate descriptors for double buffering */ ++ dwc_ep->iso_desc_addr = ++ dwc_otg_ep_alloc_desc_chain(&dwc_ep->iso_dma_desc_addr, ++ dwc_ep->desc_cnt * 2); ++ if (dwc_ep->desc_addr) { ++ DWC_WARN("%s, can't allocate DMA descriptor chain\n", __func__); ++ return; ++ } ++ ++ dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ ++ /** ISO OUT EP */ ++ if (dwc_ep->is_in == 0) { ++ dev_dma_desc_sts_t sts = {.d32 = 0 }; ++ dwc_otg_dev_dma_desc_t *dma_desc = dwc_ep->iso_desc_addr; ++ dma_addr_t dma_ad; ++ uint32_t data_per_desc; ++ dwc_otg_dev_out_ep_regs_t *out_regs = ++ core_if->dev_if->out_ep_regs[dwc_ep->num]; ++ int offset; ++ ++ addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl; ++ dma_ad = (dma_addr_t) DWC_READ_REG32(&(out_regs->doepdma)); ++ ++ /** Buffer 0 descriptors setup */ ++ dma_ad = dwc_ep->dma_addr0; ++ ++ sts.b_iso_out.bs = BS_HOST_READY; ++ sts.b_iso_out.rxsts = 0; ++ sts.b_iso_out.l = 0; ++ sts.b_iso_out.sp = 0; ++ sts.b_iso_out.ioc = 0; ++ sts.b_iso_out.pid = 0; ++ sts.b_iso_out.framenum = 0; ++ ++ offset = 0; ++ for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; ++ i += dwc_ep->pkt_per_frm) { ++ ++ for (j = 0; j < dwc_ep->pkt_per_frm; ++j) { ++ uint32_t len = (j + 1) * dwc_ep->maxpacket; ++ if (len > dwc_ep->data_per_frame) ++ data_per_desc = ++ dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket; ++ else ++ data_per_desc = dwc_ep->maxpacket; ++ len = data_per_desc % 4; ++ if (len) ++ data_per_desc += 4 - len; ++ ++ sts.b_iso_out.rxbytes = data_per_desc; ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ offset += data_per_desc; ++ dma_desc++; ++ dma_ad += data_per_desc; ++ } ++ } ++ ++ for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) { ++ uint32_t len = (j + 1) * dwc_ep->maxpacket; ++ if (len > dwc_ep->data_per_frame) ++ data_per_desc = ++ dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket; ++ else ++ data_per_desc = dwc_ep->maxpacket; ++ len = data_per_desc % 4; ++ if (len) ++ data_per_desc += 4 - len; ++ sts.b_iso_out.rxbytes = data_per_desc; ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ offset += data_per_desc; ++ dma_desc++; ++ dma_ad += data_per_desc; ++ } ++ ++ sts.b_iso_out.ioc = 1; ++ len = (j + 1) * dwc_ep->maxpacket; ++ if (len > dwc_ep->data_per_frame) ++ data_per_desc = ++ dwc_ep->data_per_frame - j * dwc_ep->maxpacket; ++ else ++ data_per_desc = dwc_ep->maxpacket; ++ len = data_per_desc % 4; ++ if (len) ++ data_per_desc += 4 - len; ++ sts.b_iso_out.rxbytes = data_per_desc; ++ ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ dma_desc++; ++ ++ /** Buffer 1 descriptors setup */ ++ sts.b_iso_out.ioc = 0; ++ dma_ad = dwc_ep->dma_addr1; ++ ++ offset = 0; ++ for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; ++ i += dwc_ep->pkt_per_frm) { ++ for (j = 0; j < dwc_ep->pkt_per_frm; ++j) { ++ uint32_t len = (j + 1) * dwc_ep->maxpacket; ++ if (len > dwc_ep->data_per_frame) ++ data_per_desc = ++ dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket; ++ else ++ data_per_desc = dwc_ep->maxpacket; ++ len = data_per_desc % 4; ++ if (len) ++ data_per_desc += 4 - len; ++ ++ data_per_desc = ++ sts.b_iso_out.rxbytes = data_per_desc; ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ offset += data_per_desc; ++ dma_desc++; ++ dma_ad += data_per_desc; ++ } ++ } ++ for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) { ++ data_per_desc = ++ ((j + 1) * dwc_ep->maxpacket > ++ dwc_ep->data_per_frame) ? dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket : dwc_ep->maxpacket; ++ data_per_desc += ++ (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0; ++ sts.b_iso_out.rxbytes = data_per_desc; ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ offset += data_per_desc; ++ dma_desc++; ++ dma_ad += data_per_desc; ++ } ++ ++ sts.b_iso_out.ioc = 1; ++ sts.b_iso_out.l = 1; ++ data_per_desc = ++ ((j + 1) * dwc_ep->maxpacket > ++ dwc_ep->data_per_frame) ? dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket : dwc_ep->maxpacket; ++ data_per_desc += ++ (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0; ++ sts.b_iso_out.rxbytes = data_per_desc; ++ ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ dwc_ep->next_frame = 0; ++ ++ /** Write dma_ad into DOEPDMA register */ ++ DWC_WRITE_REG32(&(out_regs->doepdma), ++ (uint32_t) dwc_ep->iso_dma_desc_addr); ++ ++ } ++ /** ISO IN EP */ ++ else { ++ dev_dma_desc_sts_t sts = {.d32 = 0 }; ++ dwc_otg_dev_dma_desc_t *dma_desc = dwc_ep->iso_desc_addr; ++ dma_addr_t dma_ad; ++ dwc_otg_dev_in_ep_regs_t *in_regs = ++ core_if->dev_if->in_ep_regs[dwc_ep->num]; ++ unsigned int frmnumber; ++ fifosize_data_t txfifosize, rxfifosize; ++ ++ txfifosize.d32 = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[dwc_ep->num]-> ++ dtxfsts); ++ rxfifosize.d32 = ++ DWC_READ_REG32(&core_if->core_global_regs->grxfsiz); ++ ++ addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl; ++ ++ dma_ad = dwc_ep->dma_addr0; ++ ++ dsts.d32 = ++ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ ++ sts.b_iso_in.bs = BS_HOST_READY; ++ sts.b_iso_in.txsts = 0; ++ sts.b_iso_in.sp = ++ (dwc_ep->data_per_frame % dwc_ep->maxpacket) ? 1 : 0; ++ sts.b_iso_in.ioc = 0; ++ sts.b_iso_in.pid = dwc_ep->pkt_per_frm; ++ ++ frmnumber = dwc_ep->next_frame; ++ ++ sts.b_iso_in.framenum = frmnumber; ++ sts.b_iso_in.txbytes = dwc_ep->data_per_frame; ++ sts.b_iso_in.l = 0; ++ ++ /** Buffer 0 descriptors setup */ ++ for (i = 0; i < dwc_ep->desc_cnt - 1; i++) { ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ dma_desc++; ++ ++ dma_ad += dwc_ep->data_per_frame; ++ sts.b_iso_in.framenum += dwc_ep->bInterval; ++ } ++ ++ sts.b_iso_in.ioc = 1; ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++dma_desc; ++ ++ /** Buffer 1 descriptors setup */ ++ sts.b_iso_in.ioc = 0; ++ dma_ad = dwc_ep->dma_addr1; ++ ++ for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; ++ i += dwc_ep->pkt_per_frm) { ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ dma_desc++; ++ ++ dma_ad += dwc_ep->data_per_frame; ++ sts.b_iso_in.framenum += dwc_ep->bInterval; ++ ++ sts.b_iso_in.ioc = 0; ++ } ++ sts.b_iso_in.ioc = 1; ++ sts.b_iso_in.l = 1; ++ ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval; ++ ++ /** Write dma_ad into diepdma register */ ++ DWC_WRITE_REG32(&(in_regs->diepdma), ++ (uint32_t) dwc_ep->iso_dma_desc_addr); ++ } ++ /** Enable endpoint, clear nak */ ++ depctl.d32 = 0; ++ depctl.b.epena = 1; ++ depctl.b.usbactep = 1; ++ depctl.b.cnak = 1; ++ ++ DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32); ++ depctl.d32 = DWC_READ_REG32(addr); ++} ++ ++/** ++ * This function initializes a descriptor chain for Isochronous transfer ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ * ++ */ ++void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * ep) ++{ ++ depctl_data_t depctl = {.d32 = 0 }; ++ volatile uint32_t *addr; ++ ++ if (ep->is_in) { ++ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl; ++ } else { ++ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl; ++ } ++ ++ if (core_if->dma_enable == 0 || core_if->dma_desc_enable != 0) { ++ return; ++ } else { ++ deptsiz_data_t deptsiz = {.d32 = 0 }; ++ ++ ep->xfer_len = ++ ep->data_per_frame * ep->buf_proc_intrvl / ep->bInterval; ++ ep->pkt_cnt = ++ (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; ++ ep->xfer_count = 0; ++ ep->xfer_buff = ++ (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0; ++ ep->dma_addr = ++ (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0; ++ ++ if (ep->is_in) { ++ /* Program the transfer size and packet count ++ * as follows: xfersize = N * maxpacket + ++ * short_packet pktcnt = N + (short_packet ++ * exist ? 1 : 0) ++ */ ++ deptsiz.b.mc = ep->pkt_per_frm; ++ deptsiz.b.xfersize = ep->xfer_len; ++ deptsiz.b.pktcnt = ++ (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]-> ++ dieptsiz, deptsiz.d32); ++ ++ /* Write the DMA register */ ++ DWC_WRITE_REG32(& ++ (core_if->dev_if->in_ep_regs[ep->num]-> ++ diepdma), (uint32_t) ep->dma_addr); ++ ++ } else { ++ deptsiz.b.pktcnt = ++ (ep->xfer_len + (ep->maxpacket - 1)) / ++ ep->maxpacket; ++ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; ++ ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]-> ++ doeptsiz, deptsiz.d32); ++ ++ /* Write the DMA register */ ++ DWC_WRITE_REG32(& ++ (core_if->dev_if->out_ep_regs[ep->num]-> ++ doepdma), (uint32_t) ep->dma_addr); ++ ++ } ++ /** Enable endpoint, clear nak */ ++ depctl.d32 = 0; ++ depctl.b.epena = 1; ++ depctl.b.cnak = 1; ++ ++ DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32); ++ } ++} ++ ++/** ++ * This function does the setup for a data transfer for an EP and ++ * starts the transfer. For an IN transfer, the packets will be ++ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers, ++ * the packets are unloaded from the Rx FIFO in the ISR. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ */ ++ ++static void dwc_otg_iso_ep_start_transfer(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * ep) ++{ ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable) { ++ if (ep->is_in) { ++ ep->desc_cnt = ep->pkt_cnt / ep->pkt_per_frm; ++ } else { ++ ep->desc_cnt = ep->pkt_cnt; ++ } ++ dwc_otg_iso_ep_start_ddma_transfer(core_if, ep); ++ } else { ++ if (core_if->pti_enh_enable) { ++ dwc_otg_iso_ep_start_buf_transfer(core_if, ep); ++ } else { ++ ep->cur_pkt_addr = ++ (ep->proc_buf_num) ? ep->xfer_buff1 : ep-> ++ xfer_buff0; ++ ep->cur_pkt_dma_addr = ++ (ep->proc_buf_num) ? ep->dma_addr1 : ep-> ++ dma_addr0; ++ dwc_otg_iso_ep_start_frm_transfer(core_if, ep); ++ } ++ } ++ } else { ++ ep->cur_pkt_addr = ++ (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0; ++ ep->cur_pkt_dma_addr = ++ (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0; ++ dwc_otg_iso_ep_start_frm_transfer(core_if, ep); ++ } ++} ++ ++/** ++ * This function stops transfer for an EP and ++ * resets the ep's variables. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ */ ++ ++void dwc_otg_iso_ep_stop_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ depctl_data_t depctl = {.d32 = 0 }; ++ volatile uint32_t *addr; ++ ++ if (ep->is_in == 1) { ++ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl; ++ } else { ++ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl; ++ } ++ ++ /* disable the ep */ ++ depctl.d32 = DWC_READ_REG32(addr); ++ ++ depctl.b.epdis = 1; ++ depctl.b.snak = 1; ++ ++ DWC_WRITE_REG32(addr, depctl.d32); ++ ++ if (core_if->dma_desc_enable && ++ ep->iso_desc_addr && ep->iso_dma_desc_addr) { ++ dwc_otg_ep_free_desc_chain(ep->iso_desc_addr, ++ ep->iso_dma_desc_addr, ++ ep->desc_cnt * 2); ++ } ++ ++ /* reset varibales */ ++ ep->dma_addr0 = 0; ++ ep->dma_addr1 = 0; ++ ep->xfer_buff0 = 0; ++ ep->xfer_buff1 = 0; ++ ep->data_per_frame = 0; ++ ep->data_pattern_frame = 0; ++ ep->sync_frame = 0; ++ ep->buf_proc_intrvl = 0; ++ ep->bInterval = 0; ++ ep->proc_buf_num = 0; ++ ep->pkt_per_frm = 0; ++ ep->pkt_per_frm = 0; ++ ep->desc_cnt = 0; ++ ep->iso_desc_addr = 0; ++ ep->iso_dma_desc_addr = 0; ++} ++ ++int dwc_otg_pcd_iso_ep_start(dwc_otg_pcd_t * pcd, void *ep_handle, ++ uint8_t * buf0, uint8_t * buf1, dwc_dma_t dma0, ++ dwc_dma_t dma1, int sync_frame, int dp_frame, ++ int data_per_frame, int start_frame, ++ int buf_proc_intrvl, void *req_handle, ++ int atomic_alloc) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ dwc_irqflags_t flags = 0; ++ dwc_ep_t *dwc_ep; ++ int32_t frm_data; ++ dsts_data_t dsts; ++ dwc_otg_core_if_t *core_if; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ ++ if (!ep || !ep->desc || ep->dwc_ep.num == 0) { ++ DWC_WARN("bad ep\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ core_if = GET_CORE_IF(pcd); ++ dwc_ep = &ep->dwc_ep; ++ ++ if (ep->iso_req_handle) { ++ DWC_WARN("ISO request in progress\n"); ++ } ++ ++ dwc_ep->dma_addr0 = dma0; ++ dwc_ep->dma_addr1 = dma1; ++ ++ dwc_ep->xfer_buff0 = buf0; ++ dwc_ep->xfer_buff1 = buf1; ++ ++ dwc_ep->data_per_frame = data_per_frame; ++ ++ /** @todo - pattern data support is to be implemented in the future */ ++ dwc_ep->data_pattern_frame = dp_frame; ++ dwc_ep->sync_frame = sync_frame; ++ ++ dwc_ep->buf_proc_intrvl = buf_proc_intrvl; ++ ++ dwc_ep->bInterval = 1 << (ep->desc->bInterval - 1); ++ ++ dwc_ep->proc_buf_num = 0; ++ ++ dwc_ep->pkt_per_frm = 0; ++ frm_data = ep->dwc_ep.data_per_frame; ++ while (frm_data > 0) { ++ dwc_ep->pkt_per_frm++; ++ frm_data -= ep->dwc_ep.maxpacket; ++ } ++ ++ dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ ++ if (start_frame == -1) { ++ dwc_ep->next_frame = dsts.b.soffn + 1; ++ if (dwc_ep->bInterval != 1) { ++ dwc_ep->next_frame = ++ dwc_ep->next_frame + (dwc_ep->bInterval - 1 - ++ dwc_ep->next_frame % ++ dwc_ep->bInterval); ++ } ++ } else { ++ dwc_ep->next_frame = start_frame; ++ } ++ ++ if (!core_if->pti_enh_enable) { ++ dwc_ep->pkt_cnt = ++ dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / ++ dwc_ep->bInterval; ++ } else { ++ dwc_ep->pkt_cnt = ++ (dwc_ep->data_per_frame * ++ (dwc_ep->buf_proc_intrvl / dwc_ep->bInterval) ++ - 1 + dwc_ep->maxpacket) / dwc_ep->maxpacket; ++ } ++ ++ if (core_if->dma_desc_enable) { ++ dwc_ep->desc_cnt = ++ dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm / ++ dwc_ep->bInterval; ++ } ++ ++ if (atomic_alloc) { ++ dwc_ep->pkt_info = ++ DWC_ALLOC_ATOMIC(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt); ++ } else { ++ dwc_ep->pkt_info = ++ DWC_ALLOC(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt); ++ } ++ if (!dwc_ep->pkt_info) { ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ return -DWC_E_NO_MEMORY; ++ } ++ if (core_if->pti_enh_enable) { ++ dwc_memset(dwc_ep->pkt_info, 0, ++ sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt); ++ } ++ ++ dwc_ep->cur_pkt = 0; ++ ep->iso_req_handle = req_handle; ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ dwc_otg_iso_ep_start_transfer(core_if, dwc_ep); ++ return 0; ++} ++ ++int dwc_otg_pcd_iso_ep_stop(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle) ++{ ++ dwc_irqflags_t flags = 0; ++ dwc_otg_pcd_ep_t *ep; ++ dwc_ep_t *dwc_ep; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ if (!ep || !ep->desc || ep->dwc_ep.num == 0) { ++ DWC_WARN("bad ep\n"); ++ return -DWC_E_INVALID; ++ } ++ dwc_ep = &ep->dwc_ep; ++ ++ dwc_otg_iso_ep_stop_transfer(GET_CORE_IF(pcd), dwc_ep); ++ ++ DWC_FREE(dwc_ep->pkt_info); ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ if (ep->iso_req_handle != req_handle) { ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++ ep->iso_req_handle = 0; ++ return 0; ++} ++ ++/** ++ * This function is used for perodical data exchnage between PCD and gadget drivers. ++ * for Isochronous EPs ++ * ++ * - Every time a sync period completes this function is called to ++ * perform data exchange between PCD and gadget ++ */ ++void dwc_otg_iso_buffer_done(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep, ++ void *req_handle) ++{ ++ int i; ++ dwc_ep_t *dwc_ep; ++ ++ dwc_ep = &ep->dwc_ep; ++ ++ DWC_SPINUNLOCK(ep->pcd->lock); ++ pcd->fops->isoc_complete(pcd, ep->priv, ep->iso_req_handle, ++ dwc_ep->proc_buf_num ^ 0x1); ++ DWC_SPINLOCK(ep->pcd->lock); ++ ++ for (i = 0; i < dwc_ep->pkt_cnt; ++i) { ++ dwc_ep->pkt_info[i].status = 0; ++ dwc_ep->pkt_info[i].offset = 0; ++ dwc_ep->pkt_info[i].length = 0; ++ } ++} ++ ++int dwc_otg_pcd_get_iso_packet_count(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *iso_req_handle) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ dwc_ep_t *dwc_ep; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ if (!ep->desc || ep->dwc_ep.num == 0) { ++ DWC_WARN("bad ep\n"); ++ return -DWC_E_INVALID; ++ } ++ dwc_ep = &ep->dwc_ep; ++ ++ return dwc_ep->pkt_cnt; ++} ++ ++void dwc_otg_pcd_get_iso_packet_params(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *iso_req_handle, int packet, ++ int *status, int *actual, int *offset) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ dwc_ep_t *dwc_ep; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ if (!ep) ++ DWC_WARN("bad ep\n"); ++ ++ dwc_ep = &ep->dwc_ep; ++ ++ *status = dwc_ep->pkt_info[packet].status; ++ *actual = dwc_ep->pkt_info[packet].length; ++ *offset = dwc_ep->pkt_info[packet].offset; ++} ++ ++#endif /* DWC_EN_ISOC */ ++ ++static void dwc_otg_pcd_init_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * pcd_ep, ++ uint32_t is_in, uint32_t ep_num) ++{ ++ /* Init EP structure */ ++ pcd_ep->desc = 0; ++ pcd_ep->pcd = pcd; ++ pcd_ep->stopped = 1; ++ pcd_ep->queue_sof = 0; ++ ++ /* Init DWC ep structure */ ++ pcd_ep->dwc_ep.is_in = is_in; ++ pcd_ep->dwc_ep.num = ep_num; ++ pcd_ep->dwc_ep.active = 0; ++ pcd_ep->dwc_ep.tx_fifo_num = 0; ++ /* Control until ep is actvated */ ++ pcd_ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; ++ pcd_ep->dwc_ep.maxpacket = MAX_PACKET_SIZE; ++ pcd_ep->dwc_ep.dma_addr = 0; ++ pcd_ep->dwc_ep.start_xfer_buff = 0; ++ pcd_ep->dwc_ep.xfer_buff = 0; ++ pcd_ep->dwc_ep.xfer_len = 0; ++ pcd_ep->dwc_ep.xfer_count = 0; ++ pcd_ep->dwc_ep.sent_zlp = 0; ++ pcd_ep->dwc_ep.total_len = 0; ++ pcd_ep->dwc_ep.desc_addr = 0; ++ pcd_ep->dwc_ep.dma_desc_addr = 0; ++ DWC_CIRCLEQ_INIT(&pcd_ep->queue); ++} ++ ++/** ++ * Initialize ep's ++ */ ++static void dwc_otg_pcd_reinit(dwc_otg_pcd_t * pcd) ++{ ++ int i; ++ uint32_t hwcfg1; ++ dwc_otg_pcd_ep_t *ep; ++ int in_ep_cntr, out_ep_cntr; ++ uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps; ++ uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps; ++ ++ /** ++ * Initialize the EP0 structure. ++ */ ++ ep = &pcd->ep0; ++ dwc_otg_pcd_init_ep(pcd, ep, 0, 0); ++ ++ in_ep_cntr = 0; ++ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3; ++ for (i = 1; in_ep_cntr < num_in_eps; i++) { ++ if ((hwcfg1 & 0x1) == 0) { ++ dwc_otg_pcd_ep_t *ep = &pcd->in_ep[in_ep_cntr]; ++ in_ep_cntr++; ++ /** ++ * @todo NGS: Add direction to EP, based on contents ++ * of HWCFG1. Need a copy of HWCFG1 in pcd structure? ++ * sprintf(";r ++ */ ++ dwc_otg_pcd_init_ep(pcd, ep, 1 /* IN */ , i); ++ ++ DWC_CIRCLEQ_INIT(&ep->queue); ++ } ++ hwcfg1 >>= 2; ++ } ++ ++ out_ep_cntr = 0; ++ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2; ++ for (i = 1; out_ep_cntr < num_out_eps; i++) { ++ if ((hwcfg1 & 0x1) == 0) { ++ dwc_otg_pcd_ep_t *ep = &pcd->out_ep[out_ep_cntr]; ++ out_ep_cntr++; ++ /** ++ * @todo NGS: Add direction to EP, based on contents ++ * of HWCFG1. Need a copy of HWCFG1 in pcd structure? ++ * sprintf(";r ++ */ ++ dwc_otg_pcd_init_ep(pcd, ep, 0 /* OUT */ , i); ++ DWC_CIRCLEQ_INIT(&ep->queue); ++ } ++ hwcfg1 >>= 2; ++ } ++ ++ pcd->ep0state = EP0_DISCONNECT; ++ pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE; ++ pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; ++} ++ ++/** ++ * This function is called when the SRP timer expires. The SRP should ++ * complete within 6 seconds. ++ */ ++static void srp_timeout(void *ptr) ++{ ++ gotgctl_data_t gotgctl; ++ dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr; ++ volatile uint32_t *addr = &core_if->core_global_regs->gotgctl; ++ ++ gotgctl.d32 = DWC_READ_REG32(addr); ++ ++ core_if->srp_timer_started = 0; ++ ++ if (core_if->adp_enable) { ++ if (gotgctl.b.bsesvld == 0) { ++ gpwrdn_data_t gpwrdn = {.d32 = 0 }; ++ DWC_PRINTF("SRP Timeout BSESSVLD = 0\n"); ++ /* Power off the core */ ++ if (core_if->power_down == 2) { ++ gpwrdn.b.pwrdnswtch = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs->gpwrdn, ++ gpwrdn.d32, 0); ++ } ++ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuintsel = 1; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, ++ gpwrdn.d32); ++ dwc_otg_adp_probe_start(core_if); ++ } else { ++ DWC_PRINTF("SRP Timeout BSESSVLD = 1\n"); ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ } ++ } ++ ++ if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) && ++ (core_if->core_params->i2c_enable)) { ++ DWC_PRINTF("SRP Timeout\n"); ++ ++ if ((core_if->srp_success) && (gotgctl.b.bsesvld)) { ++ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) { ++ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p); ++ } ++ ++ /* Clear Session Request */ ++ gotgctl.d32 = 0; ++ gotgctl.b.sesreq = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, ++ gotgctl.d32, 0); ++ ++ core_if->srp_success = 0; ++ } else { ++ __DWC_ERROR("Device not connected/responding\n"); ++ gotgctl.b.sesreq = 0; ++ DWC_WRITE_REG32(addr, gotgctl.d32); ++ } ++ } else if (gotgctl.b.sesreq) { ++ DWC_PRINTF("SRP Timeout\n"); ++ ++ __DWC_ERROR("Device not connected/responding\n"); ++ gotgctl.b.sesreq = 0; ++ DWC_WRITE_REG32(addr, gotgctl.d32); ++ } else { ++ DWC_PRINTF(" SRP GOTGCTL=%0x\n", gotgctl.d32); ++ } ++} ++ ++/** ++ * Tasklet ++ * ++ */ ++extern void start_next_request(dwc_otg_pcd_ep_t * ep); ++ ++static void start_xfer_tasklet_func(void *data) ++{ ++ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ ++ int i; ++ depctl_data_t diepctl; ++ ++ DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n"); ++ ++ diepctl.d32 = DWC_READ_REG32(&core_if->dev_if->in_ep_regs[0]->diepctl); ++ ++ if (pcd->ep0.queue_sof) { ++ pcd->ep0.queue_sof = 0; ++ start_next_request(&pcd->ep0); ++ // break; ++ } ++ ++ for (i = 0; i < core_if->dev_if->num_in_eps; i++) { ++ depctl_data_t diepctl; ++ diepctl.d32 = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl); ++ ++ if (pcd->in_ep[i].queue_sof) { ++ pcd->in_ep[i].queue_sof = 0; ++ start_next_request(&pcd->in_ep[i]); ++ // break; ++ } ++ } ++ ++ return; ++} ++ ++/** ++ * This function initialized the PCD portion of the driver. ++ * ++ */ ++dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_pcd_t *pcd = NULL; ++ dwc_otg_dev_if_t *dev_if; ++ int i; ++ ++ /* ++ * Allocate PCD structure ++ */ ++ pcd = DWC_ALLOC(sizeof(dwc_otg_pcd_t)); ++ ++ if (pcd == NULL) { ++ return NULL; ++ } ++ ++ pcd->lock = DWC_SPINLOCK_ALLOC(); ++ DWC_DEBUGPL(DBG_HCDV, "Init of PCD %p given core_if %p\n", ++ pcd, core_if);//GRAYG ++ if (!pcd->lock) { ++ DWC_ERROR("Could not allocate lock for pcd"); ++ DWC_FREE(pcd); ++ return NULL; ++ } ++ /* Set core_if's lock pointer to hcd->lock */ ++ core_if->lock = pcd->lock; ++ pcd->core_if = core_if; ++ ++ dev_if = core_if->dev_if; ++ dev_if->isoc_ep = NULL; ++ ++ if (core_if->hwcfg4.b.ded_fifo_en) { ++ DWC_PRINTF("Dedicated Tx FIFOs mode\n"); ++ } else { ++ DWC_PRINTF("Shared Tx FIFO mode\n"); ++ } ++ ++ /* ++ * Initialized the Core for Device mode here if there is nod ADP support. ++ * Otherwise it will be done later in dwc_otg_adp_start routine. ++ */ ++ if (dwc_otg_is_device_mode(core_if) /*&& !core_if->adp_enable*/) { ++ dwc_otg_core_dev_init(core_if); ++ } ++ ++ /* ++ * Register the PCD Callbacks. ++ */ ++ dwc_otg_cil_register_pcd_callbacks(core_if, &pcd_callbacks, pcd); ++ ++ /* ++ * Initialize the DMA buffer for SETUP packets ++ */ ++ if (GET_CORE_IF(pcd)->dma_enable) { ++ pcd->setup_pkt = ++ DWC_DMA_ALLOC(sizeof(*pcd->setup_pkt) * 5, ++ &pcd->setup_pkt_dma_handle); ++ if (pcd->setup_pkt == NULL) { ++ DWC_FREE(pcd); ++ return NULL; ++ } ++ ++ pcd->status_buf = ++ DWC_DMA_ALLOC(sizeof(uint16_t), ++ &pcd->status_buf_dma_handle); ++ if (pcd->status_buf == NULL) { ++ DWC_DMA_FREE(sizeof(*pcd->setup_pkt) * 5, ++ pcd->setup_pkt, pcd->setup_pkt_dma_handle); ++ DWC_FREE(pcd); ++ return NULL; ++ } ++ ++ if (GET_CORE_IF(pcd)->dma_desc_enable) { ++ dev_if->setup_desc_addr[0] = ++ dwc_otg_ep_alloc_desc_chain ++ (&dev_if->dma_setup_desc_addr[0], 1); ++ dev_if->setup_desc_addr[1] = ++ dwc_otg_ep_alloc_desc_chain ++ (&dev_if->dma_setup_desc_addr[1], 1); ++ dev_if->in_desc_addr = ++ dwc_otg_ep_alloc_desc_chain ++ (&dev_if->dma_in_desc_addr, 1); ++ dev_if->out_desc_addr = ++ dwc_otg_ep_alloc_desc_chain ++ (&dev_if->dma_out_desc_addr, 1); ++ pcd->data_terminated = 0; ++ ++ if (dev_if->setup_desc_addr[0] == 0 ++ || dev_if->setup_desc_addr[1] == 0 ++ || dev_if->in_desc_addr == 0 ++ || dev_if->out_desc_addr == 0) { ++ ++ if (dev_if->out_desc_addr) ++ dwc_otg_ep_free_desc_chain ++ (dev_if->out_desc_addr, ++ dev_if->dma_out_desc_addr, 1); ++ if (dev_if->in_desc_addr) ++ dwc_otg_ep_free_desc_chain ++ (dev_if->in_desc_addr, ++ dev_if->dma_in_desc_addr, 1); ++ if (dev_if->setup_desc_addr[1]) ++ dwc_otg_ep_free_desc_chain ++ (dev_if->setup_desc_addr[1], ++ dev_if->dma_setup_desc_addr[1], 1); ++ if (dev_if->setup_desc_addr[0]) ++ dwc_otg_ep_free_desc_chain ++ (dev_if->setup_desc_addr[0], ++ dev_if->dma_setup_desc_addr[0], 1); ++ ++ DWC_DMA_FREE(sizeof(*pcd->setup_pkt) * 5, ++ pcd->setup_pkt, ++ pcd->setup_pkt_dma_handle); ++ DWC_DMA_FREE(sizeof(*pcd->status_buf), ++ pcd->status_buf, ++ pcd->status_buf_dma_handle); ++ ++ DWC_FREE(pcd); ++ ++ return NULL; ++ } ++ } ++ } else { ++ pcd->setup_pkt = DWC_ALLOC(sizeof(*pcd->setup_pkt) * 5); ++ if (pcd->setup_pkt == NULL) { ++ DWC_FREE(pcd); ++ return NULL; ++ } ++ ++ pcd->status_buf = DWC_ALLOC(sizeof(uint16_t)); ++ if (pcd->status_buf == NULL) { ++ DWC_FREE(pcd->setup_pkt); ++ DWC_FREE(pcd); ++ return NULL; ++ } ++ } ++ ++ dwc_otg_pcd_reinit(pcd); ++ ++ /* Allocate the cfi object for the PCD */ ++#ifdef DWC_UTE_CFI ++ pcd->cfi = DWC_ALLOC(sizeof(cfiobject_t)); ++ if (NULL == pcd->cfi) ++ goto fail; ++ if (init_cfi(pcd->cfi)) { ++ CFI_INFO("%s: Failed to init the CFI object\n", __func__); ++ goto fail; ++ } ++#endif ++ ++ /* Initialize tasklets */ ++ pcd->start_xfer_tasklet = DWC_TASK_ALLOC("xfer_tasklet", ++ start_xfer_tasklet_func, pcd); ++ pcd->test_mode_tasklet = DWC_TASK_ALLOC("test_mode_tasklet", ++ do_test_mode, pcd); ++ ++ /* Initialize SRP timer */ ++ core_if->srp_timer = DWC_TIMER_ALLOC("SRP TIMER", srp_timeout, core_if); ++ ++ if (core_if->core_params->dev_out_nak) { ++ /** ++ * Initialize xfer timeout timer. Implemented for ++ * 2.93a feature "Device DDMA OUT NAK Enhancement" ++ */ ++ for(i = 0; i < MAX_EPS_CHANNELS; i++) { ++ pcd->core_if->ep_xfer_timer[i] = ++ DWC_TIMER_ALLOC("ep timer", ep_xfer_timeout, ++ &pcd->core_if->ep_xfer_info[i]); ++ } ++ } ++ ++ return pcd; ++#ifdef DWC_UTE_CFI ++fail: ++#endif ++ if (pcd->setup_pkt) ++ DWC_FREE(pcd->setup_pkt); ++ if (pcd->status_buf) ++ DWC_FREE(pcd->status_buf); ++#ifdef DWC_UTE_CFI ++ if (pcd->cfi) ++ DWC_FREE(pcd->cfi); ++#endif ++ if (pcd) ++ DWC_FREE(pcd); ++ return NULL; ++ ++} ++ ++/** ++ * Remove PCD specific data ++ */ ++void dwc_otg_pcd_remove(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if; ++ int i; ++ if (pcd->core_if->core_params->dev_out_nak) { ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[i]); ++ pcd->core_if->ep_xfer_info[i].state = 0; ++ } ++ } ++ ++ if (GET_CORE_IF(pcd)->dma_enable) { ++ DWC_DMA_FREE(sizeof(*pcd->setup_pkt) * 5, pcd->setup_pkt, ++ pcd->setup_pkt_dma_handle); ++ DWC_DMA_FREE(sizeof(uint16_t), pcd->status_buf, ++ pcd->status_buf_dma_handle); ++ if (GET_CORE_IF(pcd)->dma_desc_enable) { ++ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0], ++ dev_if->dma_setup_desc_addr ++ [0], 1); ++ dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1], ++ dev_if->dma_setup_desc_addr ++ [1], 1); ++ dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr, ++ dev_if->dma_in_desc_addr, 1); ++ dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr, ++ dev_if->dma_out_desc_addr, ++ 1); ++ } ++ } else { ++ DWC_FREE(pcd->setup_pkt); ++ DWC_FREE(pcd->status_buf); ++ } ++ DWC_SPINLOCK_FREE(pcd->lock); ++ /* Set core_if's lock pointer to NULL */ ++ pcd->core_if->lock = NULL; ++ ++ DWC_TASK_FREE(pcd->start_xfer_tasklet); ++ DWC_TASK_FREE(pcd->test_mode_tasklet); ++ if (pcd->core_if->core_params->dev_out_nak) { ++ for (i = 0; i < MAX_EPS_CHANNELS; i++) { ++ if (pcd->core_if->ep_xfer_timer[i]) { ++ DWC_TIMER_FREE(pcd->core_if->ep_xfer_timer[i]); ++ } ++ } ++ } ++ ++/* Release the CFI object's dynamic memory */ ++#ifdef DWC_UTE_CFI ++ if (pcd->cfi->ops.release) { ++ pcd->cfi->ops.release(pcd->cfi); ++ } ++#endif ++ ++ DWC_FREE(pcd); ++} ++ ++/** ++ * Returns whether registered pcd is dual speed or not ++ */ ++uint32_t dwc_otg_pcd_is_dualspeed(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ ++ if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) || ++ ((core_if->hwcfg2.b.hs_phy_type == 2) && ++ (core_if->hwcfg2.b.fs_phy_type == 1) && ++ (core_if->core_params->ulpi_fs_ls))) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/** ++ * Returns whether registered pcd is OTG capable or not ++ */ ++uint32_t dwc_otg_pcd_is_otg(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ gusbcfg_data_t usbcfg = {.d32 = 0 }; ++ ++ usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg); ++ if (!usbcfg.b.srpcap || !usbcfg.b.hnpcap) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/** ++ * This function assigns periodic Tx FIFO to an periodic EP ++ * in shared Tx FIFO mode ++ */ ++static uint32_t assign_tx_fifo(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t TxMsk = 1; ++ int i; ++ ++ for (i = 0; i < core_if->hwcfg4.b.num_in_eps; ++i) { ++ if ((TxMsk & core_if->tx_msk) == 0) { ++ core_if->tx_msk |= TxMsk; ++ return i + 1; ++ } ++ TxMsk <<= 1; ++ } ++ return 0; ++} ++ ++/** ++ * This function assigns periodic Tx FIFO to an periodic EP ++ * in shared Tx FIFO mode ++ */ ++static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t * core_if) ++{ ++ uint32_t PerTxMsk = 1; ++ int i; ++ for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; ++i) { ++ if ((PerTxMsk & core_if->p_tx_msk) == 0) { ++ core_if->p_tx_msk |= PerTxMsk; ++ return i + 1; ++ } ++ PerTxMsk <<= 1; ++ } ++ return 0; ++} ++ ++/** ++ * This function releases periodic Tx FIFO ++ * in shared Tx FIFO mode ++ */ ++static void release_perio_tx_fifo(dwc_otg_core_if_t * core_if, ++ uint32_t fifo_num) ++{ ++ core_if->p_tx_msk = ++ (core_if->p_tx_msk & (1 << (fifo_num - 1))) ^ core_if->p_tx_msk; ++} ++ ++/** ++ * This function releases periodic Tx FIFO ++ * in shared Tx FIFO mode ++ */ ++static void release_tx_fifo(dwc_otg_core_if_t * core_if, uint32_t fifo_num) ++{ ++ core_if->tx_msk = ++ (core_if->tx_msk & (1 << (fifo_num - 1))) ^ core_if->tx_msk; ++} ++ ++/** ++ * This function is being called from gadget ++ * to enable PCD endpoint. ++ */ ++int dwc_otg_pcd_ep_enable(dwc_otg_pcd_t * pcd, ++ const uint8_t * ep_desc, void *usb_ep) ++{ ++ int num, dir; ++ dwc_otg_pcd_ep_t *ep = NULL; ++ const usb_endpoint_descriptor_t *desc; ++ dwc_irqflags_t flags; ++ fifosize_data_t dptxfsiz = {.d32 = 0 }; ++ gdfifocfg_data_t gdfifocfg = {.d32 = 0 }; ++ gdfifocfg_data_t gdfifocfgbase = {.d32 = 0 }; ++ int retval = 0; ++ int i, epcount; ++ ++ desc = (const usb_endpoint_descriptor_t *)ep_desc; ++ ++ if (!desc) { ++ pcd->ep0.priv = usb_ep; ++ ep = &pcd->ep0; ++ retval = -DWC_E_INVALID; ++ goto out; ++ } ++ ++ num = UE_GET_ADDR(desc->bEndpointAddress); ++ dir = UE_GET_DIR(desc->bEndpointAddress); ++ ++ if (!desc->wMaxPacketSize) { ++ DWC_WARN("bad maxpacketsize\n"); ++ retval = -DWC_E_INVALID; ++ goto out; ++ } ++ ++ if (dir == UE_DIR_IN) { ++ epcount = pcd->core_if->dev_if->num_in_eps; ++ for (i = 0; i < epcount; i++) { ++ if (num == pcd->in_ep[i].dwc_ep.num) { ++ ep = &pcd->in_ep[i]; ++ break; ++ } ++ } ++ } else { ++ epcount = pcd->core_if->dev_if->num_out_eps; ++ for (i = 0; i < epcount; i++) { ++ if (num == pcd->out_ep[i].dwc_ep.num) { ++ ep = &pcd->out_ep[i]; ++ break; ++ } ++ } ++ } ++ ++ if (!ep) { ++ DWC_WARN("bad address\n"); ++ retval = -DWC_E_INVALID; ++ goto out; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ ++ ep->desc = desc; ++ ep->priv = usb_ep; ++ ++ /* ++ * Activate the EP ++ */ ++ ep->stopped = 0; ++ ++ ep->dwc_ep.is_in = (dir == UE_DIR_IN); ++ ep->dwc_ep.maxpacket = UGETW(desc->wMaxPacketSize); ++ ++ ep->dwc_ep.type = desc->bmAttributes & UE_XFERTYPE; ++ ++ if (ep->dwc_ep.is_in) { ++ if (!GET_CORE_IF(pcd)->en_multiple_tx_fifo) { ++ ep->dwc_ep.tx_fifo_num = 0; ++ ++ if (ep->dwc_ep.type == UE_ISOCHRONOUS) { ++ /* ++ * if ISOC EP then assign a Periodic Tx FIFO. ++ */ ++ ep->dwc_ep.tx_fifo_num = ++ assign_perio_tx_fifo(GET_CORE_IF(pcd)); ++ } ++ } else { ++ /* ++ * if Dedicated FIFOs mode is on then assign a Tx FIFO. ++ */ ++ ep->dwc_ep.tx_fifo_num = ++ assign_tx_fifo(GET_CORE_IF(pcd)); ++ } ++ ++ /* Calculating EP info controller base address */ ++ if (ep->dwc_ep.tx_fifo_num ++ && GET_CORE_IF(pcd)->en_multiple_tx_fifo) { ++ gdfifocfg.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)-> ++ core_global_regs->gdfifocfg); ++ gdfifocfgbase.d32 = gdfifocfg.d32 >> 16; ++ dptxfsiz.d32 = ++ (DWC_READ_REG32 ++ (&GET_CORE_IF(pcd)->core_global_regs-> ++ dtxfsiz[ep->dwc_ep.tx_fifo_num - 1]) >> 16); ++ gdfifocfg.b.epinfobase = ++ gdfifocfgbase.d32 + dptxfsiz.d32; ++ if (GET_CORE_IF(pcd)->snpsid <= OTG_CORE_REV_2_94a) { ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)-> ++ core_global_regs->gdfifocfg, ++ gdfifocfg.d32); ++ } ++ } ++ } ++ /* Set initial data PID. */ ++ if (ep->dwc_ep.type == UE_BULK) { ++ ep->dwc_ep.data_pid_start = 0; ++ } ++ ++ /* Alloc DMA Descriptors */ ++ if (GET_CORE_IF(pcd)->dma_desc_enable) { ++#ifndef DWC_UTE_PER_IO ++ if (ep->dwc_ep.type != UE_ISOCHRONOUS) { ++#endif ++ ep->dwc_ep.desc_addr = ++ dwc_otg_ep_alloc_desc_chain(&ep-> ++ dwc_ep.dma_desc_addr, ++ MAX_DMA_DESC_CNT); ++ if (!ep->dwc_ep.desc_addr) { ++ DWC_WARN("%s, can't allocate DMA descriptor\n", ++ __func__); ++ retval = -DWC_E_SHUTDOWN; ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ goto out; ++ } ++#ifndef DWC_UTE_PER_IO ++ } ++#endif ++ } ++ ++ DWC_DEBUGPL(DBG_PCD, "Activate %s: type=%d, mps=%d desc=%p\n", ++ (ep->dwc_ep.is_in ? "IN" : "OUT"), ++ ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc); ++#ifdef DWC_UTE_PER_IO ++ ep->dwc_ep.xiso_bInterval = 1 << (ep->desc->bInterval - 1); ++#endif ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) { ++ ep->dwc_ep.bInterval = 1 << (ep->desc->bInterval - 1); ++ ep->dwc_ep.frame_num = 0xFFFFFFFF; ++ } ++ ++ dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep); ++ ++#ifdef DWC_UTE_CFI ++ if (pcd->cfi->ops.ep_enable) { ++ pcd->cfi->ops.ep_enable(pcd->cfi, pcd, ep); ++ } ++#endif ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++out: ++ return retval; ++} ++ ++/** ++ * This function is being called from gadget ++ * to disable PCD endpoint. ++ */ ++int dwc_otg_pcd_ep_disable(dwc_otg_pcd_t * pcd, void *ep_handle) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ dwc_irqflags_t flags; ++ dwc_otg_dev_dma_desc_t *desc_addr; ++ dwc_dma_t dma_desc_addr; ++ gdfifocfg_data_t gdfifocfgbase = {.d32 = 0 }; ++ gdfifocfg_data_t gdfifocfg = {.d32 = 0 }; ++ fifosize_data_t dptxfsiz = {.d32 = 0 }; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ ++ if (!ep || !ep->desc) { ++ DWC_DEBUGPL(DBG_PCD, "bad ep address\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ ++ dwc_otg_request_nuke(ep); ++ ++ dwc_otg_ep_deactivate(GET_CORE_IF(pcd), &ep->dwc_ep); ++ if (pcd->core_if->core_params->dev_out_nak) { ++ DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[ep->dwc_ep.num]); ++ pcd->core_if->ep_xfer_info[ep->dwc_ep.num].state = 0; ++ } ++ ep->desc = NULL; ++ ep->stopped = 1; ++ ++ gdfifocfg.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)->core_global_regs->gdfifocfg); ++ gdfifocfgbase.d32 = gdfifocfg.d32 >> 16; ++ ++ if (ep->dwc_ep.is_in) { ++ if (GET_CORE_IF(pcd)->en_multiple_tx_fifo) { ++ /* Flush the Tx FIFO */ ++ dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), ++ ep->dwc_ep.tx_fifo_num); ++ } ++ release_perio_tx_fifo(GET_CORE_IF(pcd), ep->dwc_ep.tx_fifo_num); ++ release_tx_fifo(GET_CORE_IF(pcd), ep->dwc_ep.tx_fifo_num); ++ if (GET_CORE_IF(pcd)->en_multiple_tx_fifo) { ++ /* Decreasing EPinfo Base Addr */ ++ dptxfsiz.d32 = ++ (DWC_READ_REG32 ++ (&GET_CORE_IF(pcd)-> ++ core_global_regs->dtxfsiz[ep->dwc_ep.tx_fifo_num-1]) >> 16); ++ gdfifocfg.b.epinfobase = gdfifocfgbase.d32 - dptxfsiz.d32; ++ if (GET_CORE_IF(pcd)->snpsid <= OTG_CORE_REV_2_94a) { ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gdfifocfg, ++ gdfifocfg.d32); ++ } ++ } ++ } ++ ++ /* Free DMA Descriptors */ ++ if (GET_CORE_IF(pcd)->dma_desc_enable) { ++ if (ep->dwc_ep.type != UE_ISOCHRONOUS) { ++ desc_addr = ep->dwc_ep.desc_addr; ++ dma_desc_addr = ep->dwc_ep.dma_desc_addr; ++ ++ /* Cannot call dma_free_coherent() with IRQs disabled */ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr, ++ MAX_DMA_DESC_CNT); ++ ++ goto out_unlocked; ++ } ++ } ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++out_unlocked: ++ DWC_DEBUGPL(DBG_PCD, "%d %s disabled\n", ep->dwc_ep.num, ++ ep->dwc_ep.is_in ? "IN" : "OUT"); ++ return 0; ++ ++} ++ ++/******************************************************************************/ ++#ifdef DWC_UTE_PER_IO ++ ++/** ++ * Free the request and its extended parts ++ * ++ */ ++void dwc_pcd_xiso_ereq_free(dwc_otg_pcd_ep_t * ep, dwc_otg_pcd_request_t * req) ++{ ++ DWC_FREE(req->ext_req.per_io_frame_descs); ++ DWC_FREE(req); ++} ++ ++/** ++ * Start the next request in the endpoint's queue. ++ * ++ */ ++int dwc_otg_pcd_xiso_start_next_request(dwc_otg_pcd_t * pcd, ++ dwc_otg_pcd_ep_t * ep) ++{ ++ int i; ++ dwc_otg_pcd_request_t *req = NULL; ++ dwc_ep_t *dwcep = NULL; ++ struct dwc_iso_xreq_port *ereq = NULL; ++ struct dwc_iso_pkt_desc_port *ddesc_iso; ++ uint16_t nat; ++ depctl_data_t diepctl; ++ ++ dwcep = &ep->dwc_ep; ++ ++ if (dwcep->xiso_active_xfers > 0) { ++#if 0 //Disable this to decrease s/w overhead that is crucial for Isoc transfers ++ DWC_WARN("There are currently active transfers for EP%d \ ++ (active=%d; queued=%d)", dwcep->num, dwcep->xiso_active_xfers, ++ dwcep->xiso_queued_xfers); ++#endif ++ return 0; ++ } ++ ++ nat = UGETW(ep->desc->wMaxPacketSize); ++ nat = (nat >> 11) & 0x03; ++ ++ if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ ereq = &req->ext_req; ++ ep->stopped = 0; ++ ++ /* Get the frame number */ ++ dwcep->xiso_frame_num = ++ dwc_otg_get_frame_number(GET_CORE_IF(pcd)); ++ DWC_DEBUG("FRM_NUM=%d", dwcep->xiso_frame_num); ++ ++ ddesc_iso = ereq->per_io_frame_descs; ++ ++ if (dwcep->is_in) { ++ /* Setup DMA Descriptor chain for IN Isoc request */ ++ for (i = 0; i < ereq->pio_pkt_count; i++) { ++ //if ((i % (nat + 1)) == 0) ++ if ( i > 0 ) ++ dwcep->xiso_frame_num = ++ (dwcep->xiso_bInterval + ++ dwcep->xiso_frame_num) & 0x3FFF; ++ dwcep->desc_addr[i].buf = ++ req->dma + ddesc_iso[i].offset; ++ dwcep->desc_addr[i].status.b_iso_in.txbytes = ++ ddesc_iso[i].length; ++ dwcep->desc_addr[i].status.b_iso_in.framenum = ++ dwcep->xiso_frame_num; ++ dwcep->desc_addr[i].status.b_iso_in.bs = ++ BS_HOST_READY; ++ dwcep->desc_addr[i].status.b_iso_in.txsts = 0; ++ dwcep->desc_addr[i].status.b_iso_in.sp = ++ (ddesc_iso[i].length % ++ dwcep->maxpacket) ? 1 : 0; ++ dwcep->desc_addr[i].status.b_iso_in.ioc = 0; ++ dwcep->desc_addr[i].status.b_iso_in.pid = nat + 1; ++ dwcep->desc_addr[i].status.b_iso_in.l = 0; ++ ++ /* Process the last descriptor */ ++ if (i == ereq->pio_pkt_count - 1) { ++ dwcep->desc_addr[i].status.b_iso_in.ioc = 1; ++ dwcep->desc_addr[i].status.b_iso_in.l = 1; ++ } ++ } ++ ++ /* Setup and start the transfer for this endpoint */ ++ dwcep->xiso_active_xfers++; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->dev_if-> ++ in_ep_regs[dwcep->num]->diepdma, ++ dwcep->dma_desc_addr); ++ diepctl.d32 = 0; ++ diepctl.b.epena = 1; ++ diepctl.b.cnak = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->dev_if-> ++ in_ep_regs[dwcep->num]->diepctl, 0, ++ diepctl.d32); ++ } else { ++ /* Setup DMA Descriptor chain for OUT Isoc request */ ++ for (i = 0; i < ereq->pio_pkt_count; i++) { ++ //if ((i % (nat + 1)) == 0) ++ dwcep->xiso_frame_num = (dwcep->xiso_bInterval + ++ dwcep->xiso_frame_num) & 0x3FFF; ++ dwcep->desc_addr[i].buf = ++ req->dma + ddesc_iso[i].offset; ++ dwcep->desc_addr[i].status.b_iso_out.rxbytes = ++ ddesc_iso[i].length; ++ dwcep->desc_addr[i].status.b_iso_out.framenum = ++ dwcep->xiso_frame_num; ++ dwcep->desc_addr[i].status.b_iso_out.bs = ++ BS_HOST_READY; ++ dwcep->desc_addr[i].status.b_iso_out.rxsts = 0; ++ dwcep->desc_addr[i].status.b_iso_out.sp = ++ (ddesc_iso[i].length % ++ dwcep->maxpacket) ? 1 : 0; ++ dwcep->desc_addr[i].status.b_iso_out.ioc = 0; ++ dwcep->desc_addr[i].status.b_iso_out.pid = nat + 1; ++ dwcep->desc_addr[i].status.b_iso_out.l = 0; ++ ++ /* Process the last descriptor */ ++ if (i == ereq->pio_pkt_count - 1) { ++ dwcep->desc_addr[i].status.b_iso_out.ioc = 1; ++ dwcep->desc_addr[i].status.b_iso_out.l = 1; ++ } ++ } ++ ++ /* Setup and start the transfer for this endpoint */ ++ dwcep->xiso_active_xfers++; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)-> ++ dev_if->out_ep_regs[dwcep->num]-> ++ doepdma, dwcep->dma_desc_addr); ++ diepctl.d32 = 0; ++ diepctl.b.epena = 1; ++ diepctl.b.cnak = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)-> ++ dev_if->out_ep_regs[dwcep->num]-> ++ doepctl, 0, diepctl.d32); ++ } ++ ++ } else { ++ ep->stopped = 1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * - Remove the request from the queue ++ */ ++void complete_xiso_ep(dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_otg_pcd_request_t *req = NULL; ++ struct dwc_iso_xreq_port *ereq = NULL; ++ struct dwc_iso_pkt_desc_port *ddesc_iso = NULL; ++ dwc_ep_t *dwcep = NULL; ++ int i; ++ ++ //DWC_DEBUG(); ++ dwcep = &ep->dwc_ep; ++ ++ /* Get the first pending request from the queue */ ++ if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ if (!req) { ++ DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep); ++ return; ++ } ++ dwcep->xiso_active_xfers--; ++ dwcep->xiso_queued_xfers--; ++ /* Remove this request from the queue */ ++ DWC_CIRCLEQ_REMOVE_INIT(&ep->queue, req, queue_entry); ++ } else { ++ DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep); ++ return; ++ } ++ ++ ep->stopped = 1; ++ ereq = &req->ext_req; ++ ddesc_iso = ereq->per_io_frame_descs; ++ ++ if (dwcep->xiso_active_xfers < 0) { ++ DWC_WARN("EP#%d (xiso_active_xfers=%d)", dwcep->num, ++ dwcep->xiso_active_xfers); ++ } ++ ++ /* Fill the Isoc descs of portable extended req from dma descriptors */ ++ for (i = 0; i < ereq->pio_pkt_count; i++) { ++ if (dwcep->is_in) { /* IN endpoints */ ++ ddesc_iso[i].actual_length = ddesc_iso[i].length - ++ dwcep->desc_addr[i].status.b_iso_in.txbytes; ++ ddesc_iso[i].status = ++ dwcep->desc_addr[i].status.b_iso_in.txsts; ++ } else { /* OUT endpoints */ ++ ddesc_iso[i].actual_length = ddesc_iso[i].length - ++ dwcep->desc_addr[i].status.b_iso_out.rxbytes; ++ ddesc_iso[i].status = ++ dwcep->desc_addr[i].status.b_iso_out.rxsts; ++ } ++ } ++ ++ DWC_SPINUNLOCK(ep->pcd->lock); ++ ++ /* Call the completion function in the non-portable logic */ ++ ep->pcd->fops->xisoc_complete(ep->pcd, ep->priv, req->priv, 0, ++ &req->ext_req); ++ ++ DWC_SPINLOCK(ep->pcd->lock); ++ ++ /* Free the request - specific freeing needed for extended request object */ ++ dwc_pcd_xiso_ereq_free(ep, req); ++ ++ /* Start the next request */ ++ dwc_otg_pcd_xiso_start_next_request(ep->pcd, ep); ++ ++ return; ++} ++ ++/** ++ * Create and initialize the Isoc pkt descriptors of the extended request. ++ * ++ */ ++static int dwc_otg_pcd_xiso_create_pkt_descs(dwc_otg_pcd_request_t * req, ++ void *ereq_nonport, ++ int atomic_alloc) ++{ ++ struct dwc_iso_xreq_port *ereq = NULL; ++ struct dwc_iso_xreq_port *req_mapped = NULL; ++ struct dwc_iso_pkt_desc_port *ipds = NULL; /* To be created in this function */ ++ uint32_t pkt_count; ++ int i; ++ ++ ereq = &req->ext_req; ++ req_mapped = (struct dwc_iso_xreq_port *)ereq_nonport; ++ pkt_count = req_mapped->pio_pkt_count; ++ ++ /* Create the isoc descs */ ++ if (atomic_alloc) { ++ ipds = DWC_ALLOC_ATOMIC(sizeof(*ipds) * pkt_count); ++ } else { ++ ipds = DWC_ALLOC(sizeof(*ipds) * pkt_count); ++ } ++ ++ if (!ipds) { ++ DWC_ERROR("Failed to allocate isoc descriptors"); ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ /* Initialize the extended request fields */ ++ ereq->per_io_frame_descs = ipds; ++ ereq->error_count = 0; ++ ereq->pio_alloc_pkt_count = pkt_count; ++ ereq->pio_pkt_count = pkt_count; ++ ereq->tr_sub_flags = req_mapped->tr_sub_flags; ++ ++ /* Init the Isoc descriptors */ ++ for (i = 0; i < pkt_count; i++) { ++ ipds[i].length = req_mapped->per_io_frame_descs[i].length; ++ ipds[i].offset = req_mapped->per_io_frame_descs[i].offset; ++ ipds[i].status = req_mapped->per_io_frame_descs[i].status; /* 0 */ ++ ipds[i].actual_length = ++ req_mapped->per_io_frame_descs[i].actual_length; ++ } ++ ++ return 0; ++} ++ ++static void prn_ext_request(struct dwc_iso_xreq_port *ereq) ++{ ++ struct dwc_iso_pkt_desc_port *xfd = NULL; ++ int i; ++ ++ DWC_DEBUG("per_io_frame_descs=%p", ereq->per_io_frame_descs); ++ DWC_DEBUG("tr_sub_flags=%d", ereq->tr_sub_flags); ++ DWC_DEBUG("error_count=%d", ereq->error_count); ++ DWC_DEBUG("pio_alloc_pkt_count=%d", ereq->pio_alloc_pkt_count); ++ DWC_DEBUG("pio_pkt_count=%d", ereq->pio_pkt_count); ++ DWC_DEBUG("res=%d", ereq->res); ++ ++ for (i = 0; i < ereq->pio_pkt_count; i++) { ++ xfd = &ereq->per_io_frame_descs[0]; ++ DWC_DEBUG("FD #%d", i); ++ ++ DWC_DEBUG("xfd->actual_length=%d", xfd->actual_length); ++ DWC_DEBUG("xfd->length=%d", xfd->length); ++ DWC_DEBUG("xfd->offset=%d", xfd->offset); ++ DWC_DEBUG("xfd->status=%d", xfd->status); ++ } ++} ++ ++/** ++ * ++ */ ++int dwc_otg_pcd_xiso_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle, ++ uint8_t * buf, dwc_dma_t dma_buf, uint32_t buflen, ++ int zero, void *req_handle, int atomic_alloc, ++ void *ereq_nonport) ++{ ++ dwc_otg_pcd_request_t *req = NULL; ++ dwc_otg_pcd_ep_t *ep; ++ dwc_irqflags_t flags; ++ int res; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ if (!ep) { ++ DWC_WARN("bad ep\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ /* We support this extension only for DDMA mode */ ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) ++ if (!GET_CORE_IF(pcd)->dma_desc_enable) ++ return -DWC_E_INVALID; ++ ++ /* Create a dwc_otg_pcd_request_t object */ ++ if (atomic_alloc) { ++ req = DWC_ALLOC_ATOMIC(sizeof(*req)); ++ } else { ++ req = DWC_ALLOC(sizeof(*req)); ++ } ++ ++ if (!req) { ++ return -DWC_E_NO_MEMORY; ++ } ++ ++ /* Create the Isoc descs for this request which shall be the exact match ++ * of the structure sent to us from the non-portable logic */ ++ res = ++ dwc_otg_pcd_xiso_create_pkt_descs(req, ereq_nonport, atomic_alloc); ++ if (res) { ++ DWC_WARN("Failed to init the Isoc descriptors"); ++ DWC_FREE(req); ++ return res; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ ++ DWC_CIRCLEQ_INIT_ENTRY(req, queue_entry); ++ req->buf = buf; ++ req->dma = dma_buf; ++ req->length = buflen; ++ req->sent_zlp = zero; ++ req->priv = req_handle; ++ ++ //DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ ep->dwc_ep.dma_addr = dma_buf; ++ ep->dwc_ep.start_xfer_buff = buf; ++ ep->dwc_ep.xfer_buff = buf; ++ ep->dwc_ep.xfer_len = 0; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = buflen; ++ ++ /* Add this request to the tail */ ++ DWC_CIRCLEQ_INSERT_TAIL(&ep->queue, req, queue_entry); ++ ep->dwc_ep.xiso_queued_xfers++; ++ ++//DWC_DEBUG("CP_0"); ++//DWC_DEBUG("req->ext_req.tr_sub_flags=%d", req->ext_req.tr_sub_flags); ++//prn_ext_request((struct dwc_iso_xreq_port *) ereq_nonport); ++//prn_ext_request(&req->ext_req); ++ ++ //DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++ /* If the req->status == ASAP then check if there is any active transfer ++ * for this endpoint. If no active transfers, then get the first entry ++ * from the queue and start that transfer ++ */ ++ if (req->ext_req.tr_sub_flags == DWC_EREQ_TF_ASAP) { ++ res = dwc_otg_pcd_xiso_start_next_request(pcd, ep); ++ if (res) { ++ DWC_WARN("Failed to start the next Isoc transfer"); ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ DWC_FREE(req); ++ return res; ++ } ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ return 0; ++} ++ ++#endif ++/* END ifdef DWC_UTE_PER_IO ***************************************************/ ++int dwc_otg_pcd_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle, ++ uint8_t * buf, dwc_dma_t dma_buf, uint32_t buflen, ++ int zero, void *req_handle, int atomic_alloc) ++{ ++ dwc_irqflags_t flags; ++ dwc_otg_pcd_request_t *req; ++ dwc_otg_pcd_ep_t *ep; ++ uint32_t max_transfer; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ if (!ep || (!ep->desc && ep->dwc_ep.num != 0)) { ++ DWC_WARN("bad ep\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ if (atomic_alloc) { ++ req = DWC_ALLOC_ATOMIC(sizeof(*req)); ++ } else { ++ req = DWC_ALLOC(sizeof(*req)); ++ } ++ ++ if (!req) { ++ return -DWC_E_NO_MEMORY; ++ } ++ DWC_CIRCLEQ_INIT_ENTRY(req, queue_entry); ++ if (!GET_CORE_IF(pcd)->core_params->opt) { ++ if (ep->dwc_ep.num != 0) { ++ DWC_ERROR("queue req %p, len %d buf %p\n", ++ req_handle, buflen, buf); ++ } ++ } ++ ++ req->buf = buf; ++ req->dma = dma_buf; ++ req->length = buflen; ++ req->sent_zlp = zero; ++ req->priv = req_handle; ++ req->dw_align_buf = NULL; ++ if ((dma_buf & 0x3) && GET_CORE_IF(pcd)->dma_enable ++ && !GET_CORE_IF(pcd)->dma_desc_enable) ++ req->dw_align_buf = DWC_DMA_ALLOC(buflen, ++ &req->dw_align_buf_dma); ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ ++ /* ++ * After adding request to the queue for IN ISOC wait for In Token Received ++ * when TX FIFO is empty interrupt and for OUT ISOC wait for OUT Token ++ * Received when EP is disabled interrupt to obtain starting microframe ++ * (odd/even) start transfer ++ */ ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) { ++ if (req != 0) { ++ depctl_data_t depctl = {.d32 = ++ DWC_READ_REG32(&pcd->core_if->dev_if-> ++ in_ep_regs[ep->dwc_ep.num]-> ++ diepctl) }; ++ ++pcd->request_pending; ++ ++ DWC_CIRCLEQ_INSERT_TAIL(&ep->queue, req, queue_entry); ++ if (ep->dwc_ep.is_in) { ++ depctl.b.cnak = 1; ++ DWC_WRITE_REG32(&pcd->core_if->dev_if-> ++ in_ep_regs[ep->dwc_ep.num]-> ++ diepctl, depctl.d32); ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ } ++ return 0; ++ } ++ ++ /* ++ * For EP0 IN without premature status, zlp is required? ++ */ ++ if (ep->dwc_ep.num == 0 && ep->dwc_ep.is_in) { ++ DWC_DEBUGPL(DBG_PCDV, "%d-OUT ZLP\n", ep->dwc_ep.num); ++ //_req->zero = 1; ++ } ++ ++ /* Start the transfer */ ++ if (DWC_CIRCLEQ_EMPTY(&ep->queue) && !ep->stopped) { ++ /* EP0 Transfer? */ ++ if (ep->dwc_ep.num == 0) { ++ switch (pcd->ep0state) { ++ case EP0_IN_DATA_PHASE: ++ DWC_DEBUGPL(DBG_PCD, ++ "%s ep0: EP0_IN_DATA_PHASE\n", ++ __func__); ++ break; ++ ++ case EP0_OUT_DATA_PHASE: ++ DWC_DEBUGPL(DBG_PCD, ++ "%s ep0: EP0_OUT_DATA_PHASE\n", ++ __func__); ++ if (pcd->request_config) { ++ /* Complete STATUS PHASE */ ++ ep->dwc_ep.is_in = 1; ++ pcd->ep0state = EP0_IN_STATUS_PHASE; ++ } ++ break; ++ ++ case EP0_IN_STATUS_PHASE: ++ DWC_DEBUGPL(DBG_PCD, ++ "%s ep0: EP0_IN_STATUS_PHASE\n", ++ __func__); ++ break; ++ ++ default: ++ DWC_DEBUGPL(DBG_ANY, "ep0: odd state %d\n", ++ pcd->ep0state); ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ return -DWC_E_SHUTDOWN; ++ } ++ ++ ep->dwc_ep.dma_addr = dma_buf; ++ ep->dwc_ep.start_xfer_buff = buf; ++ ep->dwc_ep.xfer_buff = buf; ++ ep->dwc_ep.xfer_len = buflen; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = ep->dwc_ep.xfer_len; ++ ++ if (zero) { ++ if ((ep->dwc_ep.xfer_len % ++ ep->dwc_ep.maxpacket == 0) ++ && (ep->dwc_ep.xfer_len != 0)) { ++ ep->dwc_ep.sent_zlp = 1; ++ } ++ ++ } ++ ++ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), ++ &ep->dwc_ep); ++ } // non-ep0 endpoints ++ else { ++#ifdef DWC_UTE_CFI ++ if (ep->dwc_ep.buff_mode != BM_STANDARD) { ++ /* store the request length */ ++ ep->dwc_ep.cfi_req_len = buflen; ++ pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ++ ep, req); ++ } else { ++#endif ++ max_transfer = ++ GET_CORE_IF(ep->pcd)->core_params-> ++ max_transfer_size; ++ ++ /* Setup and start the Transfer */ ++ if (req->dw_align_buf){ ++ if (ep->dwc_ep.is_in) ++ dwc_memcpy(req->dw_align_buf, ++ buf, buflen); ++ ep->dwc_ep.dma_addr = ++ req->dw_align_buf_dma; ++ ep->dwc_ep.start_xfer_buff = ++ req->dw_align_buf; ++ ep->dwc_ep.xfer_buff = ++ req->dw_align_buf; ++ } else { ++ ep->dwc_ep.dma_addr = dma_buf; ++ ep->dwc_ep.start_xfer_buff = buf; ++ ep->dwc_ep.xfer_buff = buf; ++ } ++ ep->dwc_ep.xfer_len = 0; ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = buflen; ++ ++ ep->dwc_ep.maxxfer = max_transfer; ++ if (GET_CORE_IF(pcd)->dma_desc_enable) { ++ uint32_t out_max_xfer = ++ DDMA_MAX_TRANSFER_SIZE - ++ (DDMA_MAX_TRANSFER_SIZE % 4); ++ if (ep->dwc_ep.is_in) { ++ if (ep->dwc_ep.maxxfer > ++ DDMA_MAX_TRANSFER_SIZE) { ++ ep->dwc_ep.maxxfer = ++ DDMA_MAX_TRANSFER_SIZE; ++ } ++ } else { ++ if (ep->dwc_ep.maxxfer > ++ out_max_xfer) { ++ ep->dwc_ep.maxxfer = ++ out_max_xfer; ++ } ++ } ++ } ++ if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) { ++ ep->dwc_ep.maxxfer -= ++ (ep->dwc_ep.maxxfer % ++ ep->dwc_ep.maxpacket); ++ } ++ ++ if (zero) { ++ if ((ep->dwc_ep.total_len % ++ ep->dwc_ep.maxpacket == 0) ++ && (ep->dwc_ep.total_len != 0)) { ++ ep->dwc_ep.sent_zlp = 1; ++ } ++ } ++#ifdef DWC_UTE_CFI ++ } ++#endif ++ dwc_otg_ep_start_transfer(GET_CORE_IF(pcd), ++ &ep->dwc_ep); ++ } ++ } ++ ++ if (req != 0) { ++ ++pcd->request_pending; ++ DWC_CIRCLEQ_INSERT_TAIL(&ep->queue, req, queue_entry); ++ if (ep->dwc_ep.is_in && ep->stopped ++ && !(GET_CORE_IF(pcd)->dma_enable)) { ++ /** @todo NGS Create a function for this. */ ++ diepmsk_data_t diepmsk = {.d32 = 0 }; ++ diepmsk.b.intktxfemp = 1; ++ if (GET_CORE_IF(pcd)->multiproc_int_enable) { ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)-> ++ dev_if->dev_global_regs->diepeachintmsk ++ [ep->dwc_ep.num], 0, ++ diepmsk.d32); ++ } else { ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)-> ++ dev_if->dev_global_regs-> ++ diepmsk, 0, diepmsk.d32); ++ } ++ ++ } ++ } ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++ return 0; ++} ++ ++int dwc_otg_pcd_ep_dequeue(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle) ++{ ++ dwc_irqflags_t flags; ++ dwc_otg_pcd_request_t *req; ++ dwc_otg_pcd_ep_t *ep; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ if (!ep || (!ep->desc && ep->dwc_ep.num != 0)) { ++ DWC_WARN("bad argument\n"); ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ ++ /* make sure it's actually queued on this endpoint */ ++ DWC_CIRCLEQ_FOREACH(req, &ep->queue, queue_entry) { ++ if (req->priv == (void *)req_handle) { ++ break; ++ } ++ } ++ ++ if (req->priv != (void *)req_handle) { ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ return -DWC_E_INVALID; ++ } ++ ++ if (!DWC_CIRCLEQ_EMPTY_ENTRY(req, queue_entry)) { ++ dwc_otg_request_done(ep, req, -DWC_E_RESTART); ++ } else { ++ req = NULL; ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++ return req ? 0 : -DWC_E_SHUTDOWN; ++ ++} ++ ++/** ++ * dwc_otg_pcd_ep_wedge - sets the halt feature and ignores clear requests ++ * ++ * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT) ++ * requests. If the gadget driver clears the halt status, it will ++ * automatically unwedge the endpoint. ++ * ++ * Returns zero on success, else negative DWC error code. ++ */ ++int dwc_otg_pcd_ep_wedge(dwc_otg_pcd_t * pcd, void *ep_handle) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ dwc_irqflags_t flags; ++ int retval = 0; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ ++ if ((!ep->desc && ep != &pcd->ep0) || ++ (ep->desc && (ep->desc->bmAttributes == UE_ISOCHRONOUS))) { ++ DWC_WARN("%s, bad ep\n", __func__); ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ DWC_WARN("%d %s XFer In process\n", ep->dwc_ep.num, ++ ep->dwc_ep.is_in ? "IN" : "OUT"); ++ retval = -DWC_E_AGAIN; ++ } else { ++ /* This code needs to be reviewed */ ++ if (ep->dwc_ep.is_in == 1 && GET_CORE_IF(pcd)->dma_desc_enable) { ++ dtxfsts_data_t txstatus; ++ fifosize_data_t txfifosize; ++ ++ txfifosize.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)-> ++ core_global_regs->dtxfsiz[ep->dwc_ep. ++ tx_fifo_num]); ++ txstatus.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)-> ++ dev_if->in_ep_regs[ep->dwc_ep.num]-> ++ dtxfsts); ++ ++ if (txstatus.b.txfspcavail < txfifosize.b.depth) { ++ DWC_WARN("%s() Data In Tx Fifo\n", __func__); ++ retval = -DWC_E_AGAIN; ++ } else { ++ if (ep->dwc_ep.num == 0) { ++ pcd->ep0state = EP0_STALL; ++ } ++ ++ ep->stopped = 1; ++ dwc_otg_ep_set_stall(GET_CORE_IF(pcd), ++ &ep->dwc_ep); ++ } ++ } else { ++ if (ep->dwc_ep.num == 0) { ++ pcd->ep0state = EP0_STALL; ++ } ++ ++ ep->stopped = 1; ++ dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep->dwc_ep); ++ } ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++ return retval; ++} ++ ++int dwc_otg_pcd_ep_halt(dwc_otg_pcd_t * pcd, void *ep_handle, int value) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ dwc_irqflags_t flags; ++ int retval = 0; ++ ++ ep = get_ep_from_handle(pcd, ep_handle); ++ ++ if (!ep || (!ep->desc && ep != &pcd->ep0) || ++ (ep->desc && (ep->desc->bmAttributes == UE_ISOCHRONOUS))) { ++ DWC_WARN("%s, bad ep\n", __func__); ++ return -DWC_E_INVALID; ++ } ++ ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ DWC_WARN("%d %s XFer In process\n", ep->dwc_ep.num, ++ ep->dwc_ep.is_in ? "IN" : "OUT"); ++ retval = -DWC_E_AGAIN; ++ } else if (value == 0) { ++ dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep); ++ } else if (value == 1) { ++ if (ep->dwc_ep.is_in == 1 && GET_CORE_IF(pcd)->dma_desc_enable) { ++ dtxfsts_data_t txstatus; ++ fifosize_data_t txfifosize; ++ ++ txfifosize.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)->core_global_regs-> ++ dtxfsiz[ep->dwc_ep.tx_fifo_num]); ++ txstatus.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if-> ++ in_ep_regs[ep->dwc_ep.num]->dtxfsts); ++ ++ if (txstatus.b.txfspcavail < txfifosize.b.depth) { ++ DWC_WARN("%s() Data In Tx Fifo\n", __func__); ++ retval = -DWC_E_AGAIN; ++ } else { ++ if (ep->dwc_ep.num == 0) { ++ pcd->ep0state = EP0_STALL; ++ } ++ ++ ep->stopped = 1; ++ dwc_otg_ep_set_stall(GET_CORE_IF(pcd), ++ &ep->dwc_ep); ++ } ++ } else { ++ if (ep->dwc_ep.num == 0) { ++ pcd->ep0state = EP0_STALL; ++ } ++ ++ ep->stopped = 1; ++ dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep->dwc_ep); ++ } ++ } else if (value == 2) { ++ ep->dwc_ep.stall_clear_flag = 0; ++ } else if (value == 3) { ++ ep->dwc_ep.stall_clear_flag = 1; ++ } ++ ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ ++ return retval; ++} ++ ++/** ++ * This function initiates remote wakeup of the host from suspend state. ++ */ ++void dwc_otg_pcd_rem_wkup_from_suspend(dwc_otg_pcd_t * pcd, int set) ++{ ++ dctl_data_t dctl = { 0 }; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dsts_data_t dsts; ++ ++ dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ if (!dsts.b.suspsts) { ++ DWC_WARN("Remote wakeup while is not in suspend state\n"); ++ } ++ /* Check if DEVICE_REMOTE_WAKEUP feature enabled */ ++ if (pcd->remote_wakeup_enable) { ++ if (set) { ++ ++ if (core_if->adp_enable) { ++ gpwrdn_data_t gpwrdn; ++ ++ dwc_otg_adp_probe_stop(core_if); ++ ++ /* Mask SRP detected interrupt from Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.srp_det_msk = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs->gpwrdn, ++ gpwrdn.d32, 0); ++ ++ /* Disable Power Down Logic */ ++ gpwrdn.d32 = 0; ++ gpwrdn.b.pmuactv = 1; ++ DWC_MODIFY_REG32(&core_if-> ++ core_global_regs->gpwrdn, ++ gpwrdn.d32, 0); ++ ++ /* ++ * Initialize the Core for Device mode. ++ */ ++ core_if->op_state = B_PERIPHERAL; ++ dwc_otg_core_init(core_if); ++ dwc_otg_enable_global_interrupts(core_if); ++ cil_pcd_start(core_if); ++ ++ dwc_otg_initiate_srp(core_if); ++ } ++ ++ dctl.b.rmtwkupsig = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ dctl, 0, dctl.d32); ++ DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n"); ++ ++ dwc_mdelay(2); ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ dctl, dctl.d32, 0); ++ DWC_DEBUGPL(DBG_PCD, "Clear Remote Wakeup\n"); ++ } ++ } else { ++ DWC_DEBUGPL(DBG_PCD, "Remote Wakeup is disabled\n"); ++ } ++} ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++/** ++ * This function initiates remote wakeup of the host from L1 sleep state. ++ */ ++void dwc_otg_pcd_rem_wkup_from_sleep(dwc_otg_pcd_t * pcd, int set) ++{ ++ glpmcfg_data_t lpmcfg; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ ++ /* Check if we are in L1 state */ ++ if (!lpmcfg.b.prt_sleep_sts) { ++ DWC_DEBUGPL(DBG_PCD, "Device is not in sleep state\n"); ++ return; ++ } ++ ++ /* Check if host allows remote wakeup */ ++ if (!lpmcfg.b.rem_wkup_en) { ++ DWC_DEBUGPL(DBG_PCD, "Host does not allow remote wakeup\n"); ++ return; ++ } ++ ++ /* Check if Resume OK */ ++ if (!lpmcfg.b.sleep_state_resumeok) { ++ DWC_DEBUGPL(DBG_PCD, "Sleep state resume is not OK\n"); ++ return; ++ } ++ ++ lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg); ++ lpmcfg.b.en_utmi_sleep = 0; ++ lpmcfg.b.hird_thres &= (~(1 << 4)); ++ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32); ++ ++ if (set) { ++ dctl_data_t dctl = {.d32 = 0 }; ++ dctl.b.rmtwkupsig = 1; ++ /* Set RmtWkUpSig bit to start remote wakup signaling. ++ * Hardware will automatically clear this bit. ++ */ ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, ++ 0, dctl.d32); ++ DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n"); ++ } ++ ++} ++#endif ++ ++/** ++ * Performs remote wakeup. ++ */ ++void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t * pcd, int set) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_irqflags_t flags; ++ if (dwc_otg_is_device_mode(core_if)) { ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ if (core_if->lx_state == DWC_OTG_L1) { ++ dwc_otg_pcd_rem_wkup_from_sleep(pcd, set); ++ } else { ++#endif ++ dwc_otg_pcd_rem_wkup_from_suspend(pcd, set); ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ } ++#endif ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++ } ++ return; ++} ++ ++void dwc_otg_pcd_disconnect_us(dwc_otg_pcd_t * pcd, int no_of_usecs) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dctl_data_t dctl = { 0 }; ++ ++ if (dwc_otg_is_device_mode(core_if)) { ++ dctl.b.sftdiscon = 1; ++ DWC_PRINTF("Soft disconnect for %d useconds\n",no_of_usecs); ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32); ++ dwc_udelay(no_of_usecs); ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32,0); ++ ++ } else{ ++ DWC_PRINTF("NOT SUPPORTED IN HOST MODE\n"); ++ } ++ return; ++ ++} ++ ++int dwc_otg_pcd_wakeup(dwc_otg_pcd_t * pcd) ++{ ++ dsts_data_t dsts; ++ gotgctl_data_t gotgctl; ++ ++ /* ++ * This function starts the Protocol if no session is in progress. If ++ * a session is already in progress, but the device is suspended, ++ * remote wakeup signaling is started. ++ */ ++ ++ /* Check if valid session */ ++ gotgctl.d32 = ++ DWC_READ_REG32(&(GET_CORE_IF(pcd)->core_global_regs->gotgctl)); ++ if (gotgctl.b.bsesvld) { ++ /* Check if suspend state */ ++ dsts.d32 = ++ DWC_READ_REG32(& ++ (GET_CORE_IF(pcd)->dev_if-> ++ dev_global_regs->dsts)); ++ if (dsts.b.suspsts) { ++ dwc_otg_pcd_remote_wakeup(pcd, 1); ++ } ++ } else { ++ dwc_otg_pcd_initiate_srp(pcd); ++ } ++ ++ return 0; ++ ++} ++ ++/** ++ * Start the SRP timer to detect when the SRP does not complete within ++ * 6 seconds. ++ * ++ * @param pcd the pcd structure. ++ */ ++void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t * pcd) ++{ ++ dwc_irqflags_t flags; ++ DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags); ++ dwc_otg_initiate_srp(GET_CORE_IF(pcd)); ++ DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags); ++} ++ ++int dwc_otg_pcd_get_frame_number(dwc_otg_pcd_t * pcd) ++{ ++ return dwc_otg_get_frame_number(GET_CORE_IF(pcd)); ++} ++ ++int dwc_otg_pcd_is_lpm_enabled(dwc_otg_pcd_t * pcd) ++{ ++ return GET_CORE_IF(pcd)->core_params->lpm_enable; ++} ++ ++uint32_t get_b_hnp_enable(dwc_otg_pcd_t * pcd) ++{ ++ return pcd->b_hnp_enable; ++} ++ ++uint32_t get_a_hnp_support(dwc_otg_pcd_t * pcd) ++{ ++ return pcd->a_hnp_support; ++} ++ ++uint32_t get_a_alt_hnp_support(dwc_otg_pcd_t * pcd) ++{ ++ return pcd->a_alt_hnp_support; ++} ++ ++int dwc_otg_pcd_get_rmwkup_enable(dwc_otg_pcd_t * pcd) ++{ ++ return pcd->remote_wakeup_enable; ++} ++ ++#endif /* DWC_HOST_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,266 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.h $ ++ * $Revision: #48 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_HOST_ONLY ++#if !defined(__DWC_PCD_H__) ++#define __DWC_PCD_H__ ++ ++#include "dwc_otg_os_dep.h" ++#include "usb.h" ++#include "dwc_otg_cil.h" ++#include "dwc_otg_pcd_if.h" ++struct cfiobject; ++ ++/** ++ * @file ++ * ++ * This file contains the structures, constants, and interfaces for ++ * the Perpherial Contoller Driver (PCD). ++ * ++ * The Peripheral Controller Driver (PCD) for Linux will implement the ++ * Gadget API, so that the existing Gadget drivers can be used. For ++ * the Mass Storage Function driver the File-backed USB Storage Gadget ++ * (FBS) driver will be used. The FBS driver supports the ++ * Control-Bulk (CB), Control-Bulk-Interrupt (CBI), and Bulk-Only ++ * transports. ++ * ++ */ ++ ++/** Invalid DMA Address */ ++#define DWC_DMA_ADDR_INVALID (~(dwc_dma_t)0) ++ ++/** Max Transfer size for any EP */ ++#define DDMA_MAX_TRANSFER_SIZE 65535 ++ ++/** ++ * Get the pointer to the core_if from the pcd pointer. ++ */ ++#define GET_CORE_IF( _pcd ) (_pcd->core_if) ++ ++/** ++ * States of EP0. ++ */ ++typedef enum ep0_state { ++ EP0_DISCONNECT, /* no host */ ++ EP0_IDLE, ++ EP0_IN_DATA_PHASE, ++ EP0_OUT_DATA_PHASE, ++ EP0_IN_STATUS_PHASE, ++ EP0_OUT_STATUS_PHASE, ++ EP0_STALL, ++} ep0state_e; ++ ++/** Fordward declaration.*/ ++struct dwc_otg_pcd; ++ ++/** DWC_otg iso request structure. ++ * ++ */ ++typedef struct usb_iso_request dwc_otg_pcd_iso_request_t; ++ ++#ifdef DWC_UTE_PER_IO ++ ++/** ++ * This shall be the exact analogy of the same type structure defined in the ++ * usb_gadget.h. Each descriptor contains ++ */ ++struct dwc_iso_pkt_desc_port { ++ uint32_t offset; ++ uint32_t length; /* expected length */ ++ uint32_t actual_length; ++ uint32_t status; ++}; ++ ++struct dwc_iso_xreq_port { ++ /** transfer/submission flag */ ++ uint32_t tr_sub_flags; ++ /** Start the request ASAP */ ++#define DWC_EREQ_TF_ASAP 0x00000002 ++ /** Just enqueue the request w/o initiating a transfer */ ++#define DWC_EREQ_TF_ENQUEUE 0x00000004 ++ ++ /** ++ * count of ISO packets attached to this request - shall ++ * not exceed the pio_alloc_pkt_count ++ */ ++ uint32_t pio_pkt_count; ++ /** count of ISO packets allocated for this request */ ++ uint32_t pio_alloc_pkt_count; ++ /** number of ISO packet errors */ ++ uint32_t error_count; ++ /** reserved for future extension */ ++ uint32_t res; ++ /** Will be allocated and freed in the UTE gadget and based on the CFC value */ ++ struct dwc_iso_pkt_desc_port *per_io_frame_descs; ++}; ++#endif ++/** DWC_otg request structure. ++ * This structure is a list of requests. ++ */ ++typedef struct dwc_otg_pcd_request { ++ void *priv; ++ void *buf; ++ dwc_dma_t dma; ++ uint32_t length; ++ uint32_t actual; ++ unsigned sent_zlp:1; ++ /** ++ * Used instead of original buffer if ++ * it(physical address) is not dword-aligned. ++ **/ ++ uint8_t *dw_align_buf; ++ dwc_dma_t dw_align_buf_dma; ++ ++ DWC_CIRCLEQ_ENTRY(dwc_otg_pcd_request) queue_entry; ++#ifdef DWC_UTE_PER_IO ++ struct dwc_iso_xreq_port ext_req; ++ //void *priv_ereq_nport; /* */ ++#endif ++} dwc_otg_pcd_request_t; ++ ++DWC_CIRCLEQ_HEAD(req_list, dwc_otg_pcd_request); ++ ++/** PCD EP structure. ++ * This structure describes an EP, there is an array of EPs in the PCD ++ * structure. ++ */ ++typedef struct dwc_otg_pcd_ep { ++ /** USB EP Descriptor */ ++ const usb_endpoint_descriptor_t *desc; ++ ++ /** queue of dwc_otg_pcd_requests. */ ++ struct req_list queue; ++ unsigned stopped:1; ++ unsigned disabling:1; ++ unsigned dma:1; ++ unsigned queue_sof:1; ++ ++#ifdef DWC_EN_ISOC ++ /** ISOC req handle passed */ ++ void *iso_req_handle; ++#endif //_EN_ISOC_ ++ ++ /** DWC_otg ep data. */ ++ dwc_ep_t dwc_ep; ++ ++ /** Pointer to PCD */ ++ struct dwc_otg_pcd *pcd; ++ ++ void *priv; ++} dwc_otg_pcd_ep_t; ++ ++/** DWC_otg PCD Structure. ++ * This structure encapsulates the data for the dwc_otg PCD. ++ */ ++struct dwc_otg_pcd { ++ const struct dwc_otg_pcd_function_ops *fops; ++ /** The DWC otg device pointer */ ++ struct dwc_otg_device *otg_dev; ++ /** Core Interface */ ++ dwc_otg_core_if_t *core_if; ++ /** State of EP0 */ ++ ep0state_e ep0state; ++ /** EP0 Request is pending */ ++ unsigned ep0_pending:1; ++ /** Indicates when SET CONFIGURATION Request is in process */ ++ unsigned request_config:1; ++ /** The state of the Remote Wakeup Enable. */ ++ unsigned remote_wakeup_enable:1; ++ /** The state of the B-Device HNP Enable. */ ++ unsigned b_hnp_enable:1; ++ /** The state of A-Device HNP Support. */ ++ unsigned a_hnp_support:1; ++ /** The state of the A-Device Alt HNP support. */ ++ unsigned a_alt_hnp_support:1; ++ /** Count of pending Requests */ ++ unsigned request_pending; ++ ++ /** SETUP packet for EP0 ++ * This structure is allocated as a DMA buffer on PCD initialization ++ * with enough space for up to 3 setup packets. ++ */ ++ union { ++ usb_device_request_t req; ++ uint32_t d32[2]; ++ } *setup_pkt; ++ ++ dwc_dma_t setup_pkt_dma_handle; ++ ++ /* Additional buffer and flag for CTRL_WR premature case */ ++ uint8_t *backup_buf; ++ unsigned data_terminated; ++ ++ /** 2-byte dma buffer used to return status from GET_STATUS */ ++ uint16_t *status_buf; ++ dwc_dma_t status_buf_dma_handle; ++ ++ /** EP0 */ ++ dwc_otg_pcd_ep_t ep0; ++ ++ /** Array of IN EPs. */ ++ dwc_otg_pcd_ep_t in_ep[MAX_EPS_CHANNELS - 1]; ++ /** Array of OUT EPs. */ ++ dwc_otg_pcd_ep_t out_ep[MAX_EPS_CHANNELS - 1]; ++ /** number of valid EPs in the above array. */ ++// unsigned num_eps : 4; ++ dwc_spinlock_t *lock; ++ ++ /** Tasklet to defer starting of TEST mode transmissions until ++ * Status Phase has been completed. ++ */ ++ dwc_tasklet_t *test_mode_tasklet; ++ ++ /** Tasklet to delay starting of xfer in DMA mode */ ++ dwc_tasklet_t *start_xfer_tasklet; ++ ++ /** The test mode to enter when the tasklet is executed. */ ++ unsigned test_mode; ++ /** The cfi_api structure that implements most of the CFI API ++ * and OTG specific core configuration functionality ++ */ ++#ifdef DWC_UTE_CFI ++ struct cfiobject *cfi; ++#endif ++ ++}; ++ ++//FIXME this functions should be static, and this prototypes should be removed ++extern void dwc_otg_request_nuke(dwc_otg_pcd_ep_t * ep); ++extern void dwc_otg_request_done(dwc_otg_pcd_ep_t * ep, ++ dwc_otg_pcd_request_t * req, int32_t status); ++ ++void dwc_otg_iso_buffer_done(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep, ++ void *req_handle); ++ ++extern void do_test_mode(void *data); ++#endif ++#endif /* DWC_HOST_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd_if.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd_if.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,360 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_if.h $ ++ * $Revision: #11 $ ++ * $Date: 2011/10/26 $ ++ * $Change: 1873028 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_HOST_ONLY ++ ++#if !defined(__DWC_PCD_IF_H__) ++#define __DWC_PCD_IF_H__ ++ ++//#include "dwc_os.h" ++#include "dwc_otg_core_if.h" ++ ++/** @file ++ * This file defines DWC_OTG PCD Core API. ++ */ ++ ++struct dwc_otg_pcd; ++typedef struct dwc_otg_pcd dwc_otg_pcd_t; ++ ++/** Maxpacket size for EP0 */ ++#define MAX_EP0_SIZE 64 ++/** Maxpacket size for any EP */ ++#define MAX_PACKET_SIZE 1024 ++ ++/** @name Function Driver Callbacks */ ++/** @{ */ ++ ++/** This function will be called whenever a previously queued request has ++ * completed. The status value will be set to -DWC_E_SHUTDOWN to indicated a ++ * failed or aborted transfer, or -DWC_E_RESTART to indicate the device was reset, ++ * or -DWC_E_TIMEOUT to indicate it timed out, or -DWC_E_INVALID to indicate invalid ++ * parameters. */ ++typedef int (*dwc_completion_cb_t) (dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle, int32_t status, ++ uint32_t actual); ++/** ++ * This function will be called whenever a previousle queued ISOC request has ++ * completed. Count of ISOC packets could be read using dwc_otg_pcd_get_iso_packet_count ++ * function. ++ * The status of each ISOC packet could be read using dwc_otg_pcd_get_iso_packet_* ++ * functions. ++ */ ++typedef int (*dwc_isoc_completion_cb_t) (dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle, int proc_buf_num); ++/** This function should handle any SETUP request that cannot be handled by the ++ * PCD Core. This includes most GET_DESCRIPTORs, SET_CONFIGS, Any ++ * class-specific requests, etc. The function must non-blocking. ++ * ++ * Returns 0 on success. ++ * Returns -DWC_E_NOT_SUPPORTED if the request is not supported. ++ * Returns -DWC_E_INVALID if the setup request had invalid parameters or bytes. ++ * Returns -DWC_E_SHUTDOWN on any other error. */ ++typedef int (*dwc_setup_cb_t) (dwc_otg_pcd_t * pcd, uint8_t * bytes); ++/** This is called whenever the device has been disconnected. The function ++ * driver should take appropriate action to clean up all pending requests in the ++ * PCD Core, remove all endpoints (except ep0), and initialize back to reset ++ * state. */ ++typedef int (*dwc_disconnect_cb_t) (dwc_otg_pcd_t * pcd); ++/** This function is called when device has been connected. */ ++typedef int (*dwc_connect_cb_t) (dwc_otg_pcd_t * pcd, int speed); ++/** This function is called when device has been suspended */ ++typedef int (*dwc_suspend_cb_t) (dwc_otg_pcd_t * pcd); ++/** This function is called when device has received LPM tokens, i.e. ++ * device has been sent to sleep state. */ ++typedef int (*dwc_sleep_cb_t) (dwc_otg_pcd_t * pcd); ++/** This function is called when device has been resumed ++ * from suspend(L2) or L1 sleep state. */ ++typedef int (*dwc_resume_cb_t) (dwc_otg_pcd_t * pcd); ++/** This function is called whenever hnp params has been changed. ++ * User can call get_b_hnp_enable, get_a_hnp_support, get_a_alt_hnp_support functions ++ * to get hnp parameters. */ ++typedef int (*dwc_hnp_params_changed_cb_t) (dwc_otg_pcd_t * pcd); ++/** This function is called whenever USB RESET is detected. */ ++typedef int (*dwc_reset_cb_t) (dwc_otg_pcd_t * pcd); ++ ++typedef int (*cfi_setup_cb_t) (dwc_otg_pcd_t * pcd, void *ctrl_req_bytes); ++ ++/** ++ * ++ * @param ep_handle Void pointer to the usb_ep structure ++ * @param ereq_port Pointer to the extended request structure created in the ++ * portable part. ++ */ ++typedef int (*xiso_completion_cb_t) (dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle, int32_t status, ++ void *ereq_port); ++/** Function Driver Ops Data Structure */ ++struct dwc_otg_pcd_function_ops { ++ dwc_connect_cb_t connect; ++ dwc_disconnect_cb_t disconnect; ++ dwc_setup_cb_t setup; ++ dwc_completion_cb_t complete; ++ dwc_isoc_completion_cb_t isoc_complete; ++ dwc_suspend_cb_t suspend; ++ dwc_sleep_cb_t sleep; ++ dwc_resume_cb_t resume; ++ dwc_reset_cb_t reset; ++ dwc_hnp_params_changed_cb_t hnp_changed; ++ cfi_setup_cb_t cfi_setup; ++#ifdef DWC_UTE_PER_IO ++ xiso_completion_cb_t xisoc_complete; ++#endif ++}; ++/** @} */ ++ ++/** @name Function Driver Functions */ ++/** @{ */ ++ ++/** Call this function to get pointer on dwc_otg_pcd_t, ++ * this pointer will be used for all PCD API functions. ++ * ++ * @param core_if The DWC_OTG Core ++ */ ++extern dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if); ++ ++/** Frees PCD allocated by dwc_otg_pcd_init ++ * ++ * @param pcd The PCD ++ */ ++extern void dwc_otg_pcd_remove(dwc_otg_pcd_t * pcd); ++ ++/** Call this to bind the function driver to the PCD Core. ++ * ++ * @param pcd Pointer on dwc_otg_pcd_t returned by dwc_otg_pcd_init function. ++ * @param fops The Function Driver Ops data structure containing pointers to all callbacks. ++ */ ++extern void dwc_otg_pcd_start(dwc_otg_pcd_t * pcd, ++ const struct dwc_otg_pcd_function_ops *fops); ++ ++/** Enables an endpoint for use. This function enables an endpoint in ++ * the PCD. The endpoint is described by the ep_desc which has the ++ * same format as a USB ep descriptor. The ep_handle parameter is used to refer ++ * to the endpoint from other API functions and in callbacks. Normally this ++ * should be called after a SET_CONFIGURATION/SET_INTERFACE to configure the ++ * core for that interface. ++ * ++ * Returns -DWC_E_INVALID if invalid parameters were passed. ++ * Returns -DWC_E_SHUTDOWN if any other error ocurred. ++ * Returns 0 on success. ++ * ++ * @param pcd The PCD ++ * @param ep_desc Endpoint descriptor ++ * @param usb_ep Handle on endpoint, that will be used to identify endpoint. ++ */ ++extern int dwc_otg_pcd_ep_enable(dwc_otg_pcd_t * pcd, ++ const uint8_t * ep_desc, void *usb_ep); ++ ++/** Disable the endpoint referenced by ep_handle. ++ * ++ * Returns -DWC_E_INVALID if invalid parameters were passed. ++ * Returns -DWC_E_SHUTDOWN if any other error occurred. ++ * Returns 0 on success. */ ++extern int dwc_otg_pcd_ep_disable(dwc_otg_pcd_t * pcd, void *ep_handle); ++ ++/** Queue a data transfer request on the endpoint referenced by ep_handle. ++ * After the transfer is completes, the complete callback will be called with ++ * the request status. ++ * ++ * @param pcd The PCD ++ * @param ep_handle The handle of the endpoint ++ * @param buf The buffer for the data ++ * @param dma_buf The DMA buffer for the data ++ * @param buflen The length of the data transfer ++ * @param zero Specifies whether to send zero length last packet. ++ * @param req_handle Set this handle to any value to use to reference this ++ * request in the ep_dequeue function or from the complete callback ++ * @param atomic_alloc If driver need to perform atomic allocations ++ * for internal data structures. ++ * ++ * Returns -DWC_E_INVALID if invalid parameters were passed. ++ * Returns -DWC_E_SHUTDOWN if any other error ocurred. ++ * Returns 0 on success. */ ++extern int dwc_otg_pcd_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle, ++ uint8_t * buf, dwc_dma_t dma_buf, ++ uint32_t buflen, int zero, void *req_handle, ++ int atomic_alloc); ++#ifdef DWC_UTE_PER_IO ++/** ++ * ++ * @param ereq_nonport Pointer to the extended request part of the ++ * usb_request structure defined in usb_gadget.h file. ++ */ ++extern int dwc_otg_pcd_xiso_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle, ++ uint8_t * buf, dwc_dma_t dma_buf, ++ uint32_t buflen, int zero, ++ void *req_handle, int atomic_alloc, ++ void *ereq_nonport); ++ ++#endif ++ ++/** De-queue the specified data transfer that has not yet completed. ++ * ++ * Returns -DWC_E_INVALID if invalid parameters were passed. ++ * Returns -DWC_E_SHUTDOWN if any other error ocurred. ++ * Returns 0 on success. */ ++extern int dwc_otg_pcd_ep_dequeue(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle); ++ ++/** Halt (STALL) an endpoint or clear it. ++ * ++ * Returns -DWC_E_INVALID if invalid parameters were passed. ++ * Returns -DWC_E_SHUTDOWN if any other error ocurred. ++ * Returns -DWC_E_AGAIN if the STALL cannot be sent and must be tried again later ++ * Returns 0 on success. */ ++extern int dwc_otg_pcd_ep_halt(dwc_otg_pcd_t * pcd, void *ep_handle, int value); ++ ++/** This function */ ++extern int dwc_otg_pcd_ep_wedge(dwc_otg_pcd_t * pcd, void *ep_handle); ++ ++/** This function should be called on every hardware interrupt */ ++extern int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd); ++ ++/** This function returns current frame number */ ++extern int dwc_otg_pcd_get_frame_number(dwc_otg_pcd_t * pcd); ++ ++/** ++ * Start isochronous transfers on the endpoint referenced by ep_handle. ++ * For isochronous transfers duble buffering is used. ++ * After processing each of buffers comlete callback will be called with ++ * status for each transaction. ++ * ++ * @param pcd The PCD ++ * @param ep_handle The handle of the endpoint ++ * @param buf0 The virtual address of first data buffer ++ * @param buf1 The virtual address of second data buffer ++ * @param dma0 The DMA address of first data buffer ++ * @param dma1 The DMA address of second data buffer ++ * @param sync_frame Data pattern frame number ++ * @param dp_frame Data size for pattern frame ++ * @param data_per_frame Data size for regular frame ++ * @param start_frame Frame number to start transfers, if -1 then start transfers ASAP. ++ * @param buf_proc_intrvl Interval of ISOC Buffer processing ++ * @param req_handle Handle of ISOC request ++ * @param atomic_alloc Specefies whether to perform atomic allocation for ++ * internal data structures. ++ * ++ * Returns -DWC_E_NO_MEMORY if there is no enough memory. ++ * Returns -DWC_E_INVALID if incorrect arguments are passed to the function. ++ * Returns -DW_E_SHUTDOWN for any other error. ++ * Returns 0 on success ++ */ ++extern int dwc_otg_pcd_iso_ep_start(dwc_otg_pcd_t * pcd, void *ep_handle, ++ uint8_t * buf0, uint8_t * buf1, ++ dwc_dma_t dma0, dwc_dma_t dma1, ++ int sync_frame, int dp_frame, ++ int data_per_frame, int start_frame, ++ int buf_proc_intrvl, void *req_handle, ++ int atomic_alloc); ++ ++/** Stop ISOC transfers on endpoint referenced by ep_handle. ++ * ++ * @param pcd The PCD ++ * @param ep_handle The handle of the endpoint ++ * @param req_handle Handle of ISOC request ++ * ++ * Returns -DWC_E_INVALID if incorrect arguments are passed to the function ++ * Returns 0 on success ++ */ ++int dwc_otg_pcd_iso_ep_stop(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle); ++ ++/** Get ISOC packet status. ++ * ++ * @param pcd The PCD ++ * @param ep_handle The handle of the endpoint ++ * @param iso_req_handle Isochronoush request handle ++ * @param packet Number of packet ++ * @param status Out parameter for returning status ++ * @param actual Out parameter for returning actual length ++ * @param offset Out parameter for returning offset ++ * ++ */ ++extern void dwc_otg_pcd_get_iso_packet_params(dwc_otg_pcd_t * pcd, ++ void *ep_handle, ++ void *iso_req_handle, int packet, ++ int *status, int *actual, ++ int *offset); ++ ++/** Get ISOC packet count. ++ * ++ * @param pcd The PCD ++ * @param ep_handle The handle of the endpoint ++ * @param iso_req_handle ++ */ ++extern int dwc_otg_pcd_get_iso_packet_count(dwc_otg_pcd_t * pcd, ++ void *ep_handle, ++ void *iso_req_handle); ++ ++/** This function starts the SRP Protocol if no session is in progress. If ++ * a session is already in progress, but the device is suspended, ++ * remote wakeup signaling is started. ++ */ ++extern int dwc_otg_pcd_wakeup(dwc_otg_pcd_t * pcd); ++ ++/** This function returns 1 if LPM support is enabled, and 0 otherwise. */ ++extern int dwc_otg_pcd_is_lpm_enabled(dwc_otg_pcd_t * pcd); ++ ++/** This function returns 1 if remote wakeup is allowed and 0, otherwise. */ ++extern int dwc_otg_pcd_get_rmwkup_enable(dwc_otg_pcd_t * pcd); ++ ++/** Initiate SRP */ ++extern void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t * pcd); ++ ++/** Starts remote wakeup signaling. */ ++extern void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t * pcd, int set); ++ ++/** Starts micorsecond soft disconnect. */ ++extern void dwc_otg_pcd_disconnect_us(dwc_otg_pcd_t * pcd, int no_of_usecs); ++/** This function returns whether device is dualspeed.*/ ++extern uint32_t dwc_otg_pcd_is_dualspeed(dwc_otg_pcd_t * pcd); ++ ++/** This function returns whether device is otg. */ ++extern uint32_t dwc_otg_pcd_is_otg(dwc_otg_pcd_t * pcd); ++ ++/** These functions allow to get hnp parameters */ ++extern uint32_t get_b_hnp_enable(dwc_otg_pcd_t * pcd); ++extern uint32_t get_a_hnp_support(dwc_otg_pcd_t * pcd); ++extern uint32_t get_a_alt_hnp_support(dwc_otg_pcd_t * pcd); ++ ++/** CFI specific Interface functions */ ++/** Allocate a cfi buffer */ ++extern uint8_t *cfiw_ep_alloc_buffer(dwc_otg_pcd_t * pcd, void *pep, ++ dwc_dma_t * addr, size_t buflen, ++ int flags); ++ ++/******************************************************************************/ ++ ++/** @} */ ++ ++#endif /* __DWC_PCD_IF_H__ */ ++ ++#endif /* DWC_HOST_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,5147 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $ ++ * $Revision: #116 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_HOST_ONLY ++ ++#include "dwc_otg_pcd.h" ++ ++#ifdef DWC_UTE_CFI ++#include "dwc_otg_cfi.h" ++#endif ++ ++#ifdef DWC_UTE_PER_IO ++extern void complete_xiso_ep(dwc_otg_pcd_ep_t * ep); ++#endif ++//#define PRINT_CFI_DMA_DESCS ++ ++#define DEBUG_EP0 ++ ++/** ++ * This function updates OTG. ++ */ ++static void dwc_otg_pcd_update_otg(dwc_otg_pcd_t * pcd, const unsigned reset) ++{ ++ ++ if (reset) { ++ pcd->b_hnp_enable = 0; ++ pcd->a_hnp_support = 0; ++ pcd->a_alt_hnp_support = 0; ++ } ++ ++ if (pcd->fops->hnp_changed) { ++ pcd->fops->hnp_changed(pcd); ++ } ++} ++ ++/** @file ++ * This file contains the implementation of the PCD Interrupt handlers. ++ * ++ * The PCD handles the device interrupts. Many conditions can cause a ++ * device interrupt. When an interrupt occurs, the device interrupt ++ * service routine determines the cause of the interrupt and ++ * dispatches handling to the appropriate function. These interrupt ++ * handling functions are described below. ++ * All interrupt registers are processed from LSB to MSB. ++ */ ++ ++/** ++ * This function prints the ep0 state for debug purposes. ++ */ ++static inline void print_ep0_state(dwc_otg_pcd_t * pcd) ++{ ++#ifdef DEBUG ++ char str[40]; ++ ++ switch (pcd->ep0state) { ++ case EP0_DISCONNECT: ++ dwc_strcpy(str, "EP0_DISCONNECT"); ++ break; ++ case EP0_IDLE: ++ dwc_strcpy(str, "EP0_IDLE"); ++ break; ++ case EP0_IN_DATA_PHASE: ++ dwc_strcpy(str, "EP0_IN_DATA_PHASE"); ++ break; ++ case EP0_OUT_DATA_PHASE: ++ dwc_strcpy(str, "EP0_OUT_DATA_PHASE"); ++ break; ++ case EP0_IN_STATUS_PHASE: ++ dwc_strcpy(str, "EP0_IN_STATUS_PHASE"); ++ break; ++ case EP0_OUT_STATUS_PHASE: ++ dwc_strcpy(str, "EP0_OUT_STATUS_PHASE"); ++ break; ++ case EP0_STALL: ++ dwc_strcpy(str, "EP0_STALL"); ++ break; ++ default: ++ dwc_strcpy(str, "EP0_INVALID"); ++ } ++ ++ DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state); ++#endif ++} ++ ++/** ++ * This function calculate the size of the payload in the memory ++ * for out endpoints and prints size for debug purposes(used in ++ * 2.93a DevOutNak feature). ++ */ ++static inline void print_memory_payload(dwc_otg_pcd_t * pcd, dwc_ep_t * ep) ++{ ++#ifdef DEBUG ++ deptsiz_data_t deptsiz_init = {.d32 = 0 }; ++ deptsiz_data_t deptsiz_updt = {.d32 = 0 }; ++ int pack_num; ++ unsigned payload; ++ ++ deptsiz_init.d32 = pcd->core_if->start_doeptsiz_val[ep->num]; ++ deptsiz_updt.d32 = ++ DWC_READ_REG32(&pcd->core_if->dev_if-> ++ out_ep_regs[ep->num]->doeptsiz); ++ /* Payload will be */ ++ payload = deptsiz_init.b.xfersize - deptsiz_updt.b.xfersize; ++ /* Packet count is decremented every time a packet ++ * is written to the RxFIFO not in to the external memory ++ * So, if payload == 0, then it means no packet was sent to ext memory*/ ++ pack_num = (!payload) ? 0 : (deptsiz_init.b.pktcnt - deptsiz_updt.b.pktcnt); ++ DWC_DEBUGPL(DBG_PCDV, ++ "Payload for EP%d-%s\n", ++ ep->num, (ep->is_in ? "IN" : "OUT")); ++ DWC_DEBUGPL(DBG_PCDV, ++ "Number of transfered bytes = 0x%08x\n", payload); ++ DWC_DEBUGPL(DBG_PCDV, ++ "Number of transfered packets = %d\n", pack_num); ++#endif ++} ++ ++ ++#ifdef DWC_UTE_CFI ++static inline void print_desc(struct dwc_otg_dma_desc *ddesc, ++ const uint8_t * epname, int descnum) ++{ ++ CFI_INFO ++ ("%s DMA_DESC(%d) buf=0x%08x bytes=0x%04x; sp=0x%x; l=0x%x; sts=0x%02x; bs=0x%02x\n", ++ epname, descnum, ddesc->buf, ddesc->status.b.bytes, ++ ddesc->status.b.sp, ddesc->status.b.l, ddesc->status.b.sts, ++ ddesc->status.b.bs); ++} ++#endif ++ ++/** ++ * This function returns pointer to in ep struct with number ep_num ++ */ ++static inline dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num) ++{ ++ int i; ++ int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps; ++ if (ep_num == 0) { ++ return &pcd->ep0; ++ } else { ++ for (i = 0; i < num_in_eps; ++i) { ++ if (pcd->in_ep[i].dwc_ep.num == ep_num) ++ return &pcd->in_ep[i]; ++ } ++ return 0; ++ } ++} ++ ++/** ++ * This function returns pointer to out ep struct with number ep_num ++ */ ++static inline dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num) ++{ ++ int i; ++ int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps; ++ if (ep_num == 0) { ++ return &pcd->ep0; ++ } else { ++ for (i = 0; i < num_out_eps; ++i) { ++ if (pcd->out_ep[i].dwc_ep.num == ep_num) ++ return &pcd->out_ep[i]; ++ } ++ return 0; ++ } ++} ++ ++/** ++ * This functions gets a pointer to an EP from the wIndex address ++ * value of the control request. ++ */ ++dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex) ++{ ++ dwc_otg_pcd_ep_t *ep; ++ uint32_t ep_num = UE_GET_ADDR(wIndex); ++ ++ if (ep_num == 0) { ++ ep = &pcd->ep0; ++ } else if (UE_GET_DIR(wIndex) == UE_DIR_IN) { /* in ep */ ++ ep = &pcd->in_ep[ep_num - 1]; ++ } else { ++ ep = &pcd->out_ep[ep_num - 1]; ++ } ++ ++ return ep; ++} ++ ++/** ++ * This function checks the EP request queue, if the queue is not ++ * empty the next request is started. ++ */ ++void start_next_request(dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_otg_pcd_request_t *req = 0; ++ uint32_t max_transfer = ++ GET_CORE_IF(ep->pcd)->core_params->max_transfer_size; ++ ++#ifdef DWC_UTE_CFI ++ struct dwc_otg_pcd *pcd; ++ pcd = ep->pcd; ++#endif ++ ++ if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ ++#ifdef DWC_UTE_CFI ++ if (ep->dwc_ep.buff_mode != BM_STANDARD) { ++ ep->dwc_ep.cfi_req_len = req->length; ++ pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ep, req); ++ } else { ++#endif ++ /* Setup and start the Transfer */ ++ if (req->dw_align_buf) { ++ ep->dwc_ep.dma_addr = req->dw_align_buf_dma; ++ ep->dwc_ep.start_xfer_buff = req->dw_align_buf; ++ ep->dwc_ep.xfer_buff = req->dw_align_buf; ++ } else { ++ ep->dwc_ep.dma_addr = req->dma; ++ ep->dwc_ep.start_xfer_buff = req->buf; ++ ep->dwc_ep.xfer_buff = req->buf; ++ } ++ ep->dwc_ep.sent_zlp = 0; ++ ep->dwc_ep.total_len = req->length; ++ ep->dwc_ep.xfer_len = 0; ++ ep->dwc_ep.xfer_count = 0; ++ ++ ep->dwc_ep.maxxfer = max_transfer; ++ if (GET_CORE_IF(ep->pcd)->dma_desc_enable) { ++ uint32_t out_max_xfer = DDMA_MAX_TRANSFER_SIZE ++ - (DDMA_MAX_TRANSFER_SIZE % 4); ++ if (ep->dwc_ep.is_in) { ++ if (ep->dwc_ep.maxxfer > ++ DDMA_MAX_TRANSFER_SIZE) { ++ ep->dwc_ep.maxxfer = ++ DDMA_MAX_TRANSFER_SIZE; ++ } ++ } else { ++ if (ep->dwc_ep.maxxfer > out_max_xfer) { ++ ep->dwc_ep.maxxfer = ++ out_max_xfer; ++ } ++ } ++ } ++ if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) { ++ ep->dwc_ep.maxxfer -= ++ (ep->dwc_ep.maxxfer % ep->dwc_ep.maxpacket); ++ } ++ if (req->sent_zlp) { ++ if ((ep->dwc_ep.total_len % ++ ep->dwc_ep.maxpacket == 0) ++ && (ep->dwc_ep.total_len != 0)) { ++ ep->dwc_ep.sent_zlp = 1; ++ } ++ ++ } ++#ifdef DWC_UTE_CFI ++ } ++#endif ++ dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep); ++ } else if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) { ++ DWC_PRINTF("There are no more ISOC requests \n"); ++ ep->dwc_ep.frame_num = 0xFFFFFFFF; ++ } ++} ++ ++/** ++ * This function handles the SOF Interrupts. At this time the SOF ++ * Interrupt is disabled. ++ */ ++int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ ++ gintsts_data_t gintsts; ++ ++ DWC_DEBUGPL(DBG_PCD, "SOF\n"); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.sofintr = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This function handles the Rx Status Queue Level Interrupt, which ++ * indicates that there is a least one packet in the Rx FIFO. The ++ * packets are moved from the FIFO to memory, where they will be ++ * processed when the Endpoint Interrupt Register indicates Transfer ++ * Complete or SETUP Phase Done. ++ * ++ * Repeat the following until the Rx Status Queue is empty: ++ * -# Read the Receive Status Pop Register (GRXSTSP) to get Packet ++ * info ++ * -# If Receive FIFO is empty then skip to step Clear the interrupt ++ * and exit ++ * -# If SETUP Packet call dwc_otg_read_setup_packet to copy the ++ * SETUP data to the buffer ++ * -# If OUT Data Packet call dwc_otg_read_packet to copy the data ++ * to the destination buffer ++ */ ++int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ gintmsk_data_t gintmask = {.d32 = 0 }; ++ device_grxsts_data_t status; ++ dwc_otg_pcd_ep_t *ep; ++ gintsts_data_t gintsts; ++#ifdef DEBUG ++ static char *dpid_str[] = { "D0", "D2", "D1", "MDATA" }; ++#endif ++ ++ //DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd); ++ /* Disable the Rx Status Queue Level interrupt */ ++ gintmask.b.rxstsqlvl = 1; ++ DWC_MODIFY_REG32(&global_regs->gintmsk, gintmask.d32, 0); ++ ++ /* Get the Status from the top of the FIFO */ ++ status.d32 = DWC_READ_REG32(&global_regs->grxstsp); ++ ++ DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s " ++ "pktsts:%x Frame:%d(0x%0x)\n", ++ status.b.epnum, status.b.bcnt, ++ dpid_str[status.b.dpid], ++ status.b.pktsts, status.b.fn, status.b.fn); ++ /* Get pointer to EP structure */ ++ ep = get_out_ep(pcd, status.b.epnum); ++ ++ switch (status.b.pktsts) { ++ case DWC_DSTS_GOUT_NAK: ++ DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n"); ++ break; ++ case DWC_STS_DATA_UPDT: ++ DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n"); ++ if (status.b.bcnt && ep->dwc_ep.xfer_buff) { ++ /** @todo NGS Check for buffer overflow? */ ++ dwc_otg_read_packet(core_if, ++ ep->dwc_ep.xfer_buff, ++ status.b.bcnt); ++ ep->dwc_ep.xfer_count += status.b.bcnt; ++ ep->dwc_ep.xfer_buff += status.b.bcnt; ++ } ++ break; ++ case DWC_STS_XFER_COMP: ++ DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n"); ++ break; ++ case DWC_DSTS_SETUP_COMP: ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n"); ++#endif ++ break; ++ case DWC_DSTS_SETUP_UPDT: ++ dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32); ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCD, ++ "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n", ++ pcd->setup_pkt->req.bmRequestType, ++ pcd->setup_pkt->req.bRequest, ++ UGETW(pcd->setup_pkt->req.wValue), ++ UGETW(pcd->setup_pkt->req.wIndex), ++ UGETW(pcd->setup_pkt->req.wLength)); ++#endif ++ ep->dwc_ep.xfer_count += status.b.bcnt; ++ break; ++ default: ++ DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n", ++ status.b.pktsts); ++ break; ++ } ++ ++ /* Enable the Rx Status Queue Level interrupt */ ++ DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmask.d32); ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.rxstsqlvl = 1; ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ //DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__); ++ return 1; ++} ++ ++/** ++ * This function examines the Device IN Token Learning Queue to ++ * determine the EP number of the last IN token received. This ++ * implementation is for the Mass Storage device where there are only ++ * 2 IN EPs (Control-IN and BULK-IN). ++ * ++ * The EP numbers for the first six IN Tokens are in DTKNQR1 and there ++ * are 8 EP Numbers in each of the other possible DTKNQ Registers. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * ++ */ ++static inline int get_ep_of_last_in_token(dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_device_global_regs_t *dev_global_regs = ++ core_if->dev_if->dev_global_regs; ++ const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth; ++ /* Number of Token Queue Registers */ ++ const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8; ++ dtknq1_data_t dtknqr1; ++ uint32_t in_tkn_epnums[4]; ++ int ndx = 0; ++ int i = 0; ++ volatile uint32_t *addr = &dev_global_regs->dtknqr1; ++ int epnum = 0; ++ ++ //DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH); ++ ++ /* Read the DTKNQ Registers */ ++ for (i = 0; i < DTKNQ_REG_CNT; i++) { ++ in_tkn_epnums[i] = DWC_READ_REG32(addr); ++ DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1, ++ in_tkn_epnums[i]); ++ if (addr == &dev_global_regs->dvbusdis) { ++ addr = &dev_global_regs->dtknqr3_dthrctl; ++ } else { ++ ++addr; ++ } ++ ++ } ++ ++ /* Copy the DTKNQR1 data to the bit field. */ ++ dtknqr1.d32 = in_tkn_epnums[0]; ++ /* Get the EP numbers */ ++ in_tkn_epnums[0] = dtknqr1.b.epnums0_5; ++ ndx = dtknqr1.b.intknwptr - 1; ++ ++ //DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx); ++ if (ndx == -1) { ++ /** @todo Find a simpler way to calculate the max ++ * queue position.*/ ++ int cnt = TOKEN_Q_DEPTH; ++ if (TOKEN_Q_DEPTH <= 6) { ++ cnt = TOKEN_Q_DEPTH - 1; ++ } else if (TOKEN_Q_DEPTH <= 14) { ++ cnt = TOKEN_Q_DEPTH - 7; ++ } else if (TOKEN_Q_DEPTH <= 22) { ++ cnt = TOKEN_Q_DEPTH - 15; ++ } else { ++ cnt = TOKEN_Q_DEPTH - 23; ++ } ++ epnum = (in_tkn_epnums[DTKNQ_REG_CNT - 1] >> (cnt * 4)) & 0xF; ++ } else { ++ if (ndx <= 5) { ++ epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF; ++ } else if (ndx <= 13) { ++ ndx -= 6; ++ epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF; ++ } else if (ndx <= 21) { ++ ndx -= 14; ++ epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF; ++ } else if (ndx <= 29) { ++ ndx -= 22; ++ epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF; ++ } ++ } ++ //DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum); ++ return epnum; ++} ++ ++/** ++ * This interrupt occurs when the non-periodic Tx FIFO is half-empty. ++ * The active request is checked for the next packet to be loaded into ++ * the non-periodic Tx FIFO. ++ */ ++int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ dwc_otg_dev_in_ep_regs_t *ep_regs; ++ gnptxsts_data_t txstatus = {.d32 = 0 }; ++ gintsts_data_t gintsts; ++ ++ int epnum = 0; ++ dwc_otg_pcd_ep_t *ep = 0; ++ uint32_t len = 0; ++ int dwords; ++ ++ /* Get the epnum from the IN Token Learning Queue. */ ++ epnum = get_ep_of_last_in_token(core_if); ++ ep = get_in_ep(pcd, epnum); ++ ++ DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %d \n", epnum); ++ ++ ep_regs = core_if->dev_if->in_ep_regs[epnum]; ++ ++ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count; ++ if (len > ep->dwc_ep.maxpacket) { ++ len = ep->dwc_ep.maxpacket; ++ } ++ dwords = (len + 3) / 4; ++ ++ /* While there is space in the queue and space in the FIFO and ++ * More data to tranfer, Write packets to the Tx FIFO */ ++ txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts); ++ DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n", txstatus.d32); ++ ++ while (txstatus.b.nptxqspcavail > 0 && ++ txstatus.b.nptxfspcavail > dwords && ++ ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) { ++ /* Write the FIFO */ ++ dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0); ++ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count; ++ ++ if (len > ep->dwc_ep.maxpacket) { ++ len = ep->dwc_ep.maxpacket; ++ } ++ ++ dwords = (len + 3) / 4; ++ txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts); ++ DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", txstatus.d32); ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", ++ DWC_READ_REG32(&global_regs->gnptxsts)); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.nptxfempty = 1; ++ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This function is called when dedicated Tx FIFO Empty interrupt occurs. ++ * The active request is checked for the next packet to be loaded into ++ * apropriate Tx FIFO. ++ */ ++static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ dwc_otg_dev_in_ep_regs_t *ep_regs; ++ dtxfsts_data_t txstatus = {.d32 = 0 }; ++ dwc_otg_pcd_ep_t *ep = 0; ++ uint32_t len = 0; ++ int dwords; ++ ++ ep = get_in_ep(pcd, epnum); ++ ++ DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum); ++ ++ ep_regs = core_if->dev_if->in_ep_regs[epnum]; ++ ++ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count; ++ ++ if (len > ep->dwc_ep.maxpacket) { ++ len = ep->dwc_ep.maxpacket; ++ } ++ ++ dwords = (len + 3) / 4; ++ ++ /* While there is space in the queue and space in the FIFO and ++ * More data to tranfer, Write packets to the Tx FIFO */ ++ txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts); ++ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32); ++ ++ while (txstatus.b.txfspcavail > dwords && ++ ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len && ++ ep->dwc_ep.xfer_len != 0) { ++ /* Write the FIFO */ ++ dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0); ++ ++ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count; ++ if (len > ep->dwc_ep.maxpacket) { ++ len = ep->dwc_ep.maxpacket; ++ } ++ ++ dwords = (len + 3) / 4; ++ txstatus.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts); ++ DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum, ++ txstatus.d32); ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, ++ DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts)); ++ ++ return 1; ++} ++ ++/** ++ * This function is called when the Device is disconnected. It stops ++ * any active requests and informs the Gadget driver of the ++ * disconnect. ++ */ ++void dwc_otg_pcd_stop(dwc_otg_pcd_t * pcd) ++{ ++ int i, num_in_eps, num_out_eps; ++ dwc_otg_pcd_ep_t *ep; ++ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_SPINLOCK(pcd->lock); ++ ++ num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps; ++ num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__); ++ /* don't disconnect drivers more than once */ ++ if (pcd->ep0state == EP0_DISCONNECT) { ++ DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__); ++ DWC_SPINUNLOCK(pcd->lock); ++ return; ++ } ++ pcd->ep0state = EP0_DISCONNECT; ++ ++ /* Reset the OTG state. */ ++ dwc_otg_pcd_update_otg(pcd, 1); ++ ++ /* Disable the NP Tx Fifo Empty Interrupt. */ ++ intr_mask.b.nptxfempty = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ ++ /* Flush the FIFOs */ ++ /**@todo NGS Flush Periodic FIFOs */ ++ dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10); ++ dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd)); ++ ++ /* prevent new request submissions, kill any outstanding requests */ ++ ep = &pcd->ep0; ++ dwc_otg_request_nuke(ep); ++ /* prevent new request submissions, kill any outstanding requests */ ++ for (i = 0; i < num_in_eps; i++) { ++ dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i]; ++ dwc_otg_request_nuke(ep); ++ } ++ /* prevent new request submissions, kill any outstanding requests */ ++ for (i = 0; i < num_out_eps; i++) { ++ dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i]; ++ dwc_otg_request_nuke(ep); ++ } ++ ++ /* report disconnect; the driver is already quiesced */ ++ if (pcd->fops->disconnect) { ++ DWC_SPINUNLOCK(pcd->lock); ++ pcd->fops->disconnect(pcd); ++ DWC_SPINLOCK(pcd->lock); ++ } ++ DWC_SPINUNLOCK(pcd->lock); ++} ++ ++/** ++ * This interrupt indicates that ... ++ */ ++int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t * pcd) ++{ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ gintsts_data_t gintsts; ++ ++ DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "i2cintr"); ++ intr_mask.b.i2cintr = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.i2cintr = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that ... ++ */ ++int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t * pcd) ++{ ++ gintsts_data_t gintsts; ++#if defined(VERBOSE) ++ DWC_PRINTF("Early Suspend Detected\n"); ++#endif ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.erlysuspend = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ return 1; ++} ++ ++/** ++ * This function configures EPO to receive SETUP packets. ++ * ++ * @todo NGS: Update the comments from the HW FS. ++ * ++ * -# Program the following fields in the endpoint specific registers ++ * for Control OUT EP 0, in order to receive a setup packet ++ * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back ++ * setup packets) ++ * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back ++ * to back setup packets) ++ * - In DMA mode, DOEPDMA0 Register with a memory address to ++ * store any setup packets received ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param pcd Programming view of the PCD. ++ */ ++static inline void ep0_out_start(dwc_otg_core_if_t * core_if, ++ dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ deptsiz0_data_t doeptsize0 = {.d32 = 0 }; ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ depctl_data_t doepctl = {.d32 = 0 }; ++ ++#ifdef VERBOSE ++ DWC_DEBUGPL(DBG_PCDV, "%s() doepctl0=%0x\n", __func__, ++ DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl)); ++#endif ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl); ++ if (doepctl.b.epena) { ++ return; ++ } ++ } ++ ++ doeptsize0.b.supcnt = 3; ++ doeptsize0.b.pktcnt = 1; ++ doeptsize0.b.xfersize = 8 * 3; ++ ++ if (core_if->dma_enable) { ++ if (!core_if->dma_desc_enable) { ++ /** put here as for Hermes mode deptisz register should not be written */ ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz, ++ doeptsize0.d32); ++ ++ /** @todo dma needs to handle multiple setup packets (up to 3) */ ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma, ++ pcd->setup_pkt_dma_handle); ++ } else { ++ dev_if->setup_desc_index = ++ (dev_if->setup_desc_index + 1) & 1; ++ dma_desc = ++ dev_if->setup_desc_addr[dev_if->setup_desc_index]; ++ ++ /** DMA Descriptor Setup */ ++ dma_desc->status.b.bs = BS_HOST_BUSY; ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ dma_desc->status.b.sr = 0; ++ dma_desc->status.b.mtrf = 0; ++ } ++ dma_desc->status.b.l = 1; ++ dma_desc->status.b.ioc = 1; ++ dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket; ++ dma_desc->buf = pcd->setup_pkt_dma_handle; ++ dma_desc->status.b.sts = 0; ++ dma_desc->status.b.bs = BS_HOST_READY; ++ ++ /** DOEPDMA0 Register write */ ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma, ++ dev_if->dma_setup_desc_addr ++ [dev_if->setup_desc_index]); ++ } ++ ++ } else { ++ /** put here as for Hermes mode deptisz register should not be written */ ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz, ++ doeptsize0.d32); ++ } ++ ++ /** DOEPCTL0 Register write cnak will be set after setup interrupt */ ++ doepctl.d32 = 0; ++ doepctl.b.epena = 1; ++ if (core_if->snpsid <= OTG_CORE_REV_2_94a) { ++ doepctl.b.cnak = 1; ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32); ++ } else { ++ DWC_MODIFY_REG32(&dev_if->out_ep_regs[0]->doepctl, 0, doepctl.d32); ++ } ++ ++#ifdef VERBOSE ++ DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n", ++ DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl)); ++ DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n", ++ DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl)); ++#endif ++} ++ ++/** ++ * This interrupt occurs when a USB Reset is detected. When the USB ++ * Reset Interrupt occurs the device state is set to DEFAULT and the ++ * EP0 state is set to IDLE. ++ * -# Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1) ++ * -# Unmask the following interrupt bits ++ * - DAINTMSK.INEP0 = 1 (Control 0 IN endpoint) ++ * - DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint) ++ * - DOEPMSK.SETUP = 1 ++ * - DOEPMSK.XferCompl = 1 ++ * - DIEPMSK.XferCompl = 1 ++ * - DIEPMSK.TimeOut = 1 ++ * -# Program the following fields in the endpoint specific registers ++ * for Control OUT EP 0, in order to receive a setup packet ++ * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back ++ * setup packets) ++ * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back ++ * to back setup packets) ++ * - In DMA mode, DOEPDMA0 Register with a memory address to ++ * store any setup packets received ++ * At this point, all the required initialization, except for enabling ++ * the control 0 OUT endpoint is done, for receiving SETUP packets. ++ */ ++int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ depctl_data_t doepctl = {.d32 = 0 }; ++ depctl_data_t diepctl = {.d32 = 0 }; ++ daint_data_t daintmsk = {.d32 = 0 }; ++ doepmsk_data_t doepmsk = {.d32 = 0 }; ++ diepmsk_data_t diepmsk = {.d32 = 0 }; ++ dcfg_data_t dcfg = {.d32 = 0 }; ++ grstctl_t resetctl = {.d32 = 0 }; ++ dctl_data_t dctl = {.d32 = 0 }; ++ int i = 0; ++ gintsts_data_t gintsts; ++ pcgcctl_data_t power = {.d32 = 0 }; ++ ++ power.d32 = DWC_READ_REG32(core_if->pcgcctl); ++ if (power.b.stoppclk) { ++ power.d32 = 0; ++ power.b.stoppclk = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0); ++ ++ power.b.pwrclmp = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0); ++ ++ power.b.rstpdwnmodule = 1; ++ DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0); ++ } ++ ++ core_if->lx_state = DWC_OTG_L0; ++ ++ DWC_PRINTF("USB RESET\n"); ++#ifdef DWC_EN_ISOC ++ for (i = 1; i < 16; ++i) { ++ dwc_otg_pcd_ep_t *ep; ++ dwc_ep_t *dwc_ep; ++ ep = get_in_ep(pcd, i); ++ if (ep != 0) { ++ dwc_ep = &ep->dwc_ep; ++ dwc_ep->next_frame = 0xffffffff; ++ } ++ } ++#endif /* DWC_EN_ISOC */ ++ ++ /* reset the HNP settings */ ++ dwc_otg_pcd_update_otg(pcd, 1); ++ ++ /* Clear the Remote Wakeup Signalling */ ++ dctl.b.rmtwkupsig = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0); ++ ++ /* Set NAK for all OUT EPs */ ++ doepctl.b.snak = 1; ++ for (i = 0; i <= dev_if->num_out_eps; i++) { ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32); ++ } ++ ++ /* Flush the NP Tx FIFO */ ++ dwc_otg_flush_tx_fifo(core_if, 0x10); ++ /* Flush the Learning Queue */ ++ resetctl.b.intknqflsh = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32); ++ ++ if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) { ++ core_if->start_predict = 0; ++ for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) { ++ core_if->nextep_seq[i] = 0xff; // 0xff - EP not active ++ } ++ core_if->nextep_seq[0] = 0; ++ core_if->first_in_nextep_seq = 0; ++ diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl); ++ diepctl.b.nextep = 0; ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32); ++ ++ /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */ ++ dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg); ++ dcfg.b.epmscnt = 2; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32); ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "%s first_in_nextep_seq= %2d; nextep_seq[]:\n", ++ __func__, core_if->first_in_nextep_seq); ++ for (i=0; i <= core_if->dev_if->num_in_eps; i++) { ++ DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]); ++ } ++ } ++ ++ if (core_if->multiproc_int_enable) { ++ daintmsk.b.inep0 = 1; ++ daintmsk.b.outep0 = 1; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, ++ daintmsk.d32); ++ ++ doepmsk.b.setup = 1; ++ doepmsk.b.xfercompl = 1; ++ doepmsk.b.ahberr = 1; ++ doepmsk.b.epdisabled = 1; ++ ++ if ((core_if->dma_desc_enable) || ++ (core_if->dma_enable ++ && core_if->snpsid >= OTG_CORE_REV_3_00a)) { ++ doepmsk.b.stsphsercvd = 1; ++ } ++ if (core_if->dma_desc_enable) ++ doepmsk.b.bna = 1; ++/* ++ doepmsk.b.babble = 1; ++ doepmsk.b.nyet = 1; ++ ++ if (core_if->dma_enable) { ++ doepmsk.b.nak = 1; ++ } ++*/ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->doepeachintmsk[0], ++ doepmsk.d32); ++ ++ diepmsk.b.xfercompl = 1; ++ diepmsk.b.timeout = 1; ++ diepmsk.b.epdisabled = 1; ++ diepmsk.b.ahberr = 1; ++ diepmsk.b.intknepmis = 1; ++ if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) ++ diepmsk.b.intknepmis = 0; ++ ++/* if (core_if->dma_desc_enable) { ++ diepmsk.b.bna = 1; ++ } ++*/ ++/* ++ if (core_if->dma_enable) { ++ diepmsk.b.nak = 1; ++ } ++*/ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->diepeachintmsk[0], ++ diepmsk.d32); ++ } else { ++ daintmsk.b.inep0 = 1; ++ daintmsk.b.outep0 = 1; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, ++ daintmsk.d32); ++ ++ doepmsk.b.setup = 1; ++ doepmsk.b.xfercompl = 1; ++ doepmsk.b.ahberr = 1; ++ doepmsk.b.epdisabled = 1; ++ ++ if ((core_if->dma_desc_enable) || ++ (core_if->dma_enable ++ && core_if->snpsid >= OTG_CORE_REV_3_00a)) { ++ doepmsk.b.stsphsercvd = 1; ++ } ++ if (core_if->dma_desc_enable) ++ doepmsk.b.bna = 1; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32); ++ ++ diepmsk.b.xfercompl = 1; ++ diepmsk.b.timeout = 1; ++ diepmsk.b.epdisabled = 1; ++ diepmsk.b.ahberr = 1; ++ if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) ++ diepmsk.b.intknepmis = 0; ++/* ++ if (core_if->dma_desc_enable) { ++ diepmsk.b.bna = 1; ++ } ++*/ ++ ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32); ++ } ++ ++ /* Reset Device Address */ ++ dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg); ++ dcfg.b.devaddr = 0; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32); ++ ++ /* setup EP0 to receive SETUP packets */ ++ if (core_if->snpsid <= OTG_CORE_REV_2_94a) ++ ep0_out_start(core_if, pcd); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.usbreset = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * Get the device speed from the device status register and convert it ++ * to USB speed constant. ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ */ ++static int get_device_speed(dwc_otg_core_if_t * core_if) ++{ ++ dsts_data_t dsts; ++ int speed = 0; ++ dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts); ++ ++ switch (dsts.b.enumspd) { ++ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: ++ speed = USB_SPEED_HIGH; ++ break; ++ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: ++ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ: ++ speed = USB_SPEED_FULL; ++ break; ++ ++ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ: ++ speed = USB_SPEED_LOW; ++ break; ++ } ++ ++ return speed; ++} ++ ++/** ++ * Read the device status register and set the device speed in the ++ * data structure. ++ * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate. ++ */ ++int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0; ++ gintsts_data_t gintsts; ++ gusbcfg_data_t gusbcfg; ++ dwc_otg_core_global_regs_t *global_regs = ++ GET_CORE_IF(pcd)->core_global_regs; ++ uint8_t utmi16b, utmi8b; ++ int speed; ++ DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n"); ++ ++ if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) { ++ utmi16b = 6; //vahrama old value was 6; ++ utmi8b = 9; ++ } else { ++ utmi16b = 4; ++ utmi8b = 8; ++ } ++ dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep); ++ if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_3_00a) { ++ ep0_out_start(GET_CORE_IF(pcd), pcd); ++ } ++ ++#ifdef DEBUG_EP0 ++ print_ep0_state(pcd); ++#endif ++ ++ if (pcd->ep0state == EP0_DISCONNECT) { ++ pcd->ep0state = EP0_IDLE; ++ } else if (pcd->ep0state == EP0_STALL) { ++ pcd->ep0state = EP0_IDLE; ++ } ++ ++ pcd->ep0state = EP0_IDLE; ++ ++ ep0->stopped = 0; ++ ++ speed = get_device_speed(GET_CORE_IF(pcd)); ++ pcd->fops->connect(pcd, speed); ++ ++ /* Set USB turnaround time based on device speed and PHY interface. */ ++ gusbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg); ++ if (speed == USB_SPEED_HIGH) { ++ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == ++ DWC_HWCFG2_HS_PHY_TYPE_ULPI) { ++ /* ULPI interface */ ++ gusbcfg.b.usbtrdtim = 9; ++ } ++ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == ++ DWC_HWCFG2_HS_PHY_TYPE_UTMI) { ++ /* UTMI+ interface */ ++ if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) { ++ gusbcfg.b.usbtrdtim = utmi8b; ++ } else if (GET_CORE_IF(pcd)->hwcfg4. ++ b.utmi_phy_data_width == 1) { ++ gusbcfg.b.usbtrdtim = utmi16b; ++ } else if (GET_CORE_IF(pcd)-> ++ core_params->phy_utmi_width == 8) { ++ gusbcfg.b.usbtrdtim = utmi8b; ++ } else { ++ gusbcfg.b.usbtrdtim = utmi16b; ++ } ++ } ++ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == ++ DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) { ++ /* UTMI+ OR ULPI interface */ ++ if (gusbcfg.b.ulpi_utmi_sel == 1) { ++ /* ULPI interface */ ++ gusbcfg.b.usbtrdtim = 9; ++ } else { ++ /* UTMI+ interface */ ++ if (GET_CORE_IF(pcd)-> ++ core_params->phy_utmi_width == 16) { ++ gusbcfg.b.usbtrdtim = utmi16b; ++ } else { ++ gusbcfg.b.usbtrdtim = utmi8b; ++ } ++ } ++ } ++ } else { ++ /* Full or low speed */ ++ gusbcfg.b.usbtrdtim = 9; ++ } ++ DWC_WRITE_REG32(&global_regs->gusbcfg, gusbcfg.d32); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.enumdone = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that the ISO OUT Packet was dropped due to ++ * Rx FIFO full or Rx Status Queue Full. If this interrupt occurs ++ * read all the data from the Rx FIFO. ++ */ ++int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t * pcd) ++{ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ gintsts_data_t gintsts; ++ ++ DWC_WARN("INTERRUPT Handler not implemented for %s\n", ++ "ISOC Out Dropped"); ++ ++ intr_mask.b.isooutdrop = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.isooutdrop = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This interrupt indicates the end of the portion of the micro-frame ++ * for periodic transactions. If there is a periodic transaction for ++ * the next frame, load the packets into the EP periodic Tx FIFO. ++ */ ++int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t * pcd) ++{ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ gintsts_data_t gintsts; ++ DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "EOP"); ++ ++ intr_mask.b.eopframe = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.eopframe = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that EP of the packet on the top of the ++ * non-periodic Tx FIFO does not match EP of the IN Token received. ++ * ++ * The "Device IN Token Queue" Registers are read to determine the ++ * order the IN Tokens have been received. The non-periodic Tx FIFO ++ * is flushed, so it can be reloaded in the order seen in the IN Token ++ * Queue. ++ */ ++int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_pcd_t * pcd) ++{ ++ gintsts_data_t gintsts; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dctl_data_t dctl; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) { ++ core_if->start_predict = 1; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if); ++ ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ if (!gintsts.b.ginnakeff) { ++ /* Disable EP Mismatch interrupt */ ++ intr_mask.d32 = 0; ++ intr_mask.b.epmismatch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0); ++ /* Enable the Global IN NAK Effective Interrupt */ ++ intr_mask.d32 = 0; ++ intr_mask.b.ginnakeff = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32); ++ /* Set the global non-periodic IN NAK handshake */ ++ dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl); ++ dctl.b.sgnpinnak = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32); ++ } else { ++ DWC_PRINTF("gintsts.b.ginnakeff = 1! dctl.b.sgnpinnak not set\n"); ++ } ++ /* Disabling of all EP's will be done in dwc_otg_pcd_handle_in_nak_effective() ++ * handler after Global IN NAK Effective interrupt will be asserted */ ++ } ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.epmismatch = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This interrupt is valid only in DMA mode. This interrupt indicates that the ++ * core has stopped fetching data for IN endpoints due to the unavailability of ++ * TxFIFO space or Request Queue space. This interrupt is used by the ++ * application for an endpoint mismatch algorithm. ++ * ++ * @param pcd The PCD ++ */ ++int32_t dwc_otg_pcd_handle_ep_fetsusp_intr(dwc_otg_pcd_t * pcd) ++{ ++ gintsts_data_t gintsts; ++ gintmsk_data_t gintmsk_data; ++ dctl_data_t dctl; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if); ++ ++ /* Clear the global non-periodic IN NAK handshake */ ++ dctl.d32 = 0; ++ dctl.b.cgnpinnak = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); ++ ++ /* Mask GINTSTS.FETSUSP interrupt */ ++ gintmsk_data.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); ++ gintmsk_data.b.fetsusp = 0; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_data.d32); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.fetsusp = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32); ++ ++ return 1; ++} ++/** ++ * This funcion stalls EP0. ++ */ ++static inline void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val) ++{ ++ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0; ++ usb_device_request_t *ctrl = &pcd->setup_pkt->req; ++ DWC_WARN("req %02x.%02x protocol STALL; err %d\n", ++ ctrl->bmRequestType, ctrl->bRequest, err_val); ++ ++ ep0->dwc_ep.is_in = 1; ++ dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep); ++ pcd->ep0.stopped = 1; ++ pcd->ep0state = EP0_IDLE; ++ ep0_out_start(GET_CORE_IF(pcd), pcd); ++} ++ ++/** ++ * This functions delegates the setup command to the gadget driver. ++ */ ++static inline void do_gadget_setup(dwc_otg_pcd_t * pcd, ++ usb_device_request_t * ctrl) ++{ ++ int ret = 0; ++ DWC_SPINUNLOCK(pcd->lock); ++ ret = pcd->fops->setup(pcd, (uint8_t *) ctrl); ++ DWC_SPINLOCK(pcd->lock); ++ if (ret < 0) { ++ ep0_do_stall(pcd, ret); ++ } ++ ++ /** @todo This is a g_file_storage gadget driver specific ++ * workaround: a DELAYED_STATUS result from the fsg_setup ++ * routine will result in the gadget queueing a EP0 IN status ++ * phase for a two-stage control transfer. Exactly the same as ++ * a SET_CONFIGURATION/SET_INTERFACE except that this is a class ++ * specific request. Need a generic way to know when the gadget ++ * driver will queue the status phase. Can we assume when we ++ * call the gadget driver setup() function that it will always ++ * queue and require the following flag? Need to look into ++ * this. ++ */ ++ ++ if (ret == 256 + 999) { ++ pcd->request_config = 1; ++ } ++} ++ ++#ifdef DWC_UTE_CFI ++/** ++ * This functions delegates the CFI setup commands to the gadget driver. ++ * This function will return a negative value to indicate a failure. ++ */ ++static inline int cfi_gadget_setup(dwc_otg_pcd_t * pcd, ++ struct cfi_usb_ctrlrequest *ctrl_req) ++{ ++ int ret = 0; ++ ++ if (pcd->fops && pcd->fops->cfi_setup) { ++ DWC_SPINUNLOCK(pcd->lock); ++ ret = pcd->fops->cfi_setup(pcd, ctrl_req); ++ DWC_SPINLOCK(pcd->lock); ++ if (ret < 0) { ++ ep0_do_stall(pcd, ret); ++ return ret; ++ } ++ } ++ ++ return ret; ++} ++#endif ++ ++/** ++ * This function starts the Zero-Length Packet for the IN status phase ++ * of a 2 stage control transfer. ++ */ ++static inline void do_setup_in_status_phase(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0; ++ if (pcd->ep0state == EP0_STALL) { ++ return; ++ } ++ ++ pcd->ep0state = EP0_IN_STATUS_PHASE; ++ ++ /* Prepare for more SETUP Packets */ ++ DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n"); ++ if ((GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_3_00a) ++ && (pcd->core_if->dma_desc_enable) ++ && (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)) { ++ DWC_DEBUGPL(DBG_PCDV, ++ "Data terminated wait next packet in out_desc_addr\n"); ++ pcd->backup_buf = phys_to_virt(ep0->dwc_ep.dma_addr); ++ pcd->data_terminated = 1; ++ } ++ ep0->dwc_ep.xfer_len = 0; ++ ep0->dwc_ep.xfer_count = 0; ++ ep0->dwc_ep.is_in = 1; ++ ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle; ++ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep); ++ ++ /* Prepare for more SETUP Packets */ ++ //ep0_out_start(GET_CORE_IF(pcd), pcd); ++} ++ ++/** ++ * This function starts the Zero-Length Packet for the OUT status phase ++ * of a 2 stage control transfer. ++ */ ++static inline void do_setup_out_status_phase(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0; ++ if (pcd->ep0state == EP0_STALL) { ++ DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n"); ++ return; ++ } ++ pcd->ep0state = EP0_OUT_STATUS_PHASE; ++ ++ DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n"); ++ ep0->dwc_ep.xfer_len = 0; ++ ep0->dwc_ep.xfer_count = 0; ++ ep0->dwc_ep.is_in = 0; ++ ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle; ++ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep); ++ ++ /* Prepare for more SETUP Packets */ ++ if (GET_CORE_IF(pcd)->dma_enable == 0) { ++ ep0_out_start(GET_CORE_IF(pcd), pcd); ++ } ++} ++ ++/** ++ * Clear the EP halt (STALL) and if pending requests start the ++ * transfer. ++ */ ++static inline void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep) ++{ ++ if (ep->dwc_ep.stall_clear_flag == 0) ++ dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep); ++ ++ /* Reactive the EP */ ++ dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep); ++ if (ep->stopped) { ++ ep->stopped = 0; ++ /* If there is a request in the EP queue start it */ ++ ++ /** @todo FIXME: this causes an EP mismatch in DMA mode. ++ * epmismatch not yet implemented. */ ++ ++ /* ++ * Above fixme is solved by implmenting a tasklet to call the ++ * start_next_request(), outside of interrupt context at some ++ * time after the current time, after a clear-halt setup packet. ++ * Still need to implement ep mismatch in the future if a gadget ++ * ever uses more than one endpoint at once ++ */ ++ ep->queue_sof = 1; ++ DWC_TASK_SCHEDULE(pcd->start_xfer_tasklet); ++ } ++ /* Start Control Status Phase */ ++ do_setup_in_status_phase(pcd); ++} ++ ++/** ++ * This function is called when the SET_FEATURE TEST_MODE Setup packet ++ * is sent from the host. The Device Control register is written with ++ * the Test Mode bits set to the specified Test Mode. This is done as ++ * a tasklet so that the "Status" phase of the control transfer ++ * completes before transmitting the TEST packets. ++ * ++ * @todo This has not been tested since the tasklet struct was put ++ * into the PCD struct! ++ * ++ */ ++void do_test_mode(void *data) ++{ ++ dctl_data_t dctl; ++ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ int test_mode = pcd->test_mode; ++ ++// DWC_WARN("%s() has not been tested since being rewritten!\n", __func__); ++ ++ dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl); ++ switch (test_mode) { ++ case 1: // TEST_J ++ dctl.b.tstctl = 1; ++ break; ++ ++ case 2: // TEST_K ++ dctl.b.tstctl = 2; ++ break; ++ ++ case 3: // TEST_SE0_NAK ++ dctl.b.tstctl = 3; ++ break; ++ ++ case 4: // TEST_PACKET ++ dctl.b.tstctl = 4; ++ break; ++ ++ case 5: // TEST_FORCE_ENABLE ++ dctl.b.tstctl = 5; ++ break; ++ } ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32); ++} ++ ++/** ++ * This function process the GET_STATUS Setup Commands. ++ */ ++static inline void do_get_status(dwc_otg_pcd_t * pcd) ++{ ++ usb_device_request_t ctrl = pcd->setup_pkt->req; ++ dwc_otg_pcd_ep_t *ep; ++ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0; ++ uint16_t *status = pcd->status_buf; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCD, ++ "GET_STATUS %02x.%02x v%04x i%04x l%04x\n", ++ ctrl.bmRequestType, ctrl.bRequest, ++ UGETW(ctrl.wValue), UGETW(ctrl.wIndex), ++ UGETW(ctrl.wLength)); ++#endif ++ ++ switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) { ++ case UT_DEVICE: ++ if(UGETW(ctrl.wIndex) == 0xF000) { /* OTG Status selector */ ++ DWC_PRINTF("wIndex - %d\n", UGETW(ctrl.wIndex)); ++ DWC_PRINTF("OTG VERSION - %d\n", core_if->otg_ver); ++ DWC_PRINTF("OTG CAP - %d, %d\n", ++ core_if->core_params->otg_cap, ++ DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE); ++ if (core_if->otg_ver == 1 ++ && core_if->core_params->otg_cap == ++ DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) { ++ uint8_t *otgsts = (uint8_t*)pcd->status_buf; ++ *otgsts = (core_if->otg_sts & 0x1); ++ pcd->ep0_pending = 1; ++ ep0->dwc_ep.start_xfer_buff = ++ (uint8_t *) otgsts; ++ ep0->dwc_ep.xfer_buff = (uint8_t *) otgsts; ++ ep0->dwc_ep.dma_addr = ++ pcd->status_buf_dma_handle; ++ ep0->dwc_ep.xfer_len = 1; ++ ep0->dwc_ep.xfer_count = 0; ++ ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len; ++ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), ++ &ep0->dwc_ep); ++ return; ++ } else { ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ break; ++ } else { ++ *status = 0x1; /* Self powered */ ++ *status |= pcd->remote_wakeup_enable << 1; ++ break; ++ } ++ case UT_INTERFACE: ++ *status = 0; ++ break; ++ ++ case UT_ENDPOINT: ++ ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex)); ++ if (ep == 0 || UGETW(ctrl.wLength) > 2) { ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ /** @todo check for EP stall */ ++ *status = ep->stopped; ++ break; ++ } ++ pcd->ep0_pending = 1; ++ ep0->dwc_ep.start_xfer_buff = (uint8_t *) status; ++ ep0->dwc_ep.xfer_buff = (uint8_t *) status; ++ ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle; ++ ep0->dwc_ep.xfer_len = 2; ++ ep0->dwc_ep.xfer_count = 0; ++ ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len; ++ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep); ++} ++ ++/** ++ * This function process the SET_FEATURE Setup Commands. ++ */ ++static inline void do_set_feature(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++ usb_device_request_t ctrl = pcd->setup_pkt->req; ++ dwc_otg_pcd_ep_t *ep = 0; ++ int32_t otg_cap_param = core_if->core_params->otg_cap; ++ gotgctl_data_t gotgctl = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n", ++ ctrl.bmRequestType, ctrl.bRequest, ++ UGETW(ctrl.wValue), UGETW(ctrl.wIndex), ++ UGETW(ctrl.wLength)); ++ DWC_DEBUGPL(DBG_PCD, "otg_cap=%d\n", otg_cap_param); ++ ++ switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) { ++ case UT_DEVICE: ++ switch (UGETW(ctrl.wValue)) { ++ case UF_DEVICE_REMOTE_WAKEUP: ++ pcd->remote_wakeup_enable = 1; ++ break; ++ ++ case UF_TEST_MODE: ++ /* Setup the Test Mode tasklet to do the Test ++ * Packet generation after the SETUP Status ++ * phase has completed. */ ++ ++ /** @todo This has not been tested since the ++ * tasklet struct was put into the PCD ++ * struct! */ ++ pcd->test_mode = UGETW(ctrl.wIndex) >> 8; ++ DWC_TASK_SCHEDULE(pcd->test_mode_tasklet); ++ break; ++ ++ case UF_DEVICE_B_HNP_ENABLE: ++ DWC_DEBUGPL(DBG_PCDV, ++ "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n"); ++ ++ /* dev may initiate HNP */ ++ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) { ++ pcd->b_hnp_enable = 1; ++ dwc_otg_pcd_update_otg(pcd, 0); ++ DWC_DEBUGPL(DBG_PCD, "Request B HNP\n"); ++ /**@todo Is the gotgctl.devhnpen cleared ++ * by a USB Reset? */ ++ gotgctl.b.devhnpen = 1; ++ gotgctl.b.hnpreq = 1; ++ DWC_WRITE_REG32(&global_regs->gotgctl, ++ gotgctl.d32); ++ } else { ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ break; ++ ++ case UF_DEVICE_A_HNP_SUPPORT: ++ /* RH port supports HNP */ ++ DWC_DEBUGPL(DBG_PCDV, ++ "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n"); ++ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) { ++ pcd->a_hnp_support = 1; ++ dwc_otg_pcd_update_otg(pcd, 0); ++ } else { ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ break; ++ ++ case UF_DEVICE_A_ALT_HNP_SUPPORT: ++ /* other RH port does */ ++ DWC_DEBUGPL(DBG_PCDV, ++ "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n"); ++ if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) { ++ pcd->a_alt_hnp_support = 1; ++ dwc_otg_pcd_update_otg(pcd, 0); ++ } else { ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ break; ++ ++ default: ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ ++ } ++ do_setup_in_status_phase(pcd); ++ break; ++ ++ case UT_INTERFACE: ++ do_gadget_setup(pcd, &ctrl); ++ break; ++ ++ case UT_ENDPOINT: ++ if (UGETW(ctrl.wValue) == UF_ENDPOINT_HALT) { ++ ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex)); ++ if (ep == 0) { ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ ep->stopped = 1; ++ dwc_otg_ep_set_stall(core_if, &ep->dwc_ep); ++ } ++ do_setup_in_status_phase(pcd); ++ break; ++ } ++} ++ ++/** ++ * This function process the CLEAR_FEATURE Setup Commands. ++ */ ++static inline void do_clear_feature(dwc_otg_pcd_t * pcd) ++{ ++ usb_device_request_t ctrl = pcd->setup_pkt->req; ++ dwc_otg_pcd_ep_t *ep = 0; ++ ++ DWC_DEBUGPL(DBG_PCD, ++ "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n", ++ ctrl.bmRequestType, ctrl.bRequest, ++ UGETW(ctrl.wValue), UGETW(ctrl.wIndex), ++ UGETW(ctrl.wLength)); ++ ++ switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) { ++ case UT_DEVICE: ++ switch (UGETW(ctrl.wValue)) { ++ case UF_DEVICE_REMOTE_WAKEUP: ++ pcd->remote_wakeup_enable = 0; ++ break; ++ ++ case UF_TEST_MODE: ++ /** @todo Add CLEAR_FEATURE for TEST modes. */ ++ break; ++ ++ default: ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ do_setup_in_status_phase(pcd); ++ break; ++ ++ case UT_ENDPOINT: ++ ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex)); ++ if (ep == 0) { ++ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED); ++ return; ++ } ++ ++ pcd_clear_halt(pcd, ep); ++ ++ break; ++ } ++} ++ ++/** ++ * This function process the SET_ADDRESS Setup Commands. ++ */ ++static inline void do_set_address(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if; ++ usb_device_request_t ctrl = pcd->setup_pkt->req; ++ ++ if (ctrl.bmRequestType == UT_DEVICE) { ++ dcfg_data_t dcfg = {.d32 = 0 }; ++ ++#ifdef DEBUG_EP0 ++// DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue); ++#endif ++ dcfg.b.devaddr = UGETW(ctrl.wValue); ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32); ++ do_setup_in_status_phase(pcd); ++ } ++} ++ ++/** ++ * This function processes SETUP commands. In Linux, the USB Command ++ * processing is done in two places - the first being the PCD and the ++ * second in the Gadget Driver (for example, the File-Backed Storage ++ * Gadget Driver). ++ * ++ *
Parameter NameMeaning
otg_capSpecifies the OTG capabilities. The driver will automatically detect the ++ value for this parameter if none is specified. ++ - 0: HNP and SRP capable (default, if available) ++ - 1: SRP Only capable ++ - 2: No HNP/SRP capable ++
dma_enableSpecifies whether to use slave or DMA mode for accessing the data FIFOs. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: Slave ++ - 1: DMA (default, if available) ++
dma_burst_sizeThe DMA Burst size (applicable only for External DMA Mode). ++ - Values: 1, 4, 8 16, 32, 64, 128, 256 (default 32) ++
speedSpecifies the maximum speed of operation in host and device mode. The ++ actual speed depends on the speed of the attached device and the value of ++ phy_type. ++ - 0: High Speed (default) ++ - 1: Full Speed ++
host_support_fs_ls_low_powerSpecifies whether low power mode is supported when attached to a Full ++ Speed or Low Speed device in host mode. ++ - 0: Don't support low power mode (default) ++ - 1: Support low power mode ++
host_ls_low_power_phy_clkSpecifies the PHY clock rate in low power mode when connected to a Low ++ Speed device in host mode. This parameter is applicable only if ++ HOST_SUPPORT_FS_LS_LOW_POWER is enabled. ++ - 0: 48 MHz (default) ++ - 1: 6 MHz ++
enable_dynamic_fifo Specifies whether FIFOs may be resized by the driver software. ++ - 0: Use cC FIFO size parameters ++ - 1: Allow dynamic FIFO sizing (default) ++
data_fifo_sizeTotal number of 4-byte words in the data FIFO memory. This memory ++ includes the Rx FIFO, non-periodic Tx FIFO, and periodic Tx FIFOs. ++ - Values: 32 to 32768 (default 8192) ++ ++ Note: The total FIFO memory depth in the FPGA configuration is 8192. ++
dev_rx_fifo_sizeNumber of 4-byte words in the Rx FIFO in device mode when dynamic ++ FIFO sizing is enabled. ++ - Values: 16 to 32768 (default 1064) ++
dev_nperio_tx_fifo_sizeNumber of 4-byte words in the non-periodic Tx FIFO in device mode when ++ dynamic FIFO sizing is enabled. ++ - Values: 16 to 32768 (default 1024) ++
dev_perio_tx_fifo_size_n (n = 1 to 15)Number of 4-byte words in each of the periodic Tx FIFOs in device mode ++ when dynamic FIFO sizing is enabled. ++ - Values: 4 to 768 (default 256) ++
host_rx_fifo_sizeNumber of 4-byte words in the Rx FIFO in host mode when dynamic FIFO ++ sizing is enabled. ++ - Values: 16 to 32768 (default 1024) ++
host_nperio_tx_fifo_sizeNumber of 4-byte words in the non-periodic Tx FIFO in host mode when ++ dynamic FIFO sizing is enabled in the core. ++ - Values: 16 to 32768 (default 1024) ++
host_perio_tx_fifo_sizeNumber of 4-byte words in the host periodic Tx FIFO when dynamic FIFO ++ sizing is enabled. ++ - Values: 16 to 32768 (default 1024) ++
max_transfer_sizeThe maximum transfer size supported in bytes. ++ - Values: 2047 to 65,535 (default 65,535) ++
max_packet_countThe maximum number of packets in a transfer. ++ - Values: 15 to 511 (default 511) ++
host_channelsThe number of host channel registers to use. ++ - Values: 1 to 16 (default 12) ++ ++ Note: The FPGA configuration supports a maximum of 12 host channels. ++
dev_endpointsThe number of endpoints in addition to EP0 available for device mode ++ operations. ++ - Values: 1 to 15 (default 6 IN and OUT) ++ ++ Note: The FPGA configuration supports a maximum of 6 IN and OUT endpoints in ++ addition to EP0. ++
phy_typeSpecifies the type of PHY interface to use. By default, the driver will ++ automatically detect the phy_type. ++ - 0: Full Speed ++ - 1: UTMI+ (default, if available) ++ - 2: ULPI ++
phy_utmi_widthSpecifies the UTMI+ Data Width. This parameter is applicable for a ++ phy_type of UTMI+. Also, this parameter is applicable only if the ++ OTG_HSPHY_WIDTH cC parameter was set to "8 and 16 bits", meaning that the ++ core has been configured to work at either data path width. ++ - Values: 8 or 16 bits (default 16) ++
phy_ulpi_ddrSpecifies whether the ULPI operates at double or single data rate. This ++ parameter is only applicable if phy_type is ULPI. ++ - 0: single data rate ULPI interface with 8 bit wide data bus (default) ++ - 1: double data rate ULPI interface with 4 bit wide data bus ++
i2c_enableSpecifies whether to use the I2C interface for full speed PHY. This ++ parameter is only applicable if PHY_TYPE is FS. ++ - 0: Disabled (default) ++ - 1: Enabled ++
ulpi_fs_lsSpecifies whether to use ULPI FS/LS mode only. ++ - 0: Disabled (default) ++ - 1: Enabled ++
ts_dlineSpecifies whether term select D-Line pulsing for all PHYs is enabled. ++ - 0: Disabled (default) ++ - 1: Enabled ++
en_multiple_tx_fifoSpecifies whether dedicatedto tx fifos are enabled for non periodic IN EPs. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: Disabled ++ - 1: Enabled (default, if available) ++
dev_tx_fifo_size_n (n = 1 to 15)Number of 4-byte words in each of the Tx FIFOs in device mode ++ when dynamic FIFO sizing is enabled. ++ - Values: 4 to 768 (default 256) ++
tx_thr_lengthTransmit Threshold length in 32 bit double words ++ - Values: 8 to 128 (default 64) ++
rx_thr_lengthReceive Threshold length in 32 bit double words ++ - Values: 8 to 128 (default 64) ++
thr_ctlSpecifies whether to enable Thresholding for Device mode. Bits 0, 1, 2 of ++ this parmater specifies if thresholding is enabled for non-Iso Tx, Iso Tx and ++ Rx transfers accordingly. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - Values: 0 to 7 (default 0) ++ Bit values indicate: ++ - 0: Thresholding disabled ++ - 1: Thresholding enabled ++
dma_desc_enableSpecifies whether to enable Descriptor DMA mode. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: Descriptor DMA disabled ++ - 1: Descriptor DMA (default, if available) ++
mpi_enableSpecifies whether to enable MPI enhancement mode. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: MPI disabled (default) ++ - 1: MPI enable ++
pti_enableSpecifies whether to enable PTI enhancement support. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: PTI disabled (default) ++ - 1: PTI enable ++
lpm_enableSpecifies whether to enable LPM support. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: LPM disabled ++ - 1: LPM enable (default, if available) ++
ic_usb_capSpecifies whether to enable IC_USB capability. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: IC_USB disabled (default, if available) ++ - 1: IC_USB enable ++
ahb_thr_ratioSpecifies AHB Threshold ratio. ++ - Values: 0 to 3 (default 0) ++
power_downSpecifies Power Down(Hibernation) Mode. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: Power Down disabled (default) ++ - 2: Power Down enabled ++
reload_ctlSpecifies whether dynamic reloading of the HFIR register is allowed during ++ run time. The driver will automatically detect the value for this parameter if ++ none is specified. In case the HFIR value is reloaded when HFIR.RldCtrl == 1'b0 ++ the core might misbehave. ++ - 0: Reload Control disabled (default) ++ - 1: Reload Control enabled ++
dev_out_nakSpecifies whether Device OUT NAK enhancement enabled or no. ++ The driver will automatically detect the value for this parameter if ++ none is specified. This parameter is valid only when OTG_EN_DESC_DMA == 1b1. ++ - 0: The core does not set NAK after Bulk OUT transfer complete (default) ++ - 1: The core sets NAK after Bulk OUT transfer complete ++
cont_on_bnaSpecifies whether Enable Continue on BNA enabled or no. ++ After receiving BNA interrupt the core disables the endpoint,when the ++ endpoint is re-enabled by the application the ++ - 0: Core starts processing from the DOEPDMA descriptor (default) ++ - 1: Core starts processing from the descriptor which received the BNA. ++ This parameter is valid only when OTG_EN_DESC_DMA == 1b1. ++
ahb_singleThis bit when programmed supports SINGLE transfers for remainder data ++ in a transfer for DMA mode of operation. ++ - 0: The remainder data will be sent using INCR burst size (default) ++ - 1: The remainder data will be sent using SINGLE burst size. ++
adp_enableSpecifies whether ADP feature is enabled. ++ The driver will automatically detect the value for this parameter if none is ++ specified. ++ - 0: ADP feature disabled (default) ++ - 1: ADP feature enabled ++
otg_verSpecifies whether OTG is performing as USB OTG Revision 2.0 or Revision 1.3 ++ USB OTG device. ++ - 0: OTG 2.0 support disabled (default) ++ - 1: OTG 2.0 support enabled ++
++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ * ++ *
Command Driver Description
GET_STATUS PCD Command is processed as ++ * defined in chapter 9 of the USB 2.0 Specification chapter 9 ++ *
CLEAR_FEATURE PCD The Device and Endpoint ++ * requests are the ENDPOINT_HALT feature is procesed, all others the ++ * interface requests are ignored.
SET_FEATURE PCD The Device and Endpoint ++ * requests are processed by the PCD. Interface requests are passed ++ * to the Gadget Driver.
SET_ADDRESS PCD Program the DCFG reg, ++ * with device address received
GET_DESCRIPTOR Gadget Driver Return the ++ * requested descriptor
SET_DESCRIPTOR Gadget Driver Optional - ++ * not implemented by any of the existing Gadget Drivers.
SET_CONFIGURATION Gadget Driver Disable ++ * all EPs and enable EPs for new configuration.
GET_CONFIGURATION Gadget Driver Return ++ * the current configuration
SET_INTERFACE Gadget Driver Disable all ++ * EPs and enable EPs for new configuration.
GET_INTERFACE Gadget Driver Return the ++ * current interface.
SYNC_FRAME PCD Display debug ++ * message.
++ * ++ * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are ++ * processed by pcd_setup. Calling the Function Driver's setup function from ++ * pcd_setup processes the gadget SETUP commands. ++ */ ++static inline void pcd_setup(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ usb_device_request_t ctrl = pcd->setup_pkt->req; ++ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0; ++ ++ deptsiz0_data_t doeptsize0 = {.d32 = 0 }; ++ ++#ifdef DWC_UTE_CFI ++ int retval = 0; ++ struct cfi_usb_ctrlrequest cfi_req; ++#endif ++ ++ doeptsize0.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doeptsiz); ++ ++ /** In BDMA more then 1 setup packet is not supported till 3.00a */ ++ if (core_if->dma_enable && core_if->dma_desc_enable == 0 ++ && (doeptsize0.b.supcnt < 2) ++ && (core_if->snpsid < OTG_CORE_REV_2_94a)) { ++ DWC_ERROR ++ ("\n\n----------- CANNOT handle > 1 setup packet in DMA mode\n\n"); ++ } ++ if ((core_if->snpsid >= OTG_CORE_REV_3_00a) ++ && (core_if->dma_enable == 1) && (core_if->dma_desc_enable == 0)) { ++ ctrl = ++ (pcd->setup_pkt + ++ (3 - doeptsize0.b.supcnt - 1 + ++ ep0->dwc_ep.stp_rollover))->req; ++ } ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n", ++ ctrl.bmRequestType, ctrl.bRequest, ++ UGETW(ctrl.wValue), UGETW(ctrl.wIndex), ++ UGETW(ctrl.wLength)); ++#endif ++ ++ /* Clean up the request queue */ ++ dwc_otg_request_nuke(ep0); ++ ep0->stopped = 0; ++ ++ if (ctrl.bmRequestType & UE_DIR_IN) { ++ ep0->dwc_ep.is_in = 1; ++ pcd->ep0state = EP0_IN_DATA_PHASE; ++ } else { ++ ep0->dwc_ep.is_in = 0; ++ pcd->ep0state = EP0_OUT_DATA_PHASE; ++ } ++ ++ if (UGETW(ctrl.wLength) == 0) { ++ ep0->dwc_ep.is_in = 1; ++ pcd->ep0state = EP0_IN_STATUS_PHASE; ++ } ++ ++ if (UT_GET_TYPE(ctrl.bmRequestType) != UT_STANDARD) { ++ ++#ifdef DWC_UTE_CFI ++ DWC_MEMCPY(&cfi_req, &ctrl, sizeof(usb_device_request_t)); ++ ++ //printk(KERN_ALERT "CFI: req_type=0x%02x; req=0x%02x\n", ++ ctrl.bRequestType, ctrl.bRequest); ++ if (UT_GET_TYPE(cfi_req.bRequestType) == UT_VENDOR) { ++ if (cfi_req.bRequest > 0xB0 && cfi_req.bRequest < 0xBF) { ++ retval = cfi_setup(pcd, &cfi_req); ++ if (retval < 0) { ++ ep0_do_stall(pcd, retval); ++ pcd->ep0_pending = 0; ++ return; ++ } ++ ++ /* if need gadget setup then call it and check the retval */ ++ if (pcd->cfi->need_gadget_att) { ++ retval = ++ cfi_gadget_setup(pcd, ++ &pcd-> ++ cfi->ctrl_req); ++ if (retval < 0) { ++ pcd->ep0_pending = 0; ++ return; ++ } ++ } ++ ++ if (pcd->cfi->need_status_in_complete) { ++ do_setup_in_status_phase(pcd); ++ } ++ return; ++ } ++ } ++#endif ++ ++ /* handle non-standard (class/vendor) requests in the gadget driver */ ++ do_gadget_setup(pcd, &ctrl); ++ return; ++ } ++ ++ /** @todo NGS: Handle bad setup packet? */ ++ ++/////////////////////////////////////////// ++//// --- Standard Request handling --- //// ++ ++ switch (ctrl.bRequest) { ++ case UR_GET_STATUS: ++ do_get_status(pcd); ++ break; ++ ++ case UR_CLEAR_FEATURE: ++ do_clear_feature(pcd); ++ break; ++ ++ case UR_SET_FEATURE: ++ do_set_feature(pcd); ++ break; ++ ++ case UR_SET_ADDRESS: ++ do_set_address(pcd); ++ break; ++ ++ case UR_SET_INTERFACE: ++ case UR_SET_CONFIG: ++// _pcd->request_config = 1; /* Configuration changed */ ++ do_gadget_setup(pcd, &ctrl); ++ break; ++ ++ case UR_SYNCH_FRAME: ++ do_gadget_setup(pcd, &ctrl); ++ break; ++ ++ default: ++ /* Call the Gadget Driver's setup functions */ ++ do_gadget_setup(pcd, &ctrl); ++ break; ++ } ++} ++ ++/** ++ * This function completes the ep0 control transfer. ++ */ ++static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ dwc_otg_dev_in_ep_regs_t *in_ep_regs = ++ dev_if->in_ep_regs[ep->dwc_ep.num]; ++#ifdef DEBUG_EP0 ++ dwc_otg_dev_out_ep_regs_t *out_ep_regs = ++ dev_if->out_ep_regs[ep->dwc_ep.num]; ++#endif ++ deptsiz0_data_t deptsiz; ++ dev_dma_desc_sts_t desc_sts; ++ dwc_otg_pcd_request_t *req; ++ int is_last = 0; ++ dwc_otg_pcd_t *pcd = ep->pcd; ++ ++#ifdef DWC_UTE_CFI ++ struct cfi_usb_ctrlrequest *ctrlreq; ++ int retval = -DWC_E_NOT_SUPPORTED; ++#endif ++ ++ desc_sts.b.bytes = 0; ++ ++ if (pcd->ep0_pending && DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ if (ep->dwc_ep.is_in) { ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n"); ++#endif ++ do_setup_out_status_phase(pcd); ++ } else { ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n"); ++#endif ++ ++#ifdef DWC_UTE_CFI ++ ctrlreq = &pcd->cfi->ctrl_req; ++ ++ if (UT_GET_TYPE(ctrlreq->bRequestType) == UT_VENDOR) { ++ if (ctrlreq->bRequest > 0xB0 ++ && ctrlreq->bRequest < 0xBF) { ++ ++ /* Return if the PCD failed to handle the request */ ++ if ((retval = ++ pcd->cfi->ops. ++ ctrl_write_complete(pcd->cfi, ++ pcd)) < 0) { ++ CFI_INFO ++ ("ERROR setting a new value in the PCD(%d)\n", ++ retval); ++ ep0_do_stall(pcd, retval); ++ pcd->ep0_pending = 0; ++ return 0; ++ } ++ ++ /* If the gadget needs to be notified on the request */ ++ if (pcd->cfi->need_gadget_att == 1) { ++ //retval = do_gadget_setup(pcd, &pcd->cfi->ctrl_req); ++ retval = ++ cfi_gadget_setup(pcd, ++ &pcd->cfi-> ++ ctrl_req); ++ ++ /* Return from the function if the gadget failed to process ++ * the request properly - this should never happen !!! ++ */ ++ if (retval < 0) { ++ CFI_INFO ++ ("ERROR setting a new value in the gadget(%d)\n", ++ retval); ++ pcd->ep0_pending = 0; ++ return 0; ++ } ++ } ++ ++ CFI_INFO("%s: RETVAL=%d\n", __func__, ++ retval); ++ /* If we hit here then the PCD and the gadget has properly ++ * handled the request - so send the ZLP IN to the host. ++ */ ++ /* @todo: MAS - decide whether we need to start the setup ++ * stage based on the need_setup value of the cfi object ++ */ ++ do_setup_in_status_phase(pcd); ++ pcd->ep0_pending = 0; ++ return 1; ++ } ++ } ++#endif ++ ++ do_setup_in_status_phase(pcd); ++ } ++ pcd->ep0_pending = 0; ++ return 1; ++ } ++ ++ if (DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ return 0; ++ } ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ ++ if (pcd->ep0state == EP0_OUT_STATUS_PHASE ++ || pcd->ep0state == EP0_IN_STATUS_PHASE) { ++ is_last = 1; ++ } else if (ep->dwc_ep.is_in) { ++ deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz); ++ if (core_if->dma_desc_enable != 0) ++ desc_sts = dev_if->in_desc_addr->status; ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCDV, "%d len=%d xfersize=%d pktcnt=%d\n", ++ ep->dwc_ep.num, ep->dwc_ep.xfer_len, ++ deptsiz.b.xfersize, deptsiz.b.pktcnt); ++#endif ++ ++ if (((core_if->dma_desc_enable == 0) ++ && (deptsiz.b.xfersize == 0)) ++ || ((core_if->dma_desc_enable != 0) ++ && (desc_sts.b.bytes == 0))) { ++ req->actual = ep->dwc_ep.xfer_count; ++ /* Is a Zero Len Packet needed? */ ++ if (req->sent_zlp) { ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n"); ++#endif ++ req->sent_zlp = 0; ++ } ++ do_setup_out_status_phase(pcd); ++ } ++ } else { ++ /* ep0-OUT */ ++#ifdef DEBUG_EP0 ++ deptsiz.d32 = DWC_READ_REG32(&out_ep_regs->doeptsiz); ++ DWC_DEBUGPL(DBG_PCDV, "%d len=%d xsize=%d pktcnt=%d\n", ++ ep->dwc_ep.num, ep->dwc_ep.xfer_len, ++ deptsiz.b.xfersize, deptsiz.b.pktcnt); ++#endif ++ req->actual = ep->dwc_ep.xfer_count; ++ ++ /* Is a Zero Len Packet needed? */ ++ if (req->sent_zlp) { ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n"); ++#endif ++ req->sent_zlp = 0; ++ } ++ /* For older cores do setup in status phase in Slave/BDMA modes, ++ * starting from 3.00 do that only in slave, and for DMA modes ++ * just re-enable ep 0 OUT here*/ ++ if (core_if->dma_enable == 0 ++ || (core_if->dma_desc_enable == 0 ++ && core_if->snpsid <= OTG_CORE_REV_2_94a)) { ++ do_setup_in_status_phase(pcd); ++ } else if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ DWC_DEBUGPL(DBG_PCDV, ++ "Enable out ep before in status phase\n"); ++ ep0_out_start(core_if, pcd); ++ } ++ } ++ ++ /* Complete the request */ ++ if (is_last) { ++ dwc_otg_request_done(ep, req, 0); ++ ep->dwc_ep.start_xfer_buff = 0; ++ ep->dwc_ep.xfer_buff = 0; ++ ep->dwc_ep.xfer_len = 0; ++ return 1; ++ } ++ return 0; ++} ++ ++#ifdef DWC_UTE_CFI ++/** ++ * This function calculates traverses all the CFI DMA descriptors and ++ * and accumulates the bytes that are left to be transfered. ++ * ++ * @return The total bytes left to transfered, or a negative value as failure ++ */ ++static inline int cfi_calc_desc_residue(dwc_otg_pcd_ep_t * ep) ++{ ++ int32_t ret = 0; ++ int i; ++ struct dwc_otg_dma_desc *ddesc = NULL; ++ struct cfi_ep *cfiep; ++ ++ /* See if the pcd_ep has its respective cfi_ep mapped */ ++ cfiep = get_cfi_ep_by_pcd_ep(ep->pcd->cfi, ep); ++ if (!cfiep) { ++ CFI_INFO("%s: Failed to find ep\n", __func__); ++ return -1; ++ } ++ ++ ddesc = ep->dwc_ep.descs; ++ ++ for (i = 0; (i < cfiep->desc_count) && (i < MAX_DMA_DESCS_PER_EP); i++) { ++ ++#if defined(PRINT_CFI_DMA_DESCS) ++ print_desc(ddesc, ep->ep.name, i); ++#endif ++ ret += ddesc->status.b.bytes; ++ ddesc++; ++ } ++ ++ if (ret) ++ CFI_INFO("!!!!!!!!!! WARNING (%s) - residue=%d\n", __func__, ++ ret); ++ ++ return ret; ++} ++#endif ++ ++/** ++ * This function completes the request for the EP. If there are ++ * additional requests for the EP in the queue they will be started. ++ */ ++static void complete_ep(dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ dwc_otg_dev_in_ep_regs_t *in_ep_regs = ++ dev_if->in_ep_regs[ep->dwc_ep.num]; ++ deptsiz_data_t deptsiz; ++ dev_dma_desc_sts_t desc_sts; ++ dwc_otg_pcd_request_t *req = 0; ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ uint32_t byte_count = 0; ++ int is_last = 0; ++ int i; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s() %d-%s\n", __func__, ep->dwc_ep.num, ++ (ep->dwc_ep.is_in ? "IN" : "OUT")); ++ ++ /* Get any pending requests */ ++ if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ if (!req) { ++ DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep); ++ return; ++ } ++ } else { ++ DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep); ++ return; ++ } ++ ++ DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending); ++ ++ if (ep->dwc_ep.is_in) { ++ deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz); ++ ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable == 0) { ++ if (deptsiz.b.xfersize == 0 ++ && deptsiz.b.pktcnt == 0) { ++ byte_count = ++ ep->dwc_ep.xfer_len - ++ ep->dwc_ep.xfer_count; ++ ++ ep->dwc_ep.xfer_buff += byte_count; ++ ep->dwc_ep.dma_addr += byte_count; ++ ep->dwc_ep.xfer_count += byte_count; ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "%d-%s len=%d xfersize=%d pktcnt=%d\n", ++ ep->dwc_ep.num, ++ (ep->dwc_ep. ++ is_in ? "IN" : "OUT"), ++ ep->dwc_ep.xfer_len, ++ deptsiz.b.xfersize, ++ deptsiz.b.pktcnt); ++ ++ if (ep->dwc_ep.xfer_len < ++ ep->dwc_ep.total_len) { ++ dwc_otg_ep_start_transfer ++ (core_if, &ep->dwc_ep); ++ } else if (ep->dwc_ep.sent_zlp) { ++ /* ++ * This fragment of code should initiate 0 ++ * length transfer in case if it is queued ++ * a transfer with size divisible to EPs max ++ * packet size and with usb_request zero field ++ * is set, which means that after data is transfered, ++ * it is also should be transfered ++ * a 0 length packet at the end. For Slave and ++ * Buffer DMA modes in this case SW has ++ * to initiate 2 transfers one with transfer size, ++ * and the second with 0 size. For Descriptor ++ * DMA mode SW is able to initiate a transfer, ++ * which will handle all the packets including ++ * the last 0 length. ++ */ ++ ep->dwc_ep.sent_zlp = 0; ++ dwc_otg_ep_start_zl_transfer ++ (core_if, &ep->dwc_ep); ++ } else { ++ is_last = 1; ++ } ++ } else { ++ if (ep->dwc_ep.type == ++ DWC_OTG_EP_TYPE_ISOC) { ++ req->actual = 0; ++ dwc_otg_request_done(ep, req, 0); ++ ++ ep->dwc_ep.start_xfer_buff = 0; ++ ep->dwc_ep.xfer_buff = 0; ++ ep->dwc_ep.xfer_len = 0; ++ ++ /* If there is a request in the queue start it. */ ++ start_next_request(ep); ++ } else ++ DWC_WARN ++ ("Incomplete transfer (%d - %s [siz=%d pkt=%d])\n", ++ ep->dwc_ep.num, ++ (ep->dwc_ep.is_in ? "IN" : "OUT"), ++ deptsiz.b.xfersize, ++ deptsiz.b.pktcnt); ++ } ++ } else { ++ dma_desc = ep->dwc_ep.desc_addr; ++ byte_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ++#ifdef DWC_UTE_CFI ++ CFI_INFO("%s: BUFFER_MODE=%d\n", __func__, ++ ep->dwc_ep.buff_mode); ++ if (ep->dwc_ep.buff_mode != BM_STANDARD) { ++ int residue; ++ ++ residue = cfi_calc_desc_residue(ep); ++ if (residue < 0) ++ return; ++ ++ byte_count = residue; ++ } else { ++#endif ++ for (i = 0; i < ep->dwc_ep.desc_cnt; ++ ++i) { ++ desc_sts = dma_desc->status; ++ byte_count += desc_sts.b.bytes; ++ dma_desc++; ++ } ++#ifdef DWC_UTE_CFI ++ } ++#endif ++ if (byte_count == 0) { ++ ep->dwc_ep.xfer_count = ++ ep->dwc_ep.total_len; ++ is_last = 1; ++ } else { ++ DWC_WARN("Incomplete transfer\n"); ++ } ++ } ++ } else { ++ if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) { ++ DWC_DEBUGPL(DBG_PCDV, ++ "%d-%s len=%d xfersize=%d pktcnt=%d\n", ++ ep->dwc_ep.num, ++ ep->dwc_ep.is_in ? "IN" : "OUT", ++ ep->dwc_ep.xfer_len, ++ deptsiz.b.xfersize, ++ deptsiz.b.pktcnt); ++ ++ /* Check if the whole transfer was completed, ++ * if no, setup transfer for next portion of data ++ */ ++ if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) { ++ dwc_otg_ep_start_transfer(core_if, ++ &ep->dwc_ep); ++ } else if (ep->dwc_ep.sent_zlp) { ++ /* ++ * This fragment of code should initiate 0 ++ * length trasfer in case if it is queued ++ * a trasfer with size divisible to EPs max ++ * packet size and with usb_request zero field ++ * is set, which means that after data is transfered, ++ * it is also should be transfered ++ * a 0 length packet at the end. For Slave and ++ * Buffer DMA modes in this case SW has ++ * to initiate 2 transfers one with transfer size, ++ * and the second with 0 size. For Desriptor ++ * DMA mode SW is able to initiate a transfer, ++ * which will handle all the packets including ++ * the last 0 legth. ++ */ ++ ep->dwc_ep.sent_zlp = 0; ++ dwc_otg_ep_start_zl_transfer(core_if, ++ &ep->dwc_ep); ++ } else { ++ is_last = 1; ++ } ++ } else { ++ DWC_WARN ++ ("Incomplete transfer (%d-%s [siz=%d pkt=%d])\n", ++ ep->dwc_ep.num, ++ (ep->dwc_ep.is_in ? "IN" : "OUT"), ++ deptsiz.b.xfersize, deptsiz.b.pktcnt); ++ } ++ } ++ } else { ++ dwc_otg_dev_out_ep_regs_t *out_ep_regs = ++ dev_if->out_ep_regs[ep->dwc_ep.num]; ++ desc_sts.d32 = 0; ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable) { ++ dma_desc = ep->dwc_ep.desc_addr; ++ byte_count = 0; ++ ep->dwc_ep.sent_zlp = 0; ++ ++#ifdef DWC_UTE_CFI ++ CFI_INFO("%s: BUFFER_MODE=%d\n", __func__, ++ ep->dwc_ep.buff_mode); ++ if (ep->dwc_ep.buff_mode != BM_STANDARD) { ++ int residue; ++ residue = cfi_calc_desc_residue(ep); ++ if (residue < 0) ++ return; ++ byte_count = residue; ++ } else { ++#endif ++ ++ for (i = 0; i < ep->dwc_ep.desc_cnt; ++ ++i) { ++ desc_sts = dma_desc->status; ++ byte_count += desc_sts.b.bytes; ++ dma_desc++; ++ } ++ ++#ifdef DWC_UTE_CFI ++ } ++#endif ++ /* Checking for interrupt Out transfers with not ++ * dword aligned mps sizes ++ */ ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_INTR && ++ (ep->dwc_ep.maxpacket%4)) { ++ ep->dwc_ep.xfer_count = ++ ep->dwc_ep.total_len - byte_count; ++ if ((ep->dwc_ep.xfer_len % ++ ep->dwc_ep.maxpacket) ++ && (ep->dwc_ep.xfer_len / ++ ep->dwc_ep.maxpacket < ++ MAX_DMA_DESC_CNT)) ++ ep->dwc_ep.xfer_len -= ++ (ep->dwc_ep.desc_cnt - ++ 1) * ep->dwc_ep.maxpacket + ++ ep->dwc_ep.xfer_len % ++ ep->dwc_ep.maxpacket; ++ else ++ ep->dwc_ep.xfer_len -= ++ ep->dwc_ep.desc_cnt * ++ ep->dwc_ep.maxpacket; ++ if (ep->dwc_ep.xfer_len > 0) { ++ dwc_otg_ep_start_transfer ++ (core_if, &ep->dwc_ep); ++ } else { ++ is_last = 1; ++ } ++ } else { ++ ep->dwc_ep.xfer_count = ++ ep->dwc_ep.total_len - byte_count + ++ ((4 - ++ (ep->dwc_ep. ++ total_len & 0x3)) & 0x3); ++ is_last = 1; ++ } ++ } else { ++ deptsiz.d32 = 0; ++ deptsiz.d32 = ++ DWC_READ_REG32(&out_ep_regs->doeptsiz); ++ ++ byte_count = (ep->dwc_ep.xfer_len - ++ ep->dwc_ep.xfer_count - ++ deptsiz.b.xfersize); ++ ep->dwc_ep.xfer_buff += byte_count; ++ ep->dwc_ep.dma_addr += byte_count; ++ ep->dwc_ep.xfer_count += byte_count; ++ ++ /* Check if the whole transfer was completed, ++ * if no, setup transfer for next portion of data ++ */ ++ if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) { ++ dwc_otg_ep_start_transfer(core_if, ++ &ep->dwc_ep); ++ } else if (ep->dwc_ep.sent_zlp) { ++ /* ++ * This fragment of code should initiate 0 ++ * length trasfer in case if it is queued ++ * a trasfer with size divisible to EPs max ++ * packet size and with usb_request zero field ++ * is set, which means that after data is transfered, ++ * it is also should be transfered ++ * a 0 length packet at the end. For Slave and ++ * Buffer DMA modes in this case SW has ++ * to initiate 2 transfers one with transfer size, ++ * and the second with 0 size. For Desriptor ++ * DMA mode SW is able to initiate a transfer, ++ * which will handle all the packets including ++ * the last 0 legth. ++ */ ++ ep->dwc_ep.sent_zlp = 0; ++ dwc_otg_ep_start_zl_transfer(core_if, ++ &ep->dwc_ep); ++ } else { ++ is_last = 1; ++ } ++ } ++ } else { ++ /* Check if the whole transfer was completed, ++ * if no, setup transfer for next portion of data ++ */ ++ if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) { ++ dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep); ++ } else if (ep->dwc_ep.sent_zlp) { ++ /* ++ * This fragment of code should initiate 0 ++ * length transfer in case if it is queued ++ * a transfer with size divisible to EPs max ++ * packet size and with usb_request zero field ++ * is set, which means that after data is transfered, ++ * it is also should be transfered ++ * a 0 length packet at the end. For Slave and ++ * Buffer DMA modes in this case SW has ++ * to initiate 2 transfers one with transfer size, ++ * and the second with 0 size. For Descriptor ++ * DMA mode SW is able to initiate a transfer, ++ * which will handle all the packets including ++ * the last 0 length. ++ */ ++ ep->dwc_ep.sent_zlp = 0; ++ dwc_otg_ep_start_zl_transfer(core_if, ++ &ep->dwc_ep); ++ } else { ++ is_last = 1; ++ } ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "addr %p, %d-%s len=%d cnt=%d xsize=%d pktcnt=%d\n", ++ &out_ep_regs->doeptsiz, ep->dwc_ep.num, ++ ep->dwc_ep.is_in ? "IN" : "OUT", ++ ep->dwc_ep.xfer_len, ep->dwc_ep.xfer_count, ++ deptsiz.b.xfersize, deptsiz.b.pktcnt); ++ } ++ ++ /* Complete the request */ ++ if (is_last) { ++#ifdef DWC_UTE_CFI ++ if (ep->dwc_ep.buff_mode != BM_STANDARD) { ++ req->actual = ep->dwc_ep.cfi_req_len - byte_count; ++ } else { ++#endif ++ req->actual = ep->dwc_ep.xfer_count; ++#ifdef DWC_UTE_CFI ++ } ++#endif ++ if (req->dw_align_buf) { ++ if (!ep->dwc_ep.is_in) { ++ dwc_memcpy(req->buf, req->dw_align_buf, req->length); ++ } ++ DWC_DMA_FREE(req->length, req->dw_align_buf, ++ req->dw_align_buf_dma); ++ } ++ ++ dwc_otg_request_done(ep, req, 0); ++ ++ ep->dwc_ep.start_xfer_buff = 0; ++ ep->dwc_ep.xfer_buff = 0; ++ ep->dwc_ep.xfer_len = 0; ++ ++ /* If there is a request in the queue start it. */ ++ start_next_request(ep); ++ } ++} ++ ++#ifdef DWC_EN_ISOC ++ ++/** ++ * This function BNA interrupt for Isochronous EPs ++ * ++ */ ++static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_ep_t *dwc_ep = &ep->dwc_ep; ++ volatile uint32_t *addr; ++ depctl_data_t depctl = {.d32 = 0 }; ++ dwc_otg_pcd_t *pcd = ep->pcd; ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ int i; ++ ++ dma_desc = ++ dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num); ++ ++ if (dwc_ep->is_in) { ++ dev_dma_desc_sts_t sts = {.d32 = 0 }; ++ for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) { ++ sts.d32 = dma_desc->status.d32; ++ sts.b_iso_in.bs = BS_HOST_READY; ++ dma_desc->status.d32 = sts.d32; ++ } ++ } else { ++ dev_dma_desc_sts_t sts = {.d32 = 0 }; ++ for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) { ++ sts.d32 = dma_desc->status.d32; ++ sts.b_iso_out.bs = BS_HOST_READY; ++ dma_desc->status.d32 = sts.d32; ++ } ++ } ++ ++ if (dwc_ep->is_in == 0) { ++ addr = ++ &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep-> ++ num]->doepctl; ++ } else { ++ addr = ++ &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl; ++ } ++ depctl.b.epena = 1; ++ DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32); ++} ++ ++/** ++ * This function sets latest iso packet information(non-PTI mode) ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ * ++ */ ++void set_current_pkt_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ deptsiz_data_t deptsiz = {.d32 = 0 }; ++ dma_addr_t dma_addr; ++ uint32_t offset; ++ ++ if (ep->proc_buf_num) ++ dma_addr = ep->dma_addr1; ++ else ++ dma_addr = ep->dma_addr0; ++ ++ if (ep->is_in) { ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if->dev_if-> ++ in_ep_regs[ep->num]->dieptsiz); ++ offset = ep->data_per_frame; ++ } else { ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[ep->num]->doeptsiz); ++ offset = ++ ep->data_per_frame + ++ (0x4 & (0x4 - (ep->data_per_frame & 0x3))); ++ } ++ ++ if (!deptsiz.b.xfersize) { ++ ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame; ++ ep->pkt_info[ep->cur_pkt].offset = ++ ep->cur_pkt_dma_addr - dma_addr; ++ ep->pkt_info[ep->cur_pkt].status = 0; ++ } else { ++ ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame; ++ ep->pkt_info[ep->cur_pkt].offset = ++ ep->cur_pkt_dma_addr - dma_addr; ++ ep->pkt_info[ep->cur_pkt].status = -DWC_E_NO_DATA; ++ } ++ ep->cur_pkt_addr += offset; ++ ep->cur_pkt_dma_addr += offset; ++ ep->cur_pkt++; ++} ++ ++/** ++ * This function sets latest iso packet information(DDMA mode) ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param dwc_ep The EP to start the transfer on. ++ * ++ */ ++static void set_ddma_iso_pkts_info(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * dwc_ep) ++{ ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ dev_dma_desc_sts_t sts = {.d32 = 0 }; ++ iso_pkt_info_t *iso_packet; ++ uint32_t data_per_desc; ++ uint32_t offset; ++ int i, j; ++ ++ iso_packet = dwc_ep->pkt_info; ++ ++ /** Reinit closed DMA Descriptors*/ ++ /** ISO OUT EP */ ++ if (dwc_ep->is_in == 0) { ++ dma_desc = ++ dwc_ep->iso_desc_addr + ++ dwc_ep->desc_cnt * dwc_ep->proc_buf_num; ++ offset = 0; ++ ++ for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; ++ i += dwc_ep->pkt_per_frm) { ++ for (j = 0; j < dwc_ep->pkt_per_frm; ++j) { ++ data_per_desc = ++ ((j + 1) * dwc_ep->maxpacket > ++ dwc_ep-> ++ data_per_frame) ? dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket : dwc_ep->maxpacket; ++ data_per_desc += ++ (data_per_desc % 4) ? (4 - ++ data_per_desc % ++ 4) : 0; ++ ++ sts.d32 = dma_desc->status.d32; ++ ++ /* Write status in iso_packet_decsriptor */ ++ iso_packet->status = ++ sts.b_iso_out.rxsts + ++ (sts.b_iso_out.bs ^ BS_DMA_DONE); ++ if (iso_packet->status) { ++ iso_packet->status = -DWC_E_NO_DATA; ++ } ++ ++ /* Received data length */ ++ if (!sts.b_iso_out.rxbytes) { ++ iso_packet->length = ++ data_per_desc - ++ sts.b_iso_out.rxbytes; ++ } else { ++ iso_packet->length = ++ data_per_desc - ++ sts.b_iso_out.rxbytes + (4 - ++ dwc_ep->data_per_frame ++ % 4); ++ } ++ ++ iso_packet->offset = offset; ++ ++ offset += data_per_desc; ++ dma_desc++; ++ iso_packet++; ++ } ++ } ++ ++ for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) { ++ data_per_desc = ++ ((j + 1) * dwc_ep->maxpacket > ++ dwc_ep->data_per_frame) ? dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket : dwc_ep->maxpacket; ++ data_per_desc += ++ (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0; ++ ++ sts.d32 = dma_desc->status.d32; ++ ++ /* Write status in iso_packet_decsriptor */ ++ iso_packet->status = ++ sts.b_iso_out.rxsts + ++ (sts.b_iso_out.bs ^ BS_DMA_DONE); ++ if (iso_packet->status) { ++ iso_packet->status = -DWC_E_NO_DATA; ++ } ++ ++ /* Received data length */ ++ iso_packet->length = ++ dwc_ep->data_per_frame - sts.b_iso_out.rxbytes; ++ ++ iso_packet->offset = offset; ++ ++ offset += data_per_desc; ++ iso_packet++; ++ dma_desc++; ++ } ++ ++ sts.d32 = dma_desc->status.d32; ++ ++ /* Write status in iso_packet_decsriptor */ ++ iso_packet->status = ++ sts.b_iso_out.rxsts + (sts.b_iso_out.bs ^ BS_DMA_DONE); ++ if (iso_packet->status) { ++ iso_packet->status = -DWC_E_NO_DATA; ++ } ++ /* Received data length */ ++ if (!sts.b_iso_out.rxbytes) { ++ iso_packet->length = ++ dwc_ep->data_per_frame - sts.b_iso_out.rxbytes; ++ } else { ++ iso_packet->length = ++ dwc_ep->data_per_frame - sts.b_iso_out.rxbytes + ++ (4 - dwc_ep->data_per_frame % 4); ++ } ++ ++ iso_packet->offset = offset; ++ } else { ++/** ISO IN EP */ ++ ++ dma_desc = ++ dwc_ep->iso_desc_addr + ++ dwc_ep->desc_cnt * dwc_ep->proc_buf_num; ++ ++ for (i = 0; i < dwc_ep->desc_cnt - 1; i++) { ++ sts.d32 = dma_desc->status.d32; ++ ++ /* Write status in iso packet descriptor */ ++ iso_packet->status = ++ sts.b_iso_in.txsts + ++ (sts.b_iso_in.bs ^ BS_DMA_DONE); ++ if (iso_packet->status != 0) { ++ iso_packet->status = -DWC_E_NO_DATA; ++ ++ } ++ /* Bytes has been transfered */ ++ iso_packet->length = ++ dwc_ep->data_per_frame - sts.b_iso_in.txbytes; ++ ++ dma_desc++; ++ iso_packet++; ++ } ++ ++ sts.d32 = dma_desc->status.d32; ++ while (sts.b_iso_in.bs == BS_DMA_BUSY) { ++ sts.d32 = dma_desc->status.d32; ++ } ++ ++ /* Write status in iso packet descriptor ??? do be done with ERROR codes */ ++ iso_packet->status = ++ sts.b_iso_in.txsts + (sts.b_iso_in.bs ^ BS_DMA_DONE); ++ if (iso_packet->status != 0) { ++ iso_packet->status = -DWC_E_NO_DATA; ++ } ++ ++ /* Bytes has been transfered */ ++ iso_packet->length = ++ dwc_ep->data_per_frame - sts.b_iso_in.txbytes; ++ } ++} ++ ++/** ++ * This function reinitialize DMA Descriptors for Isochronous transfer ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param dwc_ep The EP to start the transfer on. ++ * ++ */ ++static void reinit_ddma_iso_xfer(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep) ++{ ++ int i, j; ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ dma_addr_t dma_ad; ++ volatile uint32_t *addr; ++ dev_dma_desc_sts_t sts = {.d32 = 0 }; ++ uint32_t data_per_desc; ++ ++ if (dwc_ep->is_in == 0) { ++ addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl; ++ } else { ++ addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl; ++ } ++ ++ if (dwc_ep->proc_buf_num == 0) { ++ /** Buffer 0 descriptors setup */ ++ dma_ad = dwc_ep->dma_addr0; ++ } else { ++ /** Buffer 1 descriptors setup */ ++ dma_ad = dwc_ep->dma_addr1; ++ } ++ ++ /** Reinit closed DMA Descriptors*/ ++ /** ISO OUT EP */ ++ if (dwc_ep->is_in == 0) { ++ dma_desc = ++ dwc_ep->iso_desc_addr + ++ dwc_ep->desc_cnt * dwc_ep->proc_buf_num; ++ ++ sts.b_iso_out.bs = BS_HOST_READY; ++ sts.b_iso_out.rxsts = 0; ++ sts.b_iso_out.l = 0; ++ sts.b_iso_out.sp = 0; ++ sts.b_iso_out.ioc = 0; ++ sts.b_iso_out.pid = 0; ++ sts.b_iso_out.framenum = 0; ++ ++ for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; ++ i += dwc_ep->pkt_per_frm) { ++ for (j = 0; j < dwc_ep->pkt_per_frm; ++j) { ++ data_per_desc = ++ ((j + 1) * dwc_ep->maxpacket > ++ dwc_ep-> ++ data_per_frame) ? dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket : dwc_ep->maxpacket; ++ data_per_desc += ++ (data_per_desc % 4) ? (4 - ++ data_per_desc % ++ 4) : 0; ++ sts.b_iso_out.rxbytes = data_per_desc; ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ dma_ad += data_per_desc; ++ dma_desc++; ++ } ++ } ++ ++ for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) { ++ ++ data_per_desc = ++ ((j + 1) * dwc_ep->maxpacket > ++ dwc_ep->data_per_frame) ? dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket : dwc_ep->maxpacket; ++ data_per_desc += ++ (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0; ++ sts.b_iso_out.rxbytes = data_per_desc; ++ ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ dma_desc++; ++ dma_ad += data_per_desc; ++ } ++ ++ sts.b_iso_out.ioc = 1; ++ sts.b_iso_out.l = dwc_ep->proc_buf_num; ++ ++ data_per_desc = ++ ((j + 1) * dwc_ep->maxpacket > ++ dwc_ep->data_per_frame) ? dwc_ep->data_per_frame - ++ j * dwc_ep->maxpacket : dwc_ep->maxpacket; ++ data_per_desc += ++ (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0; ++ sts.b_iso_out.rxbytes = data_per_desc; ++ ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ } else { ++/** ISO IN EP */ ++ ++ dma_desc = ++ dwc_ep->iso_desc_addr + ++ dwc_ep->desc_cnt * dwc_ep->proc_buf_num; ++ ++ sts.b_iso_in.bs = BS_HOST_READY; ++ sts.b_iso_in.txsts = 0; ++ sts.b_iso_in.sp = 0; ++ sts.b_iso_in.ioc = 0; ++ sts.b_iso_in.pid = dwc_ep->pkt_per_frm; ++ sts.b_iso_in.framenum = dwc_ep->next_frame; ++ sts.b_iso_in.txbytes = dwc_ep->data_per_frame; ++ sts.b_iso_in.l = 0; ++ ++ for (i = 0; i < dwc_ep->desc_cnt - 1; i++) { ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ sts.b_iso_in.framenum += dwc_ep->bInterval; ++ dma_ad += dwc_ep->data_per_frame; ++ dma_desc++; ++ } ++ ++ sts.b_iso_in.ioc = 1; ++ sts.b_iso_in.l = dwc_ep->proc_buf_num; ++ ++ dma_desc->buf = dma_ad; ++ dma_desc->status.d32 = sts.d32; ++ ++ dwc_ep->next_frame = ++ sts.b_iso_in.framenum + dwc_ep->bInterval * 1; ++ } ++ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1; ++} ++ ++/** ++ * This function is to handle Iso EP transfer complete interrupt ++ * in case Iso out packet was dropped ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param dwc_ep The EP for wihich transfer complete was asserted ++ * ++ */ ++static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t * core_if, ++ dwc_ep_t * dwc_ep) ++{ ++ uint32_t dma_addr; ++ uint32_t drp_pkt; ++ uint32_t drp_pkt_cnt; ++ deptsiz_data_t deptsiz = {.d32 = 0 }; ++ depctl_data_t depctl = {.d32 = 0 }; ++ int i; ++ ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[dwc_ep->num]->doeptsiz); ++ ++ drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt; ++ drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm); ++ ++ /* Setting dropped packets status */ ++ for (i = 0; i < drp_pkt_cnt; ++i) { ++ dwc_ep->pkt_info[drp_pkt].status = -DWC_E_NO_DATA; ++ drp_pkt++; ++ deptsiz.b.pktcnt--; ++ } ++ ++ if (deptsiz.b.pktcnt > 0) { ++ deptsiz.b.xfersize = ++ dwc_ep->xfer_len - (dwc_ep->pkt_cnt - ++ deptsiz.b.pktcnt) * dwc_ep->maxpacket; ++ } else { ++ deptsiz.b.xfersize = 0; ++ deptsiz.b.pktcnt = 0; ++ } ++ ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz, ++ deptsiz.d32); ++ ++ if (deptsiz.b.pktcnt > 0) { ++ if (dwc_ep->proc_buf_num) { ++ dma_addr = ++ dwc_ep->dma_addr1 + dwc_ep->xfer_len - ++ deptsiz.b.xfersize; ++ } else { ++ dma_addr = ++ dwc_ep->dma_addr0 + dwc_ep->xfer_len - ++ deptsiz.b.xfersize;; ++ } ++ ++ DWC_WRITE_REG32(&core_if->dev_if-> ++ out_ep_regs[dwc_ep->num]->doepdma, dma_addr); ++ ++ /** Re-enable endpoint, clear nak */ ++ depctl.d32 = 0; ++ depctl.b.epena = 1; ++ depctl.b.cnak = 1; ++ ++ DWC_MODIFY_REG32(&core_if->dev_if-> ++ out_ep_regs[dwc_ep->num]->doepctl, depctl.d32, ++ depctl.d32); ++ return 0; ++ } else { ++ return 1; ++ } ++} ++ ++/** ++ * This function sets iso packets information(PTI mode) ++ * ++ * @param core_if Programming view of DWC_otg controller. ++ * @param ep The EP to start the transfer on. ++ * ++ */ ++static uint32_t set_iso_pkts_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep) ++{ ++ int i, j; ++ dma_addr_t dma_ad; ++ iso_pkt_info_t *packet_info = ep->pkt_info; ++ uint32_t offset; ++ uint32_t frame_data; ++ deptsiz_data_t deptsiz; ++ ++ if (ep->proc_buf_num == 0) { ++ /** Buffer 0 descriptors setup */ ++ dma_ad = ep->dma_addr0; ++ } else { ++ /** Buffer 1 descriptors setup */ ++ dma_ad = ep->dma_addr1; ++ } ++ ++ if (ep->is_in) { ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]-> ++ dieptsiz); ++ } else { ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if->dev_if->out_ep_regs[ep->num]-> ++ doeptsiz); ++ } ++ ++ if (!deptsiz.b.xfersize) { ++ offset = 0; ++ for (i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm) { ++ frame_data = ep->data_per_frame; ++ for (j = 0; j < ep->pkt_per_frm; ++j) { ++ ++ /* Packet status - is not set as initially ++ * it is set to 0 and if packet was sent ++ successfully, status field will remain 0*/ ++ ++ /* Bytes has been transfered */ ++ packet_info->length = ++ (ep->maxpacket < ++ frame_data) ? ep->maxpacket : frame_data; ++ ++ /* Received packet offset */ ++ packet_info->offset = offset; ++ offset += packet_info->length; ++ frame_data -= packet_info->length; ++ ++ packet_info++; ++ } ++ } ++ return 1; ++ } else { ++ /* This is a workaround for in case of Transfer Complete with ++ * PktDrpSts interrupts merging - in this case Transfer complete ++ * interrupt for Isoc Out Endpoint is asserted without PktDrpSts ++ * set and with DOEPTSIZ register non zero. Investigations showed, ++ * that this happens when Out packet is dropped, but because of ++ * interrupts merging during first interrupt handling PktDrpSts ++ * bit is cleared and for next merged interrupts it is not reset. ++ * In this case SW hadles the interrupt as if PktDrpSts bit is set. ++ */ ++ if (ep->is_in) { ++ return 1; ++ } else { ++ return handle_iso_out_pkt_dropped(core_if, ep); ++ } ++ } ++} ++ ++/** ++ * This function is to handle Iso EP transfer complete interrupt ++ * ++ * @param pcd The PCD ++ * @param ep The EP for which transfer complete was asserted ++ * ++ */ ++static void complete_iso_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd); ++ dwc_ep_t *dwc_ep = &ep->dwc_ep; ++ uint8_t is_last = 0; ++ ++ if (ep->dwc_ep.next_frame == 0xffffffff) { ++ DWC_WARN("Next frame is not set!\n"); ++ return; ++ } ++ ++ if (core_if->dma_enable) { ++ if (core_if->dma_desc_enable) { ++ set_ddma_iso_pkts_info(core_if, dwc_ep); ++ reinit_ddma_iso_xfer(core_if, dwc_ep); ++ is_last = 1; ++ } else { ++ if (core_if->pti_enh_enable) { ++ if (set_iso_pkts_info(core_if, dwc_ep)) { ++ dwc_ep->proc_buf_num = ++ (dwc_ep->proc_buf_num ^ 1) & 0x1; ++ dwc_otg_iso_ep_start_buf_transfer ++ (core_if, dwc_ep); ++ is_last = 1; ++ } ++ } else { ++ set_current_pkt_info(core_if, dwc_ep); ++ if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) { ++ is_last = 1; ++ dwc_ep->cur_pkt = 0; ++ dwc_ep->proc_buf_num = ++ (dwc_ep->proc_buf_num ^ 1) & 0x1; ++ if (dwc_ep->proc_buf_num) { ++ dwc_ep->cur_pkt_addr = ++ dwc_ep->xfer_buff1; ++ dwc_ep->cur_pkt_dma_addr = ++ dwc_ep->dma_addr1; ++ } else { ++ dwc_ep->cur_pkt_addr = ++ dwc_ep->xfer_buff0; ++ dwc_ep->cur_pkt_dma_addr = ++ dwc_ep->dma_addr0; ++ } ++ ++ } ++ dwc_otg_iso_ep_start_frm_transfer(core_if, ++ dwc_ep); ++ } ++ } ++ } else { ++ set_current_pkt_info(core_if, dwc_ep); ++ if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) { ++ is_last = 1; ++ dwc_ep->cur_pkt = 0; ++ dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1; ++ if (dwc_ep->proc_buf_num) { ++ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1; ++ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1; ++ } else { ++ dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0; ++ dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0; ++ } ++ ++ } ++ dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep); ++ } ++ if (is_last) ++ dwc_otg_iso_buffer_done(pcd, ep, ep->iso_req_handle); ++} ++#endif /* DWC_EN_ISOC */ ++ ++/** ++ * This function handle BNA interrupt for Non Isochronous EPs ++ * ++ */ ++static void dwc_otg_pcd_handle_noniso_bna(dwc_otg_pcd_ep_t * ep) ++{ ++ dwc_ep_t *dwc_ep = &ep->dwc_ep; ++ volatile uint32_t *addr; ++ depctl_data_t depctl = {.d32 = 0 }; ++ dwc_otg_pcd_t *pcd = ep->pcd; ++ dwc_otg_dev_dma_desc_t *dma_desc; ++ dev_dma_desc_sts_t sts = {.d32 = 0 }; ++ dwc_otg_core_if_t *core_if = ep->pcd->core_if; ++ int i, start; ++ ++ if (!dwc_ep->desc_cnt) ++ DWC_WARN("Ep%d %s Descriptor count = %d \n", dwc_ep->num, ++ (dwc_ep->is_in ? "IN" : "OUT"), dwc_ep->desc_cnt); ++ ++ if (core_if->core_params->cont_on_bna && !dwc_ep->is_in ++ && dwc_ep->type != DWC_OTG_EP_TYPE_CONTROL) { ++ uint32_t doepdma; ++ dwc_otg_dev_out_ep_regs_t *out_regs = ++ core_if->dev_if->out_ep_regs[dwc_ep->num]; ++ doepdma = DWC_READ_REG32(&(out_regs->doepdma)); ++ start = (doepdma - dwc_ep->dma_desc_addr)/sizeof(dwc_otg_dev_dma_desc_t); ++ dma_desc = &(dwc_ep->desc_addr[start]); ++ } else { ++ start = 0; ++ dma_desc = dwc_ep->desc_addr; ++ } ++ ++ ++ for (i = start; i < dwc_ep->desc_cnt; ++i, ++dma_desc) { ++ sts.d32 = dma_desc->status.d32; ++ sts.b.bs = BS_HOST_READY; ++ dma_desc->status.d32 = sts.d32; ++ } ++ ++ if (dwc_ep->is_in == 0) { ++ addr = ++ &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]-> ++ doepctl; ++ } else { ++ addr = ++ &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl; ++ } ++ depctl.b.epena = 1; ++ depctl.b.cnak = 1; ++ DWC_MODIFY_REG32(addr, 0, depctl.d32); ++} ++ ++/** ++ * This function handles EP0 Control transfers. ++ * ++ * The state of the control transfers are tracked in ++ * ep0state. ++ */ ++static void handle_ep0(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0; ++ dev_dma_desc_sts_t desc_sts; ++ deptsiz0_data_t deptsiz; ++ uint32_t byte_count; ++ ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__); ++ print_ep0_state(pcd); ++#endif ++ ++// DWC_PRINTF("HANDLE EP0\n"); ++ ++ switch (pcd->ep0state) { ++ case EP0_DISCONNECT: ++ break; ++ ++ case EP0_IDLE: ++ pcd->request_config = 0; ++ ++ pcd_setup(pcd); ++ break; ++ ++ case EP0_IN_DATA_PHASE: ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n", ++ ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"), ++ ep0->dwc_ep.type, ep0->dwc_ep.maxpacket); ++#endif ++ ++ if (core_if->dma_enable != 0) { ++ /* ++ * For EP0 we can only program 1 packet at a time so we ++ * need to do the make calculations after each complete. ++ * Call write_packet to make the calculations, as in ++ * slave mode, and use those values to determine if we ++ * can complete. ++ */ ++ if (core_if->dma_desc_enable == 0) { ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if-> ++ dev_if->in_ep_regs[0]-> ++ dieptsiz); ++ byte_count = ++ ep0->dwc_ep.xfer_len - deptsiz.b.xfersize; ++ } else { ++ desc_sts = ++ core_if->dev_if->in_desc_addr->status; ++ byte_count = ++ ep0->dwc_ep.xfer_len - desc_sts.b.bytes; ++ } ++ ep0->dwc_ep.xfer_count += byte_count; ++ ep0->dwc_ep.xfer_buff += byte_count; ++ ep0->dwc_ep.dma_addr += byte_count; ++ } ++ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) { ++ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd), ++ &ep0->dwc_ep); ++ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n"); ++ } else if (ep0->dwc_ep.sent_zlp) { ++ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd), ++ &ep0->dwc_ep); ++ ep0->dwc_ep.sent_zlp = 0; ++ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER sent zlp\n"); ++ } else { ++ ep0_complete_request(ep0); ++ DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n"); ++ } ++ break; ++ case EP0_OUT_DATA_PHASE: ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n", ++ ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"), ++ ep0->dwc_ep.type, ep0->dwc_ep.maxpacket); ++#endif ++ if (core_if->dma_enable != 0) { ++ if (core_if->dma_desc_enable == 0) { ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if-> ++ dev_if->out_ep_regs[0]-> ++ doeptsiz); ++ byte_count = ++ ep0->dwc_ep.maxpacket - deptsiz.b.xfersize; ++ } else { ++ desc_sts = ++ core_if->dev_if->out_desc_addr->status; ++ byte_count = ++ ep0->dwc_ep.maxpacket - desc_sts.b.bytes; ++ } ++ ep0->dwc_ep.xfer_count += byte_count; ++ ep0->dwc_ep.xfer_buff += byte_count; ++ ep0->dwc_ep.dma_addr += byte_count; ++ } ++ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) { ++ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd), ++ &ep0->dwc_ep); ++ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n"); ++ } else if (ep0->dwc_ep.sent_zlp) { ++ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd), ++ &ep0->dwc_ep); ++ ep0->dwc_ep.sent_zlp = 0; ++ DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER sent zlp\n"); ++ } else { ++ ep0_complete_request(ep0); ++ DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n"); ++ } ++ break; ++ ++ case EP0_IN_STATUS_PHASE: ++ case EP0_OUT_STATUS_PHASE: ++ DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n"); ++ ep0_complete_request(ep0); ++ pcd->ep0state = EP0_IDLE; ++ ep0->stopped = 1; ++ ep0->dwc_ep.is_in = 0; /* OUT for next SETUP */ ++ ++ /* Prepare for more SETUP Packets */ ++ if (core_if->dma_enable) { ++ ep0_out_start(core_if, pcd); ++ } ++ break; ++ ++ case EP0_STALL: ++ DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n"); ++ break; ++ } ++#ifdef DEBUG_EP0 ++ print_ep0_state(pcd); ++#endif ++} ++ ++/** ++ * Restart transfer ++ */ ++static void restart_transfer(dwc_otg_pcd_t * pcd, const uint32_t epnum) ++{ ++ dwc_otg_core_if_t *core_if; ++ dwc_otg_dev_if_t *dev_if; ++ deptsiz_data_t dieptsiz = {.d32 = 0 }; ++ dwc_otg_pcd_ep_t *ep; ++ ++ ep = get_in_ep(pcd, epnum); ++ ++#ifdef DWC_EN_ISOC ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) { ++ return; ++ } ++#endif /* DWC_EN_ISOC */ ++ ++ core_if = GET_CORE_IF(pcd); ++ dev_if = core_if->dev_if; ++ ++ dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz); ++ ++ DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x xfer_len=%0x" ++ " stopped=%d\n", ep->dwc_ep.xfer_buff, ++ ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ep->stopped); ++ /* ++ * If xfersize is 0 and pktcnt in not 0, resend the last packet. ++ */ ++ if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 && ++ ep->dwc_ep.start_xfer_buff != 0) { ++ if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) { ++ ep->dwc_ep.xfer_count = 0; ++ ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff; ++ ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count; ++ } else { ++ ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket; ++ /* convert packet size to dwords. */ ++ ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket; ++ ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count; ++ } ++ ep->stopped = 0; ++ DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x " ++ "xfer_len=%0x stopped=%d\n", ++ ep->dwc_ep.xfer_buff, ++ ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ++ ep->stopped); ++ if (epnum == 0) { ++ dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep); ++ } else { ++ dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep); ++ } ++ } ++} ++ ++/* ++ * This function create new nextep sequnce based on Learn Queue. ++ * ++ * @param core_if Programming view of DWC_otg controller ++ */ ++void predict_nextep_seq( dwc_otg_core_if_t * core_if) ++{ ++ dwc_otg_device_global_regs_t *dev_global_regs = ++ core_if->dev_if->dev_global_regs; ++ const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth; ++ /* Number of Token Queue Registers */ ++ const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8; ++ dtknq1_data_t dtknqr1; ++ uint32_t in_tkn_epnums[4]; ++ uint8_t seqnum[MAX_EPS_CHANNELS]; ++ uint8_t intkn_seq[TOKEN_Q_DEPTH]; ++ grstctl_t resetctl = {.d32 = 0 }; ++ uint8_t temp; ++ int ndx = 0; ++ int start = 0; ++ int end = 0; ++ int sort_done = 0; ++ int i = 0; ++ volatile uint32_t *addr = &dev_global_regs->dtknqr1; ++ ++ ++ DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH); ++ ++ /* Read the DTKNQ Registers */ ++ for (i = 0; i < DTKNQ_REG_CNT; i++) { ++ in_tkn_epnums[i] = DWC_READ_REG32(addr); ++ DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1, ++ in_tkn_epnums[i]); ++ if (addr == &dev_global_regs->dvbusdis) { ++ addr = &dev_global_regs->dtknqr3_dthrctl; ++ } else { ++ ++addr; ++ } ++ ++ } ++ ++ /* Copy the DTKNQR1 data to the bit field. */ ++ dtknqr1.d32 = in_tkn_epnums[0]; ++ if (dtknqr1.b.wrap_bit) { ++ ndx = dtknqr1.b.intknwptr; ++ end = ndx -1; ++ if (end < 0) ++ end = TOKEN_Q_DEPTH -1; ++ } else { ++ ndx = 0; ++ end = dtknqr1.b.intknwptr -1; ++ if (end < 0) ++ end = 0; ++ } ++ start = ndx; ++ ++ /* Fill seqnum[] by initial values: EP number + 31 */ ++ for (i=0; i <= core_if->dev_if->num_in_eps; i++) { ++ seqnum[i] = i +31; ++ } ++ ++ /* Fill intkn_seq[] from in_tkn_epnums[0] */ ++ for (i=0; i < 6; i++) ++ intkn_seq[i] = (in_tkn_epnums[0] >> ((7-i) * 4)) & 0xf; ++ ++ if (TOKEN_Q_DEPTH > 6) { ++ /* Fill intkn_seq[] from in_tkn_epnums[1] */ ++ for (i=6; i < 14; i++) ++ intkn_seq[i] = ++ (in_tkn_epnums[1] >> ((7 - (i - 6)) * 4)) & 0xf; ++ } ++ ++ if (TOKEN_Q_DEPTH > 14) { ++ /* Fill intkn_seq[] from in_tkn_epnums[1] */ ++ for (i=14; i < 22; i++) ++ intkn_seq[i] = ++ (in_tkn_epnums[2] >> ((7 - (i - 14)) * 4)) & 0xf; ++ } ++ ++ if (TOKEN_Q_DEPTH > 22) { ++ /* Fill intkn_seq[] from in_tkn_epnums[1] */ ++ for (i=22; i < 30; i++) ++ intkn_seq[i] = ++ (in_tkn_epnums[3] >> ((7 - (i - 22)) * 4)) & 0xf; ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s start=%d end=%d intkn_seq[]:\n", __func__, ++ start, end); ++ for (i=0; idev_if->num_in_eps; i++) { ++ if (core_if->nextep_seq[i] == 0xff ) ++ seqnum[i] = 0xff; ++ } ++ ++ /* Sort seqnum[] */ ++ sort_done = 0; ++ while (!sort_done) { ++ sort_done = 1; ++ for (i=0; idev_if->num_in_eps; i++) { ++ if (seqnum[i] > seqnum[i+1]) { ++ temp = seqnum[i]; ++ seqnum[i] = seqnum[i+1]; ++ seqnum[i+1] = temp; ++ sort_done = 0; ++ } ++ } ++ } ++ ++ ndx = start + seqnum[0]; ++ if (ndx >= TOKEN_Q_DEPTH) ++ ndx = ndx % TOKEN_Q_DEPTH; ++ core_if->first_in_nextep_seq = intkn_seq[ndx]; ++ ++ /* Update seqnum[] by EP numbers */ ++ for (i=0; i<=core_if->dev_if->num_in_eps; i++) { ++ ndx = start + i; ++ if (seqnum[i] < 31) { ++ ndx = start + seqnum[i]; ++ if (ndx >= TOKEN_Q_DEPTH) ++ ndx = ndx % TOKEN_Q_DEPTH; ++ seqnum[i] = intkn_seq[ndx]; ++ } else { ++ if (seqnum[i] < 0xff) { ++ seqnum[i] = seqnum[i] - 31; ++ } else { ++ break; ++ } ++ } ++ } ++ ++ /* Update nextep_seq[] based on seqnum[] */ ++ for (i=0; idev_if->num_in_eps; i++) { ++ if (seqnum[i] != 0xff) { ++ if (seqnum[i+1] != 0xff) { ++ core_if->nextep_seq[seqnum[i]] = seqnum[i+1]; ++ } else { ++ core_if->nextep_seq[seqnum[i]] = core_if->first_in_nextep_seq; ++ break; ++ } ++ } else { ++ break; ++ } ++ } ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s first_in_nextep_seq= %2d; nextep_seq[]:\n", ++ __func__, core_if->first_in_nextep_seq); ++ for (i=0; i <= core_if->dev_if->num_in_eps; i++) { ++ DWC_DEBUGPL(DBG_PCDV,"%2d\n", core_if->nextep_seq[i]); ++ } ++ ++ /* Flush the Learning Queue */ ++ resetctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->grstctl); ++ resetctl.b.intknqflsh = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32); ++ ++ ++} ++ ++/** ++ * handle the IN EP disable interrupt. ++ */ ++static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t * pcd, ++ const uint32_t epnum) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ deptsiz_data_t dieptsiz = {.d32 = 0 }; ++ dctl_data_t dctl = {.d32 = 0 }; ++ dwc_otg_pcd_ep_t *ep; ++ dwc_ep_t *dwc_ep; ++ gintmsk_data_t gintmsk_data; ++ depctl_data_t depctl; ++ uint32_t diepdma; ++ uint32_t remain_to_transfer = 0; ++ uint8_t i; ++ uint32_t xfer_size; ++ ++ ep = get_in_ep(pcd, epnum); ++ dwc_ep = &ep->dwc_ep; ++ ++ if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num); ++ complete_ep(ep); ++ return; ++ } ++ ++ DWC_DEBUGPL(DBG_PCD, "diepctl%d=%0x\n", epnum, ++ DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl)); ++ dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz); ++ depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl); ++ ++ DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n", ++ dieptsiz.b.pktcnt, dieptsiz.b.xfersize); ++ ++ if ((core_if->start_predict == 0) || (depctl.b.eptype & 1)) { ++ if (ep->stopped) { ++ if (core_if->en_multiple_tx_fifo) ++ /* Flush the Tx FIFO */ ++ dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num); ++ /* Clear the Global IN NP NAK */ ++ dctl.d32 = 0; ++ dctl.b.cgnpinnak = 1; ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); ++ /* Restart the transaction */ ++ if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) { ++ restart_transfer(pcd, epnum); ++ } ++ } else { ++ /* Restart the transaction */ ++ if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) { ++ restart_transfer(pcd, epnum); ++ } ++ DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n"); ++ } ++ return; ++ } ++ ++ if (core_if->start_predict > 2) { // NP IN EP ++ core_if->start_predict--; ++ return; ++ } ++ ++ core_if->start_predict--; ++ ++ if (core_if->start_predict == 1) { // All NP IN Ep's disabled now ++ ++ predict_nextep_seq(core_if); ++ ++ /* Update all active IN EP's NextEP field based of nextep_seq[] */ ++ for ( i = 0; i <= core_if->dev_if->num_in_eps; i++) { ++ depctl.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ if (core_if->nextep_seq[i] != 0xff) { // Active NP IN EP ++ depctl.b.nextep = core_if->nextep_seq[i]; ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32); ++ } ++ } ++ /* Flush Shared NP TxFIFO */ ++ dwc_otg_flush_tx_fifo(core_if, 0); ++ /* Rewind buffers */ ++ if (!core_if->dma_desc_enable) { ++ i = core_if->first_in_nextep_seq; ++ do { ++ ep = get_in_ep(pcd, i); ++ dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz); ++ xfer_size = ep->dwc_ep.total_len - ep->dwc_ep.xfer_count; ++ if (xfer_size > ep->dwc_ep.maxxfer) ++ xfer_size = ep->dwc_ep.maxxfer; ++ depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ if (dieptsiz.b.pktcnt != 0) { ++ if (xfer_size == 0) { ++ remain_to_transfer = 0; ++ } else { ++ if ((xfer_size % ep->dwc_ep.maxpacket) == 0) { ++ remain_to_transfer = ++ dieptsiz.b.pktcnt * ep->dwc_ep.maxpacket; ++ } else { ++ remain_to_transfer = ((dieptsiz.b.pktcnt -1) * ep->dwc_ep.maxpacket) ++ + (xfer_size % ep->dwc_ep.maxpacket); ++ } ++ } ++ diepdma = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepdma); ++ dieptsiz.b.xfersize = remain_to_transfer; ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, dieptsiz.d32); ++ diepdma = ep->dwc_ep.dma_addr + (xfer_size - remain_to_transfer); ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, diepdma); ++ } ++ i = core_if->nextep_seq[i]; ++ } while (i != core_if->first_in_nextep_seq); ++ } else { // dma_desc_enable ++ DWC_PRINTF("%s Learning Queue not supported in DDMA\n", __func__); ++ } ++ ++ /* Restart transfers in predicted sequences */ ++ i = core_if->first_in_nextep_seq; ++ do { ++ dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz); ++ depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ if (dieptsiz.b.pktcnt != 0) { ++ depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ depctl.b.epena = 1; ++ depctl.b.cnak = 1; ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32); ++ } ++ i = core_if->nextep_seq[i]; ++ } while (i != core_if->first_in_nextep_seq); ++ ++ /* Clear the global non-periodic IN NAK handshake */ ++ dctl.d32 = 0; ++ dctl.b.cgnpinnak = 1; ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); ++ ++ /* Unmask EP Mismatch interrupt */ ++ gintmsk_data.d32 = 0; ++ gintmsk_data.b.epmismatch = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk_data.d32); ++ ++ core_if->start_predict = 0; ++ ++ } ++} ++ ++/** ++ * Handler for the IN EP timeout handshake interrupt. ++ */ ++static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t * pcd, ++ const uint32_t epnum) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ ++#ifdef DEBUG ++ deptsiz_data_t dieptsiz = {.d32 = 0 }; ++ uint32_t num = 0; ++#endif ++ dctl_data_t dctl = {.d32 = 0 }; ++ dwc_otg_pcd_ep_t *ep; ++ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ ep = get_in_ep(pcd, epnum); ++ ++ /* Disable the NP Tx Fifo Empty Interrrupt */ ++ if (!core_if->dma_enable) { ++ intr_mask.b.nptxfempty = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ } ++ /** @todo NGS Check EP type. ++ * Implement for Periodic EPs */ ++ /* ++ * Non-periodic EP ++ */ ++ /* Enable the Global IN NAK Effective Interrupt */ ++ intr_mask.b.ginnakeff = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32); ++ ++ /* Set Global IN NAK */ ++ dctl.b.sgnpinnak = 1; ++ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); ++ ++ ep->stopped = 1; ++ ++#ifdef DEBUG ++ dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[num]->dieptsiz); ++ DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n", ++ dieptsiz.b.pktcnt, dieptsiz.b.xfersize); ++#endif ++ ++#ifdef DISABLE_PERIODIC_EP ++ /* ++ * Set the NAK bit for this EP to ++ * start the disable process. ++ */ ++ diepctl.d32 = 0; ++ diepctl.b.snak = 1; ++ DWC_MODIFY_REG32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32, ++ diepctl.d32); ++ ep->disabling = 1; ++ ep->stopped = 1; ++#endif ++} ++ ++/** ++ * Handler for the IN EP NAK interrupt. ++ */ ++static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t * pcd, ++ const uint32_t epnum) ++{ ++ /** @todo implement ISR */ ++ dwc_otg_core_if_t *core_if; ++ diepmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "IN EP NAK"); ++ core_if = GET_CORE_IF(pcd); ++ intr_mask.b.nak = 1; ++ ++ if (core_if->multiproc_int_enable) { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ diepeachintmsk[epnum], intr_mask.d32, 0); ++ } else { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->diepmsk, ++ intr_mask.d32, 0); ++ } ++ ++ return 1; ++} ++ ++/** ++ * Handler for the OUT EP Babble interrupt. ++ */ ++static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t * pcd, ++ const uint32_t epnum) ++{ ++ /** @todo implement ISR */ ++ dwc_otg_core_if_t *core_if; ++ doepmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", ++ "OUT EP Babble"); ++ core_if = GET_CORE_IF(pcd); ++ intr_mask.b.babble = 1; ++ ++ if (core_if->multiproc_int_enable) { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ doepeachintmsk[epnum], intr_mask.d32, 0); ++ } else { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk, ++ intr_mask.d32, 0); ++ } ++ ++ return 1; ++} ++ ++/** ++ * Handler for the OUT EP NAK interrupt. ++ */ ++static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd, ++ const uint32_t epnum) ++{ ++ /** @todo implement ISR */ ++ dwc_otg_core_if_t *core_if; ++ doepmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_ANY, "INTERRUPT Handler not implemented for %s\n", "OUT EP NAK"); ++ core_if = GET_CORE_IF(pcd); ++ intr_mask.b.nak = 1; ++ ++ if (core_if->multiproc_int_enable) { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ doepeachintmsk[epnum], intr_mask.d32, 0); ++ } else { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk, ++ intr_mask.d32, 0); ++ } ++ ++ return 1; ++} ++ ++/** ++ * Handler for the OUT EP NYET interrupt. ++ */ ++static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd, ++ const uint32_t epnum) ++{ ++ /** @todo implement ISR */ ++ dwc_otg_core_if_t *core_if; ++ doepmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET"); ++ core_if = GET_CORE_IF(pcd); ++ intr_mask.b.nyet = 1; ++ ++ if (core_if->multiproc_int_enable) { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs-> ++ doepeachintmsk[epnum], intr_mask.d32, 0); ++ } else { ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk, ++ intr_mask.d32, 0); ++ } ++ ++ return 1; ++} ++ ++/** ++ * This interrupt indicates that an IN EP has a pending Interrupt. ++ * The sequence for handling the IN EP interrupt is shown below: ++ * -# Read the Device All Endpoint Interrupt register ++ * -# Repeat the following for each IN EP interrupt bit set (from ++ * LSB to MSB). ++ * -# Read the Device Endpoint Interrupt (DIEPINTn) register ++ * -# If "Transfer Complete" call the request complete function ++ * -# If "Endpoint Disabled" complete the EP disable procedure. ++ * -# If "AHB Error Interrupt" log error ++ * -# If "Time-out Handshake" log error ++ * -# If "IN Token Received when TxFIFO Empty" write packet to Tx ++ * FIFO. ++ * -# If "IN Token EP Mismatch" (disable, this is handled by EP ++ * Mismatch Interrupt) ++ */ ++static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd) ++{ ++#define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \ ++do { \ ++ diepint_data_t diepint = {.d32=0}; \ ++ diepint.b.__intr = 1; \ ++ DWC_WRITE_REG32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \ ++ diepint.d32); \ ++} while (0) ++ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ dwc_otg_dev_if_t *dev_if = core_if->dev_if; ++ diepint_data_t diepint = {.d32 = 0 }; ++ depctl_data_t depctl = {.d32 = 0 }; ++ uint32_t ep_intr; ++ uint32_t epnum = 0; ++ dwc_otg_pcd_ep_t *ep; ++ dwc_ep_t *dwc_ep; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd); ++ ++ /* Read in the device interrupt bits */ ++ ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if); ++ ++ /* Service the Device IN interrupts for each endpoint */ ++ while (ep_intr) { ++ if (ep_intr & 0x1) { ++ uint32_t empty_msk; ++ /* Get EP pointer */ ++ ep = get_in_ep(pcd, epnum); ++ dwc_ep = &ep->dwc_ep; ++ ++ depctl.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl); ++ empty_msk = ++ DWC_READ_REG32(&dev_if-> ++ dev_global_regs->dtknqr4_fifoemptymsk); ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "IN EP INTERRUPT - %d\nepmty_msk - %8x diepctl - %8x\n", ++ epnum, empty_msk, depctl.d32); ++ ++ DWC_DEBUGPL(DBG_PCD, ++ "EP%d-%s: type=%d, mps=%d\n", ++ dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"), ++ dwc_ep->type, dwc_ep->maxpacket); ++ ++ diepint.d32 = ++ dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep); ++ ++ DWC_DEBUGPL(DBG_PCDV, ++ "EP %d Interrupt Register - 0x%x\n", epnum, ++ diepint.d32); ++ /* Transfer complete */ ++ if (diepint.b.xfercompl) { ++ /* Disable the NP Tx FIFO Empty ++ * Interrupt */ ++ if (core_if->en_multiple_tx_fifo == 0) { ++ intr_mask.b.nptxfempty = 1; ++ DWC_MODIFY_REG32 ++ (&core_if->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ } else { ++ /* Disable the Tx FIFO Empty Interrupt for this EP */ ++ uint32_t fifoemptymsk = ++ 0x1 << dwc_ep->num; ++ DWC_MODIFY_REG32(&core_if-> ++ dev_if->dev_global_regs->dtknqr4_fifoemptymsk, ++ fifoemptymsk, 0); ++ } ++ /* Clear the bit in DIEPINTn for this interrupt */ ++ CLEAR_IN_EP_INTR(core_if, epnum, xfercompl); ++ ++ /* Complete the transfer */ ++ if (epnum == 0) { ++ handle_ep0(pcd); ++ } ++#ifdef DWC_EN_ISOC ++ else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ if (!ep->stopped) ++ complete_iso_ep(pcd, ep); ++ } ++#endif /* DWC_EN_ISOC */ ++#ifdef DWC_UTE_PER_IO ++ else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ if (!ep->stopped) ++ complete_xiso_ep(ep); ++ } ++#endif /* DWC_UTE_PER_IO */ ++ else { ++ if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC && ++ dwc_ep->bInterval > 1) { ++ dwc_ep->frame_num += dwc_ep->bInterval; ++ if (dwc_ep->frame_num > 0x3FFF) ++ { ++ dwc_ep->frm_overrun = 1; ++ dwc_ep->frame_num &= 0x3FFF; ++ } else ++ dwc_ep->frm_overrun = 0; ++ } ++ complete_ep(ep); ++ if(diepint.b.nak) ++ CLEAR_IN_EP_INTR(core_if, epnum, nak); ++ } ++ } ++ /* Endpoint disable */ ++ if (diepint.b.epdisabled) { ++ DWC_DEBUGPL(DBG_ANY, "EP%d IN disabled\n", ++ epnum); ++ handle_in_ep_disable_intr(pcd, epnum); ++ ++ /* Clear the bit in DIEPINTn for this interrupt */ ++ CLEAR_IN_EP_INTR(core_if, epnum, epdisabled); ++ } ++ /* AHB Error */ ++ if (diepint.b.ahberr) { ++ DWC_ERROR("EP%d IN AHB Error\n", epnum); ++ /* Clear the bit in DIEPINTn for this interrupt */ ++ CLEAR_IN_EP_INTR(core_if, epnum, ahberr); ++ } ++ /* TimeOUT Handshake (non-ISOC IN EPs) */ ++ if (diepint.b.timeout) { ++ DWC_ERROR("EP%d IN Time-out\n", epnum); ++ handle_in_ep_timeout_intr(pcd, epnum); ++ ++ CLEAR_IN_EP_INTR(core_if, epnum, timeout); ++ } ++ /** IN Token received with TxF Empty */ ++ if (diepint.b.intktxfemp) { ++ DWC_DEBUGPL(DBG_ANY, ++ "EP%d IN TKN TxFifo Empty\n", ++ epnum); ++ if (!ep->stopped && epnum != 0) { ++ ++ diepmsk_data_t diepmsk = {.d32 = 0 }; ++ diepmsk.b.intktxfemp = 1; ++ ++ if (core_if->multiproc_int_enable) { ++ DWC_MODIFY_REG32 ++ (&dev_if->dev_global_regs->diepeachintmsk ++ [epnum], diepmsk.d32, 0); ++ } else { ++ DWC_MODIFY_REG32 ++ (&dev_if->dev_global_regs->diepmsk, ++ diepmsk.d32, 0); ++ } ++ } else if (core_if->dma_desc_enable ++ && epnum == 0 ++ && pcd->ep0state == ++ EP0_OUT_STATUS_PHASE) { ++ // EP0 IN set STALL ++ depctl.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs ++ [epnum]->diepctl); ++ ++ /* set the disable and stall bits */ ++ if (depctl.b.epena) { ++ depctl.b.epdis = 1; ++ } ++ depctl.b.stall = 1; ++ DWC_WRITE_REG32(&dev_if->in_ep_regs ++ [epnum]->diepctl, ++ depctl.d32); ++ } ++ CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp); ++ } ++ /** IN Token Received with EP mismatch */ ++ if (diepint.b.intknepmis) { ++ DWC_DEBUGPL(DBG_ANY, ++ "EP%d IN TKN EP Mismatch\n", epnum); ++ CLEAR_IN_EP_INTR(core_if, epnum, intknepmis); ++ } ++ /** IN Endpoint NAK Effective */ ++ if (diepint.b.inepnakeff) { ++ DWC_DEBUGPL(DBG_ANY, ++ "EP%d IN EP NAK Effective\n", ++ epnum); ++ /* Periodic EP */ ++ if (ep->disabling) { ++ depctl.d32 = 0; ++ depctl.b.snak = 1; ++ depctl.b.epdis = 1; ++ DWC_MODIFY_REG32(&dev_if->in_ep_regs ++ [epnum]->diepctl, ++ depctl.d32, ++ depctl.d32); ++ } ++ CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff); ++ ++ } ++ ++ /** IN EP Tx FIFO Empty Intr */ ++ if (diepint.b.emptyintr) { ++ DWC_DEBUGPL(DBG_ANY, ++ "EP%d Tx FIFO Empty Intr \n", ++ epnum); ++ write_empty_tx_fifo(pcd, epnum); ++ ++ CLEAR_IN_EP_INTR(core_if, epnum, emptyintr); ++ ++ } ++ ++ /** IN EP BNA Intr */ ++ if (diepint.b.bna) { ++ CLEAR_IN_EP_INTR(core_if, epnum, bna); ++ if (core_if->dma_desc_enable) { ++#ifdef DWC_EN_ISOC ++ if (dwc_ep->type == ++ DWC_OTG_EP_TYPE_ISOC) { ++ /* ++ * This checking is performed to prevent first "false" BNA ++ * handling occuring right after reconnect ++ */ ++ if (dwc_ep->next_frame != ++ 0xffffffff) ++ dwc_otg_pcd_handle_iso_bna(ep); ++ } else ++#endif /* DWC_EN_ISOC */ ++ { ++ dwc_otg_pcd_handle_noniso_bna(ep); ++ } ++ } ++ } ++ /* NAK Interrutp */ ++ if (diepint.b.nak) { ++ DWC_DEBUGPL(DBG_ANY, "EP%d IN NAK Interrupt\n", ++ epnum); ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) { ++ depctl_data_t depctl; ++ if (ep->dwc_ep.frame_num == 0xFFFFFFFF) { ++ ep->dwc_ep.frame_num = core_if->frame_num; ++ if (ep->dwc_ep.bInterval > 1) { ++ depctl.d32 = 0; ++ depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl); ++ if (ep->dwc_ep.frame_num & 0x1) { ++ depctl.b.setd1pid = 1; ++ depctl.b.setd0pid = 0; ++ } else { ++ depctl.b.setd0pid = 1; ++ depctl.b.setd1pid = 0; ++ } ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32); ++ } ++ start_next_request(ep); ++ } ++ ep->dwc_ep.frame_num += ep->dwc_ep.bInterval; ++ if (dwc_ep->frame_num > 0x3FFF) { ++ dwc_ep->frm_overrun = 1; ++ dwc_ep->frame_num &= 0x3FFF; ++ } else ++ dwc_ep->frm_overrun = 0; ++ } ++ ++ CLEAR_IN_EP_INTR(core_if, epnum, nak); ++ } ++ } ++ epnum++; ++ ep_intr >>= 1; ++ } ++ ++ return 1; ++#undef CLEAR_IN_EP_INTR ++} ++ ++/** ++ * This interrupt indicates that an OUT EP has a pending Interrupt. ++ * The sequence for handling the OUT EP interrupt is shown below: ++ * -# Read the Device All Endpoint Interrupt register ++ * -# Repeat the following for each OUT EP interrupt bit set (from ++ * LSB to MSB). ++ * -# Read the Device Endpoint Interrupt (DOEPINTn) register ++ * -# If "Transfer Complete" call the request complete function ++ * -# If "Endpoint Disabled" complete the EP disable procedure. ++ * -# If "AHB Error Interrupt" log error ++ * -# If "Setup Phase Done" process Setup Packet (See Standard USB ++ * Command Processing) ++ */ ++static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd) ++{ ++#define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \ ++do { \ ++ doepint_data_t doepint = {.d32=0}; \ ++ doepint.b.__intr = 1; \ ++ DWC_WRITE_REG32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \ ++ doepint.d32); \ ++} while (0) ++ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ uint32_t ep_intr; ++ doepint_data_t doepint = {.d32 = 0 }; ++ uint32_t epnum = 0; ++ dwc_otg_pcd_ep_t *ep; ++ dwc_ep_t *dwc_ep; ++ dctl_data_t dctl = {.d32 = 0 }; ++ gintmsk_data_t gintmsk = {.d32 = 0 }; ++ ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__); ++ ++ /* Read in the device interrupt bits */ ++ ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if); ++ ++ while (ep_intr) { ++ if (ep_intr & 0x1) { ++ /* Get EP pointer */ ++ ep = get_out_ep(pcd, epnum); ++ dwc_ep = &ep->dwc_ep; ++ ++#ifdef VERBOSE ++ DWC_DEBUGPL(DBG_PCDV, ++ "EP%d-%s: type=%d, mps=%d\n", ++ dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"), ++ dwc_ep->type, dwc_ep->maxpacket); ++#endif ++ doepint.d32 = ++ dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep); ++ /* Moved this interrupt upper due to core deffect of asserting ++ * OUT EP 0 xfercompl along with stsphsrcvd in BDMA */ ++ if (doepint.b.stsphsercvd) { ++ deptsiz0_data_t deptsiz; ++ CLEAR_OUT_EP_INTR(core_if, epnum, stsphsercvd); ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[0]->doeptsiz); ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a ++ && core_if->dma_enable ++ && core_if->dma_desc_enable == 0 ++ && doepint.b.xfercompl ++ && deptsiz.b.xfersize == 24) { ++ CLEAR_OUT_EP_INTR(core_if, epnum, ++ xfercompl); ++ doepint.b.xfercompl = 0; ++ ep0_out_start(core_if, pcd); ++ } ++ if ((core_if->dma_desc_enable) || ++ (core_if->dma_enable ++ && core_if->snpsid >= ++ OTG_CORE_REV_3_00a)) { ++ do_setup_in_status_phase(pcd); ++ } ++ } ++ /* Transfer complete */ ++ if (doepint.b.xfercompl) { ++ ++ if (epnum == 0) { ++ /* Clear the bit in DOEPINTn for this interrupt */ ++ CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl); ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a) { ++ DWC_DEBUGPL(DBG_PCDV, "DOEPINT=%x doepint=%x\n", ++ DWC_READ_REG32(&core_if->dev_if->out_ep_regs[0]->doepint), ++ doepint.d32); ++ DWC_DEBUGPL(DBG_PCDV, "DOEPCTL=%x \n", ++ DWC_READ_REG32(&core_if->dev_if->out_ep_regs[0]->doepctl)); ++ ++ if (core_if->snpsid >= OTG_CORE_REV_3_00a ++ && core_if->dma_enable == 0) { ++ doepint_data_t doepint; ++ doepint.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[0]->doepint); ++ if (pcd->ep0state == EP0_IDLE && doepint.b.sr) { ++ CLEAR_OUT_EP_INTR(core_if, epnum, sr); ++ goto exit_xfercompl; ++ } ++ } ++ /* In case of DDMA look at SR bit to go to the Data Stage */ ++ if (core_if->dma_desc_enable) { ++ dev_dma_desc_sts_t status = {.d32 = 0}; ++ if (pcd->ep0state == EP0_IDLE) { ++ status.d32 = core_if->dev_if->setup_desc_addr[core_if-> ++ dev_if->setup_desc_index]->status.d32; ++ if(pcd->data_terminated) { ++ pcd->data_terminated = 0; ++ status.d32 = core_if->dev_if->out_desc_addr->status.d32; ++ dwc_memcpy(&pcd->setup_pkt->req, pcd->backup_buf, 8); ++ } ++ if (status.b.sr) { ++ if (doepint.b.setup) { ++ DWC_DEBUGPL(DBG_PCDV, "DMA DESC EP0_IDLE SR=1 setup=1\n"); ++ /* Already started data stage, clear setup */ ++ CLEAR_OUT_EP_INTR(core_if, epnum, setup); ++ doepint.b.setup = 0; ++ handle_ep0(pcd); ++ /* Prepare for more setup packets */ ++ if (pcd->ep0state == EP0_IN_STATUS_PHASE || ++ pcd->ep0state == EP0_IN_DATA_PHASE) { ++ ep0_out_start(core_if, pcd); ++ } ++ ++ goto exit_xfercompl; ++ } else { ++ /* Prepare for more setup packets */ ++ DWC_DEBUGPL(DBG_PCDV, ++ "EP0_IDLE SR=1 setup=0 new setup comes\n"); ++ ep0_out_start(core_if, pcd); ++ } ++ } ++ } else { ++ dwc_otg_pcd_request_t *req; ++ dev_dma_desc_sts_t status = {.d32 = 0}; ++ diepint_data_t diepint0; ++ diepint0.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepint); ++ ++ if (pcd->ep0state == EP0_STALL || pcd->ep0state == EP0_DISCONNECT) { ++ DWC_ERROR("EP0 is stalled/disconnected\n"); ++ } ++ ++ /* Clear IN xfercompl if set */ ++ if (diepint0.b.xfercompl && (pcd->ep0state == EP0_IN_STATUS_PHASE ++ || pcd->ep0state == EP0_IN_DATA_PHASE)) { ++ DWC_WRITE_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepint, diepint0.d32); ++ } ++ ++ status.d32 = core_if->dev_if->setup_desc_addr[core_if-> ++ dev_if->setup_desc_index]->status.d32; ++ ++ if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len ++ && (pcd->ep0state == EP0_OUT_DATA_PHASE)) ++ status.d32 = core_if->dev_if->out_desc_addr->status.d32; ++ if (pcd->ep0state == EP0_OUT_STATUS_PHASE) ++ status.d32 = status.d32 = core_if->dev_if-> ++ out_desc_addr->status.d32; ++ ++ if (status.b.sr) { ++ if (DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ DWC_DEBUGPL(DBG_PCDV, "Request queue empty!!\n"); ++ } else { ++ DWC_DEBUGPL(DBG_PCDV, "complete req!!\n"); ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len && ++ pcd->ep0state == EP0_OUT_DATA_PHASE) { ++ /* Read arrived setup packet from req->buf */ ++ dwc_memcpy(&pcd->setup_pkt->req, ++ req->buf + ep->dwc_ep.xfer_count, 8); ++ } ++ req->actual = ep->dwc_ep.xfer_count; ++ dwc_otg_request_done(ep, req, -ECONNRESET); ++ ep->dwc_ep.start_xfer_buff = 0; ++ ep->dwc_ep.xfer_buff = 0; ++ ep->dwc_ep.xfer_len = 0; ++ } ++ pcd->ep0state = EP0_IDLE; ++ if (doepint.b.setup) { ++ DWC_DEBUGPL(DBG_PCDV, "EP0_IDLE SR=1 setup=1\n"); ++ /* Data stage started, clear setup */ ++ CLEAR_OUT_EP_INTR(core_if, epnum, setup); ++ doepint.b.setup = 0; ++ handle_ep0(pcd); ++ /* Prepare for setup packets if ep0in was enabled*/ ++ if (pcd->ep0state == EP0_IN_STATUS_PHASE) { ++ ep0_out_start(core_if, pcd); ++ } ++ ++ goto exit_xfercompl; ++ } else { ++ /* Prepare for more setup packets */ ++ DWC_DEBUGPL(DBG_PCDV, ++ "EP0_IDLE SR=1 setup=0 new setup comes 2\n"); ++ ep0_out_start(core_if, pcd); ++ } ++ } ++ } ++ } ++ if (core_if->snpsid >= OTG_CORE_REV_2_94a && core_if->dma_enable ++ && core_if->dma_desc_enable == 0) { ++ doepint_data_t doepint_temp = {.d32 = 0}; ++ deptsiz0_data_t doeptsize0 = {.d32 = 0 }; ++ doepint_temp.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[ep->dwc_ep.num]->doepint); ++ doeptsize0.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[ep->dwc_ep.num]->doeptsiz); ++ if (pcd->ep0state == EP0_IDLE) { ++ if (doepint_temp.b.sr) { ++ CLEAR_OUT_EP_INTR(core_if, epnum, sr); ++ } ++ doepint.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[0]->doepint); ++ if (doeptsize0.b.supcnt == 3) { ++ DWC_DEBUGPL(DBG_ANY, "Rolling over!!!!!!!\n"); ++ ep->dwc_ep.stp_rollover = 1; ++ } ++ if (doepint.b.setup) { ++retry: ++ /* Already started data stage, clear setup */ ++ CLEAR_OUT_EP_INTR(core_if, epnum, setup); ++ doepint.b.setup = 0; ++ handle_ep0(pcd); ++ ep->dwc_ep.stp_rollover = 0; ++ /* Prepare for more setup packets */ ++ if (pcd->ep0state == EP0_IN_STATUS_PHASE || ++ pcd->ep0state == EP0_IN_DATA_PHASE) { ++ ep0_out_start(core_if, pcd); ++ } ++ goto exit_xfercompl; ++ } else { ++ /* Prepare for more setup packets */ ++ DWC_DEBUGPL(DBG_ANY, ++ "EP0_IDLE SR=1 setup=0 new setup comes\n"); ++ doepint.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[0]->doepint); ++ if(doepint.b.setup) ++ goto retry; ++ ep0_out_start(core_if, pcd); ++ } ++ } else { ++ dwc_otg_pcd_request_t *req; ++ diepint_data_t diepint0 = {.d32 = 0}; ++ doepint_data_t doepint_temp = {.d32 = 0}; ++ depctl_data_t diepctl0; ++ diepint0.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepint); ++ diepctl0.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepctl); ++ ++ if (pcd->ep0state == EP0_IN_DATA_PHASE ++ || pcd->ep0state == EP0_IN_STATUS_PHASE) { ++ if (diepint0.b.xfercompl) { ++ DWC_WRITE_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepint, diepint0.d32); ++ } ++ if (diepctl0.b.epena) { ++ diepint_data_t diepint = {.d32 = 0}; ++ diepctl0.b.snak = 1; ++ DWC_WRITE_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepctl, diepctl0.d32); ++ do { ++ dwc_udelay(10); ++ diepint.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepint); ++ } while (!diepint.b.inepnakeff); ++ diepint.b.inepnakeff = 1; ++ DWC_WRITE_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepint, diepint.d32); ++ diepctl0.d32 = 0; ++ diepctl0.b.epdis = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[0]->diepctl, ++ diepctl0.d32); ++ do { ++ dwc_udelay(10); ++ diepint.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ in_ep_regs[0]->diepint); ++ } while (!diepint.b.epdisabled); ++ diepint.b.epdisabled = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[0]->diepint, ++ diepint.d32); ++ } ++ } ++ doepint_temp.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[ep->dwc_ep.num]->doepint); ++ if (doepint_temp.b.sr) { ++ CLEAR_OUT_EP_INTR(core_if, epnum, sr); ++ if (DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ DWC_DEBUGPL(DBG_PCDV, "Request queue empty!!\n"); ++ } else { ++ DWC_DEBUGPL(DBG_PCDV, "complete req!!\n"); ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len && ++ pcd->ep0state == EP0_OUT_DATA_PHASE) { ++ /* Read arrived setup packet from req->buf */ ++ dwc_memcpy(&pcd->setup_pkt->req, ++ req->buf + ep->dwc_ep.xfer_count, 8); ++ } ++ req->actual = ep->dwc_ep.xfer_count; ++ dwc_otg_request_done(ep, req, -ECONNRESET); ++ ep->dwc_ep.start_xfer_buff = 0; ++ ep->dwc_ep.xfer_buff = 0; ++ ep->dwc_ep.xfer_len = 0; ++ } ++ pcd->ep0state = EP0_IDLE; ++ if (doepint.b.setup) { ++ DWC_DEBUGPL(DBG_PCDV, "EP0_IDLE SR=1 setup=1\n"); ++ /* Data stage started, clear setup */ ++ CLEAR_OUT_EP_INTR(core_if, epnum, setup); ++ doepint.b.setup = 0; ++ handle_ep0(pcd); ++ /* Prepare for setup packets if ep0in was enabled*/ ++ if (pcd->ep0state == EP0_IN_STATUS_PHASE) { ++ ep0_out_start(core_if, pcd); ++ } ++ goto exit_xfercompl; ++ } else { ++ /* Prepare for more setup packets */ ++ DWC_DEBUGPL(DBG_PCDV, ++ "EP0_IDLE SR=1 setup=0 new setup comes 2\n"); ++ ep0_out_start(core_if, pcd); ++ } ++ } ++ } ++ } ++ if (core_if->dma_enable == 0 || pcd->ep0state != EP0_IDLE) ++ handle_ep0(pcd); ++exit_xfercompl: ++ DWC_DEBUGPL(DBG_PCDV, "DOEPINT=%x doepint=%x\n", ++ dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep), doepint.d32); ++ } else { ++ if (core_if->dma_desc_enable == 0 ++ || pcd->ep0state != EP0_IDLE) ++ handle_ep0(pcd); ++ } ++#ifdef DWC_EN_ISOC ++ } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ if (doepint.b.pktdrpsts == 0) { ++ /* Clear the bit in DOEPINTn for this interrupt */ ++ CLEAR_OUT_EP_INTR(core_if, ++ epnum, ++ xfercompl); ++ complete_iso_ep(pcd, ep); ++ } else { ++ ++ doepint_data_t doepint = {.d32 = 0 }; ++ doepint.b.xfercompl = 1; ++ doepint.b.pktdrpsts = 1; ++ DWC_WRITE_REG32 ++ (&core_if->dev_if->out_ep_regs ++ [epnum]->doepint, ++ doepint.d32); ++ if (handle_iso_out_pkt_dropped ++ (core_if, dwc_ep)) { ++ complete_iso_ep(pcd, ++ ep); ++ } ++ } ++#endif /* DWC_EN_ISOC */ ++#ifdef DWC_UTE_PER_IO ++ } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl); ++ if (!ep->stopped) ++ complete_xiso_ep(ep); ++#endif /* DWC_UTE_PER_IO */ ++ } else { ++ /* Clear the bit in DOEPINTn for this interrupt */ ++ CLEAR_OUT_EP_INTR(core_if, epnum, ++ xfercompl); ++ ++ if (core_if->core_params->dev_out_nak) { ++ DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[epnum]); ++ pcd->core_if->ep_xfer_info[epnum].state = 0; ++#ifdef DEBUG ++ print_memory_payload(pcd, dwc_ep); ++#endif ++ } ++ complete_ep(ep); ++ } ++ ++ } ++ ++ /* Endpoint disable */ ++ if (doepint.b.epdisabled) { ++ ++ /* Clear the bit in DOEPINTn for this interrupt */ ++ CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled); ++ if (core_if->core_params->dev_out_nak) { ++#ifdef DEBUG ++ print_memory_payload(pcd, dwc_ep); ++#endif ++ /* In case of timeout condition */ ++ if (core_if->ep_xfer_info[epnum].state == 2) { ++ dctl.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ dev_global_regs->dctl); ++ dctl.b.cgoutnak = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, ++ dctl.d32); ++ /* Unmask goutnakeff interrupt which was masked ++ * during handle nak out interrupt */ ++ gintmsk.b.goutnakeff = 1; ++ DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, ++ 0, gintmsk.d32); ++ ++ complete_ep(ep); ++ } ++ } ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) ++ { ++ dctl_data_t dctl; ++ gintmsk_data_t intr_mask = {.d32 = 0}; ++ dwc_otg_pcd_request_t *req = 0; ++ ++ dctl.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ dev_global_regs->dctl); ++ dctl.b.cgoutnak = 1; ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, ++ dctl.d32); ++ ++ intr_mask.d32 = 0; ++ intr_mask.b.incomplisoout = 1; ++ ++ /* Get any pending requests */ ++ if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) { ++ req = DWC_CIRCLEQ_FIRST(&ep->queue); ++ if (!req) { ++ DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep); ++ } else { ++ dwc_otg_request_done(ep, req, 0); ++ start_next_request(ep); ++ } ++ } else { ++ DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep); ++ } ++ } ++ } ++ /* AHB Error */ ++ if (doepint.b.ahberr) { ++ DWC_ERROR("EP%d OUT AHB Error\n", epnum); ++ DWC_ERROR("EP%d DEPDMA=0x%08x \n", ++ epnum, core_if->dev_if->out_ep_regs[epnum]->doepdma); ++ CLEAR_OUT_EP_INTR(core_if, epnum, ahberr); ++ } ++ /* Setup Phase Done (contorl EPs) */ ++ if (doepint.b.setup) { ++#ifdef DEBUG_EP0 ++ DWC_DEBUGPL(DBG_PCD, "EP%d SETUP Done\n", epnum); ++#endif ++ CLEAR_OUT_EP_INTR(core_if, epnum, setup); ++ ++ handle_ep0(pcd); ++ } ++ ++ /** OUT EP BNA Intr */ ++ if (doepint.b.bna) { ++ CLEAR_OUT_EP_INTR(core_if, epnum, bna); ++ if (core_if->dma_desc_enable) { ++#ifdef DWC_EN_ISOC ++ if (dwc_ep->type == ++ DWC_OTG_EP_TYPE_ISOC) { ++ /* ++ * This checking is performed to prevent first "false" BNA ++ * handling occuring right after reconnect ++ */ ++ if (dwc_ep->next_frame != ++ 0xffffffff) ++ dwc_otg_pcd_handle_iso_bna(ep); ++ } else ++#endif /* DWC_EN_ISOC */ ++ { ++ dwc_otg_pcd_handle_noniso_bna(ep); ++ } ++ } ++ } ++ /* Babble Interrupt */ ++ if (doepint.b.babble) { ++ DWC_DEBUGPL(DBG_ANY, "EP%d OUT Babble\n", ++ epnum); ++ handle_out_ep_babble_intr(pcd, epnum); ++ ++ CLEAR_OUT_EP_INTR(core_if, epnum, babble); ++ } ++ if (doepint.b.outtknepdis) { ++ DWC_DEBUGPL(DBG_ANY, "EP%d OUT Token received when EP is \ ++ disabled\n",epnum); ++ if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) { ++ doepmsk_data_t doepmsk = {.d32 = 0}; ++ ep->dwc_ep.frame_num = core_if->frame_num; ++ if (ep->dwc_ep.bInterval > 1) { ++ depctl_data_t depctl; ++ depctl.d32 = DWC_READ_REG32(&core_if->dev_if-> ++ out_ep_regs[epnum]->doepctl); ++ if (ep->dwc_ep.frame_num & 0x1) { ++ depctl.b.setd1pid = 1; ++ depctl.b.setd0pid = 0; ++ } else { ++ depctl.b.setd0pid = 1; ++ depctl.b.setd1pid = 0; ++ } ++ DWC_WRITE_REG32(&core_if->dev_if-> ++ out_ep_regs[epnum]->doepctl, depctl.d32); ++ } ++ start_next_request(ep); ++ doepmsk.b.outtknepdis = 1; ++ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk, ++ doepmsk.d32, 0); ++ } ++ CLEAR_OUT_EP_INTR(core_if, epnum, outtknepdis); ++ } ++ ++ /* NAK Interrutp */ ++ if (doepint.b.nak) { ++ DWC_DEBUGPL(DBG_ANY, "EP%d OUT NAK\n", epnum); ++ handle_out_ep_nak_intr(pcd, epnum); ++ ++ CLEAR_OUT_EP_INTR(core_if, epnum, nak); ++ } ++ /* NYET Interrutp */ ++ if (doepint.b.nyet) { ++ DWC_DEBUGPL(DBG_ANY, "EP%d OUT NYET\n", epnum); ++ handle_out_ep_nyet_intr(pcd, epnum); ++ ++ CLEAR_OUT_EP_INTR(core_if, epnum, nyet); ++ } ++ } ++ ++ epnum++; ++ ep_intr >>= 1; ++ } ++ ++ return 1; ++ ++#undef CLEAR_OUT_EP_INTR ++} ++static int drop_transfer(uint32_t trgt_fr, uint32_t curr_fr, uint8_t frm_overrun) ++{ ++ int retval = 0; ++ if(!frm_overrun && curr_fr >= trgt_fr) ++ retval = 1; ++ else if (frm_overrun ++ && (curr_fr >= trgt_fr && ((curr_fr - trgt_fr) < 0x3FFF / 2))) ++ retval = 1; ++ return retval; ++} ++/** ++ * Incomplete ISO IN Transfer Interrupt. ++ * This interrupt indicates one of the following conditions occurred ++ * while transmitting an ISOC transaction. ++ * - Corrupted IN Token for ISOC EP. ++ * - Packet not complete in FIFO. ++ * The follow actions will be taken: ++ * -# Determine the EP ++ * -# Set incomplete flag in dwc_ep structure ++ * -# Disable EP; when "Endpoint Disabled" interrupt is received ++ * Flush FIFO ++ */ ++int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t * pcd) ++{ ++ gintsts_data_t gintsts; ++ ++#ifdef DWC_EN_ISOC ++ dwc_otg_dev_if_t *dev_if; ++ deptsiz_data_t deptsiz = {.d32 = 0 }; ++ depctl_data_t depctl = {.d32 = 0 }; ++ dsts_data_t dsts = {.d32 = 0 }; ++ dwc_ep_t *dwc_ep; ++ int i; ++ ++ dev_if = GET_CORE_IF(pcd)->dev_if; ++ ++ for (i = 1; i <= dev_if->num_in_eps; ++i) { ++ dwc_ep = &pcd->in_ep[i].dwc_ep; ++ if (dwc_ep->active && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ deptsiz.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz); ++ depctl.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ ++ if (depctl.b.epdis && deptsiz.d32) { ++ set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep); ++ if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) { ++ dwc_ep->cur_pkt = 0; ++ dwc_ep->proc_buf_num = ++ (dwc_ep->proc_buf_num ^ 1) & 0x1; ++ ++ if (dwc_ep->proc_buf_num) { ++ dwc_ep->cur_pkt_addr = ++ dwc_ep->xfer_buff1; ++ dwc_ep->cur_pkt_dma_addr = ++ dwc_ep->dma_addr1; ++ } else { ++ dwc_ep->cur_pkt_addr = ++ dwc_ep->xfer_buff0; ++ dwc_ep->cur_pkt_dma_addr = ++ dwc_ep->dma_addr0; ++ } ++ ++ } ++ ++ dsts.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if-> ++ dev_global_regs->dsts); ++ dwc_ep->next_frame = dsts.b.soffn; ++ ++ dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF ++ (pcd), ++ dwc_ep); ++ } ++ } ++ } ++ ++#else ++ depctl_data_t depctl = {.d32 = 0 }; ++ dwc_ep_t *dwc_ep; ++ dwc_otg_dev_if_t *dev_if; ++ int i; ++ dev_if = GET_CORE_IF(pcd)->dev_if; ++ ++ DWC_DEBUGPL(DBG_PCD,"Incomplete ISO IN \n"); ++ ++ for (i = 1; i <= dev_if->num_in_eps; ++i) { ++ dwc_ep = &pcd->in_ep[i-1].dwc_ep; ++ depctl.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ if (depctl.b.epena && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) { ++ if (drop_transfer(dwc_ep->frame_num, GET_CORE_IF(pcd)->frame_num, ++ dwc_ep->frm_overrun)) ++ { ++ depctl.d32 = ++ DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ depctl.b.snak = 1; ++ depctl.b.epdis = 1; ++ DWC_MODIFY_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32, depctl.d32); ++ } ++ } ++ } ++ ++ /*intr_mask.b.incomplisoin = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk, ++ intr_mask.d32, 0); */ ++#endif //DWC_EN_ISOC ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.incomplisoin = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * Incomplete ISO OUT Transfer Interrupt. ++ * ++ * This interrupt indicates that the core has dropped an ISO OUT ++ * packet. The following conditions can be the cause: ++ * - FIFO Full, the entire packet would not fit in the FIFO. ++ * - CRC Error ++ * - Corrupted Token ++ * The follow actions will be taken: ++ * -# Determine the EP ++ * -# Set incomplete flag in dwc_ep structure ++ * -# Read any data from the FIFO ++ * -# Disable EP. When "Endpoint Disabled" interrupt is received ++ * re-enable EP. ++ */ ++int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t * pcd) ++{ ++ ++ gintsts_data_t gintsts; ++ ++#ifdef DWC_EN_ISOC ++ dwc_otg_dev_if_t *dev_if; ++ deptsiz_data_t deptsiz = {.d32 = 0 }; ++ depctl_data_t depctl = {.d32 = 0 }; ++ dsts_data_t dsts = {.d32 = 0 }; ++ dwc_ep_t *dwc_ep; ++ int i; ++ ++ dev_if = GET_CORE_IF(pcd)->dev_if; ++ ++ for (i = 1; i <= dev_if->num_out_eps; ++i) { ++ dwc_ep = &pcd->in_ep[i].dwc_ep; ++ if (pcd->out_ep[i].dwc_ep.active && ++ pcd->out_ep[i].dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) { ++ deptsiz.d32 = ++ DWC_READ_REG32(&dev_if->out_ep_regs[i]->doeptsiz); ++ depctl.d32 = ++ DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl); ++ ++ if (depctl.b.epdis && deptsiz.d32) { ++ set_current_pkt_info(GET_CORE_IF(pcd), ++ &pcd->out_ep[i].dwc_ep); ++ if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) { ++ dwc_ep->cur_pkt = 0; ++ dwc_ep->proc_buf_num = ++ (dwc_ep->proc_buf_num ^ 1) & 0x1; ++ ++ if (dwc_ep->proc_buf_num) { ++ dwc_ep->cur_pkt_addr = ++ dwc_ep->xfer_buff1; ++ dwc_ep->cur_pkt_dma_addr = ++ dwc_ep->dma_addr1; ++ } else { ++ dwc_ep->cur_pkt_addr = ++ dwc_ep->xfer_buff0; ++ dwc_ep->cur_pkt_dma_addr = ++ dwc_ep->dma_addr0; ++ } ++ ++ } ++ ++ dsts.d32 = ++ DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if-> ++ dev_global_regs->dsts); ++ dwc_ep->next_frame = dsts.b.soffn; ++ ++ dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF ++ (pcd), ++ dwc_ep); ++ } ++ } ++ } ++#else ++ /** @todo implement ISR */ ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ dwc_otg_core_if_t *core_if; ++ deptsiz_data_t deptsiz = {.d32 = 0 }; ++ depctl_data_t depctl = {.d32 = 0 }; ++ dctl_data_t dctl = {.d32 = 0 }; ++ dwc_ep_t *dwc_ep = NULL; ++ int i; ++ core_if = GET_CORE_IF(pcd); ++ ++ for (i = 0; i < core_if->dev_if->num_out_eps; ++i) { ++ dwc_ep = &pcd->out_ep[i].dwc_ep; ++ depctl.d32 = ++ DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl); ++ if (depctl.b.epena && depctl.b.dpid == (core_if->frame_num & 0x1)) { ++ core_if->dev_if->isoc_ep = dwc_ep; ++ deptsiz.d32 = ++ DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz); ++ break; ++ } ++ } ++ dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl); ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ intr_mask.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); ++ ++ if (!intr_mask.b.goutnakeff) { ++ /* Unmask it */ ++ intr_mask.b.goutnakeff = 1; ++ DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32); ++ } ++ if (!gintsts.b.goutnakeff) { ++ dctl.b.sgoutnak = 1; ++ } ++ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32); ++ ++ depctl.d32 = DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl); ++ if (depctl.b.epena) { ++ depctl.b.epdis = 1; ++ depctl.b.snak = 1; ++ } ++ DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl, depctl.d32); ++ ++ intr_mask.d32 = 0; ++ intr_mask.b.incomplisoout = 1; ++ ++#endif /* DWC_EN_ISOC */ ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.incomplisoout = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * This function handles the Global IN NAK Effective interrupt. ++ * ++ */ ++int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if; ++ depctl_data_t diepctl = {.d32 = 0 }; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ gintsts_data_t gintsts; ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++ int i; ++ ++ DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n"); ++ ++ /* Disable all active IN EPs */ ++ for (i = 0; i <= dev_if->num_in_eps; i++) { ++ diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl); ++ if (!(diepctl.b.eptype & 1) && diepctl.b.epena) { ++ if (core_if->start_predict > 0) ++ core_if->start_predict++; ++ diepctl.b.epdis = 1; ++ diepctl.b.snak = 1; ++ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, diepctl.d32); ++ } ++ } ++ ++ ++ /* Disable the Global IN NAK Effective Interrupt */ ++ intr_mask.b.ginnakeff = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.ginnakeff = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * OUT NAK Effective. ++ * ++ */ ++int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if; ++ gintmsk_data_t intr_mask = {.d32 = 0 }; ++ gintsts_data_t gintsts; ++ depctl_data_t doepctl; ++ int i; ++ ++ /* Disable the Global OUT NAK Effective Interrupt */ ++ intr_mask.b.goutnakeff = 1; ++ DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk, ++ intr_mask.d32, 0); ++ ++ /* If DEV OUT NAK enabled*/ ++ if (pcd->core_if->core_params->dev_out_nak) { ++ /* Run over all out endpoints to determine the ep number on ++ * which the timeout has happened ++ */ ++ for (i = 0; i <= dev_if->num_out_eps; i++) { ++ if ( pcd->core_if->ep_xfer_info[i].state == 2 ) ++ break; ++ } ++ if (i > dev_if->num_out_eps) { ++ dctl_data_t dctl; ++ dctl.d32 = ++ DWC_READ_REG32(&dev_if->dev_global_regs->dctl); ++ dctl.b.cgoutnak = 1; ++ DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, ++ dctl.d32); ++ goto out; ++ } ++ ++ /* Disable the endpoint */ ++ doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl); ++ if (doepctl.b.epena) { ++ doepctl.b.epdis = 1; ++ doepctl.b.snak = 1; ++ } ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32); ++ return 1; ++ } ++ /* We come here from Incomplete ISO OUT handler */ ++ if (dev_if->isoc_ep) { ++ dwc_ep_t *dwc_ep = (dwc_ep_t *)dev_if->isoc_ep; ++ uint32_t epnum = dwc_ep->num; ++ doepint_data_t doepint; ++ doepint.d32 = ++ DWC_READ_REG32(&dev_if->out_ep_regs[dwc_ep->num]->doepint); ++ dev_if->isoc_ep = NULL; ++ doepctl.d32 = ++ DWC_READ_REG32(&dev_if->out_ep_regs[epnum]->doepctl); ++ DWC_PRINTF("Before disable DOEPCTL = %08x\n", doepctl.d32); ++ if (doepctl.b.epena) { ++ doepctl.b.epdis = 1; ++ doepctl.b.snak = 1; ++ } ++ DWC_WRITE_REG32(&dev_if->out_ep_regs[epnum]->doepctl, ++ doepctl.d32); ++ return 1; ++ } else ++ DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", ++ "Global OUT NAK Effective\n"); ++ ++out: ++ /* Clear interrupt */ ++ gintsts.d32 = 0; ++ gintsts.b.goutnakeff = 1; ++ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, ++ gintsts.d32); ++ ++ return 1; ++} ++ ++/** ++ * PCD interrupt handler. ++ * ++ * The PCD handles the device interrupts. Many conditions can cause a ++ * device interrupt. When an interrupt occurs, the device interrupt ++ * service routine determines the cause of the interrupt and ++ * dispatches handling to the appropriate function. These interrupt ++ * handling functions are described below. ++ * ++ * All interrupt registers are processed from LSB to MSB. ++ * ++ */ ++int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd) ++{ ++ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); ++#ifdef VERBOSE ++ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs; ++#endif ++ gintsts_data_t gintr_status; ++ int32_t retval = 0; ++ ++ /* Exit from ISR if core is hibernated */ ++ if (core_if->hibernation_suspend == 1) { ++ return retval; ++ } ++#ifdef VERBOSE ++ DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x gintmsk=%08x\n", ++ __func__, ++ DWC_READ_REG32(&global_regs->gintsts), ++ DWC_READ_REG32(&global_regs->gintmsk)); ++#endif ++ ++ if (dwc_otg_is_device_mode(core_if)) { ++ DWC_SPINLOCK(pcd->lock); ++#ifdef VERBOSE ++ DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x gintmsk=%08x\n", ++ __func__, ++ DWC_READ_REG32(&global_regs->gintsts), ++ DWC_READ_REG32(&global_regs->gintmsk)); ++#endif ++ ++ gintr_status.d32 = dwc_otg_read_core_intr(core_if); ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n", ++ __func__, gintr_status.d32); ++ ++ if (gintr_status.b.sofintr) { ++ retval |= dwc_otg_pcd_handle_sof_intr(pcd); ++ } ++ if (gintr_status.b.rxstsqlvl) { ++ retval |= ++ dwc_otg_pcd_handle_rx_status_q_level_intr(pcd); ++ } ++ if (gintr_status.b.nptxfempty) { ++ retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd); ++ } ++ if (gintr_status.b.goutnakeff) { ++ retval |= dwc_otg_pcd_handle_out_nak_effective(pcd); ++ } ++ if (gintr_status.b.i2cintr) { ++ retval |= dwc_otg_pcd_handle_i2c_intr(pcd); ++ } ++ if (gintr_status.b.erlysuspend) { ++ retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd); ++ } ++ if (gintr_status.b.usbreset) { ++ retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd); ++ } ++ if (gintr_status.b.enumdone) { ++ retval |= dwc_otg_pcd_handle_enum_done_intr(pcd); ++ } ++ if (gintr_status.b.isooutdrop) { ++ retval |= ++ dwc_otg_pcd_handle_isoc_out_packet_dropped_intr ++ (pcd); ++ } ++ if (gintr_status.b.eopframe) { ++ retval |= ++ dwc_otg_pcd_handle_end_periodic_frame_intr(pcd); ++ } ++ if (gintr_status.b.inepint) { ++ if (!core_if->multiproc_int_enable) { ++ retval |= dwc_otg_pcd_handle_in_ep_intr(pcd); ++ } ++ } ++ if (gintr_status.b.outepintr) { ++ if (!core_if->multiproc_int_enable) { ++ retval |= dwc_otg_pcd_handle_out_ep_intr(pcd); ++ } ++ } ++ if (gintr_status.b.epmismatch) { ++ retval |= dwc_otg_pcd_handle_ep_mismatch_intr(pcd); ++ } ++ if (gintr_status.b.fetsusp) { ++ retval |= dwc_otg_pcd_handle_ep_fetsusp_intr(pcd); ++ } ++ if (gintr_status.b.ginnakeff) { ++ retval |= dwc_otg_pcd_handle_in_nak_effective(pcd); ++ } ++ if (gintr_status.b.incomplisoin) { ++ retval |= ++ dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd); ++ } ++ if (gintr_status.b.incomplisoout) { ++ retval |= ++ dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd); ++ } ++ ++ /* In MPI mode Device Endpoints interrupts are asserted ++ * without setting outepintr and inepint bits set, so these ++ * Interrupt handlers are called without checking these bit-fields ++ */ ++ if (core_if->multiproc_int_enable) { ++ retval |= dwc_otg_pcd_handle_in_ep_intr(pcd); ++ retval |= dwc_otg_pcd_handle_out_ep_intr(pcd); ++ } ++#ifdef VERBOSE ++ DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__, ++ DWC_READ_REG32(&global_regs->gintsts)); ++#endif ++ DWC_SPINUNLOCK(pcd->lock); ++ } ++ return retval; ++} ++ ++#endif /* DWC_HOST_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,1358 @@ ++ /* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_linux.c $ ++ * $Revision: #21 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++#ifndef DWC_HOST_ONLY ++ ++/** @file ++ * This file implements the Peripheral Controller Driver. ++ * ++ * The Peripheral Controller Driver (PCD) is responsible for ++ * translating requests from the Function Driver into the appropriate ++ * actions on the DWC_otg controller. It isolates the Function Driver ++ * from the specifics of the controller by providing an API to the ++ * Function Driver. ++ * ++ * The Peripheral Controller Driver for Linux will implement the ++ * Gadget API, so that the existing Gadget drivers can be used. ++ * (Gadget Driver is the Linux terminology for a Function Driver.) ++ * ++ * The Linux Gadget API is defined in the header file ++ * . The USB EP operations API is ++ * defined in the structure usb_ep_ops and the USB ++ * Controller API is defined in the structure ++ * usb_gadget_ops. ++ * ++ */ ++ ++#include "dwc_otg_os_dep.h" ++#include "dwc_otg_pcd_if.h" ++#include "dwc_otg_pcd.h" ++#include "dwc_otg_driver.h" ++#include "dwc_otg_dbg.h" ++ ++static struct gadget_wrapper { ++ dwc_otg_pcd_t *pcd; ++ ++ struct usb_gadget gadget; ++ struct usb_gadget_driver *driver; ++ ++ struct usb_ep ep0; ++ struct usb_ep in_ep[16]; ++ struct usb_ep out_ep[16]; ++ ++} *gadget_wrapper; ++ ++/* Display the contents of the buffer */ ++extern void dump_msg(const u8 * buf, unsigned int length); ++/** ++ * Get the dwc_otg_pcd_ep_t* from usb_ep* pointer - NULL in case ++ * if the endpoint is not found ++ */ ++static struct dwc_otg_pcd_ep *ep_from_handle(dwc_otg_pcd_t * pcd, void *handle) ++{ ++ int i; ++ if (pcd->ep0.priv == handle) { ++ return &pcd->ep0; ++ } ++ ++ for (i = 0; i < MAX_EPS_CHANNELS - 1; i++) { ++ if (pcd->in_ep[i].priv == handle) ++ return &pcd->in_ep[i]; ++ if (pcd->out_ep[i].priv == handle) ++ return &pcd->out_ep[i]; ++ } ++ ++ return NULL; ++} ++ ++/* USB Endpoint Operations */ ++/* ++ * The following sections briefly describe the behavior of the Gadget ++ * API endpoint operations implemented in the DWC_otg driver ++ * software. Detailed descriptions of the generic behavior of each of ++ * these functions can be found in the Linux header file ++ * include/linux/usb_gadget.h. ++ * ++ * The Gadget API provides wrapper functions for each of the function ++ * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper ++ * function, which then calls the underlying PCD function. The ++ * following sections are named according to the wrapper ++ * functions. Within each section, the corresponding DWC_otg PCD ++ * function name is specified. ++ * ++ */ ++ ++/** ++ * This function is called by the Gadget Driver for each EP to be ++ * configured for the current configuration (SET_CONFIGURATION). ++ * ++ * This function initializes the dwc_otg_ep_t data structure, and then ++ * calls dwc_otg_ep_activate. ++ */ ++static int ep_enable(struct usb_ep *usb_ep, ++ const struct usb_endpoint_descriptor *ep_desc) ++{ ++ int retval; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, ep_desc); ++ ++ if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) { ++ DWC_WARN("%s, bad ep or descriptor\n", __func__); ++ return -EINVAL; ++ } ++ if (usb_ep == &gadget_wrapper->ep0) { ++ DWC_WARN("%s, bad ep(0)\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* Check FIFO size? */ ++ if (!ep_desc->wMaxPacketSize) { ++ DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name); ++ return -ERANGE; ++ } ++ ++ if (!gadget_wrapper->driver || ++ gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) { ++ DWC_WARN("%s, bogus device state\n", __func__); ++ return -ESHUTDOWN; ++ } ++ ++ /* Delete after check - MAS */ ++#if 0 ++ nat = (uint32_t) ep_desc->wMaxPacketSize; ++ printk(KERN_ALERT "%s: nat (before) =%d\n", __func__, nat); ++ nat = (nat >> 11) & 0x03; ++ printk(KERN_ALERT "%s: nat (after) =%d\n", __func__, nat); ++#endif ++ retval = dwc_otg_pcd_ep_enable(gadget_wrapper->pcd, ++ (const uint8_t *)ep_desc, ++ (void *)usb_ep); ++ if (retval) { ++ DWC_WARN("dwc_otg_pcd_ep_enable failed\n"); ++ return -EINVAL; ++ } ++ ++ usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize); ++ ++ return 0; ++} ++ ++/** ++ * This function is called when an EP is disabled due to disconnect or ++ * change in configuration. Any pending requests will terminate with a ++ * status of -ESHUTDOWN. ++ * ++ * This function modifies the dwc_otg_ep_t data structure for this EP, ++ * and then calls dwc_otg_ep_deactivate. ++ */ ++static int ep_disable(struct usb_ep *usb_ep) ++{ ++ int retval; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, usb_ep); ++ if (!usb_ep) { ++ DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__, ++ usb_ep ? usb_ep->name : NULL); ++ return -EINVAL; ++ } ++ ++ retval = dwc_otg_pcd_ep_disable(gadget_wrapper->pcd, usb_ep); ++ if (retval) { ++ retval = -EINVAL; ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function allocates a request object to use with the specified ++ * endpoint. ++ * ++ * @param ep The endpoint to be used with with the request ++ * @param gfp_flags the GFP_* flags to use. ++ */ ++static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep, ++ gfp_t gfp_flags) ++{ ++ struct usb_request *usb_req; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d)\n", __func__, ep, gfp_flags); ++ if (0 == ep) { ++ DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n"); ++ return 0; ++ } ++ usb_req = kmalloc(sizeof(*usb_req), gfp_flags); ++ if (0 == usb_req) { ++ DWC_WARN("%s() %s\n", __func__, "request allocation failed!\n"); ++ return 0; ++ } ++ memset(usb_req, 0, sizeof(*usb_req)); ++ usb_req->dma = DWC_DMA_ADDR_INVALID; ++ ++ return usb_req; ++} ++ ++/** ++ * This function frees a request object. ++ * ++ * @param ep The endpoint associated with the request ++ * @param req The request being freed ++ */ ++static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req) ++{ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, ep, req); ++ ++ if (0 == ep || 0 == req) { ++ DWC_WARN("%s() %s\n", __func__, ++ "Invalid ep or req argument!\n"); ++ return; ++ } ++ ++ kfree(req); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++/** ++ * This function allocates an I/O buffer to be used for a transfer ++ * to/from the specified endpoint. ++ * ++ * @param usb_ep The endpoint to be used with with the request ++ * @param bytes The desired number of bytes for the buffer ++ * @param dma Pointer to the buffer's DMA address; must be valid ++ * @param gfp_flags the GFP_* flags to use. ++ * @return address of a new buffer or null is buffer could not be allocated. ++ */ ++static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *usb_ep, unsigned bytes, ++ dma_addr_t * dma, gfp_t gfp_flags) ++{ ++ void *buf; ++ dwc_otg_pcd_t *pcd = 0; ++ ++ pcd = gadget_wrapper->pcd; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d,%p,%0x)\n", __func__, usb_ep, bytes, ++ dma, gfp_flags); ++ ++ /* Check dword alignment */ ++ if ((bytes & 0x3UL) != 0) { ++ DWC_WARN("%s() Buffer size is not a multiple of" ++ "DWORD size (%d)", __func__, bytes); ++ } ++ ++ buf = dma_alloc_coherent(NULL, bytes, dma, gfp_flags); ++ ++ /* Check dword alignment */ ++ if (((int)buf & 0x3UL) != 0) { ++ DWC_WARN("%s() Buffer is not DWORD aligned (%p)", ++ __func__, buf); ++ } ++ ++ return buf; ++} ++ ++/** ++ * This function frees an I/O buffer that was allocated by alloc_buffer. ++ * ++ * @param usb_ep the endpoint associated with the buffer ++ * @param buf address of the buffer ++ * @param dma The buffer's DMA address ++ * @param bytes The number of bytes of the buffer ++ */ ++static void dwc_otg_pcd_free_buffer(struct usb_ep *usb_ep, void *buf, ++ dma_addr_t dma, unsigned bytes) ++{ ++ dwc_otg_pcd_t *pcd = 0; ++ ++ pcd = gadget_wrapper->pcd; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p,%0x,%d)\n", __func__, buf, dma, bytes); ++ ++ dma_free_coherent(NULL, bytes, buf, dma); ++} ++#endif ++ ++/** ++ * This function is used to submit an I/O Request to an EP. ++ * ++ * - When the request completes the request's completion callback ++ * is called to return the request to the driver. ++ * - An EP, except control EPs, may have multiple requests ++ * pending. ++ * - Once submitted the request cannot be examined or modified. ++ * - Each request is turned into one or more packets. ++ * - A BULK EP can queue any amount of data; the transfer is ++ * packetized. ++ * - Zero length Packets are specified with the request 'zero' ++ * flag. ++ */ ++static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req, ++ gfp_t gfp_flags) ++{ ++ dwc_otg_pcd_t *pcd; ++ struct dwc_otg_pcd_ep *ep = NULL; ++ int retval = 0, is_isoc_ep = 0; ++ dma_addr_t dma_addr = DWC_DMA_ADDR_INVALID; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p,%d)\n", ++ __func__, usb_ep, usb_req, gfp_flags); ++ ++ if (!usb_req || !usb_req->complete || !usb_req->buf) { ++ DWC_WARN("bad params\n"); ++ return -EINVAL; ++ } ++ ++ if (!usb_ep) { ++ DWC_WARN("bad ep\n"); ++ return -EINVAL; ++ } ++ ++ pcd = gadget_wrapper->pcd; ++ if (!gadget_wrapper->driver || ++ gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) { ++ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", ++ gadget_wrapper->gadget.speed); ++ DWC_WARN("bogus device state\n"); ++ return -ESHUTDOWN; ++ } ++ ++ DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n", ++ usb_ep->name, usb_req, usb_req->length, usb_req->buf); ++ ++ usb_req->status = -EINPROGRESS; ++ usb_req->actual = 0; ++ ++ ep = ep_from_handle(pcd, usb_ep); ++ if (ep == NULL) ++ is_isoc_ep = 0; ++ else ++ is_isoc_ep = (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) ? 1 : 0; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++ dma_addr = usb_req->dma; ++#else ++ if (GET_CORE_IF(pcd)->dma_enable) { ++ dwc_otg_device_t *otg_dev = gadget_wrapper->pcd->otg_dev; ++ struct device *dev = NULL; ++ ++ if (otg_dev != NULL) ++ dev = DWC_OTG_OS_GETDEV(otg_dev->os_dep); ++ ++ if (usb_req->length != 0 && ++ usb_req->dma == DWC_DMA_ADDR_INVALID) { ++ dma_addr = dma_map_single(dev, usb_req->buf, ++ usb_req->length, ++ ep->dwc_ep.is_in ? ++ DMA_TO_DEVICE: ++ DMA_FROM_DEVICE); ++ } ++ } ++#endif ++ ++#ifdef DWC_UTE_PER_IO ++ if (is_isoc_ep == 1) { ++ retval = dwc_otg_pcd_xiso_ep_queue(pcd, usb_ep, usb_req->buf, dma_addr, ++ usb_req->length, usb_req->zero, usb_req, ++ gfp_flags == GFP_ATOMIC ? 1 : 0, &usb_req->ext_req); ++ if (retval) ++ return -EINVAL; ++ ++ return 0; ++ } ++#endif ++ retval = dwc_otg_pcd_ep_queue(pcd, usb_ep, usb_req->buf, dma_addr, ++ usb_req->length, usb_req->zero, usb_req, ++ gfp_flags == GFP_ATOMIC ? 1 : 0); ++ if (retval) { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/** ++ * This function cancels an I/O request from an EP. ++ */ ++static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req) ++{ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, usb_req); ++ ++ if (!usb_ep || !usb_req) { ++ DWC_WARN("bad argument\n"); ++ return -EINVAL; ++ } ++ if (!gadget_wrapper->driver || ++ gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) { ++ DWC_WARN("bogus device state\n"); ++ return -ESHUTDOWN; ++ } ++ if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/** ++ * usb_ep_set_halt stalls an endpoint. ++ * ++ * usb_ep_clear_halt clears an endpoint halt and resets its data ++ * toggle. ++ * ++ * Both of these functions are implemented with the same underlying ++ * function. The behavior depends on the value argument. ++ * ++ * @param[in] usb_ep the Endpoint to halt or clear halt. ++ * @param[in] value ++ * - 0 means clear_halt. ++ * - 1 means set_halt, ++ * - 2 means clear stall lock flag. ++ * - 3 means set stall lock flag. ++ */ ++static int ep_halt(struct usb_ep *usb_ep, int value) ++{ ++ int retval = 0; ++ ++ DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value); ++ ++ if (!usb_ep) { ++ DWC_WARN("bad ep\n"); ++ return -EINVAL; ++ } ++ ++ retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value); ++ if (retval == -DWC_E_AGAIN) { ++ return -EAGAIN; ++ } else if (retval) { ++ retval = -EINVAL; ++ } ++ ++ return retval; ++} ++ ++//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) ++#if 0 ++/** ++ * ep_wedge: sets the halt feature and ignores clear requests ++ * ++ * @usb_ep: the endpoint being wedged ++ * ++ * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT) ++ * requests. If the gadget driver clears the halt status, it will ++ * automatically unwedge the endpoint. ++ * ++ * Returns zero on success, else negative errno. * ++ * Check usb_ep_set_wedge() at "usb_gadget.h" for details ++ */ ++static int ep_wedge(struct usb_ep *usb_ep) ++{ ++ int retval = 0; ++ ++ DWC_DEBUGPL(DBG_PCD, "WEDGE %s\n", usb_ep->name); ++ ++ if (!usb_ep) { ++ DWC_WARN("bad ep\n"); ++ return -EINVAL; ++ } ++ ++ retval = dwc_otg_pcd_ep_wedge(gadget_wrapper->pcd, usb_ep); ++ if (retval == -DWC_E_AGAIN) { ++ retval = -EAGAIN; ++ } else if (retval) { ++ retval = -EINVAL; ++ } ++ ++ return retval; ++} ++#endif ++ ++#ifdef DWC_EN_ISOC ++/** ++ * This function is used to submit an ISOC Transfer Request to an EP. ++ * ++ * - Every time a sync period completes the request's completion callback ++ * is called to provide data to the gadget driver. ++ * - Once submitted the request cannot be modified. ++ * - Each request is turned into periodic data packets untill ISO ++ * Transfer is stopped.. ++ */ ++static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req, ++ gfp_t gfp_flags) ++{ ++ int retval = 0; ++ ++ if (!req || !req->process_buffer || !req->buf0 || !req->buf1) { ++ DWC_WARN("bad params\n"); ++ return -EINVAL; ++ } ++ ++ if (!usb_ep) { ++ DWC_PRINTF("bad params\n"); ++ return -EINVAL; ++ } ++ ++ req->status = -EINPROGRESS; ++ ++ retval = ++ dwc_otg_pcd_iso_ep_start(gadget_wrapper->pcd, usb_ep, req->buf0, ++ req->buf1, req->dma0, req->dma1, ++ req->sync_frame, req->data_pattern_frame, ++ req->data_per_frame, ++ req-> ++ flags & USB_REQ_ISO_ASAP ? -1 : ++ req->start_frame, req->buf_proc_intrvl, ++ req, gfp_flags == GFP_ATOMIC ? 1 : 0); ++ ++ if (retval) { ++ return -EINVAL; ++ } ++ ++ return retval; ++} ++ ++/** ++ * This function stops ISO EP Periodic Data Transfer. ++ */ ++static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req) ++{ ++ int retval = 0; ++ if (!usb_ep) { ++ DWC_WARN("bad ep\n"); ++ } ++ ++ if (!gadget_wrapper->driver || ++ gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) { ++ DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", ++ gadget_wrapper->gadget.speed); ++ DWC_WARN("bogus device state\n"); ++ } ++ ++ dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req); ++ if (retval) { ++ retval = -EINVAL; ++ } ++ ++ return retval; ++} ++ ++static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep, ++ int packets, gfp_t gfp_flags) ++{ ++ struct usb_iso_request *pReq = NULL; ++ uint32_t req_size; ++ ++ req_size = sizeof(struct usb_iso_request); ++ req_size += ++ (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor))); ++ ++ pReq = kmalloc(req_size, gfp_flags); ++ if (!pReq) { ++ DWC_WARN("Can't allocate Iso Request\n"); ++ return 0; ++ } ++ pReq->iso_packet_desc0 = (void *)(pReq + 1); ++ ++ pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets; ++ ++ return pReq; ++} ++ ++static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req) ++{ ++ kfree(req); ++} ++ ++static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = { ++ .ep_ops = { ++ .enable = ep_enable, ++ .disable = ep_disable, ++ ++ .alloc_request = dwc_otg_pcd_alloc_request, ++ .free_request = dwc_otg_pcd_free_request, ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++ .alloc_buffer = dwc_otg_pcd_alloc_buffer, ++ .free_buffer = dwc_otg_pcd_free_buffer, ++#endif ++ ++ .queue = ep_queue, ++ .dequeue = ep_dequeue, ++ ++ .set_halt = ep_halt, ++ .fifo_status = 0, ++ .fifo_flush = 0, ++ }, ++ .iso_ep_start = iso_ep_start, ++ .iso_ep_stop = iso_ep_stop, ++ .alloc_iso_request = alloc_iso_request, ++ .free_iso_request = free_iso_request, ++}; ++ ++#else ++ ++ int (*enable) (struct usb_ep *ep, ++ const struct usb_endpoint_descriptor *desc); ++ int (*disable) (struct usb_ep *ep); ++ ++ struct usb_request *(*alloc_request) (struct usb_ep *ep, ++ gfp_t gfp_flags); ++ void (*free_request) (struct usb_ep *ep, struct usb_request *req); ++ ++ int (*queue) (struct usb_ep *ep, struct usb_request *req, ++ gfp_t gfp_flags); ++ int (*dequeue) (struct usb_ep *ep, struct usb_request *req); ++ ++ int (*set_halt) (struct usb_ep *ep, int value); ++ int (*set_wedge) (struct usb_ep *ep); ++ ++ int (*fifo_status) (struct usb_ep *ep); ++ void (*fifo_flush) (struct usb_ep *ep); ++static struct usb_ep_ops dwc_otg_pcd_ep_ops = { ++ .enable = ep_enable, ++ .disable = ep_disable, ++ ++ .alloc_request = dwc_otg_pcd_alloc_request, ++ .free_request = dwc_otg_pcd_free_request, ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++ .alloc_buffer = dwc_otg_pcd_alloc_buffer, ++ .free_buffer = dwc_otg_pcd_free_buffer, ++#else ++ /* .set_wedge = ep_wedge, */ ++ .set_wedge = NULL, /* uses set_halt instead */ ++#endif ++ ++ .queue = ep_queue, ++ .dequeue = ep_dequeue, ++ ++ .set_halt = ep_halt, ++ .fifo_status = 0, ++ .fifo_flush = 0, ++ ++}; ++ ++#endif /* _EN_ISOC_ */ ++/* Gadget Operations */ ++/** ++ * The following gadget operations will be implemented in the DWC_otg ++ * PCD. Functions in the API that are not described below are not ++ * implemented. ++ * ++ * The Gadget API provides wrapper functions for each of the function ++ * pointers defined in usb_gadget_ops. The Gadget Driver calls the ++ * wrapper function, which then calls the underlying PCD function. The ++ * following sections are named according to the wrapper functions ++ * (except for ioctl, which doesn't have a wrapper function). Within ++ * each section, the corresponding DWC_otg PCD function name is ++ * specified. ++ * ++ */ ++ ++/** ++ *Gets the USB Frame number of the last SOF. ++ */ ++static int get_frame_number(struct usb_gadget *gadget) ++{ ++ struct gadget_wrapper *d; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget); ++ ++ if (gadget == 0) { ++ return -ENODEV; ++ } ++ ++ d = container_of(gadget, struct gadget_wrapper, gadget); ++ return dwc_otg_pcd_get_frame_number(d->pcd); ++} ++ ++#ifdef CONFIG_USB_DWC_OTG_LPM ++static int test_lpm_enabled(struct usb_gadget *gadget) ++{ ++ struct gadget_wrapper *d; ++ ++ d = container_of(gadget, struct gadget_wrapper, gadget); ++ ++ return dwc_otg_pcd_is_lpm_enabled(d->pcd); ++} ++#endif ++ ++/** ++ * Initiates Session Request Protocol (SRP) to wakeup the host if no ++ * session is in progress. If a session is already in progress, but ++ * the device is suspended, remote wakeup signaling is started. ++ * ++ */ ++static int wakeup(struct usb_gadget *gadget) ++{ ++ struct gadget_wrapper *d; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget); ++ ++ if (gadget == 0) { ++ return -ENODEV; ++ } else { ++ d = container_of(gadget, struct gadget_wrapper, gadget); ++ } ++ dwc_otg_pcd_wakeup(d->pcd); ++ return 0; ++} ++ ++static const struct usb_gadget_ops dwc_otg_pcd_ops = { ++ .get_frame = get_frame_number, ++ .wakeup = wakeup, ++#ifdef CONFIG_USB_DWC_OTG_LPM ++ .lpm_support = test_lpm_enabled, ++#endif ++ // current versions must always be self-powered ++}; ++ ++static int _setup(dwc_otg_pcd_t * pcd, uint8_t * bytes) ++{ ++ int retval = -DWC_E_NOT_SUPPORTED; ++ if (gadget_wrapper->driver && gadget_wrapper->driver->setup) { ++ retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget, ++ (struct usb_ctrlrequest ++ *)bytes); ++ } ++ ++ if (retval == -ENOTSUPP) { ++ retval = -DWC_E_NOT_SUPPORTED; ++ } else if (retval < 0) { ++ retval = -DWC_E_INVALID; ++ } ++ ++ return retval; ++} ++ ++#ifdef DWC_EN_ISOC ++static int _isoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle, int proc_buf_num) ++{ ++ int i, packet_count; ++ struct usb_gadget_iso_packet_descriptor *iso_packet = 0; ++ struct usb_iso_request *iso_req = req_handle; ++ ++ if (proc_buf_num) { ++ iso_packet = iso_req->iso_packet_desc1; ++ } else { ++ iso_packet = iso_req->iso_packet_desc0; ++ } ++ packet_count = ++ dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle); ++ for (i = 0; i < packet_count; ++i) { ++ int status; ++ int actual; ++ int offset; ++ dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle, ++ i, &status, &actual, &offset); ++ switch (status) { ++ case -DWC_E_NO_DATA: ++ status = -ENODATA; ++ break; ++ default: ++ if (status) { ++ DWC_PRINTF("unknown status in isoc packet\n"); ++ } ++ ++ } ++ iso_packet[i].status = status; ++ iso_packet[i].offset = offset; ++ iso_packet[i].actual_length = actual; ++ } ++ ++ iso_req->status = 0; ++ iso_req->process_buffer(ep_handle, iso_req); ++ ++ return 0; ++} ++#endif /* DWC_EN_ISOC */ ++ ++#ifdef DWC_UTE_PER_IO ++/** ++ * Copy the contents of the extended request to the Linux usb_request's ++ * extended part and call the gadget's completion. ++ * ++ * @param pcd Pointer to the pcd structure ++ * @param ep_handle Void pointer to the usb_ep structure ++ * @param req_handle Void pointer to the usb_request structure ++ * @param status Request status returned from the portable logic ++ * @param ereq_port Void pointer to the extended request structure ++ * created in the the portable part that contains the ++ * results of the processed iso packets. ++ */ ++static int _xisoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle, int32_t status, void *ereq_port) ++{ ++ struct dwc_ute_iso_req_ext *ereqorg = NULL; ++ struct dwc_iso_xreq_port *ereqport = NULL; ++ struct dwc_ute_iso_packet_descriptor *desc_org = NULL; ++ int i; ++ struct usb_request *req; ++ //struct dwc_ute_iso_packet_descriptor * ++ //int status = 0; ++ ++ req = (struct usb_request *)req_handle; ++ ereqorg = &req->ext_req; ++ ereqport = (struct dwc_iso_xreq_port *)ereq_port; ++ desc_org = ereqorg->per_io_frame_descs; ++ ++ if (req && req->complete) { ++ /* Copy the request data from the portable logic to our request */ ++ for (i = 0; i < ereqport->pio_pkt_count; i++) { ++ desc_org[i].actual_length = ++ ereqport->per_io_frame_descs[i].actual_length; ++ desc_org[i].status = ++ ereqport->per_io_frame_descs[i].status; ++ } ++ ++ switch (status) { ++ case -DWC_E_SHUTDOWN: ++ req->status = -ESHUTDOWN; ++ break; ++ case -DWC_E_RESTART: ++ req->status = -ECONNRESET; ++ break; ++ case -DWC_E_INVALID: ++ req->status = -EINVAL; ++ break; ++ case -DWC_E_TIMEOUT: ++ req->status = -ETIMEDOUT; ++ break; ++ default: ++ req->status = status; ++ } ++ ++ /* And call the gadget's completion */ ++ req->complete(ep_handle, req); ++ } ++ ++ return 0; ++} ++#endif /* DWC_UTE_PER_IO */ ++ ++static int _complete(dwc_otg_pcd_t * pcd, void *ep_handle, ++ void *req_handle, int32_t status, uint32_t actual) ++{ ++ struct usb_request *req = (struct usb_request *)req_handle; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27) ++ struct dwc_otg_pcd_ep *ep = NULL; ++#endif ++ ++ if (req && req->complete) { ++ switch (status) { ++ case -DWC_E_SHUTDOWN: ++ req->status = -ESHUTDOWN; ++ break; ++ case -DWC_E_RESTART: ++ req->status = -ECONNRESET; ++ break; ++ case -DWC_E_INVALID: ++ req->status = -EINVAL; ++ break; ++ case -DWC_E_TIMEOUT: ++ req->status = -ETIMEDOUT; ++ break; ++ default: ++ req->status = status; ++ ++ } ++ ++ req->actual = actual; ++ DWC_SPINUNLOCK(pcd->lock); ++ req->complete(ep_handle, req); ++ DWC_SPINLOCK(pcd->lock); ++ } ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27) ++ ep = ep_from_handle(pcd, ep_handle); ++ if (GET_CORE_IF(pcd)->dma_enable) { ++ if (req->length != 0) { ++ dwc_otg_device_t *otg_dev = gadget_wrapper->pcd->otg_dev; ++ struct device *dev = NULL; ++ ++ if (otg_dev != NULL) ++ dev = DWC_OTG_OS_GETDEV(otg_dev->os_dep); ++ ++ dma_unmap_single(dev, req->dma, req->length, ++ ep->dwc_ep.is_in ? ++ DMA_TO_DEVICE: DMA_FROM_DEVICE); ++ } ++ } ++#endif ++ ++ return 0; ++} ++ ++static int _connect(dwc_otg_pcd_t * pcd, int speed) ++{ ++ gadget_wrapper->gadget.speed = speed; ++ return 0; ++} ++ ++static int _disconnect(dwc_otg_pcd_t * pcd) ++{ ++ if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) { ++ gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget); ++ } ++ return 0; ++} ++ ++static int _resume(dwc_otg_pcd_t * pcd) ++{ ++ if (gadget_wrapper->driver && gadget_wrapper->driver->resume) { ++ gadget_wrapper->driver->resume(&gadget_wrapper->gadget); ++ } ++ ++ return 0; ++} ++ ++static int _suspend(dwc_otg_pcd_t * pcd) ++{ ++ if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) { ++ gadget_wrapper->driver->suspend(&gadget_wrapper->gadget); ++ } ++ return 0; ++} ++ ++/** ++ * This function updates the otg values in the gadget structure. ++ */ ++static int _hnp_changed(dwc_otg_pcd_t * pcd) ++{ ++ ++ if (!gadget_wrapper->gadget.is_otg) ++ return 0; ++ ++ gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd); ++ gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd); ++ gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd); ++ return 0; ++} ++ ++static int _reset(dwc_otg_pcd_t * pcd) ++{ ++ return 0; ++} ++ ++#ifdef DWC_UTE_CFI ++static int _cfi_setup(dwc_otg_pcd_t * pcd, void *cfi_req) ++{ ++ int retval = -DWC_E_INVALID; ++ if (gadget_wrapper->driver->cfi_feature_setup) { ++ retval = ++ gadget_wrapper->driver-> ++ cfi_feature_setup(&gadget_wrapper->gadget, ++ (struct cfi_usb_ctrlrequest *)cfi_req); ++ } ++ ++ return retval; ++} ++#endif ++ ++static const struct dwc_otg_pcd_function_ops fops = { ++ .complete = _complete, ++#ifdef DWC_EN_ISOC ++ .isoc_complete = _isoc_complete, ++#endif ++ .setup = _setup, ++ .disconnect = _disconnect, ++ .connect = _connect, ++ .resume = _resume, ++ .suspend = _suspend, ++ .hnp_changed = _hnp_changed, ++ .reset = _reset, ++#ifdef DWC_UTE_CFI ++ .cfi_setup = _cfi_setup, ++#endif ++#ifdef DWC_UTE_PER_IO ++ .xisoc_complete = _xisoc_complete, ++#endif ++}; ++ ++/** ++ * This function is the top level PCD interrupt handler. ++ */ ++static irqreturn_t dwc_otg_pcd_irq(int irq, void *dev) ++{ ++ dwc_otg_pcd_t *pcd = dev; ++ int32_t retval = IRQ_NONE; ++ ++ retval = dwc_otg_pcd_handle_intr(pcd); ++ if (retval != 0) { ++ S3C2410X_CLEAR_EINTPEND(); ++ } ++ return IRQ_RETVAL(retval); ++} ++ ++/** ++ * This function initialized the usb_ep structures to there default ++ * state. ++ * ++ * @param d Pointer on gadget_wrapper. ++ */ ++void gadget_add_eps(struct gadget_wrapper *d) ++{ ++ static const char *names[] = { ++ ++ "ep0", ++ "ep1in", ++ "ep2in", ++ "ep3in", ++ "ep4in", ++ "ep5in", ++ "ep6in", ++ "ep7in", ++ "ep8in", ++ "ep9in", ++ "ep10in", ++ "ep11in", ++ "ep12in", ++ "ep13in", ++ "ep14in", ++ "ep15in", ++ "ep1out", ++ "ep2out", ++ "ep3out", ++ "ep4out", ++ "ep5out", ++ "ep6out", ++ "ep7out", ++ "ep8out", ++ "ep9out", ++ "ep10out", ++ "ep11out", ++ "ep12out", ++ "ep13out", ++ "ep14out", ++ "ep15out" ++ }; ++ ++ int i; ++ struct usb_ep *ep; ++ int8_t dev_endpoints; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__); ++ ++ INIT_LIST_HEAD(&d->gadget.ep_list); ++ d->gadget.ep0 = &d->ep0; ++ d->gadget.speed = USB_SPEED_UNKNOWN; ++ ++ INIT_LIST_HEAD(&d->gadget.ep0->ep_list); ++ ++ /** ++ * Initialize the EP0 structure. ++ */ ++ ep = &d->ep0; ++ ++ /* Init the usb_ep structure. */ ++ ep->name = names[0]; ++ ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops; ++ ++ /** ++ * @todo NGS: What should the max packet size be set to ++ * here? Before EP type is set? ++ */ ++ ep->maxpacket = MAX_PACKET_SIZE; ++ dwc_otg_pcd_ep_enable(d->pcd, NULL, ep); ++ ++ list_add_tail(&ep->ep_list, &d->gadget.ep_list); ++ ++ /** ++ * Initialize the EP structures. ++ */ ++ dev_endpoints = d->pcd->core_if->dev_if->num_in_eps; ++ ++ for (i = 0; i < dev_endpoints; i++) { ++ ep = &d->in_ep[i]; ++ ++ /* Init the usb_ep structure. */ ++ ep->name = names[d->pcd->in_ep[i].dwc_ep.num]; ++ ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops; ++ ++ /** ++ * @todo NGS: What should the max packet size be set to ++ * here? Before EP type is set? ++ */ ++ ep->maxpacket = MAX_PACKET_SIZE; ++ list_add_tail(&ep->ep_list, &d->gadget.ep_list); ++ } ++ ++ dev_endpoints = d->pcd->core_if->dev_if->num_out_eps; ++ ++ for (i = 0; i < dev_endpoints; i++) { ++ ep = &d->out_ep[i]; ++ ++ /* Init the usb_ep structure. */ ++ ep->name = names[15 + d->pcd->out_ep[i].dwc_ep.num]; ++ ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops; ++ ++ /** ++ * @todo NGS: What should the max packet size be set to ++ * here? Before EP type is set? ++ */ ++ ep->maxpacket = MAX_PACKET_SIZE; ++ ++ list_add_tail(&ep->ep_list, &d->gadget.ep_list); ++ } ++ ++ /* remove ep0 from the list. There is a ep0 pointer. */ ++ list_del_init(&d->ep0.ep_list); ++ ++ d->ep0.maxpacket = MAX_EP0_SIZE; ++} ++ ++/** ++ * This function releases the Gadget device. ++ * required by device_unregister(). ++ * ++ * @todo Should this do something? Should it free the PCD? ++ */ ++static void dwc_otg_pcd_gadget_release(struct device *dev) ++{ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev); ++} ++ ++static struct gadget_wrapper *alloc_wrapper(dwc_bus_dev_t *_dev) ++{ ++ static char pcd_name[] = "dwc_otg_pcd"; ++ dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev); ++ struct gadget_wrapper *d; ++ int retval; ++ ++ d = DWC_ALLOC(sizeof(*d)); ++ if (d == NULL) { ++ return NULL; ++ } ++ ++ memset(d, 0, sizeof(*d)); ++ ++ d->gadget.name = pcd_name; ++ d->pcd = otg_dev->pcd; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) ++ strcpy(d->gadget.dev.bus_id, "gadget"); ++#else ++ dev_set_name(&d->gadget.dev, "%s", "gadget"); ++#endif ++ ++ d->gadget.dev.parent = &_dev->dev; ++ d->gadget.dev.release = dwc_otg_pcd_gadget_release; ++ d->gadget.ops = &dwc_otg_pcd_ops; ++ d->gadget.max_speed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd) ? USB_SPEED_HIGH:USB_SPEED_FULL; ++ d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd); ++ ++ d->driver = 0; ++ /* Register the gadget device */ ++ retval = device_register(&d->gadget.dev); ++ if (retval != 0) { ++ DWC_ERROR("device_register failed\n"); ++ DWC_FREE(d); ++ return NULL; ++ } ++ ++ return d; ++} ++ ++static void free_wrapper(struct gadget_wrapper *d) ++{ ++ if (d->driver) { ++ /* should have been done already by driver model core */ ++ DWC_WARN("driver '%s' is still registered\n", ++ d->driver->driver.name); ++ usb_gadget_unregister_driver(d->driver); ++ } ++ ++ device_unregister(&d->gadget.dev); ++ DWC_FREE(d); ++} ++ ++/** ++ * This function initialized the PCD portion of the driver. ++ * ++ */ ++int pcd_init(dwc_bus_dev_t *_dev) ++{ ++ dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev); ++ int retval = 0; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p) otg_dev=%p\n", __func__, _dev, otg_dev); ++ ++ otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if); ++ ++ if (!otg_dev->pcd) { ++ DWC_ERROR("dwc_otg_pcd_init failed\n"); ++ return -ENOMEM; ++ } ++ ++ otg_dev->pcd->otg_dev = otg_dev; ++ gadget_wrapper = alloc_wrapper(_dev); ++ ++ /* ++ * Initialize EP structures ++ */ ++ gadget_add_eps(gadget_wrapper); ++ /* ++ * Setup interupt handler ++ */ ++#ifdef PLATFORM_INTERFACE ++ DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", ++ platform_get_irq(_dev, 0)); ++ retval = request_irq(platform_get_irq(_dev, 0), dwc_otg_pcd_irq, ++ IRQF_SHARED, gadget_wrapper->gadget.name, ++ otg_dev->pcd); ++ if (retval != 0) { ++ DWC_ERROR("request of irq%d failed\n", ++ platform_get_irq(_dev, 0)); ++ free_wrapper(gadget_wrapper); ++ return -EBUSY; ++ } ++#else ++ DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", ++ _dev->irq); ++ retval = request_irq(_dev->irq, dwc_otg_pcd_irq, ++ IRQF_SHARED | IRQF_DISABLED, ++ gadget_wrapper->gadget.name, otg_dev->pcd); ++ if (retval != 0) { ++ DWC_ERROR("request of irq%d failed\n", _dev->irq); ++ free_wrapper(gadget_wrapper); ++ return -EBUSY; ++ } ++#endif ++ ++ dwc_otg_pcd_start(gadget_wrapper->pcd, &fops); ++ ++ return retval; ++} ++ ++/** ++ * Cleanup the PCD. ++ */ ++void pcd_remove(dwc_bus_dev_t *_dev) ++{ ++ dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev); ++ dwc_otg_pcd_t *pcd = otg_dev->pcd; ++ ++ DWC_DEBUGPL(DBG_PCDV, "%s(%p) otg_dev %p\n", __func__, _dev, otg_dev); ++ ++ /* ++ * Free the IRQ ++ */ ++#ifdef PLATFORM_INTERFACE ++ free_irq(platform_get_irq(_dev, 0), pcd); ++#else ++ free_irq(_dev->irq, pcd); ++#endif ++ dwc_otg_pcd_remove(otg_dev->pcd); ++ free_wrapper(gadget_wrapper); ++ otg_dev->pcd = 0; ++} ++ ++/** ++ * This function registers a gadget driver with the PCD. ++ * ++ * When a driver is successfully registered, it will receive control ++ * requests including set_configuration(), which enables non-control ++ * requests. then usb traffic follows until a disconnect is reported. ++ * then a host may connect again, or the driver might get unbound. ++ * ++ * @param driver The driver being registered ++ * @param bind The bind function of gadget driver ++ */ ++ ++int usb_gadget_probe_driver(struct usb_gadget_driver *driver) ++{ ++ int retval; ++ ++ DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", ++ driver->driver.name); ++ ++ if (!driver || driver->max_speed == USB_SPEED_UNKNOWN || ++ !driver->bind || ++ !driver->unbind || !driver->disconnect || !driver->setup) { ++ DWC_DEBUGPL(DBG_PCDV, "EINVAL\n"); ++ return -EINVAL; ++ } ++ if (gadget_wrapper == 0) { ++ DWC_DEBUGPL(DBG_PCDV, "ENODEV\n"); ++ return -ENODEV; ++ } ++ if (gadget_wrapper->driver != 0) { ++ DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver); ++ return -EBUSY; ++ } ++ ++ /* hook up the driver */ ++ gadget_wrapper->driver = driver; ++ gadget_wrapper->gadget.dev.driver = &driver->driver; ++ ++ DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name); ++ retval = driver->bind(&gadget_wrapper->gadget, gadget_wrapper->driver); ++ if (retval) { ++ DWC_ERROR("bind to driver %s --> error %d\n", ++ driver->driver.name, retval); ++ gadget_wrapper->driver = 0; ++ gadget_wrapper->gadget.dev.driver = 0; ++ return retval; ++ } ++ DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n", ++ driver->driver.name); ++ return 0; ++} ++EXPORT_SYMBOL(usb_gadget_probe_driver); ++ ++/** ++ * This function unregisters a gadget driver ++ * ++ * @param driver The driver being unregistered ++ */ ++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ++{ ++ //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); ++ ++ if (gadget_wrapper == 0) { ++ DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__, ++ -ENODEV); ++ return -ENODEV; ++ } ++ if (driver == 0 || driver != gadget_wrapper->driver) { ++ DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__, ++ -EINVAL); ++ return -EINVAL; ++ } ++ ++ driver->unbind(&gadget_wrapper->gadget); ++ gadget_wrapper->driver = 0; ++ ++ DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", driver->driver.name); ++ return 0; ++} ++ ++EXPORT_SYMBOL(usb_gadget_unregister_driver); ++ ++#endif /* DWC_HOST_ONLY */ +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_regs.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/dwc_otg_regs.h 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,2550 @@ ++/* ========================================================================== ++ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_regs.h $ ++ * $Revision: #98 $ ++ * $Date: 2012/08/10 $ ++ * $Change: 2047372 $ ++ * ++ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, ++ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless ++ * otherwise expressly agreed to in writing between Synopsys and you. ++ * ++ * The Software IS NOT an item of Licensed Software or Licensed Product under ++ * any End User Software License Agreement or Agreement for Licensed Product ++ * with Synopsys or any supplement thereto. You are permitted to use and ++ * redistribute this Software in source and binary forms, with or without ++ * modification, provided that redistributions of source code must retain this ++ * notice. You may not view, use, disclose, copy or distribute this file or ++ * any information contained herein except pursuant to this license grant from ++ * Synopsys. If you do not agree with this notice, including the disclaimer ++ * below, then you are not authorized to use the Software. ++ * ++ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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. ++ * ========================================================================== */ ++ ++#ifndef __DWC_OTG_REGS_H__ ++#define __DWC_OTG_REGS_H__ ++ ++#include "dwc_otg_core_if.h" ++ ++/** ++ * @file ++ * ++ * This file contains the data structures for accessing the DWC_otg core registers. ++ * ++ * The application interfaces with the HS OTG core by reading from and ++ * writing to the Control and Status Register (CSR) space through the ++ * AHB Slave interface. These registers are 32 bits wide, and the ++ * addresses are 32-bit-block aligned. ++ * CSRs are classified as follows: ++ * - Core Global Registers ++ * - Device Mode Registers ++ * - Device Global Registers ++ * - Device Endpoint Specific Registers ++ * - Host Mode Registers ++ * - Host Global Registers ++ * - Host Port CSRs ++ * - Host Channel Specific Registers ++ * ++ * Only the Core Global registers can be accessed in both Device and ++ * Host modes. When the HS OTG core is operating in one mode, either ++ * Device or Host, the application must not access registers from the ++ * other mode. When the core switches from one mode to another, the ++ * registers in the new mode of operation must be reprogrammed as they ++ * would be after a power-on reset. ++ */ ++ ++/****************************************************************************/ ++/** DWC_otg Core registers . ++ * The dwc_otg_core_global_regs structure defines the size ++ * and relative field offsets for the Core Global registers. ++ */ ++typedef struct dwc_otg_core_global_regs { ++ /** OTG Control and Status Register. Offset: 000h */ ++ volatile uint32_t gotgctl; ++ /** OTG Interrupt Register. Offset: 004h */ ++ volatile uint32_t gotgint; ++ /**Core AHB Configuration Register. Offset: 008h */ ++ volatile uint32_t gahbcfg; ++ ++#define DWC_GLBINTRMASK 0x0001 ++#define DWC_DMAENABLE 0x0020 ++#define DWC_NPTXEMPTYLVL_EMPTY 0x0080 ++#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000 ++#define DWC_PTXEMPTYLVL_EMPTY 0x0100 ++#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000 ++ ++ /**Core USB Configuration Register. Offset: 00Ch */ ++ volatile uint32_t gusbcfg; ++ /**Core Reset Register. Offset: 010h */ ++ volatile uint32_t grstctl; ++ /**Core Interrupt Register. Offset: 014h */ ++ volatile uint32_t gintsts; ++ /**Core Interrupt Mask Register. Offset: 018h */ ++ volatile uint32_t gintmsk; ++ /**Receive Status Queue Read Register (Read Only). Offset: 01Ch */ ++ volatile uint32_t grxstsr; ++ /**Receive Status Queue Read & POP Register (Read Only). Offset: 020h*/ ++ volatile uint32_t grxstsp; ++ /**Receive FIFO Size Register. Offset: 024h */ ++ volatile uint32_t grxfsiz; ++ /**Non Periodic Transmit FIFO Size Register. Offset: 028h */ ++ volatile uint32_t gnptxfsiz; ++ /**Non Periodic Transmit FIFO/Queue Status Register (Read ++ * Only). Offset: 02Ch */ ++ volatile uint32_t gnptxsts; ++ /**I2C Access Register. Offset: 030h */ ++ volatile uint32_t gi2cctl; ++ /**PHY Vendor Control Register. Offset: 034h */ ++ volatile uint32_t gpvndctl; ++ /**General Purpose Input/Output Register. Offset: 038h */ ++ volatile uint32_t ggpio; ++ /**User ID Register. Offset: 03Ch */ ++ volatile uint32_t guid; ++ /**Synopsys ID Register (Read Only). Offset: 040h */ ++ volatile uint32_t gsnpsid; ++ /**User HW Config1 Register (Read Only). Offset: 044h */ ++ volatile uint32_t ghwcfg1; ++ /**User HW Config2 Register (Read Only). Offset: 048h */ ++ volatile uint32_t ghwcfg2; ++#define DWC_SLAVE_ONLY_ARCH 0 ++#define DWC_EXT_DMA_ARCH 1 ++#define DWC_INT_DMA_ARCH 2 ++ ++#define DWC_MODE_HNP_SRP_CAPABLE 0 ++#define DWC_MODE_SRP_ONLY_CAPABLE 1 ++#define DWC_MODE_NO_HNP_SRP_CAPABLE 2 ++#define DWC_MODE_SRP_CAPABLE_DEVICE 3 ++#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4 ++#define DWC_MODE_SRP_CAPABLE_HOST 5 ++#define DWC_MODE_NO_SRP_CAPABLE_HOST 6 ++ ++ /**User HW Config3 Register (Read Only). Offset: 04Ch */ ++ volatile uint32_t ghwcfg3; ++ /**User HW Config4 Register (Read Only). Offset: 050h*/ ++ volatile uint32_t ghwcfg4; ++ /** Core LPM Configuration register Offset: 054h*/ ++ volatile uint32_t glpmcfg; ++ /** Global PowerDn Register Offset: 058h */ ++ volatile uint32_t gpwrdn; ++ /** Global DFIFO SW Config Register Offset: 05Ch */ ++ volatile uint32_t gdfifocfg; ++ /** ADP Control Register Offset: 060h */ ++ volatile uint32_t adpctl; ++ /** Reserved Offset: 064h-0FFh */ ++ volatile uint32_t reserved39[39]; ++ /** Host Periodic Transmit FIFO Size Register. Offset: 100h */ ++ volatile uint32_t hptxfsiz; ++ /** Device Periodic Transmit FIFO#n Register if dedicated fifos are disabled, ++ otherwise Device Transmit FIFO#n Register. ++ * Offset: 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15 (1<=n<=15). */ ++ volatile uint32_t dtxfsiz[15]; ++} dwc_otg_core_global_regs_t; ++ ++/** ++ * This union represents the bit fields of the Core OTG Control ++ * and Status Register (GOTGCTL). Set the bits using the bit ++ * fields then write the d32 value to the register. ++ */ ++typedef union gotgctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned sesreqscs:1; ++ unsigned sesreq:1; ++ unsigned vbvalidoven:1; ++ unsigned vbvalidovval:1; ++ unsigned avalidoven:1; ++ unsigned avalidovval:1; ++ unsigned bvalidoven:1; ++ unsigned bvalidovval:1; ++ unsigned hstnegscs:1; ++ unsigned hnpreq:1; ++ unsigned hstsethnpen:1; ++ unsigned devhnpen:1; ++ unsigned reserved12_15:4; ++ unsigned conidsts:1; ++ unsigned dbnctime:1; ++ unsigned asesvld:1; ++ unsigned bsesvld:1; ++ unsigned otgver:1; ++ unsigned reserved1:1; ++ unsigned multvalidbc:5; ++ unsigned chirpen:1; ++ unsigned reserved28_31:4; ++ } b; ++} gotgctl_data_t; ++ ++/** ++ * This union represents the bit fields of the Core OTG Interrupt Register ++ * (GOTGINT). Set/clear the bits using the bit fields then write the d32 ++ * value to the register. ++ */ ++typedef union gotgint_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Current Mode */ ++ unsigned reserved0_1:2; ++ ++ /** Session End Detected */ ++ unsigned sesenddet:1; ++ ++ unsigned reserved3_7:5; ++ ++ /** Session Request Success Status Change */ ++ unsigned sesreqsucstschng:1; ++ /** Host Negotiation Success Status Change */ ++ unsigned hstnegsucstschng:1; ++ ++ unsigned reserved10_16:7; ++ ++ /** Host Negotiation Detected */ ++ unsigned hstnegdet:1; ++ /** A-Device Timeout Change */ ++ unsigned adevtoutchng:1; ++ /** Debounce Done */ ++ unsigned debdone:1; ++ /** Multi-Valued input changed */ ++ unsigned mvic:1; ++ ++ unsigned reserved31_21:11; ++ ++ } b; ++} gotgint_data_t; ++ ++/** ++ * This union represents the bit fields of the Core AHB Configuration ++ * Register (GAHBCFG). Set/clear the bits using the bit fields then ++ * write the d32 value to the register. ++ */ ++typedef union gahbcfg_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned glblintrmsk:1; ++#define DWC_GAHBCFG_GLBINT_ENABLE 1 ++ ++ unsigned hburstlen:4; ++#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0 ++#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1 ++#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3 ++#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5 ++#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7 ++ ++ unsigned dmaenable:1; ++#define DWC_GAHBCFG_DMAENABLE 1 ++ unsigned reserved:1; ++ unsigned nptxfemplvl_txfemplvl:1; ++ unsigned ptxfemplvl:1; ++#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1 ++#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 ++ unsigned reserved9_20:12; ++ unsigned remmemsupp:1; ++ unsigned notialldmawrit:1; ++ unsigned ahbsingle:1; ++ unsigned reserved24_31:8; ++ } b; ++} gahbcfg_data_t; ++ ++/** ++ * This union represents the bit fields of the Core USB Configuration ++ * Register (GUSBCFG). Set the bits using the bit fields then write ++ * the d32 value to the register. ++ */ ++typedef union gusbcfg_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned toutcal:3; ++ unsigned phyif:1; ++ unsigned ulpi_utmi_sel:1; ++ unsigned fsintf:1; ++ unsigned physel:1; ++ unsigned ddrsel:1; ++ unsigned srpcap:1; ++ unsigned hnpcap:1; ++ unsigned usbtrdtim:4; ++ unsigned reserved1:1; ++ unsigned phylpwrclksel:1; ++ unsigned otgutmifssel:1; ++ unsigned ulpi_fsls:1; ++ unsigned ulpi_auto_res:1; ++ unsigned ulpi_clk_sus_m:1; ++ unsigned ulpi_ext_vbus_drv:1; ++ unsigned ulpi_int_vbus_indicator:1; ++ unsigned term_sel_dl_pulse:1; ++ unsigned indicator_complement:1; ++ unsigned indicator_pass_through:1; ++ unsigned ulpi_int_prot_dis:1; ++ unsigned ic_usb_cap:1; ++ unsigned ic_traffic_pull_remove:1; ++ unsigned tx_end_delay:1; ++ unsigned force_host_mode:1; ++ unsigned force_dev_mode:1; ++ unsigned reserved31:1; ++ } b; ++} gusbcfg_data_t; ++ ++/** ++ * This union represents the bit fields of the Core Reset Register ++ * (GRSTCTL). Set/clear the bits using the bit fields then write the ++ * d32 value to the register. ++ */ ++typedef union grstctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Core Soft Reset (CSftRst) (Device and Host) ++ * ++ * The application can flush the control logic in the ++ * entire core using this bit. This bit resets the ++ * pipelines in the AHB Clock domain as well as the ++ * PHY Clock domain. ++ * ++ * The state machines are reset to an IDLE state, the ++ * control bits in the CSRs are cleared, all the ++ * transmit FIFOs and the receive FIFO are flushed. ++ * ++ * The status mask bits that control the generation of ++ * the interrupt, are cleared, to clear the ++ * interrupt. The interrupt status bits are not ++ * cleared, so the application can get the status of ++ * any events that occurred in the core after it has ++ * set this bit. ++ * ++ * Any transactions on the AHB are terminated as soon ++ * as possible following the protocol. Any ++ * transactions on the USB are terminated immediately. ++ * ++ * The configuration settings in the CSRs are ++ * unchanged, so the software doesn't have to ++ * reprogram these registers (Device ++ * Configuration/Host Configuration/Core System ++ * Configuration/Core PHY Configuration). ++ * ++ * The application can write to this bit, any time it ++ * wants to reset the core. This is a self clearing ++ * bit and the core clears this bit after all the ++ * necessary logic is reset in the core, which may ++ * take several clocks, depending on the current state ++ * of the core. ++ */ ++ unsigned csftrst:1; ++ /** Hclk Soft Reset ++ * ++ * The application uses this bit to reset the control logic in ++ * the AHB clock domain. Only AHB clock domain pipelines are ++ * reset. ++ */ ++ unsigned hsftrst:1; ++ /** Host Frame Counter Reset (Host Only)
++ * ++ * The application can reset the (micro)frame number ++ * counter inside the core, using this bit. When the ++ * (micro)frame counter is reset, the subsequent SOF ++ * sent out by the core, will have a (micro)frame ++ * number of 0. ++ */ ++ unsigned hstfrm:1; ++ /** In Token Sequence Learning Queue Flush ++ * (INTknQFlsh) (Device Only) ++ */ ++ unsigned intknqflsh:1; ++ /** RxFIFO Flush (RxFFlsh) (Device and Host) ++ * ++ * The application can flush the entire Receive FIFO ++ * using this bit. The application must first ++ * ensure that the core is not in the middle of a ++ * transaction. The application should write into ++ * this bit, only after making sure that neither the ++ * DMA engine is reading from the RxFIFO nor the MAC ++ * is writing the data in to the FIFO. The ++ * application should wait until the bit is cleared ++ * before performing any other operations. This bit ++ * will takes 8 clocks (slowest of PHY or AHB clock) ++ * to clear. ++ */ ++ unsigned rxfflsh:1; ++ /** TxFIFO Flush (TxFFlsh) (Device and Host). ++ * ++ * This bit is used to selectively flush a single or ++ * all transmit FIFOs. The application must first ++ * ensure that the core is not in the middle of a ++ * transaction. The application should write into ++ * this bit, only after making sure that neither the ++ * DMA engine is writing into the TxFIFO nor the MAC ++ * is reading the data out of the FIFO. The ++ * application should wait until the core clears this ++ * bit, before performing any operations. This bit ++ * will takes 8 clocks (slowest of PHY or AHB clock) ++ * to clear. ++ */ ++ unsigned txfflsh:1; ++ ++ /** TxFIFO Number (TxFNum) (Device and Host). ++ * ++ * This is the FIFO number which needs to be flushed, ++ * using the TxFIFO Flush bit. This field should not ++ * be changed until the TxFIFO Flush bit is cleared by ++ * the core. ++ * - 0x0 : Non Periodic TxFIFO Flush ++ * - 0x1 : Periodic TxFIFO #1 Flush in device mode ++ * or Periodic TxFIFO in host mode ++ * - 0x2 : Periodic TxFIFO #2 Flush in device mode. ++ * - ... ++ * - 0xF : Periodic TxFIFO #15 Flush in device mode ++ * - 0x10: Flush all the Transmit NonPeriodic and ++ * Transmit Periodic FIFOs in the core ++ */ ++ unsigned txfnum:5; ++ /** Reserved */ ++ unsigned reserved11_29:19; ++ /** DMA Request Signal. Indicated DMA request is in ++ * probress. Used for debug purpose. */ ++ unsigned dmareq:1; ++ /** AHB Master Idle. Indicates the AHB Master State ++ * Machine is in IDLE condition. */ ++ unsigned ahbidle:1; ++ } b; ++} grstctl_t; ++ ++/** ++ * This union represents the bit fields of the Core Interrupt Mask ++ * Register (GINTMSK). Set/clear the bits using the bit fields then ++ * write the d32 value to the register. ++ */ ++typedef union gintmsk_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned reserved0:1; ++ unsigned modemismatch:1; ++ unsigned otgintr:1; ++ unsigned sofintr:1; ++ unsigned rxstsqlvl:1; ++ unsigned nptxfempty:1; ++ unsigned ginnakeff:1; ++ unsigned goutnakeff:1; ++ unsigned ulpickint:1; ++ unsigned i2cintr:1; ++ unsigned erlysuspend:1; ++ unsigned usbsuspend:1; ++ unsigned usbreset:1; ++ unsigned enumdone:1; ++ unsigned isooutdrop:1; ++ unsigned eopframe:1; ++ unsigned restoredone:1; ++ unsigned epmismatch:1; ++ unsigned inepintr:1; ++ unsigned outepintr:1; ++ unsigned incomplisoin:1; ++ unsigned incomplisoout:1; ++ unsigned fetsusp:1; ++ unsigned resetdet:1; ++ unsigned portintr:1; ++ unsigned hcintr:1; ++ unsigned ptxfempty:1; ++ unsigned lpmtranrcvd:1; ++ unsigned conidstschng:1; ++ unsigned disconnect:1; ++ unsigned sessreqintr:1; ++ unsigned wkupintr:1; ++ } b; ++} gintmsk_data_t; ++/** ++ * This union represents the bit fields of the Core Interrupt Register ++ * (GINTSTS). Set/clear the bits using the bit fields then write the ++ * d32 value to the register. ++ */ ++typedef union gintsts_data { ++ /** raw register data */ ++ uint32_t d32; ++#define DWC_SOF_INTR_MASK 0x0008 ++ /** register bits */ ++ struct { ++#define DWC_HOST_MODE 1 ++ unsigned curmode:1; ++ unsigned modemismatch:1; ++ unsigned otgintr:1; ++ unsigned sofintr:1; ++ unsigned rxstsqlvl:1; ++ unsigned nptxfempty:1; ++ unsigned ginnakeff:1; ++ unsigned goutnakeff:1; ++ unsigned ulpickint:1; ++ unsigned i2cintr:1; ++ unsigned erlysuspend:1; ++ unsigned usbsuspend:1; ++ unsigned usbreset:1; ++ unsigned enumdone:1; ++ unsigned isooutdrop:1; ++ unsigned eopframe:1; ++ unsigned restoredone:1; ++ unsigned epmismatch:1; ++ unsigned inepint:1; ++ unsigned outepintr:1; ++ unsigned incomplisoin:1; ++ unsigned incomplisoout:1; ++ unsigned fetsusp:1; ++ unsigned resetdet:1; ++ unsigned portintr:1; ++ unsigned hcintr:1; ++ unsigned ptxfempty:1; ++ unsigned lpmtranrcvd:1; ++ unsigned conidstschng:1; ++ unsigned disconnect:1; ++ unsigned sessreqintr:1; ++ unsigned wkupintr:1; ++ } b; ++} gintsts_data_t; ++ ++/** ++ * This union represents the bit fields in the Device Receive Status Read and ++ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 ++ * element then read out the bits using the bit elements. ++ */ ++typedef union device_grxsts_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned epnum:4; ++ unsigned bcnt:11; ++ unsigned dpid:2; ++ ++#define DWC_STS_DATA_UPDT 0x2 // OUT Data Packet ++#define DWC_STS_XFER_COMP 0x3 // OUT Data Transfer Complete ++ ++#define DWC_DSTS_GOUT_NAK 0x1 // Global OUT NAK ++#define DWC_DSTS_SETUP_COMP 0x4 // Setup Phase Complete ++#define DWC_DSTS_SETUP_UPDT 0x6 // SETUP Packet ++ unsigned pktsts:4; ++ unsigned fn:4; ++ unsigned reserved25_31:7; ++ } b; ++} device_grxsts_data_t; ++ ++/** ++ * This union represents the bit fields in the Host Receive Status Read and ++ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 ++ * element then read out the bits using the bit elements. ++ */ ++typedef union host_grxsts_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned chnum:4; ++ unsigned bcnt:11; ++ unsigned dpid:2; ++ ++ unsigned pktsts:4; ++#define DWC_GRXSTS_PKTSTS_IN 0x2 ++#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3 ++#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5 ++#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7 ++ ++ unsigned reserved21_31:11; ++ } b; ++} host_grxsts_data_t; ++ ++/** ++ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ, ++ * GNPTXFSIZ, DPTXFSIZn, DIEPTXFn). Read the register into the d32 element ++ * then read out the bits using the bit elements. ++ */ ++typedef union fifosize_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned startaddr:16; ++ unsigned depth:16; ++ } b; ++} fifosize_data_t; ++ ++/** ++ * This union represents the bit fields in the Non-Periodic Transmit ++ * FIFO/Queue Status Register (GNPTXSTS). Read the register into the ++ * d32 element then read out the bits using the bit ++ * elements. ++ */ ++typedef union gnptxsts_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned nptxfspcavail:16; ++ unsigned nptxqspcavail:8; ++ /** Top of the Non-Periodic Transmit Request Queue ++ * - bit 24 - Terminate (Last entry for the selected ++ * channel/EP) ++ * - bits 26:25 - Token Type ++ * - 2'b00 - IN/OUT ++ * - 2'b01 - Zero Length OUT ++ * - 2'b10 - PING/Complete Split ++ * - 2'b11 - Channel Halt ++ * - bits 30:27 - Channel/EP Number ++ */ ++ unsigned nptxqtop_terminate:1; ++ unsigned nptxqtop_token:2; ++ unsigned nptxqtop_chnep:4; ++ unsigned reserved:1; ++ } b; ++} gnptxsts_data_t; ++ ++/** ++ * This union represents the bit fields in the Transmit ++ * FIFO Status Register (DTXFSTS). Read the register into the ++ * d32 element then read out the bits using the bit ++ * elements. ++ */ ++typedef union dtxfsts_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned txfspcavail:16; ++ unsigned reserved:16; ++ } b; ++} dtxfsts_data_t; ++ ++/** ++ * This union represents the bit fields in the I2C Control Register ++ * (I2CCTL). Read the register into the d32 element then read out the ++ * bits using the bit elements. ++ */ ++typedef union gi2cctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned rwdata:8; ++ unsigned regaddr:8; ++ unsigned addr:7; ++ unsigned i2cen:1; ++ unsigned ack:1; ++ unsigned i2csuspctl:1; ++ unsigned i2cdevaddr:2; ++ unsigned i2cdatse0:1; ++ unsigned reserved:1; ++ unsigned rw:1; ++ unsigned bsydne:1; ++ } b; ++} gi2cctl_data_t; ++ ++/** ++ * This union represents the bit fields in the PHY Vendor Control Register ++ * (GPVNDCTL). Read the register into the d32 element then read out the ++ * bits using the bit elements. ++ */ ++typedef union gpvndctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned regdata:8; ++ unsigned vctrl:8; ++ unsigned regaddr16_21:6; ++ unsigned regwr:1; ++ unsigned reserved23_24:2; ++ unsigned newregreq:1; ++ unsigned vstsbsy:1; ++ unsigned vstsdone:1; ++ unsigned reserved28_30:3; ++ unsigned disulpidrvr:1; ++ } b; ++} gpvndctl_data_t; ++ ++/** ++ * This union represents the bit fields in the General Purpose ++ * Input/Output Register (GGPIO). ++ * Read the register into the d32 element then read out the ++ * bits using the bit elements. ++ */ ++typedef union ggpio_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned gpi:16; ++ unsigned gpo:16; ++ } b; ++} ggpio_data_t; ++ ++/** ++ * This union represents the bit fields in the User ID Register ++ * (GUID). Read the register into the d32 element then read out the ++ * bits using the bit elements. ++ */ ++typedef union guid_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned rwdata:32; ++ } b; ++} guid_data_t; ++ ++/** ++ * This union represents the bit fields in the Synopsys ID Register ++ * (GSNPSID). Read the register into the d32 element then read out the ++ * bits using the bit elements. ++ */ ++typedef union gsnpsid_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned rwdata:32; ++ } b; ++} gsnpsid_data_t; ++ ++/** ++ * This union represents the bit fields in the User HW Config1 ++ * Register. Read the register into the d32 element then read ++ * out the bits using the bit elements. ++ */ ++typedef union hwcfg1_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned ep_dir0:2; ++ unsigned ep_dir1:2; ++ unsigned ep_dir2:2; ++ unsigned ep_dir3:2; ++ unsigned ep_dir4:2; ++ unsigned ep_dir5:2; ++ unsigned ep_dir6:2; ++ unsigned ep_dir7:2; ++ unsigned ep_dir8:2; ++ unsigned ep_dir9:2; ++ unsigned ep_dir10:2; ++ unsigned ep_dir11:2; ++ unsigned ep_dir12:2; ++ unsigned ep_dir13:2; ++ unsigned ep_dir14:2; ++ unsigned ep_dir15:2; ++ } b; ++} hwcfg1_data_t; ++ ++/** ++ * This union represents the bit fields in the User HW Config2 ++ * Register. Read the register into the d32 element then read ++ * out the bits using the bit elements. ++ */ ++typedef union hwcfg2_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /* GHWCFG2 */ ++ unsigned op_mode:3; ++#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0 ++#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1 ++#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2 ++#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3 ++#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4 ++#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5 ++#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6 ++ ++ unsigned architecture:2; ++ unsigned point2point:1; ++ unsigned hs_phy_type:2; ++#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0 ++#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1 ++#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2 ++#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3 ++ ++ unsigned fs_phy_type:2; ++ unsigned num_dev_ep:4; ++ unsigned num_host_chan:4; ++ unsigned perio_ep_supported:1; ++ unsigned dynamic_fifo:1; ++ unsigned multi_proc_int:1; ++ unsigned reserved21:1; ++ unsigned nonperio_tx_q_depth:2; ++ unsigned host_perio_tx_q_depth:2; ++ unsigned dev_token_q_depth:5; ++ unsigned otg_enable_ic_usb:1; ++ } b; ++} hwcfg2_data_t; ++ ++/** ++ * This union represents the bit fields in the User HW Config3 ++ * Register. Read the register into the d32 element then read ++ * out the bits using the bit elements. ++ */ ++typedef union hwcfg3_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /* GHWCFG3 */ ++ unsigned xfer_size_cntr_width:4; ++ unsigned packet_size_cntr_width:3; ++ unsigned otg_func:1; ++ unsigned i2c:1; ++ unsigned vendor_ctrl_if:1; ++ unsigned optional_features:1; ++ unsigned synch_reset_type:1; ++ unsigned adp_supp:1; ++ unsigned otg_enable_hsic:1; ++ unsigned bc_support:1; ++ unsigned otg_lpm_en:1; ++ unsigned dfifo_depth:16; ++ } b; ++} hwcfg3_data_t; ++ ++/** ++ * This union represents the bit fields in the User HW Config4 ++ * Register. Read the register into the d32 element then read ++ * out the bits using the bit elements. ++ */ ++typedef union hwcfg4_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned num_dev_perio_in_ep:4; ++ unsigned power_optimiz:1; ++ unsigned min_ahb_freq:1; ++ unsigned hiber:1; ++ unsigned xhiber:1; ++ unsigned reserved:6; ++ unsigned utmi_phy_data_width:2; ++ unsigned num_dev_mode_ctrl_ep:4; ++ unsigned iddig_filt_en:1; ++ unsigned vbus_valid_filt_en:1; ++ unsigned a_valid_filt_en:1; ++ unsigned b_valid_filt_en:1; ++ unsigned session_end_filt_en:1; ++ unsigned ded_fifo_en:1; ++ unsigned num_in_eps:4; ++ unsigned desc_dma:1; ++ unsigned desc_dma_dyn:1; ++ } b; ++} hwcfg4_data_t; ++ ++/** ++ * This union represents the bit fields of the Core LPM Configuration ++ * Register (GLPMCFG). Set the bits using bit fields then write ++ * the d32 value to the register. ++ */ ++typedef union glpmctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** LPM-Capable (LPMCap) (Device and Host) ++ * The application uses this bit to control ++ * the DWC_otg core LPM capabilities. ++ */ ++ unsigned lpm_cap_en:1; ++ /** LPM response programmed by application (AppL1Res) (Device) ++ * Handshake response to LPM token pre-programmed ++ * by device application software. ++ */ ++ unsigned appl_resp:1; ++ /** Host Initiated Resume Duration (HIRD) (Device and Host) ++ * In Host mode this field indicates the value of HIRD ++ * to be sent in an LPM transaction. ++ * In Device mode this field is updated with the ++ * Received LPM Token HIRD bmAttribute ++ * when an ACK/NYET/STALL response is sent ++ * to an LPM transaction. ++ */ ++ unsigned hird:4; ++ /** RemoteWakeEnable (bRemoteWake) (Device and Host) ++ * In Host mode this bit indicates the value of remote ++ * wake up to be sent in wIndex field of LPM transaction. ++ * In Device mode this field is updated with the ++ * Received LPM Token bRemoteWake bmAttribute ++ * when an ACK/NYET/STALL response is sent ++ * to an LPM transaction. ++ */ ++ unsigned rem_wkup_en:1; ++ /** Enable utmi_sleep_n (EnblSlpM) (Device and Host) ++ * The application uses this bit to control ++ * the utmi_sleep_n assertion to the PHY when in L1 state. ++ */ ++ unsigned en_utmi_sleep:1; ++ /** HIRD Threshold (HIRD_Thres) (Device and Host) ++ */ ++ unsigned hird_thres:5; ++ /** LPM Response (CoreL1Res) (Device and Host) ++ * In Host mode this bit contains handsake response to ++ * LPM transaction. ++ * In Device mode the response of the core to ++ * LPM transaction received is reflected in these two bits. ++ - 0x0 : ERROR (No handshake response) ++ - 0x1 : STALL ++ - 0x2 : NYET ++ - 0x3 : ACK ++ */ ++ unsigned lpm_resp:2; ++ /** Port Sleep Status (SlpSts) (Device and Host) ++ * This bit is set as long as a Sleep condition ++ * is present on the USB bus. ++ */ ++ unsigned prt_sleep_sts:1; ++ /** Sleep State Resume OK (L1ResumeOK) (Device and Host) ++ * Indicates that the application or host ++ * can start resume from Sleep state. ++ */ ++ unsigned sleep_state_resumeok:1; ++ /** LPM channel Index (LPM_Chnl_Indx) (Host) ++ * The channel number on which the LPM transaction ++ * has to be applied while sending ++ * an LPM transaction to the local device. ++ */ ++ unsigned lpm_chan_index:4; ++ /** LPM Retry Count (LPM_Retry_Cnt) (Host) ++ * Number host retries that would be performed ++ * if the device response was not valid response. ++ */ ++ unsigned retry_count:3; ++ /** Send LPM Transaction (SndLPM) (Host) ++ * When set by application software, ++ * an LPM transaction containing two tokens ++ * is sent. ++ */ ++ unsigned send_lpm:1; ++ /** LPM Retry status (LPM_RetryCnt_Sts) (Host) ++ * Number of LPM Host Retries still remaining ++ * to be transmitted for the current LPM sequence ++ */ ++ unsigned retry_count_sts:3; ++ unsigned reserved28_29:2; ++ /** In host mode once this bit is set, the host ++ * configures to drive the HSIC Idle state on the bus. ++ * It then waits for the device to initiate the Connect sequence. ++ * In device mode once this bit is set, the device waits for ++ * the HSIC Idle line state on the bus. Upon receving the Idle ++ * line state, it initiates the HSIC Connect sequence. ++ */ ++ unsigned hsic_connect:1; ++ /** This bit overrides and functionally inverts ++ * the if_select_hsic input port signal. ++ */ ++ unsigned inv_sel_hsic:1; ++ } b; ++} glpmcfg_data_t; ++ ++/** ++ * This union represents the bit fields of the Core ADP Timer, Control and ++ * Status Register (ADPTIMCTLSTS). Set the bits using bit fields then write ++ * the d32 value to the register. ++ */ ++typedef union adpctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Probe Discharge (PRB_DSCHG) ++ * These bits set the times for TADP_DSCHG. ++ * These bits are defined as follows: ++ * 2'b00 - 4 msec ++ * 2'b01 - 8 msec ++ * 2'b10 - 16 msec ++ * 2'b11 - 32 msec ++ */ ++ unsigned prb_dschg:2; ++ /** Probe Delta (PRB_DELTA) ++ * These bits set the resolution for RTIM value. ++ * The bits are defined in units of 32 kHz clock cycles as follows: ++ * 2'b00 - 1 cycles ++ * 2'b01 - 2 cycles ++ * 2'b10 - 3 cycles ++ * 2'b11 - 4 cycles ++ * For example if this value is chosen to 2'b01, it means that RTIM ++ * increments for every 3(three) 32Khz clock cycles. ++ */ ++ unsigned prb_delta:2; ++ /** Probe Period (PRB_PER) ++ * These bits sets the TADP_PRD as shown in Figure 4 as follows: ++ * 2'b00 - 0.625 to 0.925 sec (typical 0.775 sec) ++ * 2'b01 - 1.25 to 1.85 sec (typical 1.55 sec) ++ * 2'b10 - 1.9 to 2.6 sec (typical 2.275 sec) ++ * 2'b11 - Reserved ++ */ ++ unsigned prb_per:2; ++ /** These bits capture the latest time it took for VBUS to ramp from ++ * VADP_SINK to VADP_PRB. ++ * 0x000 - 1 cycles ++ * 0x001 - 2 cycles ++ * 0x002 - 3 cycles ++ * etc ++ * 0x7FF - 2048 cycles ++ * A time of 1024 cycles at 32 kHz corresponds to a time of 32 msec. ++ */ ++ unsigned rtim:11; ++ /** Enable Probe (EnaPrb) ++ * When programmed to 1'b1, the core performs a probe operation. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned enaprb:1; ++ /** Enable Sense (EnaSns) ++ * When programmed to 1'b1, the core performs a Sense operation. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned enasns:1; ++ /** ADP Reset (ADPRes) ++ * When set, ADP controller is reset. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adpres:1; ++ /** ADP Enable (ADPEn) ++ * When set, the core performs either ADP probing or sensing ++ * based on EnaPrb or EnaSns. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adpen:1; ++ /** ADP Probe Interrupt (ADP_PRB_INT) ++ * When this bit is set, it means that the VBUS ++ * voltage is greater than VADP_PRB or VADP_PRB is reached. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adp_prb_int:1; ++ /** ++ * ADP Sense Interrupt (ADP_SNS_INT) ++ * When this bit is set, it means that the VBUS voltage is greater than ++ * VADP_SNS value or VADP_SNS is reached. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adp_sns_int:1; ++ /** ADP Tomeout Interrupt (ADP_TMOUT_INT) ++ * This bit is relevant only for an ADP probe. ++ * When this bit is set, it means that the ramp time has ++ * completed ie ADPCTL.RTIM has reached its terminal value ++ * of 0x7FF. This is a debug feature that allows software ++ * to read the ramp time after each cycle. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adp_tmout_int:1; ++ /** ADP Probe Interrupt Mask (ADP_PRB_INT_MSK) ++ * When this bit is set, it unmasks the interrupt due to ADP_PRB_INT. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adp_prb_int_msk:1; ++ /** ADP Sense Interrupt Mask (ADP_SNS_INT_MSK) ++ * When this bit is set, it unmasks the interrupt due to ADP_SNS_INT. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adp_sns_int_msk:1; ++ /** ADP Timoeout Interrupt Mask (ADP_TMOUT_MSK) ++ * When this bit is set, it unmasks the interrupt due to ADP_TMOUT_INT. ++ * This bit is valid only if OTG_Ver = 1'b1. ++ */ ++ unsigned adp_tmout_int_msk:1; ++ /** Access Request ++ * 2'b00 - Read/Write Valid (updated by the core) ++ * 2'b01 - Read ++ * 2'b00 - Write ++ * 2'b00 - Reserved ++ */ ++ unsigned ar:2; ++ /** Reserved */ ++ unsigned reserved29_31:3; ++ } b; ++} adpctl_data_t; ++ ++//////////////////////////////////////////// ++// Device Registers ++/** ++ * Device Global Registers. Offsets 800h-BFFh ++ * ++ * The following structures define the size and relative field offsets ++ * for the Device Mode Registers. ++ * ++ * These registers are visible only in Device mode and must not be ++ * accessed in Host mode, as the results are unknown. ++ */ ++typedef struct dwc_otg_dev_global_regs { ++ /** Device Configuration Register. Offset 800h */ ++ volatile uint32_t dcfg; ++ /** Device Control Register. Offset: 804h */ ++ volatile uint32_t dctl; ++ /** Device Status Register (Read Only). Offset: 808h */ ++ volatile uint32_t dsts; ++ /** Reserved. Offset: 80Ch */ ++ uint32_t unused; ++ /** Device IN Endpoint Common Interrupt Mask ++ * Register. Offset: 810h */ ++ volatile uint32_t diepmsk; ++ /** Device OUT Endpoint Common Interrupt Mask ++ * Register. Offset: 814h */ ++ volatile uint32_t doepmsk; ++ /** Device All Endpoints Interrupt Register. Offset: 818h */ ++ volatile uint32_t daint; ++ /** Device All Endpoints Interrupt Mask Register. Offset: ++ * 81Ch */ ++ volatile uint32_t daintmsk; ++ /** Device IN Token Queue Read Register-1 (Read Only). ++ * Offset: 820h */ ++ volatile uint32_t dtknqr1; ++ /** Device IN Token Queue Read Register-2 (Read Only). ++ * Offset: 824h */ ++ volatile uint32_t dtknqr2; ++ /** Device VBUS discharge Register. Offset: 828h */ ++ volatile uint32_t dvbusdis; ++ /** Device VBUS Pulse Register. Offset: 82Ch */ ++ volatile uint32_t dvbuspulse; ++ /** Device IN Token Queue Read Register-3 (Read Only). / ++ * Device Thresholding control register (Read/Write) ++ * Offset: 830h */ ++ volatile uint32_t dtknqr3_dthrctl; ++ /** Device IN Token Queue Read Register-4 (Read Only). / ++ * Device IN EPs empty Inr. Mask Register (Read/Write) ++ * Offset: 834h */ ++ volatile uint32_t dtknqr4_fifoemptymsk; ++ /** Device Each Endpoint Interrupt Register (Read Only). / ++ * Offset: 838h */ ++ volatile uint32_t deachint; ++ /** Device Each Endpoint Interrupt mask Register (Read/Write). / ++ * Offset: 83Ch */ ++ volatile uint32_t deachintmsk; ++ /** Device Each In Endpoint Interrupt mask Register (Read/Write). / ++ * Offset: 840h */ ++ volatile uint32_t diepeachintmsk[MAX_EPS_CHANNELS]; ++ /** Device Each Out Endpoint Interrupt mask Register (Read/Write). / ++ * Offset: 880h */ ++ volatile uint32_t doepeachintmsk[MAX_EPS_CHANNELS]; ++} dwc_otg_device_global_regs_t; ++ ++/** ++ * This union represents the bit fields in the Device Configuration ++ * Register. Read the register into the d32 member then ++ * set/clear the bits using the bit elements. Write the ++ * d32 member to the dcfg register. ++ */ ++typedef union dcfg_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Device Speed */ ++ unsigned devspd:2; ++ /** Non Zero Length Status OUT Handshake */ ++ unsigned nzstsouthshk:1; ++#define DWC_DCFG_SEND_STALL 1 ++ ++ unsigned ena32khzs:1; ++ /** Device Addresses */ ++ unsigned devaddr:7; ++ /** Periodic Frame Interval */ ++ unsigned perfrint:2; ++#define DWC_DCFG_FRAME_INTERVAL_80 0 ++#define DWC_DCFG_FRAME_INTERVAL_85 1 ++#define DWC_DCFG_FRAME_INTERVAL_90 2 ++#define DWC_DCFG_FRAME_INTERVAL_95 3 ++ ++ /** Enable Device OUT NAK for bulk in DDMA mode */ ++ unsigned endevoutnak:1; ++ ++ unsigned reserved14_17:4; ++ /** In Endpoint Mis-match count */ ++ unsigned epmscnt:5; ++ /** Enable Descriptor DMA in Device mode */ ++ unsigned descdma:1; ++ unsigned perschintvl:2; ++ unsigned resvalid:6; ++ } b; ++} dcfg_data_t; ++ ++/** ++ * This union represents the bit fields in the Device Control ++ * Register. Read the register into the d32 member then ++ * set/clear the bits using the bit elements. ++ */ ++typedef union dctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Remote Wakeup */ ++ unsigned rmtwkupsig:1; ++ /** Soft Disconnect */ ++ unsigned sftdiscon:1; ++ /** Global Non-Periodic IN NAK Status */ ++ unsigned gnpinnaksts:1; ++ /** Global OUT NAK Status */ ++ unsigned goutnaksts:1; ++ /** Test Control */ ++ unsigned tstctl:3; ++ /** Set Global Non-Periodic IN NAK */ ++ unsigned sgnpinnak:1; ++ /** Clear Global Non-Periodic IN NAK */ ++ unsigned cgnpinnak:1; ++ /** Set Global OUT NAK */ ++ unsigned sgoutnak:1; ++ /** Clear Global OUT NAK */ ++ unsigned cgoutnak:1; ++ /** Power-On Programming Done */ ++ unsigned pwronprgdone:1; ++ /** Reserved */ ++ unsigned reserved:1; ++ /** Global Multi Count */ ++ unsigned gmc:2; ++ /** Ignore Frame Number for ISOC EPs */ ++ unsigned ifrmnum:1; ++ /** NAK on Babble */ ++ unsigned nakonbble:1; ++ /** Enable Continue on BNA */ ++ unsigned encontonbna:1; ++ ++ unsigned reserved18_31:14; ++ } b; ++} dctl_data_t; ++ ++/** ++ * This union represents the bit fields in the Device Status ++ * Register. Read the register into the d32 member then ++ * set/clear the bits using the bit elements. ++ */ ++typedef union dsts_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Suspend Status */ ++ unsigned suspsts:1; ++ /** Enumerated Speed */ ++ unsigned enumspd:2; ++#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0 ++#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1 ++#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2 ++#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3 ++ /** Erratic Error */ ++ unsigned errticerr:1; ++ unsigned reserved4_7:4; ++ /** Frame or Microframe Number of the received SOF */ ++ unsigned soffn:14; ++ unsigned reserved22_31:10; ++ } b; ++} dsts_data_t; ++ ++/** ++ * This union represents the bit fields in the Device IN EP Interrupt ++ * Register and the Device IN EP Common Mask Register. ++ * ++ * - Read the register into the d32 member then set/clear the ++ * bits using the bit elements. ++ */ ++typedef union diepint_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Transfer complete mask */ ++ unsigned xfercompl:1; ++ /** Endpoint disable mask */ ++ unsigned epdisabled:1; ++ /** AHB Error mask */ ++ unsigned ahberr:1; ++ /** TimeOUT Handshake mask (non-ISOC EPs) */ ++ unsigned timeout:1; ++ /** IN Token received with TxF Empty mask */ ++ unsigned intktxfemp:1; ++ /** IN Token Received with EP mismatch mask */ ++ unsigned intknepmis:1; ++ /** IN Endpoint NAK Effective mask */ ++ unsigned inepnakeff:1; ++ /** Reserved */ ++ unsigned emptyintr:1; ++ ++ unsigned txfifoundrn:1; ++ ++ /** BNA Interrupt mask */ ++ unsigned bna:1; ++ ++ unsigned reserved10_12:3; ++ /** BNA Interrupt mask */ ++ unsigned nak:1; ++ ++ unsigned reserved14_31:18; ++ } b; ++} diepint_data_t; ++ ++/** ++ * This union represents the bit fields in the Device IN EP ++ * Common/Dedicated Interrupt Mask Register. ++ */ ++typedef union diepint_data diepmsk_data_t; ++ ++/** ++ * This union represents the bit fields in the Device OUT EP Interrupt ++ * Registerand Device OUT EP Common Interrupt Mask Register. ++ * ++ * - Read the register into the d32 member then set/clear the ++ * bits using the bit elements. ++ */ ++typedef union doepint_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Transfer complete */ ++ unsigned xfercompl:1; ++ /** Endpoint disable */ ++ unsigned epdisabled:1; ++ /** AHB Error */ ++ unsigned ahberr:1; ++ /** Setup Phase Done (contorl EPs) */ ++ unsigned setup:1; ++ /** OUT Token Received when Endpoint Disabled */ ++ unsigned outtknepdis:1; ++ ++ unsigned stsphsercvd:1; ++ /** Back-to-Back SETUP Packets Received */ ++ unsigned back2backsetup:1; ++ ++ unsigned reserved7:1; ++ /** OUT packet Error */ ++ unsigned outpkterr:1; ++ /** BNA Interrupt */ ++ unsigned bna:1; ++ ++ unsigned reserved10:1; ++ /** Packet Drop Status */ ++ unsigned pktdrpsts:1; ++ /** Babble Interrupt */ ++ unsigned babble:1; ++ /** NAK Interrupt */ ++ unsigned nak:1; ++ /** NYET Interrupt */ ++ unsigned nyet:1; ++ /** Bit indicating setup packet received */ ++ unsigned sr:1; ++ ++ unsigned reserved16_31:16; ++ } b; ++} doepint_data_t; ++ ++/** ++ * This union represents the bit fields in the Device OUT EP ++ * Common/Dedicated Interrupt Mask Register. ++ */ ++typedef union doepint_data doepmsk_data_t; ++ ++/** ++ * This union represents the bit fields in the Device All EP Interrupt ++ * and Mask Registers. ++ * - Read the register into the d32 member then set/clear the ++ * bits using the bit elements. ++ */ ++typedef union daint_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** IN Endpoint bits */ ++ unsigned in:16; ++ /** OUT Endpoint bits */ ++ unsigned out:16; ++ } ep; ++ struct { ++ /** IN Endpoint bits */ ++ unsigned inep0:1; ++ unsigned inep1:1; ++ unsigned inep2:1; ++ unsigned inep3:1; ++ unsigned inep4:1; ++ unsigned inep5:1; ++ unsigned inep6:1; ++ unsigned inep7:1; ++ unsigned inep8:1; ++ unsigned inep9:1; ++ unsigned inep10:1; ++ unsigned inep11:1; ++ unsigned inep12:1; ++ unsigned inep13:1; ++ unsigned inep14:1; ++ unsigned inep15:1; ++ /** OUT Endpoint bits */ ++ unsigned outep0:1; ++ unsigned outep1:1; ++ unsigned outep2:1; ++ unsigned outep3:1; ++ unsigned outep4:1; ++ unsigned outep5:1; ++ unsigned outep6:1; ++ unsigned outep7:1; ++ unsigned outep8:1; ++ unsigned outep9:1; ++ unsigned outep10:1; ++ unsigned outep11:1; ++ unsigned outep12:1; ++ unsigned outep13:1; ++ unsigned outep14:1; ++ unsigned outep15:1; ++ } b; ++} daint_data_t; ++ ++/** ++ * This union represents the bit fields in the Device IN Token Queue ++ * Read Registers. ++ * - Read the register into the d32 member. ++ * - READ-ONLY Register ++ */ ++typedef union dtknq1_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** In Token Queue Write Pointer */ ++ unsigned intknwptr:5; ++ /** Reserved */ ++ unsigned reserved05_06:2; ++ /** write pointer has wrapped. */ ++ unsigned wrap_bit:1; ++ /** EP Numbers of IN Tokens 0 ... 4 */ ++ unsigned epnums0_5:24; ++ } b; ++} dtknq1_data_t; ++ ++/** ++ * This union represents Threshold control Register ++ * - Read and write the register into the d32 member. ++ * - READ-WRITABLE Register ++ */ ++typedef union dthrctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** non ISO Tx Thr. Enable */ ++ unsigned non_iso_thr_en:1; ++ /** ISO Tx Thr. Enable */ ++ unsigned iso_thr_en:1; ++ /** Tx Thr. Length */ ++ unsigned tx_thr_len:9; ++ /** AHB Threshold ratio */ ++ unsigned ahb_thr_ratio:2; ++ /** Reserved */ ++ unsigned reserved13_15:3; ++ /** Rx Thr. Enable */ ++ unsigned rx_thr_en:1; ++ /** Rx Thr. Length */ ++ unsigned rx_thr_len:9; ++ unsigned reserved26:1; ++ /** Arbiter Parking Enable*/ ++ unsigned arbprken:1; ++ /** Reserved */ ++ unsigned reserved28_31:4; ++ } b; ++} dthrctl_data_t; ++ ++/** ++ * Device Logical IN Endpoint-Specific Registers. Offsets ++ * 900h-AFCh ++ * ++ * There will be one set of endpoint registers per logical endpoint ++ * implemented. ++ * ++ * These registers are visible only in Device mode and must not be ++ * accessed in Host mode, as the results are unknown. ++ */ ++typedef struct dwc_otg_dev_in_ep_regs { ++ /** Device IN Endpoint Control Register. Offset:900h + ++ * (ep_num * 20h) + 00h */ ++ volatile uint32_t diepctl; ++ /** Reserved. Offset:900h + (ep_num * 20h) + 04h */ ++ uint32_t reserved04; ++ /** Device IN Endpoint Interrupt Register. Offset:900h + ++ * (ep_num * 20h) + 08h */ ++ volatile uint32_t diepint; ++ /** Reserved. Offset:900h + (ep_num * 20h) + 0Ch */ ++ uint32_t reserved0C; ++ /** Device IN Endpoint Transfer Size ++ * Register. Offset:900h + (ep_num * 20h) + 10h */ ++ volatile uint32_t dieptsiz; ++ /** Device IN Endpoint DMA Address Register. Offset:900h + ++ * (ep_num * 20h) + 14h */ ++ volatile uint32_t diepdma; ++ /** Device IN Endpoint Transmit FIFO Status Register. Offset:900h + ++ * (ep_num * 20h) + 18h */ ++ volatile uint32_t dtxfsts; ++ /** Device IN Endpoint DMA Buffer Register. Offset:900h + ++ * (ep_num * 20h) + 1Ch */ ++ volatile uint32_t diepdmab; ++} dwc_otg_dev_in_ep_regs_t; ++ ++/** ++ * Device Logical OUT Endpoint-Specific Registers. Offsets: ++ * B00h-CFCh ++ * ++ * There will be one set of endpoint registers per logical endpoint ++ * implemented. ++ * ++ * These registers are visible only in Device mode and must not be ++ * accessed in Host mode, as the results are unknown. ++ */ ++typedef struct dwc_otg_dev_out_ep_regs { ++ /** Device OUT Endpoint Control Register. Offset:B00h + ++ * (ep_num * 20h) + 00h */ ++ volatile uint32_t doepctl; ++ /** Reserved. Offset:B00h + (ep_num * 20h) + 04h */ ++ uint32_t reserved04; ++ /** Device OUT Endpoint Interrupt Register. Offset:B00h + ++ * (ep_num * 20h) + 08h */ ++ volatile uint32_t doepint; ++ /** Reserved. Offset:B00h + (ep_num * 20h) + 0Ch */ ++ uint32_t reserved0C; ++ /** Device OUT Endpoint Transfer Size Register. Offset: ++ * B00h + (ep_num * 20h) + 10h */ ++ volatile uint32_t doeptsiz; ++ /** Device OUT Endpoint DMA Address Register. Offset:B00h ++ * + (ep_num * 20h) + 14h */ ++ volatile uint32_t doepdma; ++ /** Reserved. Offset:B00h + * (ep_num * 20h) + 18h */ ++ uint32_t unused; ++ /** Device OUT Endpoint DMA Buffer Register. Offset:B00h ++ * + (ep_num * 20h) + 1Ch */ ++ uint32_t doepdmab; ++} dwc_otg_dev_out_ep_regs_t; ++ ++/** ++ * This union represents the bit fields in the Device EP Control ++ * Register. Read the register into the d32 member then ++ * set/clear the bits using the bit elements. ++ */ ++typedef union depctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Maximum Packet Size ++ * IN/OUT EPn ++ * IN/OUT EP0 - 2 bits ++ * 2'b00: 64 Bytes ++ * 2'b01: 32 ++ * 2'b10: 16 ++ * 2'b11: 8 */ ++ unsigned mps:11; ++#define DWC_DEP0CTL_MPS_64 0 ++#define DWC_DEP0CTL_MPS_32 1 ++#define DWC_DEP0CTL_MPS_16 2 ++#define DWC_DEP0CTL_MPS_8 3 ++ ++ /** Next Endpoint ++ * IN EPn/IN EP0 ++ * OUT EPn/OUT EP0 - reserved */ ++ unsigned nextep:4; ++ ++ /** USB Active Endpoint */ ++ unsigned usbactep:1; ++ ++ /** Endpoint DPID (INTR/Bulk IN and OUT endpoints) ++ * This field contains the PID of the packet going to ++ * be received or transmitted on this endpoint. The ++ * application should program the PID of the first ++ * packet going to be received or transmitted on this ++ * endpoint , after the endpoint is ++ * activated. Application use the SetD1PID and ++ * SetD0PID fields of this register to program either ++ * D0 or D1 PID. ++ * ++ * The encoding for this field is ++ * - 0: D0 ++ * - 1: D1 ++ */ ++ unsigned dpid:1; ++ ++ /** NAK Status */ ++ unsigned naksts:1; ++ ++ /** Endpoint Type ++ * 2'b00: Control ++ * 2'b01: Isochronous ++ * 2'b10: Bulk ++ * 2'b11: Interrupt */ ++ unsigned eptype:2; ++ ++ /** Snoop Mode ++ * OUT EPn/OUT EP0 ++ * IN EPn/IN EP0 - reserved */ ++ unsigned snp:1; ++ ++ /** Stall Handshake */ ++ unsigned stall:1; ++ ++ /** Tx Fifo Number ++ * IN EPn/IN EP0 ++ * OUT EPn/OUT EP0 - reserved */ ++ unsigned txfnum:4; ++ ++ /** Clear NAK */ ++ unsigned cnak:1; ++ /** Set NAK */ ++ unsigned snak:1; ++ /** Set DATA0 PID (INTR/Bulk IN and OUT endpoints) ++ * Writing to this field sets the Endpoint DPID (DPID) ++ * field in this register to DATA0. Set Even ++ * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints) ++ * Writing to this field sets the Even/Odd ++ * (micro)frame (EO_FrNum) field to even (micro) ++ * frame. ++ */ ++ unsigned setd0pid:1; ++ /** Set DATA1 PID (INTR/Bulk IN and OUT endpoints) ++ * Writing to this field sets the Endpoint DPID (DPID) ++ * field in this register to DATA1 Set Odd ++ * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints) ++ * Writing to this field sets the Even/Odd ++ * (micro)frame (EO_FrNum) field to odd (micro) frame. ++ */ ++ unsigned setd1pid:1; ++ ++ /** Endpoint Disable */ ++ unsigned epdis:1; ++ /** Endpoint Enable */ ++ unsigned epena:1; ++ } b; ++} depctl_data_t; ++ ++/** ++ * This union represents the bit fields in the Device EP Transfer ++ * Size Register. Read the register into the d32 member then ++ * set/clear the bits using the bit elements. ++ */ ++typedef union deptsiz_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Transfer size */ ++ unsigned xfersize:19; ++/** Max packet count for EP (pow(2,10)-1) */ ++#define MAX_PKT_CNT 1023 ++ /** Packet Count */ ++ unsigned pktcnt:10; ++ /** Multi Count - Periodic IN endpoints */ ++ unsigned mc:2; ++ unsigned reserved:1; ++ } b; ++} deptsiz_data_t; ++ ++/** ++ * This union represents the bit fields in the Device EP 0 Transfer ++ * Size Register. Read the register into the d32 member then ++ * set/clear the bits using the bit elements. ++ */ ++typedef union deptsiz0_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Transfer size */ ++ unsigned xfersize:7; ++ /** Reserved */ ++ unsigned reserved7_18:12; ++ /** Packet Count */ ++ unsigned pktcnt:2; ++ /** Reserved */ ++ unsigned reserved21_28:8; ++ /**Setup Packet Count (DOEPTSIZ0 Only) */ ++ unsigned supcnt:2; ++ unsigned reserved31; ++ } b; ++} deptsiz0_data_t; ++ ++///////////////////////////////////////////////// ++// DMA Descriptor Specific Structures ++// ++ ++/** Buffer status definitions */ ++ ++#define BS_HOST_READY 0x0 ++#define BS_DMA_BUSY 0x1 ++#define BS_DMA_DONE 0x2 ++#define BS_HOST_BUSY 0x3 ++ ++/** Receive/Transmit status definitions */ ++ ++#define RTS_SUCCESS 0x0 ++#define RTS_BUFFLUSH 0x1 ++#define RTS_RESERVED 0x2 ++#define RTS_BUFERR 0x3 ++ ++/** ++ * This union represents the bit fields in the DMA Descriptor ++ * status quadlet. Read the quadlet into the d32 member then ++ * set/clear the bits using the bit, b_iso_out and ++ * b_iso_in elements. ++ */ ++typedef union dev_dma_desc_sts { ++ /** raw register data */ ++ uint32_t d32; ++ /** quadlet bits */ ++ struct { ++ /** Received number of bytes */ ++ unsigned bytes:16; ++ /** NAK bit - only for OUT EPs */ ++ unsigned nak:1; ++ unsigned reserved17_22:6; ++ /** Multiple Transfer - only for OUT EPs */ ++ unsigned mtrf:1; ++ /** Setup Packet received - only for OUT EPs */ ++ unsigned sr:1; ++ /** Interrupt On Complete */ ++ unsigned ioc:1; ++ /** Short Packet */ ++ unsigned sp:1; ++ /** Last */ ++ unsigned l:1; ++ /** Receive Status */ ++ unsigned sts:2; ++ /** Buffer Status */ ++ unsigned bs:2; ++ } b; ++ ++//#ifdef DWC_EN_ISOC ++ /** iso out quadlet bits */ ++ struct { ++ /** Received number of bytes */ ++ unsigned rxbytes:11; ++ ++ unsigned reserved11:1; ++ /** Frame Number */ ++ unsigned framenum:11; ++ /** Received ISO Data PID */ ++ unsigned pid:2; ++ /** Interrupt On Complete */ ++ unsigned ioc:1; ++ /** Short Packet */ ++ unsigned sp:1; ++ /** Last */ ++ unsigned l:1; ++ /** Receive Status */ ++ unsigned rxsts:2; ++ /** Buffer Status */ ++ unsigned bs:2; ++ } b_iso_out; ++ ++ /** iso in quadlet bits */ ++ struct { ++ /** Transmited number of bytes */ ++ unsigned txbytes:12; ++ /** Frame Number */ ++ unsigned framenum:11; ++ /** Transmited ISO Data PID */ ++ unsigned pid:2; ++ /** Interrupt On Complete */ ++ unsigned ioc:1; ++ /** Short Packet */ ++ unsigned sp:1; ++ /** Last */ ++ unsigned l:1; ++ /** Transmit Status */ ++ unsigned txsts:2; ++ /** Buffer Status */ ++ unsigned bs:2; ++ } b_iso_in; ++//#endif /* DWC_EN_ISOC */ ++} dev_dma_desc_sts_t; ++ ++/** ++ * DMA Descriptor structure ++ * ++ * DMA Descriptor structure contains two quadlets: ++ * Status quadlet and Data buffer pointer. ++ */ ++typedef struct dwc_otg_dev_dma_desc { ++ /** DMA Descriptor status quadlet */ ++ dev_dma_desc_sts_t status; ++ /** DMA Descriptor data buffer pointer */ ++ uint32_t buf; ++} dwc_otg_dev_dma_desc_t; ++ ++/** ++ * The dwc_otg_dev_if structure contains information needed to manage ++ * the DWC_otg controller acting in device mode. It represents the ++ * programming view of the device-specific aspects of the controller. ++ */ ++typedef struct dwc_otg_dev_if { ++ /** Pointer to device Global registers. ++ * Device Global Registers starting at offset 800h ++ */ ++ dwc_otg_device_global_regs_t *dev_global_regs; ++#define DWC_DEV_GLOBAL_REG_OFFSET 0x800 ++ ++ /** ++ * Device Logical IN Endpoint-Specific Registers 900h-AFCh ++ */ ++ dwc_otg_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS]; ++#define DWC_DEV_IN_EP_REG_OFFSET 0x900 ++#define DWC_EP_REG_OFFSET 0x20 ++ ++ /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */ ++ dwc_otg_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS]; ++#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00 ++ ++ /* Device configuration information */ ++ uint8_t speed; /**< Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */ ++ uint8_t num_in_eps; /**< Number # of Tx EP range: 0-15 exept ep0 */ ++ uint8_t num_out_eps; /**< Number # of Rx EP range: 0-15 exept ep 0*/ ++ ++ /** Size of periodic FIFOs (Bytes) */ ++ uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS]; ++ ++ /** Size of Tx FIFOs (Bytes) */ ++ uint16_t tx_fifo_size[MAX_TX_FIFOS]; ++ ++ /** Thresholding enable flags and length varaiables **/ ++ uint16_t rx_thr_en; ++ uint16_t iso_tx_thr_en; ++ uint16_t non_iso_tx_thr_en; ++ ++ uint16_t rx_thr_length; ++ uint16_t tx_thr_length; ++ ++ /** ++ * Pointers to the DMA Descriptors for EP0 Control ++ * transfers (virtual and physical) ++ */ ++ ++ /** 2 descriptors for SETUP packets */ ++ dwc_dma_t dma_setup_desc_addr[2]; ++ dwc_otg_dev_dma_desc_t *setup_desc_addr[2]; ++ ++ /** Pointer to Descriptor with latest SETUP packet */ ++ dwc_otg_dev_dma_desc_t *psetup; ++ ++ /** Index of current SETUP handler descriptor */ ++ uint32_t setup_desc_index; ++ ++ /** Descriptor for Data In or Status In phases */ ++ dwc_dma_t dma_in_desc_addr; ++ dwc_otg_dev_dma_desc_t *in_desc_addr; ++ ++ /** Descriptor for Data Out or Status Out phases */ ++ dwc_dma_t dma_out_desc_addr; ++ dwc_otg_dev_dma_desc_t *out_desc_addr; ++ ++ /** Setup Packet Detected - if set clear NAK when queueing */ ++ uint32_t spd; ++ /** Isoc ep pointer on which incomplete happens */ ++ void *isoc_ep; ++ ++} dwc_otg_dev_if_t; ++ ++///////////////////////////////////////////////// ++// Host Mode Register Structures ++// ++/** ++ * The Host Global Registers structure defines the size and relative ++ * field offsets for the Host Mode Global Registers. Host Global ++ * Registers offsets 400h-7FFh. ++*/ ++typedef struct dwc_otg_host_global_regs { ++ /** Host Configuration Register. Offset: 400h */ ++ volatile uint32_t hcfg; ++ /** Host Frame Interval Register. Offset: 404h */ ++ volatile uint32_t hfir; ++ /** Host Frame Number / Frame Remaining Register. Offset: 408h */ ++ volatile uint32_t hfnum; ++ /** Reserved. Offset: 40Ch */ ++ uint32_t reserved40C; ++ /** Host Periodic Transmit FIFO/ Queue Status Register. Offset: 410h */ ++ volatile uint32_t hptxsts; ++ /** Host All Channels Interrupt Register. Offset: 414h */ ++ volatile uint32_t haint; ++ /** Host All Channels Interrupt Mask Register. Offset: 418h */ ++ volatile uint32_t haintmsk; ++ /** Host Frame List Base Address Register . Offset: 41Ch */ ++ volatile uint32_t hflbaddr; ++} dwc_otg_host_global_regs_t; ++ ++/** ++ * This union represents the bit fields in the Host Configuration Register. ++ * Read the register into the d32 member then set/clear the bits using ++ * the bit elements. Write the d32 member to the hcfg register. ++ */ ++typedef union hcfg_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ /** FS/LS Phy Clock Select */ ++ unsigned fslspclksel:2; ++#define DWC_HCFG_30_60_MHZ 0 ++#define DWC_HCFG_48_MHZ 1 ++#define DWC_HCFG_6_MHZ 2 ++ ++ /** FS/LS Only Support */ ++ unsigned fslssupp:1; ++ unsigned reserved3_6:4; ++ /** Enable 32-KHz Suspend Mode */ ++ unsigned ena32khzs:1; ++ /** Resume Validation Periiod */ ++ unsigned resvalid:8; ++ unsigned reserved16_22:7; ++ /** Enable Scatter/gather DMA in Host mode */ ++ unsigned descdma:1; ++ /** Frame List Entries */ ++ unsigned frlisten:2; ++ /** Enable Periodic Scheduling */ ++ unsigned perschedena:1; ++ unsigned reserved27_30:4; ++ unsigned modechtimen:1; ++ } b; ++} hcfg_data_t; ++ ++/** ++ * This union represents the bit fields in the Host Frame Remaing/Number ++ * Register. ++ */ ++typedef union hfir_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ unsigned frint:16; ++ unsigned hfirrldctrl:1; ++ unsigned reserved:15; ++ } b; ++} hfir_data_t; ++ ++/** ++ * This union represents the bit fields in the Host Frame Remaing/Number ++ * Register. ++ */ ++typedef union hfnum_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ unsigned frnum:16; ++#define DWC_HFNUM_MAX_FRNUM 0x3FFF ++ unsigned frrem:16; ++ } b; ++} hfnum_data_t; ++ ++typedef union hptxsts_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ unsigned ptxfspcavail:16; ++ unsigned ptxqspcavail:8; ++ /** Top of the Periodic Transmit Request Queue ++ * - bit 24 - Terminate (last entry for the selected channel) ++ * - bits 26:25 - Token Type ++ * - 2'b00 - Zero length ++ * - 2'b01 - Ping ++ * - 2'b10 - Disable ++ * - bits 30:27 - Channel Number ++ * - bit 31 - Odd/even microframe ++ */ ++ unsigned ptxqtop_terminate:1; ++ unsigned ptxqtop_token:2; ++ unsigned ptxqtop_chnum:4; ++ unsigned ptxqtop_odd:1; ++ } b; ++} hptxsts_data_t; ++ ++/** ++ * This union represents the bit fields in the Host Port Control and Status ++ * Register. Read the register into the d32 member then set/clear the ++ * bits using the bit elements. Write the d32 member to the ++ * hprt0 register. ++ */ ++typedef union hprt0_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned prtconnsts:1; ++ unsigned prtconndet:1; ++ unsigned prtena:1; ++ unsigned prtenchng:1; ++ unsigned prtovrcurract:1; ++ unsigned prtovrcurrchng:1; ++ unsigned prtres:1; ++ unsigned prtsusp:1; ++ unsigned prtrst:1; ++ unsigned reserved9:1; ++ unsigned prtlnsts:2; ++ unsigned prtpwr:1; ++ unsigned prttstctl:4; ++ unsigned prtspd:2; ++#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0 ++#define DWC_HPRT0_PRTSPD_FULL_SPEED 1 ++#define DWC_HPRT0_PRTSPD_LOW_SPEED 2 ++ unsigned reserved19_31:13; ++ } b; ++} hprt0_data_t; ++ ++/** ++ * This union represents the bit fields in the Host All Interrupt ++ * Register. ++ */ ++typedef union haint_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned ch0:1; ++ unsigned ch1:1; ++ unsigned ch2:1; ++ unsigned ch3:1; ++ unsigned ch4:1; ++ unsigned ch5:1; ++ unsigned ch6:1; ++ unsigned ch7:1; ++ unsigned ch8:1; ++ unsigned ch9:1; ++ unsigned ch10:1; ++ unsigned ch11:1; ++ unsigned ch12:1; ++ unsigned ch13:1; ++ unsigned ch14:1; ++ unsigned ch15:1; ++ unsigned reserved:16; ++ } b; ++ ++ struct { ++ unsigned chint:16; ++ unsigned reserved:16; ++ } b2; ++} haint_data_t; ++ ++/** ++ * This union represents the bit fields in the Host All Interrupt ++ * Register. ++ */ ++typedef union haintmsk_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned ch0:1; ++ unsigned ch1:1; ++ unsigned ch2:1; ++ unsigned ch3:1; ++ unsigned ch4:1; ++ unsigned ch5:1; ++ unsigned ch6:1; ++ unsigned ch7:1; ++ unsigned ch8:1; ++ unsigned ch9:1; ++ unsigned ch10:1; ++ unsigned ch11:1; ++ unsigned ch12:1; ++ unsigned ch13:1; ++ unsigned ch14:1; ++ unsigned ch15:1; ++ unsigned reserved:16; ++ } b; ++ ++ struct { ++ unsigned chint:16; ++ unsigned reserved:16; ++ } b2; ++} haintmsk_data_t; ++ ++/** ++ * Host Channel Specific Registers. 500h-5FCh ++ */ ++typedef struct dwc_otg_hc_regs { ++ /** Host Channel 0 Characteristic Register. Offset: 500h + (chan_num * 20h) + 00h */ ++ volatile uint32_t hcchar; ++ /** Host Channel 0 Split Control Register. Offset: 500h + (chan_num * 20h) + 04h */ ++ volatile uint32_t hcsplt; ++ /** Host Channel 0 Interrupt Register. Offset: 500h + (chan_num * 20h) + 08h */ ++ volatile uint32_t hcint; ++ /** Host Channel 0 Interrupt Mask Register. Offset: 500h + (chan_num * 20h) + 0Ch */ ++ volatile uint32_t hcintmsk; ++ /** Host Channel 0 Transfer Size Register. Offset: 500h + (chan_num * 20h) + 10h */ ++ volatile uint32_t hctsiz; ++ /** Host Channel 0 DMA Address Register. Offset: 500h + (chan_num * 20h) + 14h */ ++ volatile uint32_t hcdma; ++ volatile uint32_t reserved; ++ /** Host Channel 0 DMA Buffer Address Register. Offset: 500h + (chan_num * 20h) + 1Ch */ ++ volatile uint32_t hcdmab; ++} dwc_otg_hc_regs_t; ++ ++/** ++ * This union represents the bit fields in the Host Channel Characteristics ++ * Register. Read the register into the d32 member then set/clear the ++ * bits using the bit elements. Write the d32 member to the ++ * hcchar register. ++ */ ++typedef union hcchar_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ /** Maximum packet size in bytes */ ++ unsigned mps:11; ++ ++ /** Endpoint number */ ++ unsigned epnum:4; ++ ++ /** 0: OUT, 1: IN */ ++ unsigned epdir:1; ++ ++ unsigned reserved:1; ++ ++ /** 0: Full/high speed device, 1: Low speed device */ ++ unsigned lspddev:1; ++ ++ /** 0: Control, 1: Isoc, 2: Bulk, 3: Intr */ ++ unsigned eptype:2; ++ ++ /** Packets per frame for periodic transfers. 0 is reserved. */ ++ unsigned multicnt:2; ++ ++ /** Device address */ ++ unsigned devaddr:7; ++ ++ /** ++ * Frame to transmit periodic transaction. ++ * 0: even, 1: odd ++ */ ++ unsigned oddfrm:1; ++ ++ /** Channel disable */ ++ unsigned chdis:1; ++ ++ /** Channel enable */ ++ unsigned chen:1; ++ } b; ++} hcchar_data_t; ++ ++typedef union hcsplt_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ /** Port Address */ ++ unsigned prtaddr:7; ++ ++ /** Hub Address */ ++ unsigned hubaddr:7; ++ ++ /** Transaction Position */ ++ unsigned xactpos:2; ++#define DWC_HCSPLIT_XACTPOS_MID 0 ++#define DWC_HCSPLIT_XACTPOS_END 1 ++#define DWC_HCSPLIT_XACTPOS_BEGIN 2 ++#define DWC_HCSPLIT_XACTPOS_ALL 3 ++ ++ /** Do Complete Split */ ++ unsigned compsplt:1; ++ ++ /** Reserved */ ++ unsigned reserved:14; ++ ++ /** Split Enble */ ++ unsigned spltena:1; ++ } b; ++} hcsplt_data_t; ++ ++/** ++ * This union represents the bit fields in the Host All Interrupt ++ * Register. ++ */ ++typedef union hcint_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** Transfer Complete */ ++ unsigned xfercomp:1; ++ /** Channel Halted */ ++ unsigned chhltd:1; ++ /** AHB Error */ ++ unsigned ahberr:1; ++ /** STALL Response Received */ ++ unsigned stall:1; ++ /** NAK Response Received */ ++ unsigned nak:1; ++ /** ACK Response Received */ ++ unsigned ack:1; ++ /** NYET Response Received */ ++ unsigned nyet:1; ++ /** Transaction Err */ ++ unsigned xacterr:1; ++ /** Babble Error */ ++ unsigned bblerr:1; ++ /** Frame Overrun */ ++ unsigned frmovrun:1; ++ /** Data Toggle Error */ ++ unsigned datatglerr:1; ++ /** Buffer Not Available (only for DDMA mode) */ ++ unsigned bna:1; ++ /** Exessive transaction error (only for DDMA mode) */ ++ unsigned xcs_xact:1; ++ /** Frame List Rollover interrupt */ ++ unsigned frm_list_roll:1; ++ /** Reserved */ ++ unsigned reserved14_31:18; ++ } b; ++} hcint_data_t; ++ ++/** ++ * This union represents the bit fields in the Host Channel Interrupt Mask ++ * Register. Read the register into the d32 member then set/clear the ++ * bits using the bit elements. Write the d32 member to the ++ * hcintmsk register. ++ */ ++typedef union hcintmsk_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ unsigned xfercompl:1; ++ unsigned chhltd:1; ++ unsigned ahberr:1; ++ unsigned stall:1; ++ unsigned nak:1; ++ unsigned ack:1; ++ unsigned nyet:1; ++ unsigned xacterr:1; ++ unsigned bblerr:1; ++ unsigned frmovrun:1; ++ unsigned datatglerr:1; ++ unsigned bna:1; ++ unsigned xcs_xact:1; ++ unsigned frm_list_roll:1; ++ unsigned reserved14_31:18; ++ } b; ++} hcintmsk_data_t; ++ ++/** ++ * This union represents the bit fields in the Host Channel Transfer Size ++ * Register. Read the register into the d32 member then set/clear the ++ * bits using the bit elements. Write the d32 member to the ++ * hcchar register. ++ */ ++ ++typedef union hctsiz_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ /** Total transfer size in bytes */ ++ unsigned xfersize:19; ++ ++ /** Data packets to transfer */ ++ unsigned pktcnt:10; ++ ++ /** ++ * Packet ID for next data packet ++ * 0: DATA0 ++ * 1: DATA2 ++ * 2: DATA1 ++ * 3: MDATA (non-Control), SETUP (Control) ++ */ ++ unsigned pid:2; ++#define DWC_HCTSIZ_DATA0 0 ++#define DWC_HCTSIZ_DATA1 2 ++#define DWC_HCTSIZ_DATA2 1 ++#define DWC_HCTSIZ_MDATA 3 ++#define DWC_HCTSIZ_SETUP 3 ++ ++ /** Do PING protocol when 1 */ ++ unsigned dopng:1; ++ } b; ++ ++ /** register bits */ ++ struct { ++ /** Scheduling information */ ++ unsigned schinfo:8; ++ ++ /** Number of transfer descriptors. ++ * Max value: ++ * 64 in general, ++ * 256 only for HS isochronous endpoint. ++ */ ++ unsigned ntd:8; ++ ++ /** Data packets to transfer */ ++ unsigned reserved16_28:13; ++ ++ /** ++ * Packet ID for next data packet ++ * 0: DATA0 ++ * 1: DATA2 ++ * 2: DATA1 ++ * 3: MDATA (non-Control) ++ */ ++ unsigned pid:2; ++ ++ /** Do PING protocol when 1 */ ++ unsigned dopng:1; ++ } b_ddma; ++} hctsiz_data_t; ++ ++/** ++ * This union represents the bit fields in the Host DMA Address ++ * Register used in Descriptor DMA mode. ++ */ ++typedef union hcdma_data { ++ /** raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ unsigned reserved0_2:3; ++ /** Current Transfer Descriptor. Not used for ISOC */ ++ unsigned ctd:8; ++ /** Start Address of Descriptor List */ ++ unsigned dma_addr:21; ++ } b; ++} hcdma_data_t; ++ ++/** ++ * This union represents the bit fields in the DMA Descriptor ++ * status quadlet for host mode. Read the quadlet into the d32 member then ++ * set/clear the bits using the bit elements. ++ */ ++typedef union host_dma_desc_sts { ++ /** raw register data */ ++ uint32_t d32; ++ /** quadlet bits */ ++ ++ /* for non-isochronous */ ++ struct { ++ /** Number of bytes */ ++ unsigned n_bytes:17; ++ /** QTD offset to jump when Short Packet received - only for IN EPs */ ++ unsigned qtd_offset:6; ++ /** ++ * Set to request the core to jump to alternate QTD if ++ * Short Packet received - only for IN EPs ++ */ ++ unsigned a_qtd:1; ++ /** ++ * Setup Packet bit. When set indicates that buffer contains ++ * setup packet. ++ */ ++ unsigned sup:1; ++ /** Interrupt On Complete */ ++ unsigned ioc:1; ++ /** End of List */ ++ unsigned eol:1; ++ unsigned reserved27:1; ++ /** Rx/Tx Status */ ++ unsigned sts:2; ++#define DMA_DESC_STS_PKTERR 1 ++ unsigned reserved30:1; ++ /** Active Bit */ ++ unsigned a:1; ++ } b; ++ /* for isochronous */ ++ struct { ++ /** Number of bytes */ ++ unsigned n_bytes:12; ++ unsigned reserved12_24:13; ++ /** Interrupt On Complete */ ++ unsigned ioc:1; ++ unsigned reserved26_27:2; ++ /** Rx/Tx Status */ ++ unsigned sts:2; ++ unsigned reserved30:1; ++ /** Active Bit */ ++ unsigned a:1; ++ } b_isoc; ++} host_dma_desc_sts_t; ++ ++#define MAX_DMA_DESC_SIZE 131071 ++#define MAX_DMA_DESC_NUM_GENERIC 64 ++#define MAX_DMA_DESC_NUM_HS_ISOC 256 ++#define MAX_FRLIST_EN_NUM 64 ++/** ++ * Host-mode DMA Descriptor structure ++ * ++ * DMA Descriptor structure contains two quadlets: ++ * Status quadlet and Data buffer pointer. ++ */ ++typedef struct dwc_otg_host_dma_desc { ++ /** DMA Descriptor status quadlet */ ++ host_dma_desc_sts_t status; ++ /** DMA Descriptor data buffer pointer */ ++ uint32_t buf; ++} dwc_otg_host_dma_desc_t; ++ ++/** OTG Host Interface Structure. ++ * ++ * The OTG Host Interface Structure structure contains information ++ * needed to manage the DWC_otg controller acting in host mode. It ++ * represents the programming view of the host-specific aspects of the ++ * controller. ++ */ ++typedef struct dwc_otg_host_if { ++ /** Host Global Registers starting at offset 400h.*/ ++ dwc_otg_host_global_regs_t *host_global_regs; ++#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400 ++ ++ /** Host Port 0 Control and Status Register */ ++ volatile uint32_t *hprt0; ++#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440 ++ ++ /** Host Channel Specific Registers at offsets 500h-5FCh. */ ++ dwc_otg_hc_regs_t *hc_regs[MAX_EPS_CHANNELS]; ++#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500 ++#define DWC_OTG_CHAN_REGS_OFFSET 0x20 ++ ++ /* Host configuration information */ ++ /** Number of Host Channels (range: 1-16) */ ++ uint8_t num_host_channels; ++ /** Periodic EPs supported (0: no, 1: yes) */ ++ uint8_t perio_eps_supported; ++ /** Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */ ++ uint16_t perio_tx_fifo_size; ++ ++} dwc_otg_host_if_t; ++ ++/** ++ * This union represents the bit fields in the Power and Clock Gating Control ++ * Register. Read the register into the d32 member then set/clear the ++ * bits using the bit elements. ++ */ ++typedef union pcgcctl_data { ++ /** raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ /** Stop Pclk */ ++ unsigned stoppclk:1; ++ /** Gate Hclk */ ++ unsigned gatehclk:1; ++ /** Power Clamp */ ++ unsigned pwrclmp:1; ++ /** Reset Power Down Modules */ ++ unsigned rstpdwnmodule:1; ++ /** Reserved */ ++ unsigned reserved:1; ++ /** Enable Sleep Clock Gating (Enbl_L1Gating) */ ++ unsigned enbl_sleep_gating:1; ++ /** PHY In Sleep (PhySleep) */ ++ unsigned phy_in_sleep:1; ++ /** Deep Sleep*/ ++ unsigned deep_sleep:1; ++ unsigned resetaftsusp:1; ++ unsigned restoremode:1; ++ unsigned enbl_extnd_hiber:1; ++ unsigned extnd_hiber_pwrclmp:1; ++ unsigned extnd_hiber_switch:1; ++ unsigned ess_reg_restored:1; ++ unsigned prt_clk_sel:2; ++ unsigned port_power:1; ++ unsigned max_xcvrselect:2; ++ unsigned max_termsel:1; ++ unsigned mac_dev_addr:7; ++ unsigned p2hd_dev_enum_spd:2; ++ unsigned p2hd_prt_spd:2; ++ unsigned if_dev_mode:1; ++ } b; ++} pcgcctl_data_t; ++ ++/** ++ * This union represents the bit fields in the Global Data FIFO Software ++ * Configuration Register. Read the register into the d32 member then ++ * set/clear the bits using the bit elements. ++ */ ++typedef union gdfifocfg_data { ++ /* raw register data */ ++ uint32_t d32; ++ /** register bits */ ++ struct { ++ /** OTG Data FIFO depth */ ++ unsigned gdfifocfg:16; ++ /** Start address of EP info controller */ ++ unsigned epinfobase:16; ++ } b; ++} gdfifocfg_data_t; ++ ++/** ++ * This union represents the bit fields in the Global Power Down Register ++ * Register. Read the register into the d32 member then set/clear the ++ * bits using the bit elements. ++ */ ++typedef union gpwrdn_data { ++ /* raw register data */ ++ uint32_t d32; ++ ++ /** register bits */ ++ struct { ++ /** PMU Interrupt Select */ ++ unsigned pmuintsel:1; ++ /** PMU Active */ ++ unsigned pmuactv:1; ++ /** Restore */ ++ unsigned restore:1; ++ /** Power Down Clamp */ ++ unsigned pwrdnclmp:1; ++ /** Power Down Reset */ ++ unsigned pwrdnrstn:1; ++ /** Power Down Switch */ ++ unsigned pwrdnswtch:1; ++ /** Disable VBUS */ ++ unsigned dis_vbus:1; ++ /** Line State Change */ ++ unsigned lnstschng:1; ++ /** Line state change mask */ ++ unsigned lnstchng_msk:1; ++ /** Reset Detected */ ++ unsigned rst_det:1; ++ /** Reset Detect mask */ ++ unsigned rst_det_msk:1; ++ /** Disconnect Detected */ ++ unsigned disconn_det:1; ++ /** Disconnect Detect mask */ ++ unsigned disconn_det_msk:1; ++ /** Connect Detected*/ ++ unsigned connect_det:1; ++ /** Connect Detected Mask*/ ++ unsigned connect_det_msk:1; ++ /** SRP Detected */ ++ unsigned srp_det:1; ++ /** SRP Detect mask */ ++ unsigned srp_det_msk:1; ++ /** Status Change Interrupt */ ++ unsigned sts_chngint:1; ++ /** Status Change Interrupt Mask */ ++ unsigned sts_chngint_msk:1; ++ /** Line State */ ++ unsigned linestate:2; ++ /** Indicates current mode(status of IDDIG signal) */ ++ unsigned idsts:1; ++ /** B Session Valid signal status*/ ++ unsigned bsessvld:1; ++ /** ADP Event Detected */ ++ unsigned adp_int:1; ++ /** Multi Valued ID pin */ ++ unsigned mult_val_id_bc:5; ++ /** Reserved 24_31 */ ++ unsigned reserved29_31:3; ++ } b; ++} gpwrdn_data_t; ++ ++#endif +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/Makefile 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,16 @@ ++ ++PERL=/usr/bin/perl ++PL_TESTS=test_sysfs.pl test_mod_param.pl ++ ++.PHONY : test ++test : perl_tests ++ ++perl_tests : ++ @echo ++ @echo Running perl tests ++ @for test in $(PL_TESTS); do \ ++ if $(PERL) ./$$test ; then \ ++ echo "=======> $$test, PASSED" ; \ ++ else echo "=======> $$test, FAILED" ; \ ++ fi \ ++ done +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/dwc_otg_test.pm +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/dwc_otg_test.pm 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,337 @@ ++package dwc_otg_test; ++ ++use strict; ++use Exporter (); ++ ++use vars qw(@ISA @EXPORT ++$sysfsdir $paramdir $errors $params ++); ++ ++@ISA = qw(Exporter); ++ ++# ++# Globals ++# ++$sysfsdir = "/sys/devices/lm0"; ++$paramdir = "/sys/module/dwc_otg"; ++$errors = 0; ++ ++$params = [ ++ { ++ NAME => "otg_cap", ++ DEFAULT => 0, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 2 ++ }, ++ { ++ NAME => "dma_enable", ++ DEFAULT => 0, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 1 ++ }, ++ { ++ NAME => "dma_burst_size", ++ DEFAULT => 32, ++ ENUM => [1, 4, 8, 16, 32, 64, 128, 256], ++ LOW => 1, ++ HIGH => 256 ++ }, ++ { ++ NAME => "host_speed", ++ DEFAULT => 0, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 1 ++ }, ++ { ++ NAME => "host_support_fs_ls_low_power", ++ DEFAULT => 0, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 1 ++ }, ++ { ++ NAME => "host_ls_low_power_phy_clk", ++ DEFAULT => 0, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 1 ++ }, ++ { ++ NAME => "dev_speed", ++ DEFAULT => 0, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 1 ++ }, ++ { ++ NAME => "enable_dynamic_fifo", ++ DEFAULT => 1, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 1 ++ }, ++ { ++ NAME => "data_fifo_size", ++ DEFAULT => 8192, ++ ENUM => [], ++ LOW => 32, ++ HIGH => 32768 ++ }, ++ { ++ NAME => "dev_rx_fifo_size", ++ DEFAULT => 1064, ++ ENUM => [], ++ LOW => 16, ++ HIGH => 32768 ++ }, ++ { ++ NAME => "dev_nperio_tx_fifo_size", ++ DEFAULT => 1024, ++ ENUM => [], ++ LOW => 16, ++ HIGH => 32768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_1", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_2", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_3", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_4", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_5", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_6", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_7", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_8", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_9", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_10", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_11", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_12", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_13", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_14", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "dev_perio_tx_fifo_size_15", ++ DEFAULT => 256, ++ ENUM => [], ++ LOW => 4, ++ HIGH => 768 ++ }, ++ { ++ NAME => "host_rx_fifo_size", ++ DEFAULT => 1024, ++ ENUM => [], ++ LOW => 16, ++ HIGH => 32768 ++ }, ++ { ++ NAME => "host_nperio_tx_fifo_size", ++ DEFAULT => 1024, ++ ENUM => [], ++ LOW => 16, ++ HIGH => 32768 ++ }, ++ { ++ NAME => "host_perio_tx_fifo_size", ++ DEFAULT => 1024, ++ ENUM => [], ++ LOW => 16, ++ HIGH => 32768 ++ }, ++ { ++ NAME => "max_transfer_size", ++ DEFAULT => 65535, ++ ENUM => [], ++ LOW => 2047, ++ HIGH => 65535 ++ }, ++ { ++ NAME => "max_packet_count", ++ DEFAULT => 511, ++ ENUM => [], ++ LOW => 15, ++ HIGH => 511 ++ }, ++ { ++ NAME => "host_channels", ++ DEFAULT => 12, ++ ENUM => [], ++ LOW => 1, ++ HIGH => 16 ++ }, ++ { ++ NAME => "dev_endpoints", ++ DEFAULT => 6, ++ ENUM => [], ++ LOW => 1, ++ HIGH => 15 ++ }, ++ { ++ NAME => "phy_type", ++ DEFAULT => 1, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 2 ++ }, ++ { ++ NAME => "phy_utmi_width", ++ DEFAULT => 16, ++ ENUM => [8, 16], ++ LOW => 8, ++ HIGH => 16 ++ }, ++ { ++ NAME => "phy_ulpi_ddr", ++ DEFAULT => 0, ++ ENUM => [], ++ LOW => 0, ++ HIGH => 1 ++ }, ++ ]; ++ ++ ++# ++# ++sub check_arch { ++ $_ = `uname -m`; ++ chomp; ++ unless (m/armv4tl/) { ++ warn "# \n# Can't execute on $_. Run on integrator platform.\n# \n"; ++ return 0; ++ } ++ return 1; ++} ++ ++# ++# ++sub load_module { ++ my $params = shift; ++ print "\nRemoving Module\n"; ++ system "rmmod dwc_otg"; ++ print "Loading Module\n"; ++ if ($params ne "") { ++ print "Module Parameters: $params\n"; ++ } ++ if (system("modprobe dwc_otg $params")) { ++ warn "Unable to load module\n"; ++ return 0; ++ } ++ return 1; ++} ++ ++# ++# ++sub test_status { ++ my $arg = shift; ++ ++ print "\n"; ++ ++ if (defined $arg) { ++ warn "WARNING: $arg\n"; ++ } ++ ++ if ($errors > 0) { ++ warn "TEST FAILED with $errors errors\n"; ++ return 0; ++ } else { ++ print "TEST PASSED\n"; ++ return 0 if (defined $arg); ++ } ++ return 1; ++} ++ ++# ++# ++@EXPORT = qw( ++$sysfsdir ++$paramdir ++$params ++$errors ++check_arch ++load_module ++test_status ++); ++ ++1; +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/test_mod_param.pl +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/test_mod_param.pl 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,133 @@ ++#!/usr/bin/perl -w ++# ++# Run this program on the integrator. ++# ++# - Tests module parameter default values. ++# - Tests setting of valid module parameter values via modprobe. ++# - Tests invalid module parameter values. ++# ----------------------------------------------------------------------------- ++use strict; ++use dwc_otg_test; ++ ++check_arch() or die; ++ ++# ++# ++sub test { ++ my ($param,$expected) = @_; ++ my $value = get($param); ++ ++ if ($value == $expected) { ++ print "$param = $value, okay\n"; ++ } ++ ++ else { ++ warn "ERROR: value of $param != $expected, $value\n"; ++ $errors ++; ++ } ++} ++ ++# ++# ++sub get { ++ my $param = shift; ++ my $tmp = `cat $paramdir/$param`; ++ chomp $tmp; ++ return $tmp; ++} ++ ++# ++# ++sub test_main { ++ ++ print "\nTesting Module Parameters\n"; ++ ++ load_module("") or die; ++ ++ # Test initial values ++ print "\nTesting Default Values\n"; ++ foreach (@{$params}) { ++ test ($_->{NAME}, $_->{DEFAULT}); ++ } ++ ++ # Test low value ++ print "\nTesting Low Value\n"; ++ my $cmd_params = ""; ++ foreach (@{$params}) { ++ $cmd_params = $cmd_params . "$_->{NAME}=$_->{LOW} "; ++ } ++ load_module($cmd_params) or die; ++ ++ foreach (@{$params}) { ++ test ($_->{NAME}, $_->{LOW}); ++ } ++ ++ # Test high value ++ print "\nTesting High Value\n"; ++ $cmd_params = ""; ++ foreach (@{$params}) { ++ $cmd_params = $cmd_params . "$_->{NAME}=$_->{HIGH} "; ++ } ++ load_module($cmd_params) or die; ++ ++ foreach (@{$params}) { ++ test ($_->{NAME}, $_->{HIGH}); ++ } ++ ++ # Test Enum ++ print "\nTesting Enumerated\n"; ++ foreach (@{$params}) { ++ if (defined $_->{ENUM}) { ++ my $value; ++ foreach $value (@{$_->{ENUM}}) { ++ $cmd_params = "$_->{NAME}=$value"; ++ load_module($cmd_params) or die; ++ test ($_->{NAME}, $value); ++ } ++ } ++ } ++ ++ # Test Invalid Values ++ print "\nTesting Invalid Values\n"; ++ $cmd_params = ""; ++ foreach (@{$params}) { ++ $cmd_params = $cmd_params . sprintf "$_->{NAME}=%d ", $_->{LOW}-1; ++ } ++ load_module($cmd_params) or die; ++ ++ foreach (@{$params}) { ++ test ($_->{NAME}, $_->{DEFAULT}); ++ } ++ ++ $cmd_params = ""; ++ foreach (@{$params}) { ++ $cmd_params = $cmd_params . sprintf "$_->{NAME}=%d ", $_->{HIGH}+1; ++ } ++ load_module($cmd_params) or die; ++ ++ foreach (@{$params}) { ++ test ($_->{NAME}, $_->{DEFAULT}); ++ } ++ ++ print "\nTesting Enumerated\n"; ++ foreach (@{$params}) { ++ if (defined $_->{ENUM}) { ++ my $value; ++ foreach $value (@{$_->{ENUM}}) { ++ $value = $value + 1; ++ $cmd_params = "$_->{NAME}=$value"; ++ load_module($cmd_params) or die; ++ test ($_->{NAME}, $_->{DEFAULT}); ++ $value = $value - 2; ++ $cmd_params = "$_->{NAME}=$value"; ++ load_module($cmd_params) or die; ++ test ($_->{NAME}, $_->{DEFAULT}); ++ } ++ } ++ } ++ ++ test_status() or die; ++} ++ ++test_main(); ++0; +Index: linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/test_sysfs.pl +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/usb/host/dwc_otg/test/test_sysfs.pl 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1,193 @@ ++#!/usr/bin/perl -w ++# ++# Run this program on the integrator ++# - Tests select sysfs attributes. ++# - Todo ... test more attributes, hnp/srp, buspower/bussuspend, etc. ++# ----------------------------------------------------------------------------- ++use strict; ++use dwc_otg_test; ++ ++check_arch() or die; ++ ++# ++# ++sub test { ++ my ($attr,$expected) = @_; ++ my $string = get($attr); ++ ++ if ($string eq $expected) { ++ printf("$attr = $string, okay\n"); ++ } ++ else { ++ warn "ERROR: value of $attr != $expected, $string\n"; ++ $errors ++; ++ } ++} ++ ++# ++# ++sub set { ++ my ($reg, $value) = @_; ++ system "echo $value > $sysfsdir/$reg"; ++} ++ ++# ++# ++sub get { ++ my $attr = shift; ++ my $string = `cat $sysfsdir/$attr`; ++ chomp $string; ++ if ($string =~ m/\s\=\s/) { ++ my $tmp; ++ ($tmp, $string) = split /\s=\s/, $string; ++ } ++ return $string; ++} ++ ++# ++# ++sub test_main { ++ print("\nTesting Sysfs Attributes\n"); ++ ++ load_module("") or die; ++ ++ # Test initial values of regoffset/regvalue/guid/gsnpsid ++ print("\nTesting Default Values\n"); ++ ++ test("regoffset", "0xffffffff"); ++ test("regvalue", "invalid offset"); ++ test("guid", "0x12345678"); # this will fail if it has been changed ++ test("gsnpsid", "0x4f54200a"); ++ ++ # Test operation of regoffset/regvalue ++ print("\nTesting regoffset\n"); ++ set('regoffset', '5a5a5a5a'); ++ test("regoffset", "0xffffffff"); ++ ++ set('regoffset', '0'); ++ test("regoffset", "0x00000000"); ++ ++ set('regoffset', '40000'); ++ test("regoffset", "0x00000000"); ++ ++ set('regoffset', '3ffff'); ++ test("regoffset", "0x0003ffff"); ++ ++ set('regoffset', '1'); ++ test("regoffset", "0x00000001"); ++ ++ print("\nTesting regvalue\n"); ++ set('regoffset', '3c'); ++ test("regvalue", "0x12345678"); ++ set('regvalue', '5a5a5a5a'); ++ test("regvalue", "0x5a5a5a5a"); ++ set('regvalue','a5a5a5a5'); ++ test("regvalue", "0xa5a5a5a5"); ++ set('guid','12345678'); ++ ++ # Test HNP Capable ++ print("\nTesting HNP Capable bit\n"); ++ set('hnpcapable', '1'); ++ test("hnpcapable", "0x1"); ++ set('hnpcapable','0'); ++ test("hnpcapable", "0x0"); ++ ++ set('regoffset','0c'); ++ ++ my $old = get('gusbcfg'); ++ print("setting hnpcapable\n"); ++ set('hnpcapable', '1'); ++ test("hnpcapable", "0x1"); ++ test('gusbcfg', sprintf "0x%08x", (oct ($old) | (1<<9))); ++ test('regvalue', sprintf "0x%08x", (oct ($old) | (1<<9))); ++ ++ $old = get('gusbcfg'); ++ print("clearing hnpcapable\n"); ++ set('hnpcapable', '0'); ++ test("hnpcapable", "0x0"); ++ test ('gusbcfg', sprintf "0x%08x", oct ($old) & (~(1<<9))); ++ test ('regvalue', sprintf "0x%08x", oct ($old) & (~(1<<9))); ++ ++ # Test SRP Capable ++ print("\nTesting SRP Capable bit\n"); ++ set('srpcapable', '1'); ++ test("srpcapable", "0x1"); ++ set('srpcapable','0'); ++ test("srpcapable", "0x0"); ++ ++ set('regoffset','0c'); ++ ++ $old = get('gusbcfg'); ++ print("setting srpcapable\n"); ++ set('srpcapable', '1'); ++ test("srpcapable", "0x1"); ++ test('gusbcfg', sprintf "0x%08x", (oct ($old) | (1<<8))); ++ test('regvalue', sprintf "0x%08x", (oct ($old) | (1<<8))); ++ ++ $old = get('gusbcfg'); ++ print("clearing srpcapable\n"); ++ set('srpcapable', '0'); ++ test("srpcapable", "0x0"); ++ test('gusbcfg', sprintf "0x%08x", oct ($old) & (~(1<<8))); ++ test('regvalue', sprintf "0x%08x", oct ($old) & (~(1<<8))); ++ ++ # Test GGPIO ++ print("\nTesting GGPIO\n"); ++ set('ggpio','5a5a5a5a'); ++ test('ggpio','0x5a5a0000'); ++ set('ggpio','a5a5a5a5'); ++ test('ggpio','0xa5a50000'); ++ set('ggpio','11110000'); ++ test('ggpio','0x11110000'); ++ set('ggpio','00001111'); ++ test('ggpio','0x00000000'); ++ ++ # Test DEVSPEED ++ print("\nTesting DEVSPEED\n"); ++ set('regoffset','800'); ++ $old = get('regvalue'); ++ set('devspeed','0'); ++ test('devspeed','0x0'); ++ test('regvalue',sprintf("0x%08x", oct($old) & ~(0x3))); ++ set('devspeed','1'); ++ test('devspeed','0x1'); ++ test('regvalue',sprintf("0x%08x", oct($old) & ~(0x3) | 1)); ++ set('devspeed','2'); ++ test('devspeed','0x2'); ++ test('regvalue',sprintf("0x%08x", oct($old) & ~(0x3) | 2)); ++ set('devspeed','3'); ++ test('devspeed','0x3'); ++ test('regvalue',sprintf("0x%08x", oct($old) & ~(0x3) | 3)); ++ set('devspeed','4'); ++ test('devspeed','0x0'); ++ test('regvalue',sprintf("0x%08x", oct($old) & ~(0x3))); ++ set('devspeed','5'); ++ test('devspeed','0x1'); ++ test('regvalue',sprintf("0x%08x", oct($old) & ~(0x3) | 1)); ++ ++ ++ # mode Returns the current mode:0 for device mode1 for host mode Read ++ # hnp Initiate the Host Negotiation Protocol. Read returns the status. Read/Write ++ # srp Initiate the Session Request Protocol. Read returns the status. Read/Write ++ # buspower Get or Set the Power State of the bus (0 - Off or 1 - On) Read/Write ++ # bussuspend Suspend the USB bus. Read/Write ++ # busconnected Get the connection status of the bus Read ++ ++ # gotgctl Get or set the Core Control Status Register. Read/Write ++ ## gusbcfg Get or set the Core USB Configuration Register Read/Write ++ # grxfsiz Get or set the Receive FIFO Size Register Read/Write ++ # gnptxfsiz Get or set the non-periodic Transmit Size Register Read/Write ++ # gpvndctl Get or set the PHY Vendor Control Register Read/Write ++ ## ggpio Get the value in the lower 16-bits of the General Purpose IO Register or Set the upper 16 bits. Read/Write ++ ## guid Get or set the value of the User ID Register Read/Write ++ ## gsnpsid Get the value of the Synopsys ID Regester Read ++ ## devspeed Get or set the device speed setting in the DCFG register Read/Write ++ # enumspeed Gets the device enumeration Speed. Read ++ # hptxfsiz Get the value of the Host Periodic Transmit FIFO Read ++ # hprt0 Get or Set the value in the Host Port Control and Status Register Read/Write ++ ++ test_status("TEST NYI") or die; ++} ++ ++test_main(); ++0; +Index: linux-3.10-3.10.11/dummy/rpi_1572_a0b25b587dfcc4c6816b655fa452eb4b03d55e33.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1572_a0b25b587dfcc4c6816b655fa452eb4b03d55e33.txt 2014-05-05 12:51:14.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1573_6f547e8f73eedc83fe224ef457ea55f48673776a.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1573_6f547e8f73eedc83fe224ef457ea55f48673776a.patch --- linux-3.10.11/debian/patches/rpi/rpi_1573_6f547e8f73eedc83fe224ef457ea55f48673776a.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1573_6f547e8f73eedc83fe224ef457ea55f48673776a.patch 2014-05-05 12:51:21.000000000 +0000 @@ -0,0 +1,433 @@ +commit 6f547e8f73eedc83fe224ef457ea55f48673776a +Author: popcornmix +Date: Wed May 1 19:54:32 2013 +0100 + + bcm2708 watchdog driver + + Signed-off-by: popcornmix + +Index: linux-3.10-3.10.11/drivers/watchdog/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/watchdog/Kconfig 2014-05-05 11:48:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/watchdog/Kconfig 2014-05-05 12:51:20.000000000 +0000 +@@ -391,6 +391,12 @@ + To compile this driver as a module, choose M here: the + module will be called retu_wdt. + ++config BCM2708_WDT ++ tristate "BCM2708 Watchdog" ++ depends on ARCH_BCM2708 ++ help ++ Enables BCM2708 watchdog support. ++ + # AVR32 Architecture + + config AT32AP700X_WDT +Index: linux-3.10-3.10.11/drivers/watchdog/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/watchdog/Makefile 2014-05-05 11:48:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/watchdog/Makefile 2014-05-05 12:51:20.000000000 +0000 +@@ -54,6 +54,7 @@ + obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o + obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o + obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o ++obj-$(CONFIG_BCM2708_WDT) += bcm2708_wdog.o + + # AVR32 Architecture + obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o +Index: linux-3.10-3.10.11/drivers/watchdog/bcm2708_wdog.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/watchdog/bcm2708_wdog.c 2014-05-05 12:51:20.000000000 +0000 +@@ -0,0 +1,385 @@ ++/* ++ * Broadcom BCM2708 watchdog driver. ++ * ++ * (c) Copyright 2010 Broadcom Europe Ltd ++ * ++ * 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. ++ * ++ * BCM2708 watchdog driver. Loosely based on wdt driver. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define SECS_TO_WDOG_TICKS(x) ((x) << 16) ++#define WDOG_TICKS_TO_SECS(x) ((x) >> 16) ++ ++static unsigned long wdog_is_open; ++static uint32_t wdog_ticks; /* Ticks to load into wdog timer */ ++static char expect_close; ++ ++/* ++ * Module parameters ++ */ ++ ++#define WD_TIMO 10 /* Default heartbeat = 60 seconds */ ++static int heartbeat = WD_TIMO; /* Heartbeat in seconds */ ++ ++module_param(heartbeat, int, 0); ++MODULE_PARM_DESC(heartbeat, ++ "Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default=" ++ __MODULE_STRING(WD_TIMO) ")"); ++ ++static int nowayout = WATCHDOG_NOWAYOUT; ++module_param(nowayout, int, 0); ++MODULE_PARM_DESC(nowayout, ++ "Watchdog cannot be stopped once started (default=" ++ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); ++ ++static DEFINE_SPINLOCK(wdog_lock); ++ ++/** ++ * Start the watchdog driver. ++ */ ++ ++static int wdog_start(unsigned long timeout) ++{ ++ uint32_t cur; ++ unsigned long flags; ++ spin_lock_irqsave(&wdog_lock, flags); ++ ++ /* enable the watchdog */ ++ iowrite32(PM_PASSWORD | (timeout & PM_WDOG_TIME_SET), ++ __io_address(PM_WDOG)); ++ cur = ioread32(__io_address(PM_RSTC)); ++ iowrite32(PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) | ++ PM_RSTC_WRCFG_FULL_RESET, __io_address(PM_RSTC)); ++ ++ spin_unlock_irqrestore(&wdog_lock, flags); ++ return 0; ++} ++ ++/** ++ * Stop the watchdog driver. ++ */ ++ ++static int wdog_stop(void) ++{ ++ iowrite32(PM_PASSWORD | PM_RSTC_RESET, __io_address(PM_RSTC)); ++ printk(KERN_INFO "watchdog stopped\n"); ++ return 0; ++} ++ ++/** ++ * Reload counter one with the watchdog heartbeat. We don't bother ++ * reloading the cascade counter. ++ */ ++ ++static void wdog_ping(void) ++{ ++ wdog_start(wdog_ticks); ++} ++ ++/** ++ * @t: the new heartbeat value that needs to be set. ++ * ++ * Set a new heartbeat value for the watchdog device. If the heartbeat ++ * value is incorrect we keep the old value and return -EINVAL. If ++ * successful we return 0. ++ */ ++ ++static int wdog_set_heartbeat(int t) ++{ ++ if (t < 1 || t > WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET)) ++ return -EINVAL; ++ ++ heartbeat = t; ++ wdog_ticks = SECS_TO_WDOG_TICKS(t); ++ return 0; ++} ++ ++/** ++ * @file: file handle to the watchdog ++ * @buf: buffer to write (unused as data does not matter here ++ * @count: count of bytes ++ * @ppos: pointer to the position to write. No seeks allowed ++ * ++ * A write to a watchdog device is defined as a keepalive signal. ++ * ++ * if 'nowayout' is set then normally a close() is ignored. But ++ * if you write 'V' first then the close() will stop the timer. ++ */ ++ ++static ssize_t wdog_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ if (count) { ++ if (!nowayout) { ++ size_t i; ++ ++ /* In case it was set long ago */ ++ expect_close = 0; ++ ++ for (i = 0; i != count; i++) { ++ char c; ++ if (get_user(c, buf + i)) ++ return -EFAULT; ++ if (c == 'V') ++ expect_close = 42; ++ } ++ } ++ wdog_ping(); ++ } ++ return count; ++} ++ ++static int wdog_get_status(void) ++{ ++ unsigned long flags; ++ int status = 0; ++ spin_lock_irqsave(&wdog_lock, flags); ++ /* FIXME: readback reset reason */ ++ spin_unlock_irqrestore(&wdog_lock, flags); ++ return status; ++} ++ ++static uint32_t wdog_get_remaining(void) ++{ ++ uint32_t ret = ioread32(__io_address(PM_WDOG)); ++ return ret & PM_WDOG_TIME_SET; ++} ++ ++/** ++ * @file: file handle to the device ++ * @cmd: watchdog command ++ * @arg: argument pointer ++ * ++ * The watchdog API defines a common set of functions for all watchdogs ++ * according to their available features. We only actually usefully support ++ * querying capabilities and current status. ++ */ ++ ++static long wdog_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ void __user *argp = (void __user *)arg; ++ int __user *p = argp; ++ int new_heartbeat; ++ int status; ++ int options; ++ uint32_t remaining; ++ ++ struct watchdog_info ident = { ++ .options = WDIOF_SETTIMEOUT| ++ WDIOF_MAGICCLOSE| ++ WDIOF_KEEPALIVEPING, ++ .firmware_version = 1, ++ .identity = "BCM2708", ++ }; ++ ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; ++ case WDIOC_GETSTATUS: ++ status = wdog_get_status(); ++ return put_user(status, p); ++ case WDIOC_GETBOOTSTATUS: ++ return put_user(0, p); ++ case WDIOC_KEEPALIVE: ++ wdog_ping(); ++ return 0; ++ case WDIOC_SETTIMEOUT: ++ if (get_user(new_heartbeat, p)) ++ return -EFAULT; ++ if (wdog_set_heartbeat(new_heartbeat)) ++ return -EINVAL; ++ wdog_ping(); ++ /* Fall */ ++ case WDIOC_GETTIMEOUT: ++ return put_user(heartbeat, p); ++ case WDIOC_GETTIMELEFT: ++ remaining = WDOG_TICKS_TO_SECS(wdog_get_remaining()); ++ return put_user(remaining, p); ++ case WDIOC_SETOPTIONS: ++ if (get_user(options, p)) ++ return -EFAULT; ++ if (options & WDIOS_DISABLECARD) ++ wdog_stop(); ++ if (options & WDIOS_ENABLECARD) ++ wdog_start(wdog_ticks); ++ return 0; ++ default: ++ return -ENOTTY; ++ } ++} ++ ++/** ++ * @inode: inode of device ++ * @file: file handle to device ++ * ++ * The watchdog device has been opened. The watchdog device is single ++ * open and on opening we load the counters. ++ */ ++ ++static int wdog_open(struct inode *inode, struct file *file) ++{ ++ if (test_and_set_bit(0, &wdog_is_open)) ++ return -EBUSY; ++ /* ++ * Activate ++ */ ++ wdog_start(wdog_ticks); ++ return nonseekable_open(inode, file); ++} ++ ++/** ++ * @inode: inode to board ++ * @file: file handle to board ++ * ++ * The watchdog has a configurable API. There is a religious dispute ++ * between people who want their watchdog to be able to shut down and ++ * those who want to be sure if the watchdog manager dies the machine ++ * reboots. In the former case we disable the counters, in the latter ++ * case you have to open it again very soon. ++ */ ++ ++static int wdog_release(struct inode *inode, struct file *file) ++{ ++ if (expect_close == 42) { ++ wdog_stop(); ++ } else { ++ printk(KERN_CRIT ++ "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); ++ wdog_ping(); ++ } ++ clear_bit(0, &wdog_is_open); ++ expect_close = 0; ++ return 0; ++} ++ ++/** ++ * @this: our notifier block ++ * @code: the event being reported ++ * @unused: unused ++ * ++ * Our notifier is called on system shutdowns. Turn the watchdog ++ * off so that it does not fire during the next reboot. ++ */ ++ ++static int wdog_notify_sys(struct notifier_block *this, unsigned long code, ++ void *unused) ++{ ++ if (code == SYS_DOWN || code == SYS_HALT) ++ wdog_stop(); ++ return NOTIFY_DONE; ++} ++ ++/* ++ * Kernel Interfaces ++ */ ++ ++ ++static const struct file_operations wdog_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .write = wdog_write, ++ .unlocked_ioctl = wdog_ioctl, ++ .open = wdog_open, ++ .release = wdog_release, ++}; ++ ++static struct miscdevice wdog_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &wdog_fops, ++}; ++ ++/* ++ * The WDT card needs to learn about soft shutdowns in order to ++ * turn the timebomb registers off. ++ */ ++ ++static struct notifier_block wdog_notifier = { ++ .notifier_call = wdog_notify_sys, ++}; ++ ++/** ++ * cleanup_module: ++ * ++ * Unload the watchdog. You cannot do this with any file handles open. ++ * If your watchdog is set to continue ticking on close and you unload ++ * it, well it keeps ticking. We won't get the interrupt but the board ++ * will not touch PC memory so all is fine. You just have to load a new ++ * module in 60 seconds or reboot. ++ */ ++ ++static void __exit wdog_exit(void) ++{ ++ misc_deregister(&wdog_miscdev); ++ unregister_reboot_notifier(&wdog_notifier); ++} ++ ++static int __init wdog_init(void) ++{ ++ int ret; ++ ++ /* Check that the heartbeat value is within it's range; ++ if not reset to the default */ ++ if (wdog_set_heartbeat(heartbeat)) { ++ wdog_set_heartbeat(WD_TIMO); ++ printk(KERN_INFO "bcm2708_wdog: heartbeat value must be " ++ "0 < heartbeat < %d, using %d\n", ++ WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET), ++ WD_TIMO); ++ } ++ ++ ret = register_reboot_notifier(&wdog_notifier); ++ if (ret) { ++ printk(KERN_ERR ++ "wdt: cannot register reboot notifier (err=%d)\n", ret); ++ goto out_reboot; ++ } ++ ++ ret = misc_register(&wdog_miscdev); ++ if (ret) { ++ printk(KERN_ERR ++ "wdt: cannot register miscdev on minor=%d (err=%d)\n", ++ WATCHDOG_MINOR, ret); ++ goto out_misc; ++ } ++ ++ printk(KERN_INFO "bcm2708 watchdog, heartbeat=%d sec (nowayout=%d)\n", ++ heartbeat, nowayout); ++ return 0; ++ ++out_misc: ++ unregister_reboot_notifier(&wdog_notifier); ++out_reboot: ++ return ret; ++} ++ ++module_init(wdog_init); ++module_exit(wdog_exit); ++ ++MODULE_AUTHOR("Luke Diamand"); ++MODULE_DESCRIPTION("Driver for BCM2708 watchdog"); ++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); ++MODULE_ALIAS_MISCDEV(TEMP_MINOR); ++MODULE_LICENSE("GPL"); ++ +Index: linux-3.10-3.10.11/dummy/rpi_1573_6f547e8f73eedc83fe224ef457ea55f48673776a.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1573_6f547e8f73eedc83fe224ef457ea55f48673776a.txt 2014-05-05 12:51:20.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1574_5ee582d3526b124b504d8dc353ced66b6c21ba00.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1574_5ee582d3526b124b504d8dc353ced66b6c21ba00.patch --- linux-3.10.11/debian/patches/rpi/rpi_1574_5ee582d3526b124b504d8dc353ced66b6c21ba00.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1574_5ee582d3526b124b504d8dc353ced66b6c21ba00.patch 2014-05-05 12:51:22.000000000 +0000 @@ -0,0 +1,3037 @@ +commit 5ee582d3526b124b504d8dc353ced66b6c21ba00 +Author: popcornmix +Date: Wed May 1 19:55:09 2013 +0100 + + bcm2708 framebuffer driver + + Signed-off-by: popcornmix + +Index: linux-3.10-3.10.11/drivers/video/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/Kconfig 2014-05-05 11:48:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/Kconfig 2014-05-05 12:51:21.000000000 +0000 +@@ -310,6 +310,20 @@ + help + Support the Permedia2 FIFO disconnect feature. + ++config FB_BCM2708 ++ tristate "BCM2708 framebuffer support" ++ depends on FB && ARM ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT ++ help ++ This framebuffer device driver is for the BCM2708 framebuffer. ++ ++ If you want to compile this as a module (=code which can be ++ inserted into and removed from the running kernel), say M ++ here and read . The module ++ will be called bcm2708_fb. ++ + config FB_ARMCLCD + tristate "ARM PrimeCell PL110 support" + depends on FB && ARM && ARM_AMBA +Index: linux-3.10-3.10.11/drivers/video/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/Makefile 2014-05-05 11:48:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/Makefile 2014-05-05 12:51:21.000000000 +0000 +@@ -98,6 +98,7 @@ + obj-$(CONFIG_FB_VOODOO1) += sstfb.o + obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o + obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o ++obj-$(CONFIG_FB_BCM2708) += bcm2708_fb.o + obj-$(CONFIG_FB_68328) += 68328fb.o + obj-$(CONFIG_FB_GBE) += gbefb.o + obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o +Index: linux-3.10-3.10.11/drivers/video/bcm2708_fb.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/bcm2708_fb.c 2014-05-05 12:51:21.000000000 +0000 +@@ -0,0 +1,491 @@ ++/* ++ * linux/drivers/video/bcm2708_fb.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file COPYING in the main directory of this archive ++ * for more details. ++ * ++ * Broadcom simple framebuffer driver ++ * ++ * This file is derived from cirrusfb.c ++ * Copyright 1999-2001 Jeff Garzik ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifdef BCM2708_FB_DEBUG ++#define print_debug(fmt,...) pr_debug("%s:%s:%d: "fmt, MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) ++#else ++#define print_debug(fmt,...) ++#endif ++ ++/* This is limited to 16 characters when displayed by X startup */ ++static const char *bcm2708_name = "BCM2708 FB"; ++ ++#define DRIVER_NAME "bcm2708_fb" ++ ++/* this data structure describes each frame buffer device we find */ ++ ++struct fbinfo_s { ++ u32 xres, yres, xres_virtual, yres_virtual; ++ u32 pitch, bpp; ++ u32 xoffset, yoffset; ++ u32 base; ++ u32 screen_size; ++ u16 cmap[256]; ++}; ++ ++struct bcm2708_fb { ++ struct fb_info fb; ++ struct platform_device *dev; ++ struct fbinfo_s *info; ++ dma_addr_t dma; ++ u32 cmap[16]; ++}; ++ ++#define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) ++ ++static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) ++{ ++ int ret = 0; ++ ++ memset(&var->transp, 0, sizeof(var->transp)); ++ ++ var->red.msb_right = 0; ++ var->green.msb_right = 0; ++ var->blue.msb_right = 0; ++ ++ switch (var->bits_per_pixel) { ++ case 1: ++ case 2: ++ case 4: ++ case 8: ++ var->red.length = var->bits_per_pixel; ++ var->red.offset = 0; ++ var->green.length = var->bits_per_pixel; ++ var->green.offset = 0; ++ var->blue.length = var->bits_per_pixel; ++ var->blue.offset = 0; ++ break; ++ case 16: ++ var->red.length = 5; ++ var->blue.length = 5; ++ /* ++ * Green length can be 5 or 6 depending whether ++ * we're operating in RGB555 or RGB565 mode. ++ */ ++ if (var->green.length != 5 && var->green.length != 6) ++ var->green.length = 6; ++ break; ++ case 24: ++ var->red.length = 8; ++ var->blue.length = 8; ++ var->green.length = 8; ++ break; ++ case 32: ++ var->red.length = 8; ++ var->green.length = 8; ++ var->blue.length = 8; ++ var->transp.length = 8; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ /* ++ * >= 16bpp displays have separate colour component bitfields ++ * encoded in the pixel data. Calculate their position from ++ * the bitfield length defined above. ++ */ ++ if (ret == 0 && var->bits_per_pixel >= 24) { ++ var->red.offset = 0; ++ var->green.offset = var->red.offset + var->red.length; ++ var->blue.offset = var->green.offset + var->green.length; ++ var->transp.offset = var->blue.offset + var->blue.length; ++ } else if (ret == 0 && var->bits_per_pixel >= 16) { ++ var->blue.offset = 0; ++ var->green.offset = var->blue.offset + var->blue.length; ++ var->red.offset = var->green.offset + var->green.length; ++ var->transp.offset = var->red.offset + var->red.length; ++ } ++ ++ return ret; ++} ++ ++static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ /* info input, var output */ ++ int yres; ++ ++ /* info input, var output */ ++ print_debug("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info, ++ info->var.xres, info->var.yres, info->var.xres_virtual, ++ info->var.yres_virtual, (int)info->screen_size, ++ info->var.bits_per_pixel); ++ print_debug("bcm2708_fb_check_var var(%p) %dx%d (%dx%d), %d\n", var, ++ var->xres, var->yres, var->xres_virtual, var->yres_virtual, ++ var->bits_per_pixel); ++ ++ if (!var->bits_per_pixel) ++ var->bits_per_pixel = 16; ++ ++ if (bcm2708_fb_set_bitfields(var) != 0) { ++ pr_err("bcm2708_fb_check_var: invalid bits_per_pixel %d\n", ++ var->bits_per_pixel); ++ return -EINVAL; ++ } ++ ++ ++ if (var->xres_virtual < var->xres) ++ var->xres_virtual = var->xres; ++ /* use highest possible virtual resolution */ ++ if (var->yres_virtual == -1) { ++ var->yres_virtual = 480; ++ ++ pr_err ++ ("bcm2708_fb_check_var: virtual resolution set to maximum of %dx%d\n", ++ var->xres_virtual, var->yres_virtual); ++ } ++ if (var->yres_virtual < var->yres) ++ var->yres_virtual = var->yres; ++ ++ if (var->xoffset < 0) ++ var->xoffset = 0; ++ if (var->yoffset < 0) ++ var->yoffset = 0; ++ ++ /* truncate xoffset and yoffset to maximum if too high */ ++ if (var->xoffset > var->xres_virtual - var->xres) ++ var->xoffset = var->xres_virtual - var->xres - 1; ++ if (var->yoffset > var->yres_virtual - var->yres) ++ var->yoffset = var->yres_virtual - var->yres - 1; ++ ++ yres = var->yres; ++ if (var->vmode & FB_VMODE_DOUBLE) ++ yres *= 2; ++ else if (var->vmode & FB_VMODE_INTERLACED) ++ yres = (yres + 1) / 2; ++ ++ if (yres > 1200) { ++ pr_err("bcm2708_fb_check_var: ERROR: VerticalTotal >= 1200; " ++ "special treatment required! (TODO)\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int bcm2708_fb_set_par(struct fb_info *info) ++{ ++ uint32_t val = 0; ++ struct bcm2708_fb *fb = to_bcm2708(info); ++ volatile struct fbinfo_s *fbinfo = fb->info; ++ fbinfo->xres = info->var.xres; ++ fbinfo->yres = info->var.yres; ++ fbinfo->xres_virtual = info->var.xres_virtual; ++ fbinfo->yres_virtual = info->var.yres_virtual; ++ fbinfo->bpp = info->var.bits_per_pixel; ++ fbinfo->xoffset = info->var.xoffset; ++ fbinfo->yoffset = info->var.yoffset; ++ fbinfo->base = 0; /* filled in by VC */ ++ fbinfo->pitch = 0; /* filled in by VC */ ++ ++ print_debug("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, ++ info->var.xres, info->var.yres, info->var.xres_virtual, ++ info->var.yres_virtual, (int)info->screen_size, ++ info->var.bits_per_pixel); ++ ++ /* ensure last write to fbinfo is visible to GPU */ ++ wmb(); ++ ++ /* inform vc about new framebuffer */ ++ bcm_mailbox_write(MBOX_CHAN_FB, fb->dma); ++ ++ /* TODO: replace fb driver with vchiq version */ ++ /* wait for response */ ++ bcm_mailbox_read(MBOX_CHAN_FB, &val); ++ ++ /* ensure GPU writes are visible to us */ ++ rmb(); ++ ++ if (val == 0) { ++ fb->fb.fix.line_length = fbinfo->pitch; ++ ++ if (info->var.bits_per_pixel <= 8) ++ fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ else ++ fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; ++ ++ fb->fb.fix.smem_start = fbinfo->base; ++ fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; ++ fb->fb.screen_size = fbinfo->screen_size; ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ fb->fb.screen_base = ++ (void *)ioremap_wc(fb->fb.fix.smem_start, fb->fb.screen_size); ++ if (!fb->fb.screen_base) { ++ /* the console may currently be locked */ ++ console_trylock(); ++ console_unlock(); ++ ++ BUG(); /* what can we do here */ ++ } ++ } ++ print_debug ++ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", ++ (void *)fb->fb.screen_base, (void *)fb->fb.fix.smem_start, ++ fbinfo->xres, fbinfo->yres, fbinfo->bpp, ++ fbinfo->pitch, (int)fb->fb.screen_size, val); ++ ++ return val; ++} ++ ++static inline u32 convert_bitfield(int val, struct fb_bitfield *bf) ++{ ++ unsigned int mask = (1 << bf->length) - 1; ++ ++ return (val >> (16 - bf->length) & mask) << bf->offset; ++} ++ ++ ++static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, ++ unsigned int green, unsigned int blue, ++ unsigned int transp, struct fb_info *info) ++{ ++ struct bcm2708_fb *fb = to_bcm2708(info); ++ ++ /*print_debug("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/ ++ if (fb->fb.var.bits_per_pixel <= 8) { ++ if (regno < 256) { ++ /* blue [0:4], green [5:10], red [11:15] */ ++ fb->info->cmap[regno] = ((red >> (16-5)) & 0x1f) << 11 | ++ ((green >> (16-6)) & 0x3f) << 5 | ++ ((blue >> (16-5)) & 0x1f) << 0; ++ } ++ /* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */ ++ /* So just call it for what looks like the last colour in a list for now. */ ++ if (regno == 15 || regno == 255) ++ bcm2708_fb_set_par(info); ++ } else if (regno < 16) { ++ fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | ++ convert_bitfield(blue, &fb->fb.var.blue) | ++ convert_bitfield(green, &fb->fb.var.green) | ++ convert_bitfield(red, &fb->fb.var.red); ++ } ++ return regno > 255; ++} ++ ++static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) ++{ ++ /*print_debug("bcm2708_fb_blank\n"); */ ++ return -1; ++} ++ ++static void bcm2708_fb_fillrect(struct fb_info *info, ++ const struct fb_fillrect *rect) ++{ ++ /* (is called) print_debug("bcm2708_fb_fillrect\n"); */ ++ cfb_fillrect(info, rect); ++} ++ ++static void bcm2708_fb_copyarea(struct fb_info *info, ++ const struct fb_copyarea *region) ++{ ++ /*print_debug("bcm2708_fb_copyarea\n"); */ ++ cfb_copyarea(info, region); ++} ++ ++static void bcm2708_fb_imageblit(struct fb_info *info, ++ const struct fb_image *image) ++{ ++ /* (is called) print_debug("bcm2708_fb_imageblit\n"); */ ++ cfb_imageblit(info, image); ++} ++ ++static struct fb_ops bcm2708_fb_ops = { ++ .owner = THIS_MODULE, ++ .fb_check_var = bcm2708_fb_check_var, ++ .fb_set_par = bcm2708_fb_set_par, ++ .fb_setcolreg = bcm2708_fb_setcolreg, ++ .fb_blank = bcm2708_fb_blank, ++ .fb_fillrect = bcm2708_fb_fillrect, ++ .fb_copyarea = bcm2708_fb_copyarea, ++ .fb_imageblit = bcm2708_fb_imageblit, ++}; ++ ++static int fbwidth = 800; /* module parameter */ ++static int fbheight = 480; /* module parameter */ ++static int fbdepth = 16; /* module parameter */ ++ ++static int bcm2708_fb_register(struct bcm2708_fb *fb) ++{ ++ int ret; ++ dma_addr_t dma; ++ void *mem; ++ ++ mem = ++ dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), &dma, ++ GFP_KERNEL); ++ ++ if (NULL == mem) { ++ pr_err(": unable to allocate fbinfo buffer\n"); ++ ret = -ENOMEM; ++ } else { ++ fb->info = (struct fbinfo_s *)mem; ++ fb->dma = dma; ++ } ++ fb->fb.fbops = &bcm2708_fb_ops; ++ fb->fb.flags = FBINFO_FLAG_DEFAULT; ++ fb->fb.pseudo_palette = fb->cmap; ++ ++ strncpy(fb->fb.fix.id, bcm2708_name, sizeof(fb->fb.fix.id)); ++ fb->fb.fix.type = FB_TYPE_PACKED_PIXELS; ++ fb->fb.fix.type_aux = 0; ++ fb->fb.fix.xpanstep = 0; ++ fb->fb.fix.ypanstep = 0; ++ fb->fb.fix.ywrapstep = 0; ++ fb->fb.fix.accel = FB_ACCEL_NONE; ++ ++ fb->fb.var.xres = fbwidth; ++ fb->fb.var.yres = fbheight; ++ fb->fb.var.xres_virtual = fbwidth; ++ fb->fb.var.yres_virtual = fbheight; ++ fb->fb.var.bits_per_pixel = fbdepth; ++ fb->fb.var.vmode = FB_VMODE_NONINTERLACED; ++ fb->fb.var.activate = FB_ACTIVATE_NOW; ++ fb->fb.var.nonstd = 0; ++ fb->fb.var.height = -1; /* height of picture in mm */ ++ fb->fb.var.width = -1; /* width of picture in mm */ ++ fb->fb.var.accel_flags = 0; ++ ++ fb->fb.monspecs.hfmin = 0; ++ fb->fb.monspecs.hfmax = 100000; ++ fb->fb.monspecs.vfmin = 0; ++ fb->fb.monspecs.vfmax = 400; ++ fb->fb.monspecs.dclkmin = 1000000; ++ fb->fb.monspecs.dclkmax = 100000000; ++ ++ bcm2708_fb_set_bitfields(&fb->fb.var); ++ ++ /* ++ * Allocate colourmap. ++ */ ++ ++ fb_set_var(&fb->fb, &fb->fb.var); ++ ++ print_debug("BCM2708FB: registering framebuffer (%dx%d@%d)\n", fbwidth, ++ fbheight, fbdepth); ++ ++ ret = register_framebuffer(&fb->fb); ++ print_debug("BCM2708FB: register framebuffer (%d)\n", ret); ++ if (ret == 0) ++ goto out; ++ ++ print_debug("BCM2708FB: cannot register framebuffer (%d)\n", ret); ++out: ++ return ret; ++} ++ ++static int bcm2708_fb_probe(struct platform_device *dev) ++{ ++ struct bcm2708_fb *fb; ++ int ret; ++ ++ fb = kmalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); ++ if (!fb) { ++ dev_err(&dev->dev, ++ "could not allocate new bcm2708_fb struct\n"); ++ ret = -ENOMEM; ++ goto free_region; ++ } ++ memset(fb, 0, sizeof(struct bcm2708_fb)); ++ ++ fb->dev = dev; ++ ++ ret = bcm2708_fb_register(fb); ++ if (ret == 0) { ++ platform_set_drvdata(dev, fb); ++ goto out; ++ } ++ ++ kfree(fb); ++free_region: ++ dev_err(&dev->dev, "probe failed, err %d\n", ret); ++out: ++ return ret; ++} ++ ++static int bcm2708_fb_remove(struct platform_device *dev) ++{ ++ struct bcm2708_fb *fb = platform_get_drvdata(dev); ++ ++ platform_set_drvdata(dev, NULL); ++ ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ unregister_framebuffer(&fb->fb); ++ ++ dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, ++ fb->dma); ++ kfree(fb); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm2708_fb_driver = { ++ .probe = bcm2708_fb_probe, ++ .remove = bcm2708_fb_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init bcm2708_fb_init(void) ++{ ++ return platform_driver_register(&bcm2708_fb_driver); ++} ++ ++module_init(bcm2708_fb_init); ++ ++static void __exit bcm2708_fb_exit(void) ++{ ++ platform_driver_unregister(&bcm2708_fb_driver); ++} ++ ++module_exit(bcm2708_fb_exit); ++ ++module_param(fbwidth, int, 0644); ++module_param(fbheight, int, 0644); ++module_param(fbdepth, int, 0644); ++ ++MODULE_DESCRIPTION("BCM2708 framebuffer driver"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM_DESC(fbwidth, "Width of ARM Framebuffer"); ++MODULE_PARM_DESC(fbheight, "Height of ARM Framebuffer"); ++MODULE_PARM_DESC(fbdepth, "Bit depth of ARM Framebuffer"); +Index: linux-3.10-3.10.11/drivers/video/logo/logo_linux_clut224.ppm +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/video/logo/logo_linux_clut224.ppm 2014-05-05 11:48:34.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/video/logo/logo_linux_clut224.ppm 2014-05-05 12:51:21.000000000 +0000 +@@ -1,1604 +1,883 @@ + P3 +-# Standard 224-color Linux logo +-80 80 ++63 80 + 255 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 6 6 6 10 10 10 10 10 10 +- 10 10 10 6 6 6 6 6 6 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 10 10 10 14 14 14 +- 22 22 22 26 26 26 30 30 30 34 34 34 +- 30 30 30 30 30 30 26 26 26 18 18 18 +- 14 14 14 10 10 10 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 14 14 14 26 26 26 42 42 42 +- 54 54 54 66 66 66 78 78 78 78 78 78 +- 78 78 78 74 74 74 66 66 66 54 54 54 +- 42 42 42 26 26 26 18 18 18 10 10 10 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 22 22 22 42 42 42 66 66 66 86 86 86 +- 66 66 66 38 38 38 38 38 38 22 22 22 +- 26 26 26 34 34 34 54 54 54 66 66 66 +- 86 86 86 70 70 70 46 46 46 26 26 26 +- 14 14 14 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 10 10 10 26 26 26 +- 50 50 50 82 82 82 58 58 58 6 6 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 6 6 6 54 54 54 86 86 86 66 66 66 +- 38 38 38 18 18 18 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 22 22 22 50 50 50 +- 78 78 78 34 34 34 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 6 6 6 70 70 70 +- 78 78 78 46 46 46 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 18 18 18 42 42 42 82 82 82 +- 26 26 26 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 14 14 14 +- 46 46 46 34 34 34 6 6 6 2 2 6 +- 42 42 42 78 78 78 42 42 42 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 0 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 10 10 10 30 30 30 66 66 66 58 58 58 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 26 26 26 +- 86 86 86 101 101 101 46 46 46 10 10 10 +- 2 2 6 58 58 58 70 70 70 34 34 34 +- 10 10 10 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 14 14 14 42 42 42 86 86 86 10 10 10 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 30 30 30 +- 94 94 94 94 94 94 58 58 58 26 26 26 +- 2 2 6 6 6 6 78 78 78 54 54 54 +- 22 22 22 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 22 22 22 62 62 62 62 62 62 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 26 26 26 +- 54 54 54 38 38 38 18 18 18 10 10 10 +- 2 2 6 2 2 6 34 34 34 82 82 82 +- 38 38 38 14 14 14 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 30 30 30 78 78 78 30 30 30 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 10 10 10 +- 10 10 10 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 78 78 78 +- 50 50 50 18 18 18 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 38 38 38 86 86 86 14 14 14 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 54 54 54 +- 66 66 66 26 26 26 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 42 42 42 82 82 82 2 2 6 2 2 6 +- 2 2 6 6 6 6 10 10 10 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 6 6 6 +- 14 14 14 10 10 10 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 18 18 18 +- 82 82 82 34 34 34 10 10 10 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 46 46 46 86 86 86 2 2 6 2 2 6 +- 6 6 6 6 6 6 22 22 22 34 34 34 +- 6 6 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 18 18 18 34 34 34 +- 10 10 10 50 50 50 22 22 22 2 2 6 +- 2 2 6 2 2 6 2 2 6 10 10 10 +- 86 86 86 42 42 42 14 14 14 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 1 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 46 46 46 86 86 86 2 2 6 2 2 6 +- 38 38 38 116 116 116 94 94 94 22 22 22 +- 22 22 22 2 2 6 2 2 6 2 2 6 +- 14 14 14 86 86 86 138 138 138 162 162 162 +-154 154 154 38 38 38 26 26 26 6 6 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 86 86 86 46 46 46 14 14 14 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 46 46 46 86 86 86 2 2 6 14 14 14 +-134 134 134 198 198 198 195 195 195 116 116 116 +- 10 10 10 2 2 6 2 2 6 6 6 6 +-101 98 89 187 187 187 210 210 210 218 218 218 +-214 214 214 134 134 134 14 14 14 6 6 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 86 86 86 50 50 50 18 18 18 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 1 0 0 0 +- 0 0 1 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 46 46 46 86 86 86 2 2 6 54 54 54 +-218 218 218 195 195 195 226 226 226 246 246 246 +- 58 58 58 2 2 6 2 2 6 30 30 30 +-210 210 210 253 253 253 174 174 174 123 123 123 +-221 221 221 234 234 234 74 74 74 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 70 70 70 58 58 58 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 46 46 46 82 82 82 2 2 6 106 106 106 +-170 170 170 26 26 26 86 86 86 226 226 226 +-123 123 123 10 10 10 14 14 14 46 46 46 +-231 231 231 190 190 190 6 6 6 70 70 70 +- 90 90 90 238 238 238 158 158 158 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 70 70 70 58 58 58 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 1 0 0 0 +- 0 0 1 0 0 1 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 42 42 42 86 86 86 6 6 6 116 116 116 +-106 106 106 6 6 6 70 70 70 149 149 149 +-128 128 128 18 18 18 38 38 38 54 54 54 +-221 221 221 106 106 106 2 2 6 14 14 14 +- 46 46 46 190 190 190 198 198 198 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 74 74 74 62 62 62 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 1 0 0 0 +- 0 0 1 0 0 0 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 42 42 42 94 94 94 14 14 14 101 101 101 +-128 128 128 2 2 6 18 18 18 116 116 116 +-118 98 46 121 92 8 121 92 8 98 78 10 +-162 162 162 106 106 106 2 2 6 2 2 6 +- 2 2 6 195 195 195 195 195 195 6 6 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 74 74 74 62 62 62 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 1 0 0 1 +- 0 0 1 0 0 0 0 0 1 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 38 38 38 90 90 90 14 14 14 58 58 58 +-210 210 210 26 26 26 54 38 6 154 114 10 +-226 170 11 236 186 11 225 175 15 184 144 12 +-215 174 15 175 146 61 37 26 9 2 2 6 +- 70 70 70 246 246 246 138 138 138 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 70 70 70 66 66 66 26 26 26 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 38 38 38 86 86 86 14 14 14 10 10 10 +-195 195 195 188 164 115 192 133 9 225 175 15 +-239 182 13 234 190 10 232 195 16 232 200 30 +-245 207 45 241 208 19 232 195 16 184 144 12 +-218 194 134 211 206 186 42 42 42 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 50 50 50 74 74 74 30 30 30 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 34 34 34 86 86 86 14 14 14 2 2 6 +-121 87 25 192 133 9 219 162 10 239 182 13 +-236 186 11 232 195 16 241 208 19 244 214 54 +-246 218 60 246 218 38 246 215 20 241 208 19 +-241 208 19 226 184 13 121 87 25 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 50 50 50 82 82 82 34 34 34 10 10 10 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 34 34 34 82 82 82 30 30 30 61 42 6 +-180 123 7 206 145 10 230 174 11 239 182 13 +-234 190 10 238 202 15 241 208 19 246 218 74 +-246 218 38 246 215 20 246 215 20 246 215 20 +-226 184 13 215 174 15 184 144 12 6 6 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 26 26 26 94 94 94 42 42 42 14 14 14 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 30 30 30 78 78 78 50 50 50 104 69 6 +-192 133 9 216 158 10 236 178 12 236 186 11 +-232 195 16 241 208 19 244 214 54 245 215 43 +-246 215 20 246 215 20 241 208 19 198 155 10 +-200 144 11 216 158 10 156 118 10 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 6 6 6 90 90 90 54 54 54 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 30 30 30 78 78 78 46 46 46 22 22 22 +-137 92 6 210 162 10 239 182 13 238 190 10 +-238 202 15 241 208 19 246 215 20 246 215 20 +-241 208 19 203 166 17 185 133 11 210 150 10 +-216 158 10 210 150 10 102 78 10 2 2 6 +- 6 6 6 54 54 54 14 14 14 2 2 6 +- 2 2 6 62 62 62 74 74 74 30 30 30 +- 10 10 10 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 34 34 34 78 78 78 50 50 50 6 6 6 +- 94 70 30 139 102 15 190 146 13 226 184 13 +-232 200 30 232 195 16 215 174 15 190 146 13 +-168 122 10 192 133 9 210 150 10 213 154 11 +-202 150 34 182 157 106 101 98 89 2 2 6 +- 2 2 6 78 78 78 116 116 116 58 58 58 +- 2 2 6 22 22 22 90 90 90 46 46 46 +- 18 18 18 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 38 38 38 86 86 86 50 50 50 6 6 6 +-128 128 128 174 154 114 156 107 11 168 122 10 +-198 155 10 184 144 12 197 138 11 200 144 11 +-206 145 10 206 145 10 197 138 11 188 164 115 +-195 195 195 198 198 198 174 174 174 14 14 14 +- 2 2 6 22 22 22 116 116 116 116 116 116 +- 22 22 22 2 2 6 74 74 74 70 70 70 +- 30 30 30 10 10 10 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 18 18 18 +- 50 50 50 101 101 101 26 26 26 10 10 10 +-138 138 138 190 190 190 174 154 114 156 107 11 +-197 138 11 200 144 11 197 138 11 192 133 9 +-180 123 7 190 142 34 190 178 144 187 187 187 +-202 202 202 221 221 221 214 214 214 66 66 66 +- 2 2 6 2 2 6 50 50 50 62 62 62 +- 6 6 6 2 2 6 10 10 10 90 90 90 +- 50 50 50 18 18 18 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 10 10 10 34 34 34 +- 74 74 74 74 74 74 2 2 6 6 6 6 +-144 144 144 198 198 198 190 190 190 178 166 146 +-154 121 60 156 107 11 156 107 11 168 124 44 +-174 154 114 187 187 187 190 190 190 210 210 210 +-246 246 246 253 253 253 253 253 253 182 182 182 +- 6 6 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 62 62 62 +- 74 74 74 34 34 34 14 14 14 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 10 10 10 22 22 22 54 54 54 +- 94 94 94 18 18 18 2 2 6 46 46 46 +-234 234 234 221 221 221 190 190 190 190 190 190 +-190 190 190 187 187 187 187 187 187 190 190 190 +-190 190 190 195 195 195 214 214 214 242 242 242 +-253 253 253 253 253 253 253 253 253 253 253 253 +- 82 82 82 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 14 14 14 +- 86 86 86 54 54 54 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 18 18 18 46 46 46 90 90 90 +- 46 46 46 18 18 18 6 6 6 182 182 182 +-253 253 253 246 246 246 206 206 206 190 190 190 +-190 190 190 190 190 190 190 190 190 190 190 190 +-206 206 206 231 231 231 250 250 250 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-202 202 202 14 14 14 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 42 42 42 86 86 86 42 42 42 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 14 14 14 38 38 38 74 74 74 66 66 66 +- 2 2 6 6 6 6 90 90 90 250 250 250 +-253 253 253 253 253 253 238 238 238 198 198 198 +-190 190 190 190 190 190 195 195 195 221 221 221 +-246 246 246 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 82 82 82 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 78 78 78 70 70 70 34 34 34 +- 14 14 14 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 34 34 34 66 66 66 78 78 78 6 6 6 +- 2 2 6 18 18 18 218 218 218 253 253 253 +-253 253 253 253 253 253 253 253 253 246 246 246 +-226 226 226 231 231 231 246 246 246 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 178 178 178 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 18 18 18 90 90 90 62 62 62 +- 30 30 30 10 10 10 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 10 10 10 26 26 26 +- 58 58 58 90 90 90 18 18 18 2 2 6 +- 2 2 6 110 110 110 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-250 250 250 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 231 231 231 18 18 18 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 18 18 18 94 94 94 +- 54 54 54 26 26 26 10 10 10 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 22 22 22 50 50 50 +- 90 90 90 26 26 26 2 2 6 2 2 6 +- 14 14 14 195 195 195 250 250 250 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-250 250 250 242 242 242 54 54 54 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 38 38 38 +- 86 86 86 50 50 50 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 14 14 14 38 38 38 82 82 82 +- 34 34 34 2 2 6 2 2 6 2 2 6 +- 42 42 42 195 195 195 246 246 246 253 253 253 +-253 253 253 253 253 253 253 253 253 250 250 250 +-242 242 242 242 242 242 250 250 250 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 250 250 250 246 246 246 238 238 238 +-226 226 226 231 231 231 101 101 101 6 6 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 38 38 38 82 82 82 42 42 42 14 14 14 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 10 10 10 26 26 26 62 62 62 66 66 66 +- 2 2 6 2 2 6 2 2 6 6 6 6 +- 70 70 70 170 170 170 206 206 206 234 234 234 +-246 246 246 250 250 250 250 250 250 238 238 238 +-226 226 226 231 231 231 238 238 238 250 250 250 +-250 250 250 250 250 250 246 246 246 231 231 231 +-214 214 214 206 206 206 202 202 202 202 202 202 +-198 198 198 202 202 202 182 182 182 18 18 18 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 62 62 62 66 66 66 30 30 30 +- 10 10 10 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 14 14 14 42 42 42 82 82 82 18 18 18 +- 2 2 6 2 2 6 2 2 6 10 10 10 +- 94 94 94 182 182 182 218 218 218 242 242 242 +-250 250 250 253 253 253 253 253 253 250 250 250 +-234 234 234 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 246 246 246 +-238 238 238 226 226 226 210 210 210 202 202 202 +-195 195 195 195 195 195 210 210 210 158 158 158 +- 6 6 6 14 14 14 50 50 50 14 14 14 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 6 6 6 86 86 86 46 46 46 +- 18 18 18 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 22 22 22 54 54 54 70 70 70 2 2 6 +- 2 2 6 10 10 10 2 2 6 22 22 22 +-166 166 166 231 231 231 250 250 250 253 253 253 +-253 253 253 253 253 253 253 253 253 250 250 250 +-242 242 242 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 246 246 246 +-231 231 231 206 206 206 198 198 198 226 226 226 +- 94 94 94 2 2 6 6 6 6 38 38 38 +- 30 30 30 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 62 62 62 66 66 66 +- 26 26 26 10 10 10 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 30 30 30 74 74 74 50 50 50 2 2 6 +- 26 26 26 26 26 26 2 2 6 106 106 106 +-238 238 238 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 246 246 246 218 218 218 202 202 202 +-210 210 210 14 14 14 2 2 6 2 2 6 +- 30 30 30 22 22 22 2 2 6 2 2 6 +- 2 2 6 2 2 6 18 18 18 86 86 86 +- 42 42 42 14 14 14 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 42 42 42 90 90 90 22 22 22 2 2 6 +- 42 42 42 2 2 6 18 18 18 218 218 218 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 250 250 250 221 221 221 +-218 218 218 101 101 101 2 2 6 14 14 14 +- 18 18 18 38 38 38 10 10 10 2 2 6 +- 2 2 6 2 2 6 2 2 6 78 78 78 +- 58 58 58 22 22 22 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 18 18 18 +- 54 54 54 82 82 82 2 2 6 26 26 26 +- 22 22 22 2 2 6 123 123 123 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 250 250 250 +-238 238 238 198 198 198 6 6 6 38 38 38 +- 58 58 58 26 26 26 38 38 38 2 2 6 +- 2 2 6 2 2 6 2 2 6 46 46 46 +- 78 78 78 30 30 30 10 10 10 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 10 10 10 30 30 30 +- 74 74 74 58 58 58 2 2 6 42 42 42 +- 2 2 6 22 22 22 231 231 231 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 250 250 250 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 246 246 246 46 46 46 38 38 38 +- 42 42 42 14 14 14 38 38 38 14 14 14 +- 2 2 6 2 2 6 2 2 6 6 6 6 +- 86 86 86 46 46 46 14 14 14 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 14 14 14 42 42 42 +- 90 90 90 18 18 18 18 18 18 26 26 26 +- 2 2 6 116 116 116 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 250 250 250 238 238 238 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 94 94 94 6 6 6 +- 2 2 6 2 2 6 10 10 10 34 34 34 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 74 74 74 58 58 58 22 22 22 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 10 10 10 26 26 26 66 66 66 +- 82 82 82 2 2 6 38 38 38 6 6 6 +- 14 14 14 210 210 210 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 246 246 246 242 242 242 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 144 144 144 2 2 6 +- 2 2 6 2 2 6 2 2 6 46 46 46 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 42 42 42 74 74 74 30 30 30 10 10 10 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 14 14 14 42 42 42 90 90 90 +- 26 26 26 6 6 6 42 42 42 2 2 6 +- 74 74 74 250 250 250 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 242 242 242 242 242 242 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 182 182 182 2 2 6 +- 2 2 6 2 2 6 2 2 6 46 46 46 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 10 10 10 86 86 86 38 38 38 10 10 10 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 10 10 10 26 26 26 66 66 66 82 82 82 +- 2 2 6 22 22 22 18 18 18 2 2 6 +-149 149 149 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 234 234 234 242 242 242 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 206 206 206 2 2 6 +- 2 2 6 2 2 6 2 2 6 38 38 38 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 6 6 6 86 86 86 46 46 46 14 14 14 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 18 18 18 46 46 46 86 86 86 18 18 18 +- 2 2 6 34 34 34 10 10 10 6 6 6 +-210 210 210 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 234 234 234 242 242 242 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 221 221 221 6 6 6 +- 2 2 6 2 2 6 6 6 6 30 30 30 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 82 82 82 54 54 54 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 26 26 26 66 66 66 62 62 62 2 2 6 +- 2 2 6 38 38 38 10 10 10 26 26 26 +-238 238 238 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 238 238 238 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 6 6 6 +- 2 2 6 2 2 6 10 10 10 30 30 30 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 66 66 66 58 58 58 22 22 22 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 38 38 38 78 78 78 6 6 6 2 2 6 +- 2 2 6 46 46 46 14 14 14 42 42 42 +-246 246 246 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 242 242 242 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 234 234 234 10 10 10 +- 2 2 6 2 2 6 22 22 22 14 14 14 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 66 66 66 62 62 62 22 22 22 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 18 18 18 +- 50 50 50 74 74 74 2 2 6 2 2 6 +- 14 14 14 70 70 70 34 34 34 62 62 62 +-250 250 250 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 246 246 246 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 234 234 234 14 14 14 +- 2 2 6 2 2 6 30 30 30 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 66 66 66 62 62 62 22 22 22 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 18 18 18 +- 54 54 54 62 62 62 2 2 6 2 2 6 +- 2 2 6 30 30 30 46 46 46 70 70 70 +-250 250 250 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 246 246 246 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 226 226 226 10 10 10 +- 2 2 6 6 6 6 30 30 30 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 66 66 66 58 58 58 22 22 22 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 22 22 22 +- 58 58 58 62 62 62 2 2 6 2 2 6 +- 2 2 6 2 2 6 30 30 30 78 78 78 +-250 250 250 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 246 246 246 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 206 206 206 2 2 6 +- 22 22 22 34 34 34 18 14 6 22 22 22 +- 26 26 26 18 18 18 6 6 6 2 2 6 +- 2 2 6 82 82 82 54 54 54 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 26 26 26 +- 62 62 62 106 106 106 74 54 14 185 133 11 +-210 162 10 121 92 8 6 6 6 62 62 62 +-238 238 238 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 246 246 246 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 158 158 158 18 18 18 +- 14 14 14 2 2 6 2 2 6 2 2 6 +- 6 6 6 18 18 18 66 66 66 38 38 38 +- 6 6 6 94 94 94 50 50 50 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 10 10 10 10 10 10 18 18 18 38 38 38 +- 78 78 78 142 134 106 216 158 10 242 186 14 +-246 190 14 246 190 14 156 118 10 10 10 10 +- 90 90 90 238 238 238 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 250 250 250 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 246 230 190 +-238 204 91 238 204 91 181 142 44 37 26 9 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 38 38 38 46 46 46 +- 26 26 26 106 106 106 54 54 54 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 14 14 14 22 22 22 +- 30 30 30 38 38 38 50 50 50 70 70 70 +-106 106 106 190 142 34 226 170 11 242 186 14 +-246 190 14 246 190 14 246 190 14 154 114 10 +- 6 6 6 74 74 74 226 226 226 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 231 231 231 250 250 250 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 228 184 62 +-241 196 14 241 208 19 232 195 16 38 30 10 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 6 6 6 30 30 30 26 26 26 +-203 166 17 154 142 90 66 66 66 26 26 26 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 18 18 18 38 38 38 58 58 58 +- 78 78 78 86 86 86 101 101 101 123 123 123 +-175 146 61 210 150 10 234 174 13 246 186 14 +-246 190 14 246 190 14 246 190 14 238 190 10 +-102 78 10 2 2 6 46 46 46 198 198 198 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 234 234 234 242 242 242 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 224 178 62 +-242 186 14 241 196 14 210 166 10 22 18 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 6 6 6 121 92 8 +-238 202 15 232 195 16 82 82 82 34 34 34 +- 10 10 10 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 14 14 14 38 38 38 70 70 70 154 122 46 +-190 142 34 200 144 11 197 138 11 197 138 11 +-213 154 11 226 170 11 242 186 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-225 175 15 46 32 6 2 2 6 22 22 22 +-158 158 158 250 250 250 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 250 250 250 242 242 242 224 178 62 +-239 182 13 236 186 11 213 154 11 46 32 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 61 42 6 225 175 15 +-238 190 10 236 186 11 112 100 78 42 42 42 +- 14 14 14 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 22 22 22 54 54 54 154 122 46 213 154 11 +-226 170 11 230 174 11 226 170 11 226 170 11 +-236 178 12 242 186 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-241 196 14 184 144 12 10 10 10 2 2 6 +- 6 6 6 116 116 116 242 242 242 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 231 231 231 198 198 198 214 170 54 +-236 178 12 236 178 12 210 150 10 137 92 6 +- 18 14 6 2 2 6 2 2 6 2 2 6 +- 6 6 6 70 47 6 200 144 11 236 178 12 +-239 182 13 239 182 13 124 112 88 58 58 58 +- 22 22 22 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 30 30 30 70 70 70 180 133 36 226 170 11 +-239 182 13 242 186 14 242 186 14 246 186 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 232 195 16 98 70 6 2 2 6 +- 2 2 6 2 2 6 66 66 66 221 221 221 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 206 206 206 198 198 198 214 166 58 +-230 174 11 230 174 11 216 158 10 192 133 9 +-163 110 8 116 81 8 102 78 10 116 81 8 +-167 114 7 197 138 11 226 170 11 239 182 13 +-242 186 14 242 186 14 162 146 94 78 78 78 +- 34 34 34 14 14 14 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 30 30 30 78 78 78 190 142 34 226 170 11 +-239 182 13 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 241 196 14 203 166 17 22 18 6 +- 2 2 6 2 2 6 2 2 6 38 38 38 +-218 218 218 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-250 250 250 206 206 206 198 198 198 202 162 69 +-226 170 11 236 178 12 224 166 10 210 150 10 +-200 144 11 197 138 11 192 133 9 197 138 11 +-210 150 10 226 170 11 242 186 14 246 190 14 +-246 190 14 246 186 14 225 175 15 124 112 88 +- 62 62 62 30 30 30 14 14 14 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 30 30 30 78 78 78 174 135 50 224 166 10 +-239 182 13 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 241 196 14 139 102 15 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 78 78 78 250 250 250 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-250 250 250 214 214 214 198 198 198 190 150 46 +-219 162 10 236 178 12 234 174 13 224 166 10 +-216 158 10 213 154 11 213 154 11 216 158 10 +-226 170 11 239 182 13 246 190 14 246 190 14 +-246 190 14 246 190 14 242 186 14 206 162 42 +-101 101 101 58 58 58 30 30 30 14 14 14 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 30 30 30 74 74 74 174 135 50 216 158 10 +-236 178 12 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 241 196 14 226 184 13 +- 61 42 6 2 2 6 2 2 6 2 2 6 +- 22 22 22 238 238 238 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 226 226 226 187 187 187 180 133 36 +-216 158 10 236 178 12 239 182 13 236 178 12 +-230 174 11 226 170 11 226 170 11 230 174 11 +-236 178 12 242 186 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 186 14 239 182 13 +-206 162 42 106 106 106 66 66 66 34 34 34 +- 14 14 14 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 26 26 26 70 70 70 163 133 67 213 154 11 +-236 178 12 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 241 196 14 +-190 146 13 18 14 6 2 2 6 2 2 6 +- 46 46 46 246 246 246 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 221 221 221 86 86 86 156 107 11 +-216 158 10 236 178 12 242 186 14 246 186 14 +-242 186 14 239 182 13 239 182 13 242 186 14 +-242 186 14 246 186 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-242 186 14 225 175 15 142 122 72 66 66 66 +- 30 30 30 10 10 10 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 26 26 26 70 70 70 163 133 67 210 150 10 +-236 178 12 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-232 195 16 121 92 8 34 34 34 106 106 106 +-221 221 221 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-242 242 242 82 82 82 18 14 6 163 110 8 +-216 158 10 236 178 12 242 186 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 242 186 14 163 133 67 +- 46 46 46 18 18 18 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 10 10 10 +- 30 30 30 78 78 78 163 133 67 210 150 10 +-236 178 12 246 186 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-241 196 14 215 174 15 190 178 144 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 218 218 218 +- 58 58 58 2 2 6 22 18 6 167 114 7 +-216 158 10 236 178 12 246 186 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 186 14 242 186 14 190 150 46 +- 54 54 54 22 22 22 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 38 38 38 86 86 86 180 133 36 213 154 11 +-236 178 12 246 186 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 232 195 16 190 146 13 214 214 214 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 250 250 250 170 170 170 26 26 26 +- 2 2 6 2 2 6 37 26 9 163 110 8 +-219 162 10 239 182 13 246 186 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 186 14 236 178 12 224 166 10 142 122 72 +- 46 46 46 18 18 18 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 18 18 18 +- 50 50 50 109 106 95 192 133 9 224 166 10 +-242 186 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-242 186 14 226 184 13 210 162 10 142 110 46 +-226 226 226 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-253 253 253 253 253 253 253 253 253 253 253 253 +-198 198 198 66 66 66 2 2 6 2 2 6 +- 2 2 6 2 2 6 50 34 6 156 107 11 +-219 162 10 239 182 13 246 186 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 242 186 14 +-234 174 13 213 154 11 154 122 46 66 66 66 +- 30 30 30 10 10 10 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 22 22 22 +- 58 58 58 154 121 60 206 145 10 234 174 13 +-242 186 14 246 186 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 186 14 236 178 12 210 162 10 163 110 8 +- 61 42 6 138 138 138 218 218 218 250 250 250 +-253 253 253 253 253 253 253 253 253 250 250 250 +-242 242 242 210 210 210 144 144 144 66 66 66 +- 6 6 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 61 42 6 163 110 8 +-216 158 10 236 178 12 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 239 182 13 230 174 11 216 158 10 +-190 142 34 124 112 88 70 70 70 38 38 38 +- 18 18 18 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 22 22 22 +- 62 62 62 168 124 44 206 145 10 224 166 10 +-236 178 12 239 182 13 242 186 14 242 186 14 +-246 186 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 236 178 12 216 158 10 175 118 6 +- 80 54 7 2 2 6 6 6 6 30 30 30 +- 54 54 54 62 62 62 50 50 50 38 38 38 +- 14 14 14 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 6 6 6 80 54 7 167 114 7 +-213 154 11 236 178 12 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 190 14 242 186 14 239 182 13 239 182 13 +-230 174 11 210 150 10 174 135 50 124 112 88 +- 82 82 82 54 54 54 34 34 34 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 18 18 18 +- 50 50 50 158 118 36 192 133 9 200 144 11 +-216 158 10 219 162 10 224 166 10 226 170 11 +-230 174 11 236 178 12 239 182 13 239 182 13 +-242 186 14 246 186 14 246 190 14 246 190 14 +-246 190 14 246 190 14 246 190 14 246 190 14 +-246 186 14 230 174 11 210 150 10 163 110 8 +-104 69 6 10 10 10 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 6 6 6 91 60 6 167 114 7 +-206 145 10 230 174 11 242 186 14 246 190 14 +-246 190 14 246 190 14 246 186 14 242 186 14 +-239 182 13 230 174 11 224 166 10 213 154 11 +-180 133 36 124 112 88 86 86 86 58 58 58 +- 38 38 38 22 22 22 10 10 10 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 14 14 14 +- 34 34 34 70 70 70 138 110 50 158 118 36 +-167 114 7 180 123 7 192 133 9 197 138 11 +-200 144 11 206 145 10 213 154 11 219 162 10 +-224 166 10 230 174 11 239 182 13 242 186 14 +-246 186 14 246 186 14 246 186 14 246 186 14 +-239 182 13 216 158 10 185 133 11 152 99 6 +-104 69 6 18 14 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 2 2 6 2 2 6 2 2 6 +- 2 2 6 6 6 6 80 54 7 152 99 6 +-192 133 9 219 162 10 236 178 12 239 182 13 +-246 186 14 242 186 14 239 182 13 236 178 12 +-224 166 10 206 145 10 192 133 9 154 121 60 +- 94 94 94 62 62 62 42 42 42 22 22 22 +- 14 14 14 6 6 6 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 18 18 18 34 34 34 58 58 58 78 78 78 +-101 98 89 124 112 88 142 110 46 156 107 11 +-163 110 8 167 114 7 175 118 6 180 123 7 +-185 133 11 197 138 11 210 150 10 219 162 10 +-226 170 11 236 178 12 236 178 12 234 174 13 +-219 162 10 197 138 11 163 110 8 130 83 6 +- 91 60 6 10 10 10 2 2 6 2 2 6 +- 18 18 18 38 38 38 38 38 38 38 38 38 +- 38 38 38 38 38 38 38 38 38 38 38 38 +- 38 38 38 38 38 38 26 26 26 2 2 6 +- 2 2 6 6 6 6 70 47 6 137 92 6 +-175 118 6 200 144 11 219 162 10 230 174 11 +-234 174 13 230 174 11 219 162 10 210 150 10 +-192 133 9 163 110 8 124 112 88 82 82 82 +- 50 50 50 30 30 30 14 14 14 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 14 14 14 22 22 22 34 34 34 +- 42 42 42 58 58 58 74 74 74 86 86 86 +-101 98 89 122 102 70 130 98 46 121 87 25 +-137 92 6 152 99 6 163 110 8 180 123 7 +-185 133 11 197 138 11 206 145 10 200 144 11 +-180 123 7 156 107 11 130 83 6 104 69 6 +- 50 34 6 54 54 54 110 110 110 101 98 89 +- 86 86 86 82 82 82 78 78 78 78 78 78 +- 78 78 78 78 78 78 78 78 78 78 78 78 +- 78 78 78 82 82 82 86 86 86 94 94 94 +-106 106 106 101 101 101 86 66 34 124 80 6 +-156 107 11 180 123 7 192 133 9 200 144 11 +-206 145 10 200 144 11 192 133 9 175 118 6 +-139 102 15 109 106 95 70 70 70 42 42 42 +- 22 22 22 10 10 10 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 6 6 6 10 10 10 +- 14 14 14 22 22 22 30 30 30 38 38 38 +- 50 50 50 62 62 62 74 74 74 90 90 90 +-101 98 89 112 100 78 121 87 25 124 80 6 +-137 92 6 152 99 6 152 99 6 152 99 6 +-138 86 6 124 80 6 98 70 6 86 66 30 +-101 98 89 82 82 82 58 58 58 46 46 46 +- 38 38 38 34 34 34 34 34 34 34 34 34 +- 34 34 34 34 34 34 34 34 34 34 34 34 +- 34 34 34 34 34 34 38 38 38 42 42 42 +- 54 54 54 82 82 82 94 86 76 91 60 6 +-134 86 6 156 107 11 167 114 7 175 118 6 +-175 118 6 167 114 7 152 99 6 121 87 25 +-101 98 89 62 62 62 34 34 34 18 18 18 +- 6 6 6 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 6 6 6 10 10 10 +- 18 18 18 22 22 22 30 30 30 42 42 42 +- 50 50 50 66 66 66 86 86 86 101 98 89 +-106 86 58 98 70 6 104 69 6 104 69 6 +-104 69 6 91 60 6 82 62 34 90 90 90 +- 62 62 62 38 38 38 22 22 22 14 14 14 +- 10 10 10 10 10 10 10 10 10 10 10 10 +- 10 10 10 10 10 10 6 6 6 10 10 10 +- 10 10 10 10 10 10 10 10 10 14 14 14 +- 22 22 22 42 42 42 70 70 70 89 81 66 +- 80 54 7 104 69 6 124 80 6 137 92 6 +-134 86 6 116 81 8 100 82 52 86 86 86 +- 58 58 58 30 30 30 14 14 14 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 10 10 10 14 14 14 +- 18 18 18 26 26 26 38 38 38 54 54 54 +- 70 70 70 86 86 86 94 86 76 89 81 66 +- 89 81 66 86 86 86 74 74 74 50 50 50 +- 30 30 30 14 14 14 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 18 18 18 34 34 34 58 58 58 +- 82 82 82 89 81 66 89 81 66 89 81 66 +- 94 86 66 94 86 76 74 74 74 50 50 50 +- 26 26 26 14 14 14 6 6 6 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 6 6 6 6 6 6 14 14 14 18 18 18 +- 30 30 30 38 38 38 46 46 46 54 54 54 +- 50 50 50 42 42 42 30 30 30 18 18 18 +- 10 10 10 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 6 6 6 14 14 14 26 26 26 +- 38 38 38 50 50 50 58 58 58 58 58 58 +- 54 54 54 42 42 42 30 30 30 18 18 18 +- 10 10 10 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 6 6 6 10 10 10 14 14 14 18 18 18 +- 18 18 18 14 14 14 10 10 10 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 6 6 6 +- 14 14 14 18 18 18 22 22 22 22 22 22 +- 18 18 18 14 14 14 10 10 10 6 6 6 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 +- 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 ++0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ++0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 ++10 15 3 2 3 1 12 18 4 42 61 14 19 27 6 11 16 4 ++38 55 13 10 15 3 3 4 1 10 15 3 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 1 ++12 18 4 1 1 0 23 34 8 31 45 11 10 15 3 32 47 11 ++34 49 12 3 4 1 3 4 1 3 4 1 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 10 15 3 29 42 10 26 37 9 12 18 4 ++55 80 19 81 118 28 55 80 19 92 132 31 106 153 36 69 100 23 ++100 144 34 80 116 27 42 61 14 81 118 28 23 34 8 27 40 9 ++15 21 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 1 1 0 29 42 10 15 21 5 50 72 17 ++74 107 25 45 64 15 102 148 35 80 116 27 84 121 28 111 160 38 ++69 100 23 65 94 22 81 118 28 29 42 10 17 25 6 29 42 10 ++23 34 8 2 3 1 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 4 1 ++15 21 5 15 21 5 34 49 12 101 146 34 111 161 38 97 141 33 ++97 141 33 119 172 41 117 170 40 116 167 40 118 170 40 118 171 40 ++117 169 40 118 170 40 111 160 38 118 170 40 96 138 32 89 128 30 ++81 118 28 11 16 4 10 15 3 1 1 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++3 4 1 3 4 1 34 49 12 101 146 34 79 115 27 111 160 38 ++114 165 39 113 163 39 118 170 40 117 169 40 118 171 40 117 169 40 ++116 167 40 119 172 41 113 163 39 92 132 31 105 151 36 113 163 39 ++75 109 26 19 27 6 16 23 5 11 16 4 0 1 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 15 3 ++80 116 27 106 153 36 105 151 36 114 165 39 118 170 40 118 171 40 ++118 171 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 170 40 117 169 40 118 170 40 118 170 40 ++117 170 40 75 109 26 75 109 26 34 49 12 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 4 1 ++64 92 22 65 94 22 100 144 34 118 171 40 118 170 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 118 171 41 118 170 40 117 169 40 ++109 158 37 105 151 36 104 150 35 47 69 16 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++42 61 14 115 167 39 118 170 40 117 169 40 117 169 40 117 169 40 ++117 170 40 117 170 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 118 170 40 96 138 32 17 25 6 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 47 69 16 ++114 165 39 117 168 40 117 170 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 118 170 40 117 169 40 117 169 40 117 169 40 ++117 170 40 119 172 41 96 138 32 12 18 4 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 15 3 ++32 47 11 105 151 36 118 170 40 117 169 40 117 169 40 116 168 40 ++109 157 37 111 160 38 117 169 40 118 171 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 118 171 40 69 100 23 2 3 1 ++0 0 0 0 0 0 0 0 0 0 0 0 19 27 6 101 146 34 ++118 171 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 170 40 ++118 171 40 115 166 39 107 154 36 111 161 38 117 169 40 117 169 40 ++117 169 40 118 171 40 75 109 26 19 27 6 2 3 1 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 23 5 ++89 128 30 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++111 160 38 92 132 31 79 115 27 96 138 32 115 166 39 119 171 41 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 118 170 40 109 157 37 26 37 9 ++0 0 0 0 0 0 0 0 0 0 0 0 64 92 22 118 171 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 118 170 40 118 171 40 109 157 37 ++89 128 30 81 118 28 100 144 34 115 166 39 117 169 40 117 169 40 ++117 169 40 117 170 40 113 163 39 60 86 20 1 1 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++27 40 9 96 138 32 118 170 40 117 169 40 117 169 40 117 169 40 ++117 170 40 117 169 40 101 146 34 67 96 23 55 80 19 84 121 28 ++113 163 39 119 171 41 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 119 171 41 65 94 22 ++0 0 0 0 0 0 0 0 0 15 21 5 101 146 34 118 171 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 118 170 40 118 171 40 104 150 35 69 100 23 53 76 18 ++81 118 28 111 160 38 118 170 40 117 169 40 117 169 40 117 169 40 ++117 169 40 114 165 39 69 100 23 10 15 3 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 ++31 45 11 77 111 26 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 118 170 40 116 168 40 92 132 31 47 69 16 ++38 55 13 81 118 28 113 163 39 119 171 41 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 118 171 41 92 132 31 ++10 15 3 0 0 0 0 0 0 36 52 12 115 166 39 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 118 170 40 ++118 171 40 102 148 35 64 92 22 34 49 12 65 94 22 106 153 36 ++118 171 40 117 170 40 117 169 40 117 169 40 117 169 40 117 169 40 ++118 170 40 107 154 36 55 80 19 15 21 5 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++29 42 10 101 146 34 118 171 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 118 171 40 113 163 39 ++75 109 26 27 40 9 36 52 12 89 128 30 116 167 40 118 171 40 ++117 169 40 117 169 40 117 169 40 117 169 40 118 170 40 104 150 35 ++16 23 5 0 0 0 0 0 0 53 76 18 118 171 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 119 171 41 109 157 37 ++67 96 23 23 34 8 42 61 14 96 138 32 118 170 40 118 170 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 74 107 25 10 15 3 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 31 45 11 101 146 34 118 170 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++119 171 41 102 148 35 47 69 16 14 20 5 50 72 17 102 148 35 ++118 171 40 117 169 40 117 169 40 117 169 40 118 170 40 102 148 35 ++15 21 5 0 0 0 0 0 0 50 72 17 118 170 40 117 169 40 ++117 169 40 117 169 40 118 170 40 116 167 40 84 121 28 27 40 9 ++19 27 6 74 107 25 114 165 39 118 171 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 75 109 26 10 15 4 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 38 55 13 102 148 35 118 171 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 118 170 40 115 167 39 77 111 26 17 25 6 19 27 6 ++77 111 26 115 166 39 118 170 40 117 169 40 119 172 41 81 118 28 ++3 4 1 0 0 0 0 0 0 27 40 9 111 160 38 118 170 40 ++117 169 40 118 171 40 105 151 36 50 72 17 10 15 3 38 55 13 ++100 144 34 118 171 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 79 115 27 15 21 5 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 10 15 3 64 92 22 111 160 38 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 118 171 40 96 138 32 32 47 11 ++3 4 1 50 72 17 107 154 36 120 173 41 105 151 36 31 45 11 ++0 0 0 0 0 0 0 0 0 3 4 1 65 94 22 117 169 40 ++118 170 40 89 128 30 26 37 9 3 4 1 60 86 20 111 161 38 ++118 171 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++97 141 33 36 52 12 1 1 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 14 20 5 75 109 26 117 168 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 118 171 40 107 154 36 ++45 64 15 2 3 1 31 45 11 75 109 26 32 47 11 0 1 0 ++0 0 0 0 0 0 0 0 0 0 0 0 10 15 3 55 80 19 ++65 94 22 11 16 4 11 16 4 75 109 26 116 168 40 118 170 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 118 170 40 107 154 36 ++47 69 16 3 4 1 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 12 18 4 69 100 23 111 161 38 118 171 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 118 170 40 ++111 160 38 50 72 17 2 3 1 2 3 1 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 ++1 1 0 12 18 4 81 118 28 118 170 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 170 40 118 171 40 101 146 34 ++42 61 14 2 3 1 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 3 4 1 36 52 12 89 128 30 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++118 171 41 101 146 34 14 20 5 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 47 69 16 118 170 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 170 40 111 160 38 69 100 23 19 27 6 ++0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 11 16 4 69 100 23 ++115 167 39 119 172 41 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++119 172 41 75 109 26 3 4 1 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 23 34 8 106 153 36 118 170 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++117 169 40 118 170 40 119 172 41 105 151 36 42 61 14 2 3 1 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 15 21 5 ++45 64 15 80 116 27 114 165 39 118 170 40 117 169 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 119 172 41 ++97 141 33 20 30 7 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 1 1 0 53 76 18 114 165 39 118 171 40 117 169 40 ++117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 117 169 40 ++118 171 40 104 150 35 64 92 22 31 45 11 10 15 3 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 36 52 12 97 141 33 109 158 37 113 163 39 116 168 40 ++117 169 40 117 170 40 118 170 40 119 172 41 115 167 39 84 121 28 ++23 34 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 3 4 1 50 72 17 102 148 35 118 171 40 ++119 171 41 118 170 40 117 169 40 117 169 40 115 166 39 111 161 38 ++109 157 37 79 115 27 12 18 4 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 3 4 1 15 21 5 23 34 8 45 64 15 106 153 36 ++116 167 40 111 160 38 101 146 34 79 115 27 42 61 14 10 15 3 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 1 1 0 20 30 7 60 86 20 ++89 128 30 106 153 36 113 163 39 117 169 40 84 121 28 29 42 10 ++19 27 6 10 15 3 2 3 1 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 16 23 5 38 55 13 ++36 52 12 26 37 9 12 18 4 2 3 1 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 1 0 0 19 2 7 52 5 18 ++78 7 27 88 8 31 81 7 29 56 5 19 25 2 9 3 0 1 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++3 4 1 19 27 6 31 45 11 38 55 13 32 47 11 3 4 1 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 1 ++9 0 3 12 1 4 9 0 3 4 0 1 0 0 0 0 0 0 ++0 0 0 0 0 0 28 3 10 99 9 35 156 14 55 182 16 64 ++189 17 66 190 17 67 189 17 66 184 17 65 166 15 58 118 13 41 ++45 4 16 3 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 11 1 4 52 5 18 101 9 35 134 12 47 ++151 14 53 154 14 54 151 14 53 113 10 40 11 1 4 0 0 0 ++3 0 1 67 6 24 159 14 56 190 17 67 190 17 67 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 191 17 67 ++174 16 61 101 9 35 14 1 5 0 0 0 35 3 12 108 10 38 ++122 11 43 122 11 43 112 10 39 87 8 30 50 5 17 13 1 5 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++3 0 1 56 5 19 141 13 49 182 16 64 191 17 67 191 17 67 ++190 17 67 190 17 67 191 17 67 113 10 40 3 0 1 1 0 0 ++79 7 28 180 16 63 190 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++189 17 66 188 17 66 122 11 43 11 1 4 41 4 14 176 16 62 ++191 17 67 191 17 67 191 17 67 190 17 67 181 16 63 146 13 51 ++75 7 26 10 1 4 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 1 2 ++90 8 32 178 16 62 191 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 190 17 67 141 13 49 22 2 8 0 0 0 41 4 14 ++173 16 61 190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 88 8 31 1 0 0 89 8 31 ++185 17 65 189 17 66 188 17 66 188 17 66 189 17 66 191 17 67 ++186 17 65 124 11 43 25 2 9 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 89 8 31 ++184 17 65 189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++190 17 67 151 14 53 34 3 12 0 0 0 0 0 0 79 7 28 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 191 17 67 146 13 51 9 1 3 7 1 2 ++108 10 38 187 17 66 189 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 190 17 67 141 13 49 22 2 8 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 52 5 18 176 16 62 ++189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 ++151 14 53 38 3 13 0 0 0 0 0 0 0 0 0 50 5 17 ++180 16 63 189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 191 17 67 141 13 49 7 1 3 0 0 0 ++11 1 4 112 10 39 187 17 66 189 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 190 17 67 113 10 40 5 0 2 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 7 1 3 132 12 46 191 17 67 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 146 13 51 ++35 3 12 0 0 0 0 0 0 0 0 0 0 0 0 5 0 2 ++101 9 35 185 17 65 190 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 190 17 67 180 16 63 67 6 24 0 0 0 0 0 0 ++0 0 0 11 1 4 108 10 38 186 17 65 189 17 66 188 17 66 ++188 17 66 188 17 66 189 17 66 180 16 63 56 5 19 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 44 4 15 177 16 62 189 17 66 ++188 17 66 188 17 66 189 17 66 189 17 66 134 12 47 28 3 10 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++8 1 3 79 7 28 159 14 56 188 17 66 191 17 67 190 17 67 ++189 17 66 189 17 66 189 17 66 189 17 66 190 17 67 191 17 67 ++188 17 66 158 14 55 72 7 25 4 0 1 0 0 0 0 0 0 ++0 0 0 0 0 0 8 1 3 95 9 33 182 16 64 189 17 67 ++188 17 66 188 17 66 188 17 66 191 17 67 122 11 43 3 0 1 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 88 8 31 190 17 67 188 17 66 ++188 17 66 189 17 66 185 17 65 113 10 40 18 2 6 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 1 0 0 24 2 8 77 7 27 124 11 43 154 14 54 ++168 15 59 173 16 61 173 16 61 168 15 59 154 14 54 124 11 43 ++77 7 27 22 2 8 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 5 0 2 77 7 27 173 16 61 ++190 17 67 188 17 66 188 17 66 190 17 67 164 15 57 23 2 8 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 1 0 0 118 13 41 191 17 67 188 17 66 ++190 17 67 174 16 61 87 8 30 8 1 3 0 0 0 0 0 0 ++0 0 0 0 0 0 10 1 4 29 3 10 40 4 14 36 3 13 ++18 2 6 2 0 1 0 0 0 0 0 0 3 0 1 14 1 5 ++26 2 9 33 3 11 32 3 11 25 2 9 13 1 5 3 0 1 ++0 0 0 14 1 5 56 5 19 95 9 33 109 10 38 101 9 35 ++77 7 27 35 3 12 5 0 2 0 0 0 1 0 0 56 5 19 ++156 14 55 190 17 67 188 17 66 188 17 66 182 16 64 50 5 17 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 5 0 2 134 12 47 191 17 67 189 17 66 ++151 14 53 52 5 18 2 0 1 0 0 0 0 0 0 1 0 0 ++28 3 10 90 8 32 146 13 51 170 15 60 178 16 62 174 16 61 ++158 14 55 112 10 39 40 4 14 1 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 1 ++56 5 19 146 13 51 183 17 64 191 17 67 191 17 67 191 17 67 ++188 17 66 173 16 61 122 11 43 41 4 14 1 0 0 0 0 0 ++30 3 10 124 11 43 185 17 65 190 17 67 187 17 66 67 6 24 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 6 1 2 134 12 47 168 15 59 99 9 35 ++21 2 7 0 0 0 0 0 0 0 0 0 6 1 2 77 7 27 ++162 15 57 190 17 67 191 17 67 189 17 66 189 17 66 189 17 66 ++190 17 67 191 17 67 169 15 59 75 7 26 3 0 1 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 79 7 28 ++178 16 62 191 17 67 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 191 17 67 170 15 60 79 7 28 5 0 2 ++0 0 0 10 1 3 78 7 27 159 14 56 188 17 66 75 7 26 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 1 0 0 35 3 12 29 3 10 2 0 1 ++0 0 0 0 0 0 0 0 0 9 1 3 101 9 35 183 17 64 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 190 17 67 178 16 63 67 6 23 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 52 5 18 174 16 61 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 190 17 67 182 16 64 89 8 31 ++4 0 1 0 0 0 0 0 0 25 2 9 73 7 26 31 3 11 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 4 0 1 98 9 34 187 17 66 189 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 190 17 67 158 14 55 25 2 9 ++0 0 0 0 0 0 0 0 0 8 1 3 134 12 47 191 17 67 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 189 17 66 180 16 63 ++68 6 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 6 1 2 19 2 7 3 0 1 0 0 0 0 0 0 ++0 0 0 0 0 0 65 6 23 180 16 63 189 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 189 17 66 83 8 29 ++0 0 0 0 0 0 0 0 0 41 4 14 177 16 62 189 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 ++159 14 56 28 3 10 0 0 0 0 0 0 0 0 0 23 2 8 ++41 4 14 5 0 2 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++23 2 8 113 10 40 159 14 56 65 6 23 0 0 0 0 0 0 ++0 0 0 16 1 6 146 13 51 191 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 191 17 67 132 12 46 ++5 0 2 0 0 0 0 0 0 77 7 27 189 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++190 17 67 98 9 34 0 0 0 0 0 0 12 1 4 134 12 47 ++178 16 63 108 10 38 16 1 6 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30 3 10 ++141 13 49 190 17 67 191 17 67 134 12 47 6 1 2 0 0 0 ++0 0 0 68 6 24 186 17 65 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 156 14 55 ++14 1 5 0 0 0 0 0 0 98 9 34 191 17 67 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++190 17 67 156 14 55 19 2 7 0 0 0 47 4 16 181 16 63 ++190 17 67 189 17 66 126 14 44 17 2 6 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 16 1 6 134 12 47 ++191 17 67 188 17 66 190 17 67 162 15 57 19 2 7 0 0 0 ++3 0 1 123 11 43 191 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 163 15 57 ++20 2 7 0 0 0 0 0 0 101 9 35 191 17 67 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 182 16 64 52 5 18 0 0 0 73 7 26 188 17 66 ++188 17 66 188 17 66 189 17 66 109 10 38 5 0 2 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 95 9 33 189 17 66 ++188 17 66 188 17 66 189 17 66 171 15 60 29 3 10 0 0 0 ++16 1 6 156 14 55 190 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 158 14 55 ++17 2 6 0 0 0 0 0 0 85 8 30 190 17 67 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 81 7 29 0 0 0 85 8 30 190 17 67 ++188 17 66 188 17 66 189 17 66 180 16 63 56 5 19 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 25 2 9 162 15 57 190 17 67 ++188 17 66 188 17 66 189 17 66 173 16 61 31 3 11 0 0 0 ++30 3 10 171 15 60 189 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 191 17 67 141 13 49 ++7 1 2 0 0 0 0 0 0 56 5 19 183 17 64 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 191 17 67 98 9 34 0 0 0 88 8 31 190 17 67 ++188 17 66 188 17 66 188 17 66 191 17 67 124 11 43 5 0 2 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 68 6 24 187 17 66 188 17 66 ++188 17 66 188 17 66 189 17 66 170 15 60 28 3 10 0 0 0 ++34 3 12 174 16 61 189 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 191 17 67 101 9 35 ++0 0 0 0 0 0 0 0 0 21 2 7 159 14 56 190 17 67 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 191 17 67 98 9 34 0 0 0 81 7 29 189 17 66 ++188 17 66 188 17 66 188 17 66 189 17 66 168 15 59 28 3 10 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 109 10 38 191 17 67 188 17 66 ++188 17 66 188 17 66 190 17 67 163 15 57 21 2 7 0 0 0 ++26 2 9 168 15 59 189 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 189 17 66 180 16 63 47 4 16 ++0 0 0 0 0 0 0 0 0 0 0 0 108 10 38 190 17 67 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 78 7 27 0 0 0 68 6 24 187 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 183 17 64 56 5 19 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 3 0 1 131 12 46 191 17 67 188 17 66 ++188 17 66 188 17 66 190 17 67 151 14 53 12 1 4 0 0 0 ++11 1 4 146 13 51 190 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 191 17 67 126 14 44 7 1 2 ++0 0 0 0 0 0 0 0 0 0 0 0 32 3 11 164 15 58 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++189 17 66 178 16 62 44 4 15 0 0 0 50 5 17 182 16 64 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 72 7 25 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 5 0 2 134 12 47 191 17 67 188 17 66 ++188 17 66 188 17 66 191 17 67 131 12 46 3 0 1 0 0 0 ++0 0 0 101 9 35 190 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 190 17 67 170 15 60 44 4 15 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 7 27 ++183 17 64 189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++191 17 67 134 12 47 9 1 3 0 0 0 31 3 11 171 15 60 ++189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 72 7 25 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 2 0 1 124 11 43 191 17 67 188 17 66 ++188 17 66 188 17 66 191 17 67 101 9 35 0 0 0 0 0 0 ++0 0 0 35 3 12 168 15 59 190 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 182 16 64 77 7 27 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 1 2 ++99 9 35 185 17 65 189 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 189 17 66 ++177 16 62 56 5 19 0 0 0 0 0 0 13 1 5 151 14 53 ++190 17 67 188 17 66 188 17 66 188 17 66 185 17 65 56 5 19 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 99 9 35 191 17 67 188 17 66 ++188 17 66 188 17 66 186 17 65 65 6 23 0 0 0 0 0 0 ++0 0 0 0 0 0 79 7 28 182 16 64 190 17 67 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++191 17 67 177 16 62 83 8 29 4 0 1 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++8 1 3 89 8 31 175 16 62 191 17 67 189 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 181 16 63 ++85 8 30 3 0 1 0 0 0 0 0 0 1 0 0 118 13 41 ++191 17 67 188 17 66 188 17 66 189 17 66 173 16 61 34 3 12 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 56 5 19 183 17 64 188 17 66 ++188 17 66 189 17 66 169 15 59 30 3 10 0 0 0 0 0 0 ++0 0 0 0 0 0 5 0 2 83 8 29 173 16 61 191 17 67 ++190 17 67 189 17 66 189 17 66 190 17 67 191 17 67 187 17 66 ++151 14 53 56 5 19 3 0 1 0 0 0 16 1 6 50 5 17 ++79 7 28 95 9 33 95 9 33 75 7 26 41 4 14 10 1 4 ++0 0 0 2 0 1 50 5 17 132 12 46 178 16 62 190 17 67 ++191 17 67 191 17 67 191 17 67 186 17 65 154 14 54 68 6 24 ++4 0 1 0 0 0 0 0 0 0 0 0 0 0 0 72 7 25 ++187 17 66 188 17 66 188 17 66 191 17 67 141 13 49 9 1 3 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 14 1 5 151 14 53 190 17 67 ++188 17 66 191 17 67 131 12 46 5 0 2 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 2 0 1 44 4 15 113 10 40 ++156 14 55 173 16 61 174 16 61 164 15 58 134 12 47 77 7 27 ++18 2 6 0 0 0 16 1 6 85 8 30 151 14 53 182 16 64 ++189 17 66 191 17 67 190 17 67 188 17 66 177 16 62 141 13 49 ++68 6 24 8 1 3 0 0 0 8 1 3 44 4 15 88 8 31 ++113 10 40 122 11 43 108 10 38 67 6 24 20 2 7 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 28 3 10 ++166 15 58 190 17 67 188 17 66 187 17 66 79 7 28 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 73 7 26 185 17 65 ++189 17 66 184 17 65 65 6 23 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 ++17 2 6 32 3 11 34 3 12 22 2 8 6 1 2 0 0 0 ++0 0 0 38 3 13 141 13 49 188 17 66 190 17 67 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 189 17 66 191 17 67 ++184 17 65 122 11 43 21 2 7 0 0 0 0 0 0 0 0 0 ++0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ++108 10 38 191 17 67 191 17 67 141 13 49 16 1 6 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 8 1 3 112 10 39 ++186 17 65 124 11 43 10 1 4 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++36 3 13 156 14 55 191 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++189 17 66 190 17 67 134 12 47 18 2 6 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 7 1 2 41 4 14 75 7 26 66 5 23 19 2 7 ++26 2 9 144 13 50 154 14 54 40 4 14 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 1 5 ++56 5 19 19 2 7 0 0 0 7 1 2 29 3 10 35 3 12 ++19 2 7 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 1 5 ++134 12 47 191 17 67 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 189 17 67 108 10 38 3 0 1 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ++40 4 14 124 11 43 177 16 62 188 17 66 187 17 66 144 13 50 ++24 2 8 17 2 6 22 2 8 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 19 2 7 122 11 43 171 15 60 175 16 62 ++159 14 56 112 10 39 40 4 14 2 0 1 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 72 7 25 ++186 17 65 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 189 17 66 174 16 61 41 4 14 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 3 0 1 72 7 25 ++168 15 59 191 17 67 189 17 66 188 17 66 188 17 66 190 17 67 ++95 9 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 95 9 33 191 17 67 189 17 66 189 17 66 ++190 17 67 191 17 67 171 15 60 90 8 32 12 1 4 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 5 0 2 132 12 46 ++191 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 190 17 67 98 9 34 0 0 0 ++0 0 0 0 0 0 0 0 0 5 0 2 88 8 31 180 16 63 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 191 17 67 ++146 13 51 11 1 4 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 9 1 3 144 13 50 191 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 189 17 66 187 17 66 123 11 43 20 2 7 ++0 0 0 0 0 0 0 0 0 0 0 0 21 2 7 163 15 57 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 191 17 67 134 12 47 5 0 2 ++0 0 0 0 0 0 3 0 1 88 8 31 182 16 64 189 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 189 17 66 ++171 15 60 31 3 11 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 20 2 7 162 15 57 190 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 132 12 46 ++20 2 7 0 0 0 0 0 0 0 0 0 32 3 11 173 16 61 ++189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 190 17 67 151 14 53 12 1 4 ++0 0 0 0 0 0 72 7 25 180 16 63 189 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++181 16 63 47 4 16 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 21 2 7 163 15 57 190 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 ++122 11 43 9 1 3 0 0 0 0 0 0 30 3 10 171 15 60 ++189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 190 17 67 146 13 51 10 1 4 ++0 0 0 38 3 13 166 15 58 190 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++183 17 64 52 5 18 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 13 1 5 154 14 54 190 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++186 17 65 79 7 28 0 0 0 0 0 0 14 1 5 156 14 54 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 191 17 67 124 11 43 2 0 1 ++5 0 2 122 11 43 191 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++182 16 64 47 4 16 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 3 0 1 126 14 44 191 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++190 17 67 158 14 55 23 2 8 0 0 0 1 0 0 113 10 40 ++191 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 78 7 27 0 0 0 ++47 4 16 177 16 62 189 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 189 17 66 ++173 16 61 34 3 12 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 85 8 30 189 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 79 7 28 0 0 0 0 0 0 47 4 16 ++175 16 62 189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 190 17 67 156 14 55 22 2 8 0 0 0 ++109 10 38 191 17 67 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 ++151 14 53 13 1 5 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 35 3 12 173 16 61 189 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 191 17 67 134 12 47 7 1 2 0 0 0 3 0 1 ++99 9 35 188 17 66 189 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 181 16 63 68 6 24 0 0 0 18 2 6 ++156 14 55 190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 ++101 9 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 3 0 1 118 13 41 191 17 67 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 168 15 59 28 3 10 0 0 0 0 0 0 ++12 1 4 113 10 40 187 17 66 189 17 67 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++190 17 67 180 16 63 88 8 31 4 0 1 0 0 0 47 4 16 ++180 16 63 189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 190 17 67 168 15 59 ++36 3 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 38 3 13 164 15 58 190 17 67 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 182 16 64 50 5 17 0 0 0 0 0 0 ++0 0 0 11 1 4 90 8 32 169 15 59 190 17 67 190 17 67 ++189 17 66 189 17 66 189 17 66 189 17 66 191 17 67 189 17 66 ++158 14 55 68 6 24 4 0 1 0 0 0 0 0 0 73 7 26 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 189 17 66 185 17 65 83 8 29 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 65 6 23 174 16 61 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 185 17 65 56 5 19 0 0 0 0 0 0 ++0 0 0 0 0 0 2 0 1 35 3 12 99 9 35 146 13 51 ++170 15 60 177 16 62 177 16 62 166 15 58 141 13 49 85 8 30 ++24 2 8 0 0 0 0 0 0 0 0 0 0 0 0 85 8 30 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 189 17 66 112 10 39 8 1 3 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 68 6 24 ++170 15 60 191 17 67 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 182 16 64 50 5 17 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 11 1 4 ++28 3 10 40 4 14 38 3 13 25 2 9 8 1 3 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 78 7 27 ++189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 187 17 66 113 10 40 14 1 5 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ++47 4 16 141 13 49 186 17 65 191 17 67 190 17 67 189 17 66 ++189 17 66 191 17 67 156 14 55 20 2 7 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 4 15 ++178 16 62 190 17 67 188 17 66 188 17 66 188 17 66 190 17 67 ++191 17 67 173 16 61 90 8 32 10 1 4 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 14 1 5 68 6 24 131 12 46 162 15 57 174 16 61 ++171 15 60 146 13 51 56 5 19 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 3 0 1 14 1 5 29 3 10 ++41 4 14 47 4 16 50 5 17 45 4 16 34 3 12 18 2 6 ++5 0 2 0 0 0 0 0 0 0 0 0 0 0 0 5 0 2 ++90 8 32 169 15 59 185 17 65 187 17 66 182 16 64 163 15 57 ++113 10 40 41 4 14 2 0 1 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 5 0 2 21 2 7 34 3 12 ++29 3 10 11 1 4 0 0 0 0 0 0 0 0 0 0 0 0 ++3 0 1 32 3 11 79 7 28 124 11 43 154 14 54 171 15 60 ++180 16 63 182 16 64 182 16 64 180 16 63 174 16 61 159 14 56 ++132 12 46 88 8 31 34 3 12 3 0 1 0 0 0 0 0 0 ++3 0 1 29 3 10 56 5 19 65 6 23 50 5 17 23 2 8 ++3 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 2 9 ++109 10 38 169 15 59 189 17 66 191 17 67 190 17 67 189 17 66 ++189 17 66 188 17 66 188 17 66 188 17 66 189 17 66 190 17 67 ++191 17 67 190 17 67 171 15 60 98 9 34 10 1 3 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 14 1 5 141 13 49 ++191 17 67 189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 189 17 67 186 17 65 65 6 23 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 23 2 8 166 15 58 ++190 17 67 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 189 17 66 176 16 62 45 4 16 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 83 8 29 ++183 17 64 189 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++188 17 66 189 17 66 185 17 65 95 9 33 3 0 1 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 2 ++85 8 30 176 16 62 191 17 67 188 17 66 188 17 66 188 17 66 ++188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 188 17 66 ++191 17 67 180 16 63 95 9 33 7 1 3 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++2 0 1 52 5 18 141 13 49 185 17 65 191 17 67 189 17 67 ++189 17 66 188 17 66 188 17 66 189 17 66 191 17 67 187 17 66 ++146 13 51 56 5 19 4 0 1 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 14 1 5 68 6 24 131 12 46 166 15 58 ++180 16 63 183 17 64 180 16 63 168 15 59 134 12 47 75 7 26 ++17 2 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 5 0 2 24 2 8 ++44 4 15 52 5 18 45 4 16 26 2 9 6 1 2 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 +Index: linux-3.10-3.10.11/dummy/rpi_1574_5ee582d3526b124b504d8dc353ced66b6c21ba00.txt +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/dummy/rpi_1574_5ee582d3526b124b504d8dc353ced66b6c21ba00.txt 2014-05-05 12:51:21.000000000 +0000 +@@ -0,0 +1 @@ ++dummy file to ensure patch has content. diff -Nru linux-3.10.11/debian/patches/rpi/rpi_1575_6e071d83898b7165638d959c8732e030a83cbd60.patch linux-3.10-3.10.11/debian/patches/rpi/rpi_1575_6e071d83898b7165638d959c8732e030a83cbd60.patch --- linux-3.10.11/debian/patches/rpi/rpi_1575_6e071d83898b7165638d959c8732e030a83cbd60.patch 1970-01-01 00:00:00.000000000 +0000 +++ linux-3.10-3.10.11/debian/patches/rpi/rpi_1575_6e071d83898b7165638d959c8732e030a83cbd60.patch 2014-05-05 12:51:25.000000000 +0000 @@ -0,0 +1,12417 @@ +commit 6e071d83898b7165638d959c8732e030a83cbd60 +Author: popcornmix +Date: Tue Jul 2 23:42:01 2013 +0100 + + bcm2708 vchiq driver + + Signed-off-by: popcornmix + +Index: linux-3.10-3.10.11/drivers/misc/Kconfig +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/Kconfig 2014-05-05 12:42:36.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/Kconfig 2014-05-05 12:51:22.000000000 +0000 +@@ -536,4 +536,6 @@ + source "drivers/misc/altera-stapl/Kconfig" + source "drivers/misc/mei/Kconfig" + source "drivers/misc/vmw_vmci/Kconfig" ++source "drivers/misc/vc04_services/Kconfig" + endmenu ++ +Index: linux-3.10-3.10.11/drivers/misc/Makefile +=================================================================== +--- linux-3.10-3.10.11.orig/drivers/misc/Makefile 2014-05-05 11:48:33.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/Makefile 2014-05-05 12:51:22.000000000 +0000 +@@ -53,3 +53,4 @@ + obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ + obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o + obj-$(CONFIG_SRAM) += sram.o ++obj-y += vc04_services/ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/Kconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/Kconfig 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,10 @@ ++config BCM2708_VCHIQ ++ tristate "Videocore VCHIQ" ++ depends on MACH_BCM2708 ++ default y ++ help ++ Kernel to VideoCore communication interface for the ++ BCM2708 family of products. ++ Defaults to Y when the Broadcom Videocore services ++ are included in the build, N otherwise. ++ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/Makefile 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,18 @@ ++ifeq ($(CONFIG_MACH_BCM2708),y) ++ ++obj-$(CONFIG_BCM2708_VCHIQ) += vchiq.o ++ ++vchiq-objs := \ ++ interface/vchiq_arm/vchiq_core.o \ ++ interface/vchiq_arm/vchiq_arm.o \ ++ interface/vchiq_arm/vchiq_kern_lib.o \ ++ interface/vchiq_arm/vchiq_2835_arm.o \ ++ interface/vchiq_arm/vchiq_proc.o \ ++ interface/vchiq_arm/vchiq_shim.o \ ++ interface/vchiq_arm/vchiq_util.o \ ++ interface/vchiq_arm/vchiq_connected.o \ ++ ++EXTRA_CFLAGS += -DVCOS_VERIFY_BKPTS=1 -Idrivers/misc/vc04_services -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 ++ ++endif ++ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/connections/connection.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/connections/connection.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,328 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef CONNECTION_H_ ++#define CONNECTION_H_ ++ ++#include ++#include ++#include ++ ++#include "interface/vchi/vchi_cfg_internal.h" ++#include "interface/vchi/vchi_common.h" ++#include "interface/vchi/message_drivers/message.h" ++ ++/****************************************************************************** ++ Global defs ++ *****************************************************************************/ ++ ++// Opaque handle for a connection / service pair ++typedef struct opaque_vchi_connection_connected_service_handle_t *VCHI_CONNECTION_SERVICE_HANDLE_T; ++ ++// opaque handle to the connection state information ++typedef struct opaque_vchi_connection_info_t VCHI_CONNECTION_STATE_T; ++ ++typedef struct vchi_connection_t VCHI_CONNECTION_T; ++ ++ ++/****************************************************************************** ++ API ++ *****************************************************************************/ ++ ++// Routine to init a connection with a particular low level driver ++typedef VCHI_CONNECTION_STATE_T * (*VCHI_CONNECTION_INIT_T)( struct vchi_connection_t * connection, ++ const VCHI_MESSAGE_DRIVER_T * driver ); ++ ++// Routine to control CRC enabling at a connection level ++typedef int32_t (*VCHI_CONNECTION_CRC_CONTROL_T)( VCHI_CONNECTION_STATE_T *state_handle, ++ VCHI_CRC_CONTROL_T control ); ++ ++// Routine to create a service ++typedef int32_t (*VCHI_CONNECTION_SERVICE_CONNECT_T)( VCHI_CONNECTION_STATE_T *state_handle, ++ int32_t service_id, ++ uint32_t rx_fifo_size, ++ uint32_t tx_fifo_size, ++ int server, ++ VCHI_CALLBACK_T callback, ++ void *callback_param, ++ int32_t want_crc, ++ int32_t want_unaligned_bulk_rx, ++ int32_t want_unaligned_bulk_tx, ++ VCHI_CONNECTION_SERVICE_HANDLE_T *service_handle ); ++ ++// Routine to close a service ++typedef int32_t (*VCHI_CONNECTION_SERVICE_DISCONNECT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle ); ++ ++// Routine to queue a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ const void *data, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// scatter-gather (vector) message queueing ++typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ VCHI_MSG_VECTOR_T *vector, ++ uint32_t count, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// Routine to dequeue a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *data, ++ uint32_t max_data_size_to_read, ++ uint32_t *actual_msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to peek at a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void **data, ++ uint32_t *msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to hold a message ++typedef int32_t (*VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void **data, ++ uint32_t *msg_size, ++ VCHI_FLAGS_T flags, ++ void **message_handle ); ++ ++// Routine to initialise a received message iterator ++typedef int32_t (*VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ VCHI_MSG_ITER_T *iter, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to release a held message ++typedef int32_t (*VCHI_CONNECTION_HELD_MSG_RELEASE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *message_handle ); ++ ++// Routine to get info on a held message ++typedef int32_t (*VCHI_CONNECTION_HELD_MSG_INFO_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *message_handle, ++ void **data, ++ int32_t *msg_size, ++ uint32_t *tx_timestamp, ++ uint32_t *rx_timestamp ); ++ ++// Routine to check whether the iterator has a next message ++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ const VCHI_MSG_ITER_T *iter ); ++ ++// Routine to advance the iterator ++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ VCHI_MSG_ITER_T *iter, ++ void **data, ++ uint32_t *msg_size ); ++ ++// Routine to remove the last message returned by the iterator ++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_REMOVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ VCHI_MSG_ITER_T *iter ); ++ ++// Routine to hold the last message returned by the iterator ++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HOLD_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service, ++ VCHI_MSG_ITER_T *iter, ++ void **msg_handle ); ++ ++// Routine to transmit bulk data ++typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ const void *data_src, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *bulk_handle ); ++ ++// Routine to receive data ++typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, ++ void *data_dst, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *bulk_handle ); ++ ++// Routine to report if a server is available ++typedef int32_t (*VCHI_CONNECTION_SERVER_PRESENT)( VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t peer_flags ); ++ ++// Routine to report the number of RX slots available ++typedef int (*VCHI_CONNECTION_RX_SLOTS_AVAILABLE)( const VCHI_CONNECTION_STATE_T *state ); ++ ++// Routine to report the RX slot size ++typedef uint32_t (*VCHI_CONNECTION_RX_SLOT_SIZE)( const VCHI_CONNECTION_STATE_T *state ); ++ ++// Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO ++typedef void (*VCHI_CONNECTION_RX_BULK_BUFFER_ADDED)(VCHI_CONNECTION_STATE_T *state, ++ int32_t service, ++ uint32_t length, ++ MESSAGE_TX_CHANNEL_T channel, ++ uint32_t channel_params, ++ uint32_t data_length, ++ uint32_t data_offset); ++ ++// Callback to inform a service that a Xon or Xoff message has been received ++typedef void (*VCHI_CONNECTION_FLOW_CONTROL)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t xoff); ++ ++// Callback to inform a service that a server available reply message has been received ++typedef void (*VCHI_CONNECTION_SERVER_AVAILABLE_REPLY)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, uint32_t flags); ++ ++// Callback to indicate that bulk auxiliary messages have arrived ++typedef void (*VCHI_CONNECTION_BULK_AUX_RECEIVED)(VCHI_CONNECTION_STATE_T *state); ++ ++// Callback to indicate that bulk auxiliary messages have arrived ++typedef void (*VCHI_CONNECTION_BULK_AUX_TRANSMITTED)(VCHI_CONNECTION_STATE_T *state, void *handle); ++ ++// Callback with all the connection info you require ++typedef void (*VCHI_CONNECTION_INFO)(VCHI_CONNECTION_STATE_T *state, uint32_t protocol_version, uint32_t slot_size, uint32_t num_slots, uint32_t min_bulk_size); ++ ++// Callback to inform of a disconnect ++typedef void (*VCHI_CONNECTION_DISCONNECT)(VCHI_CONNECTION_STATE_T *state, uint32_t flags); ++ ++// Callback to inform of a power control request ++typedef void (*VCHI_CONNECTION_POWER_CONTROL)(VCHI_CONNECTION_STATE_T *state, MESSAGE_TX_CHANNEL_T channel, int32_t enable); ++ ++// allocate memory suitably aligned for this connection ++typedef void * (*VCHI_BUFFER_ALLOCATE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, uint32_t * length); ++ ++// free memory allocated by buffer_allocate ++typedef void (*VCHI_BUFFER_FREE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, void * address); ++ ++ ++/****************************************************************************** ++ System driver struct ++ *****************************************************************************/ ++ ++struct opaque_vchi_connection_api_t ++{ ++ // Routine to init the connection ++ VCHI_CONNECTION_INIT_T init; ++ ++ // Connection-level CRC control ++ VCHI_CONNECTION_CRC_CONTROL_T crc_control; ++ ++ // Routine to connect to or create service ++ VCHI_CONNECTION_SERVICE_CONNECT_T service_connect; ++ ++ // Routine to disconnect from a service ++ VCHI_CONNECTION_SERVICE_DISCONNECT_T service_disconnect; ++ ++ // Routine to queue a message ++ VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T service_queue_msg; ++ ++ // scatter-gather (vector) message queue ++ VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T service_queue_msgv; ++ ++ // Routine to dequeue a message ++ VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T service_dequeue_msg; ++ ++ // Routine to peek at a message ++ VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T service_peek_msg; ++ ++ // Routine to hold a message ++ VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T service_hold_msg; ++ ++ // Routine to initialise a received message iterator ++ VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T service_look_ahead_msg; ++ ++ // Routine to release a message ++ VCHI_CONNECTION_HELD_MSG_RELEASE_T held_msg_release; ++ ++ // Routine to get information on a held message ++ VCHI_CONNECTION_HELD_MSG_INFO_T held_msg_info; ++ ++ // Routine to check for next message on iterator ++ VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T msg_iter_has_next; ++ ++ // Routine to get next message on iterator ++ VCHI_CONNECTION_MSG_ITER_NEXT_T msg_iter_next; ++ ++ // Routine to remove the last message returned by iterator ++ VCHI_CONNECTION_MSG_ITER_REMOVE_T msg_iter_remove; ++ ++ // Routine to hold the last message returned by iterator ++ VCHI_CONNECTION_MSG_ITER_HOLD_T msg_iter_hold; ++ ++ // Routine to transmit bulk data ++ VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T bulk_queue_transmit; ++ ++ // Routine to receive data ++ VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T bulk_queue_receive; ++ ++ // Routine to report the available servers ++ VCHI_CONNECTION_SERVER_PRESENT server_present; ++ ++ // Routine to report the number of RX slots available ++ VCHI_CONNECTION_RX_SLOTS_AVAILABLE connection_rx_slots_available; ++ ++ // Routine to report the RX slot size ++ VCHI_CONNECTION_RX_SLOT_SIZE connection_rx_slot_size; ++ ++ // Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO ++ VCHI_CONNECTION_RX_BULK_BUFFER_ADDED rx_bulk_buffer_added; ++ ++ // Callback to inform a service that a Xon or Xoff message has been received ++ VCHI_CONNECTION_FLOW_CONTROL flow_control; ++ ++ // Callback to inform a service that a server available reply message has been received ++ VCHI_CONNECTION_SERVER_AVAILABLE_REPLY server_available_reply; ++ ++ // Callback to indicate that bulk auxiliary messages have arrived ++ VCHI_CONNECTION_BULK_AUX_RECEIVED bulk_aux_received; ++ ++ // Callback to indicate that a bulk auxiliary message has been transmitted ++ VCHI_CONNECTION_BULK_AUX_TRANSMITTED bulk_aux_transmitted; ++ ++ // Callback to provide information about the connection ++ VCHI_CONNECTION_INFO connection_info; ++ ++ // Callback to notify that peer has requested disconnect ++ VCHI_CONNECTION_DISCONNECT disconnect; ++ ++ // Callback to notify that peer has requested power change ++ VCHI_CONNECTION_POWER_CONTROL power_control; ++ ++ // allocate memory suitably aligned for this connection ++ VCHI_BUFFER_ALLOCATE buffer_allocate; ++ ++ // free memory allocated by buffer_allocate ++ VCHI_BUFFER_FREE buffer_free; ++ ++}; ++ ++struct vchi_connection_t { ++ const VCHI_CONNECTION_API_T *api; ++ VCHI_CONNECTION_STATE_T *state; ++#ifdef VCHI_COARSE_LOCKING ++ struct semaphore sem; ++#endif ++}; ++ ++ ++#endif /* CONNECTION_H_ */ ++ ++/****************************** End of file **********************************/ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/message_drivers/message.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/message_drivers/message.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,204 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef _VCHI_MESSAGE_H_ ++#define _VCHI_MESSAGE_H_ ++ ++#include ++#include ++#include ++ ++#include "interface/vchi/vchi_cfg_internal.h" ++#include "interface/vchi/vchi_common.h" ++ ++ ++typedef enum message_event_type { ++ MESSAGE_EVENT_NONE, ++ MESSAGE_EVENT_NOP, ++ MESSAGE_EVENT_MESSAGE, ++ MESSAGE_EVENT_SLOT_COMPLETE, ++ MESSAGE_EVENT_RX_BULK_PAUSED, ++ MESSAGE_EVENT_RX_BULK_COMPLETE, ++ MESSAGE_EVENT_TX_COMPLETE, ++ MESSAGE_EVENT_MSG_DISCARDED ++} MESSAGE_EVENT_TYPE_T; ++ ++typedef enum vchi_msg_flags ++{ ++ VCHI_MSG_FLAGS_NONE = 0x0, ++ VCHI_MSG_FLAGS_TERMINATE_DMA = 0x1 ++} VCHI_MSG_FLAGS_T; ++ ++typedef enum message_tx_channel ++{ ++ MESSAGE_TX_CHANNEL_MESSAGE = 0, ++ MESSAGE_TX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards ++} MESSAGE_TX_CHANNEL_T; ++ ++// Macros used for cycling through bulk channels ++#define MESSAGE_TX_CHANNEL_BULK_PREV(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION-1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION) ++#define MESSAGE_TX_CHANNEL_BULK_NEXT(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION) ++ ++typedef enum message_rx_channel ++{ ++ MESSAGE_RX_CHANNEL_MESSAGE = 0, ++ MESSAGE_RX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards ++} MESSAGE_RX_CHANNEL_T; ++ ++// Message receive slot information ++typedef struct rx_msg_slot_info { ++ ++ struct rx_msg_slot_info *next; ++ //struct slot_info *prev; ++#if !defined VCHI_COARSE_LOCKING ++ struct semaphore sem; ++#endif ++ ++ uint8_t *addr; // base address of slot ++ uint32_t len; // length of slot in bytes ++ ++ uint32_t write_ptr; // hardware causes this to advance ++ uint32_t read_ptr; // this module does the reading ++ int active; // is this slot in the hardware dma fifo? ++ uint32_t msgs_parsed; // count how many messages are in this slot ++ uint32_t msgs_released; // how many messages have been released ++ void *state; // connection state information ++ uint8_t ref_count[VCHI_MAX_SERVICES_PER_CONNECTION]; // reference count for slots held by services ++} RX_MSG_SLOTINFO_T; ++ ++// The message driver no longer needs to know about the fields of RX_BULK_SLOTINFO_T - sort this out. ++// In particular, it mustn't use addr and len - they're the client buffer, but the message ++// driver will be tasked with sending the aligned core section. ++typedef struct rx_bulk_slotinfo_t { ++ struct rx_bulk_slotinfo_t *next; ++ ++ struct semaphore *blocking; ++ ++ // needed by DMA ++ void *addr; ++ uint32_t len; ++ ++ // needed for the callback ++ void *service; ++ void *handle; ++ VCHI_FLAGS_T flags; ++} RX_BULK_SLOTINFO_T; ++ ++ ++/* ---------------------------------------------------------------------- ++ * each connection driver will have a pool of the following struct. ++ * ++ * the pool will be managed by vchi_qman_* ++ * this means there will be multiple queues (single linked lists) ++ * a given struct message_info will be on exactly one of these queues ++ * at any one time ++ * -------------------------------------------------------------------- */ ++typedef struct rx_message_info { ++ ++ struct message_info *next; ++ //struct message_info *prev; ++ ++ uint8_t *addr; ++ uint32_t len; ++ RX_MSG_SLOTINFO_T *slot; // points to whichever slot contains this message ++ uint32_t tx_timestamp; ++ uint32_t rx_timestamp; ++ ++} RX_MESSAGE_INFO_T; ++ ++typedef struct { ++ MESSAGE_EVENT_TYPE_T type; ++ ++ struct { ++ // for messages ++ void *addr; // address of message ++ uint16_t slot_delta; // whether this message indicated slot delta ++ uint32_t len; // length of message ++ RX_MSG_SLOTINFO_T *slot; // slot this message is in ++ int32_t service; // service id this message is destined for ++ uint32_t tx_timestamp; // timestamp from the header ++ uint32_t rx_timestamp; // timestamp when we parsed it ++ } message; ++ ++ // FIXME: cleanup slot reporting... ++ RX_MSG_SLOTINFO_T *rx_msg; ++ RX_BULK_SLOTINFO_T *rx_bulk; ++ void *tx_handle; ++ MESSAGE_TX_CHANNEL_T tx_channel; ++ ++} MESSAGE_EVENT_T; ++ ++ ++// callbacks ++typedef void VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T( void *state ); ++ ++typedef struct { ++ VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T *event_callback; ++} VCHI_MESSAGE_DRIVER_OPEN_T; ++ ++ ++// handle to this instance of message driver (as returned by ->open) ++typedef struct opaque_mhandle_t *VCHI_MDRIVER_HANDLE_T; ++ ++struct opaque_vchi_message_driver_t { ++ VCHI_MDRIVER_HANDLE_T *(*open)( VCHI_MESSAGE_DRIVER_OPEN_T *params, void *state ); ++ int32_t (*suspending)( VCHI_MDRIVER_HANDLE_T *handle ); ++ int32_t (*resumed)( VCHI_MDRIVER_HANDLE_T *handle ); ++ int32_t (*power_control)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T, int32_t enable ); ++ int32_t (*add_msg_rx_slot)( VCHI_MDRIVER_HANDLE_T *handle, RX_MSG_SLOTINFO_T *slot ); // rx message ++ int32_t (*add_bulk_rx)( VCHI_MDRIVER_HANDLE_T *handle, void *data, uint32_t len, RX_BULK_SLOTINFO_T *slot ); // rx data (bulk) ++ int32_t (*send)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, VCHI_MSG_FLAGS_T flags, void *send_handle ); // tx (message & bulk) ++ void (*next_event)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_EVENT_T *event ); // get the next event from message_driver ++ int32_t (*enable)( VCHI_MDRIVER_HANDLE_T *handle ); ++ int32_t (*form_message)( VCHI_MDRIVER_HANDLE_T *handle, int32_t service_id, VCHI_MSG_VECTOR_T *vector, uint32_t count, void ++ *address, uint32_t length_avail, uint32_t max_total_length, int32_t pad_to_fill, int32_t allow_partial ); ++ ++ int32_t (*update_message)( VCHI_MDRIVER_HANDLE_T *handle, void *dest, int16_t *slot_count ); ++ int32_t (*buffer_aligned)( VCHI_MDRIVER_HANDLE_T *handle, int tx, int uncached, const void *address, const uint32_t length ); ++ void * (*allocate_buffer)( VCHI_MDRIVER_HANDLE_T *handle, uint32_t *length ); ++ void (*free_buffer)( VCHI_MDRIVER_HANDLE_T *handle, void *address ); ++ int (*rx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size ); ++ int (*tx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size ); ++ ++ int32_t (*tx_supports_terminate)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel ); ++ uint32_t (*tx_bulk_chunk_size)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel ); ++ int (*tx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel ); ++ int (*rx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_RX_CHANNEL_T channel ); ++ void (*form_bulk_aux)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, uint32_t chunk_size, const void **aux_data, int32_t *aux_len ); ++ void (*debug)( VCHI_MDRIVER_HANDLE_T *handle ); ++}; ++ ++ ++#endif // _VCHI_MESSAGE_H_ ++ ++/****************************** End of file ***********************************/ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,373 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHI_H_ ++#define VCHI_H_ ++ ++#include "interface/vchi/vchi_cfg.h" ++#include "interface/vchi/vchi_common.h" ++#include "interface/vchi/connections/connection.h" ++#include "vchi_mh.h" ++ ++ ++/****************************************************************************** ++ Global defs ++ *****************************************************************************/ ++ ++#define VCHI_BULK_ROUND_UP(x) ((((unsigned long)(x))+VCHI_BULK_ALIGN-1) & ~(VCHI_BULK_ALIGN-1)) ++#define VCHI_BULK_ROUND_DOWN(x) (((unsigned long)(x)) & ~(VCHI_BULK_ALIGN-1)) ++#define VCHI_BULK_ALIGN_NBYTES(x) (VCHI_BULK_ALIGNED(x) ? 0 : (VCHI_BULK_ALIGN - ((unsigned long)(x) & (VCHI_BULK_ALIGN-1)))) ++ ++#ifdef USE_VCHIQ_ARM ++#define VCHI_BULK_ALIGNED(x) 1 ++#else ++#define VCHI_BULK_ALIGNED(x) (((unsigned long)(x) & (VCHI_BULK_ALIGN-1)) == 0) ++#endif ++ ++struct vchi_version { ++ uint32_t version; ++ uint32_t version_min; ++}; ++#define VCHI_VERSION(v_) { v_, v_ } ++#define VCHI_VERSION_EX(v_, m_) { v_, m_ } ++ ++typedef enum ++{ ++ VCHI_VEC_POINTER, ++ VCHI_VEC_HANDLE, ++ VCHI_VEC_LIST ++} VCHI_MSG_VECTOR_TYPE_T; ++ ++typedef struct vchi_msg_vector_ex { ++ ++ VCHI_MSG_VECTOR_TYPE_T type; ++ union ++ { ++ // a memory handle ++ struct ++ { ++ VCHI_MEM_HANDLE_T handle; ++ uint32_t offset; ++ int32_t vec_len; ++ } handle; ++ ++ // an ordinary data pointer ++ struct ++ { ++ const void *vec_base; ++ int32_t vec_len; ++ } ptr; ++ ++ // a nested vector list ++ struct ++ { ++ struct vchi_msg_vector_ex *vec; ++ uint32_t vec_len; ++ } list; ++ } u; ++} VCHI_MSG_VECTOR_EX_T; ++ ++ ++// Construct an entry in a msg vector for a pointer (p) of length (l) ++#define VCHI_VEC_POINTER(p,l) VCHI_VEC_POINTER, { { (VCHI_MEM_HANDLE_T)(p), (l) } } ++ ++// Construct an entry in a msg vector for a message handle (h), starting at offset (o) of length (l) ++#define VCHI_VEC_HANDLE(h,o,l) VCHI_VEC_HANDLE, { { (h), (o), (l) } } ++ ++// Macros to manipulate 'FOURCC' values ++#define MAKE_FOURCC(x) ((int32_t)( (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] )) ++#define FOURCC_TO_CHAR(x) (x >> 24) & 0xFF,(x >> 16) & 0xFF,(x >> 8) & 0xFF, x & 0xFF ++ ++ ++// Opaque service information ++struct opaque_vchi_service_t; ++ ++// Descriptor for a held message. Allocated by client, initialised by vchi_msg_hold, ++// vchi_msg_iter_hold or vchi_msg_iter_hold_next. Fields are for internal VCHI use only. ++typedef struct ++{ ++ struct opaque_vchi_service_t *service; ++ void *message; ++} VCHI_HELD_MSG_T; ++ ++ ++ ++// structure used to provide the information needed to open a server or a client ++typedef struct { ++ struct vchi_version version; ++ int32_t service_id; ++ VCHI_CONNECTION_T *connection; ++ uint32_t rx_fifo_size; ++ uint32_t tx_fifo_size; ++ VCHI_CALLBACK_T callback; ++ void *callback_param; ++ /* client intends to receive bulk transfers of ++ odd lengths or into unaligned buffers */ ++ int32_t want_unaligned_bulk_rx; ++ /* client intends to transmit bulk transfers of ++ odd lengths or out of unaligned buffers */ ++ int32_t want_unaligned_bulk_tx; ++ /* client wants to check CRCs on (bulk) xfers. ++ Only needs to be set at 1 end - will do both directions. */ ++ int32_t want_crc; ++} SERVICE_CREATION_T; ++ ++// Opaque handle for a VCHI instance ++typedef struct opaque_vchi_instance_handle_t *VCHI_INSTANCE_T; ++ ++// Opaque handle for a server or client ++typedef struct opaque_vchi_service_handle_t *VCHI_SERVICE_HANDLE_T; ++ ++// Service registration & startup ++typedef void (*VCHI_SERVICE_INIT)(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections); ++ ++typedef struct service_info_tag { ++ const char * const vll_filename; /* VLL to load to start this service. This is an empty string if VLL is "static" */ ++ VCHI_SERVICE_INIT init; /* Service initialisation function */ ++ void *vll_handle; /* VLL handle; NULL when unloaded or a "static VLL" in build */ ++} SERVICE_INFO_T; ++ ++/****************************************************************************** ++ Global funcs - implementation is specific to which side you are on (local / remote) ++ *****************************************************************************/ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++extern /*@observer@*/ VCHI_CONNECTION_T * vchi_create_connection( const VCHI_CONNECTION_API_T * function_table, ++ const VCHI_MESSAGE_DRIVER_T * low_level); ++ ++ ++// Routine used to initialise the vchi on both local + remote connections ++extern int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle ); ++ ++extern int32_t vchi_exit( void ); ++ ++extern int32_t vchi_connect( VCHI_CONNECTION_T **connections, ++ const uint32_t num_connections, ++ VCHI_INSTANCE_T instance_handle ); ++ ++//When this is called, ensure that all services have no data pending. ++//Bulk transfers can remain 'queued' ++extern int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle ); ++ ++// Global control over bulk CRC checking ++extern int32_t vchi_crc_control( VCHI_CONNECTION_T *connection, ++ VCHI_CRC_CONTROL_T control ); ++ ++// helper functions ++extern void * vchi_allocate_buffer(VCHI_SERVICE_HANDLE_T handle, uint32_t *length); ++extern void vchi_free_buffer(VCHI_SERVICE_HANDLE_T handle, void *address); ++extern uint32_t vchi_current_time(VCHI_INSTANCE_T instance_handle); ++ ++ ++/****************************************************************************** ++ Global service API ++ *****************************************************************************/ ++// Routine to create a named service ++extern int32_t vchi_service_create( VCHI_INSTANCE_T instance_handle, ++ SERVICE_CREATION_T *setup, ++ VCHI_SERVICE_HANDLE_T *handle ); ++ ++// Routine to destory a service ++extern int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to open a named service ++extern int32_t vchi_service_open( VCHI_INSTANCE_T instance_handle, ++ SERVICE_CREATION_T *setup, ++ VCHI_SERVICE_HANDLE_T *handle); ++ ++extern int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, ++ short *peer_version ); ++ ++// Routine to close a named service ++extern int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to increment ref count on a named service ++extern int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to decrement ref count on a named service ++extern int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to send a message accross a service ++extern int32_t vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle, ++ const void *data, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// scatter-gather (vector) and send message ++int32_t vchi_msg_queuev_ex( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MSG_VECTOR_EX_T *vector, ++ uint32_t count, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// legacy scatter-gather (vector) and send message, only handles pointers ++int32_t vchi_msg_queuev( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MSG_VECTOR_T *vector, ++ uint32_t count, ++ VCHI_FLAGS_T flags, ++ void *msg_handle ); ++ ++// Routine to receive a msg from a service ++// Dequeue is equivalent to hold, copy into client buffer, release ++extern int32_t vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle, ++ void *data, ++ uint32_t max_data_size_to_read, ++ uint32_t *actual_msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to look at a message in place. ++// The message is not dequeued, so a subsequent call to peek or dequeue ++// will return the same message. ++extern int32_t vchi_msg_peek( VCHI_SERVICE_HANDLE_T handle, ++ void **data, ++ uint32_t *msg_size, ++ VCHI_FLAGS_T flags ); ++ ++// Routine to remove a message after it has been read in place with peek ++// The first message on the queue is dequeued. ++extern int32_t vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle ); ++ ++// Routine to look at a message in place. ++// The message is dequeued, so the caller is left holding it; the descriptor is ++// filled in and must be released when the user has finished with the message. ++extern int32_t vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle, ++ void **data, // } may be NULL, as info can be ++ uint32_t *msg_size, // } obtained from HELD_MSG_T ++ VCHI_FLAGS_T flags, ++ VCHI_HELD_MSG_T *message_descriptor ); ++ ++// Initialise an iterator to look through messages in place ++extern int32_t vchi_msg_look_ahead( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MSG_ITER_T *iter, ++ VCHI_FLAGS_T flags ); ++ ++/****************************************************************************** ++ Global service support API - operations on held messages and message iterators ++ *****************************************************************************/ ++ ++// Routine to get the address of a held message ++extern void *vchi_held_msg_ptr( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to get the size of a held message ++extern int32_t vchi_held_msg_size( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to get the transmit timestamp as written into the header by the peer ++extern uint32_t vchi_held_msg_tx_timestamp( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to get the reception timestamp, written as we parsed the header ++extern uint32_t vchi_held_msg_rx_timestamp( const VCHI_HELD_MSG_T *message ); ++ ++// Routine to release a held message after it has been processed ++extern int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message ); ++ ++// Indicates whether the iterator has a next message. ++extern int32_t vchi_msg_iter_has_next( const VCHI_MSG_ITER_T *iter ); ++ ++// Return the pointer and length for the next message and advance the iterator. ++extern int32_t vchi_msg_iter_next( VCHI_MSG_ITER_T *iter, ++ void **data, ++ uint32_t *msg_size ); ++ ++// Remove the last message returned by vchi_msg_iter_next. ++// Can only be called once after each call to vchi_msg_iter_next. ++extern int32_t vchi_msg_iter_remove( VCHI_MSG_ITER_T *iter ); ++ ++// Hold the last message returned by vchi_msg_iter_next. ++// Can only be called once after each call to vchi_msg_iter_next. ++extern int32_t vchi_msg_iter_hold( VCHI_MSG_ITER_T *iter, ++ VCHI_HELD_MSG_T *message ); ++ ++// Return information for the next message, and hold it, advancing the iterator. ++extern int32_t vchi_msg_iter_hold_next( VCHI_MSG_ITER_T *iter, ++ void **data, // } may be NULL ++ uint32_t *msg_size, // } ++ VCHI_HELD_MSG_T *message ); ++ ++ ++/****************************************************************************** ++ Global bulk API ++ *****************************************************************************/ ++ ++// Routine to prepare interface for a transfer from the other side ++extern int32_t vchi_bulk_queue_receive( VCHI_SERVICE_HANDLE_T handle, ++ void *data_dst, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *transfer_handle ); ++ ++ ++// Prepare interface for a transfer from the other side into relocatable memory. ++int32_t vchi_bulk_queue_receive_reloc( const VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MEM_HANDLE_T h_dst, ++ uint32_t offset, ++ uint32_t data_size, ++ const VCHI_FLAGS_T flags, ++ void * const bulk_handle ); ++ ++// Routine to queue up data ready for transfer to the other (once they have signalled they are ready) ++extern int32_t vchi_bulk_queue_transmit( VCHI_SERVICE_HANDLE_T handle, ++ const void *data_src, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *transfer_handle ); ++ ++ ++/****************************************************************************** ++ Configuration plumbing ++ *****************************************************************************/ ++ ++// function prototypes for the different mid layers (the state info gives the different physical connections) ++extern const VCHI_CONNECTION_API_T *single_get_func_table( void ); ++//extern const VCHI_CONNECTION_API_T *local_server_get_func_table( void ); ++//extern const VCHI_CONNECTION_API_T *local_client_get_func_table( void ); ++ ++// declare all message drivers here ++const VCHI_MESSAGE_DRIVER_T *vchi_mphi_message_driver_func_table( void ); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++extern int32_t vchi_bulk_queue_transmit_reloc( VCHI_SERVICE_HANDLE_T handle, ++ VCHI_MEM_HANDLE_T h_src, ++ uint32_t offset, ++ uint32_t data_size, ++ VCHI_FLAGS_T flags, ++ void *transfer_handle ); ++#endif /* VCHI_H_ */ ++ ++/****************************** End of file **********************************/ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_cfg.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_cfg.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,224 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHI_CFG_H_ ++#define VCHI_CFG_H_ ++ ++/**************************************************************************************** ++ * Defines in this first section are part of the VCHI API and may be examined by VCHI ++ * services. ++ ***************************************************************************************/ ++ ++/* Required alignment of base addresses for bulk transfer, if unaligned transfers are not enabled */ ++/* Really determined by the message driver, and should be available from a run-time call. */ ++#ifndef VCHI_BULK_ALIGN ++# if __VCCOREVER__ >= 0x04000000 ++# define VCHI_BULK_ALIGN 32 // Allows for the need to do cache cleans ++# else ++# define VCHI_BULK_ALIGN 16 ++# endif ++#endif ++ ++/* Required length multiple for bulk transfers, if unaligned transfers are not enabled */ ++/* May be less than or greater than VCHI_BULK_ALIGN */ ++/* Really determined by the message driver, and should be available from a run-time call. */ ++#ifndef VCHI_BULK_GRANULARITY ++# if __VCCOREVER__ >= 0x04000000 ++# define VCHI_BULK_GRANULARITY 32 // Allows for the need to do cache cleans ++# else ++# define VCHI_BULK_GRANULARITY 16 ++# endif ++#endif ++ ++/* The largest possible message to be queued with vchi_msg_queue. */ ++#ifndef VCHI_MAX_MSG_SIZE ++# if defined VCHI_LOCAL_HOST_PORT ++# define VCHI_MAX_MSG_SIZE 16384 // makes file transfers fast, but should they be using bulk? ++# else ++# define VCHI_MAX_MSG_SIZE 4096 // NOTE: THIS MUST BE LARGER THAN OR EQUAL TO THE SIZE OF THE KHRONOS MERGE BUFFER!! ++# endif ++#endif ++ ++/****************************************************************************************** ++ * Defines below are system configuration options, and should not be used by VCHI services. ++ *****************************************************************************************/ ++ ++/* How many connections can we support? A localhost implementation uses 2 connections, ++ * 1 for host-app, 1 for VMCS, and these are hooked together by a loopback MPHI VCFW ++ * driver. */ ++#ifndef VCHI_MAX_NUM_CONNECTIONS ++# define VCHI_MAX_NUM_CONNECTIONS 3 ++#endif ++ ++/* How many services can we open per connection? Extending this doesn't cost processing time, just a small ++ * amount of static memory. */ ++#ifndef VCHI_MAX_SERVICES_PER_CONNECTION ++# define VCHI_MAX_SERVICES_PER_CONNECTION 36 ++#endif ++ ++/* Adjust if using a message driver that supports more logical TX channels */ ++#ifndef VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION ++# define VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION 9 // 1 MPHI + 8 CCP2 logical channels ++#endif ++ ++/* Adjust if using a message driver that supports more logical RX channels */ ++#ifndef VCHI_MAX_BULK_RX_CHANNELS_PER_CONNECTION ++# define VCHI_MAX_BULK_RX_CHANNELS_PER_CONNECTION 1 // 1 MPHI ++#endif ++ ++/* How many receive slots do we use. This times VCHI_MAX_MSG_SIZE gives the effective ++ * receive queue space, less message headers. */ ++#ifndef VCHI_NUM_READ_SLOTS ++# if defined(VCHI_LOCAL_HOST_PORT) ++# define VCHI_NUM_READ_SLOTS 4 ++# else ++# define VCHI_NUM_READ_SLOTS 48 ++# endif ++#endif ++ ++/* Do we utilise overrun facility for receive message slots? Can aid peer transmit ++ * performance. Only define on VideoCore end, talking to host. ++ */ ++//#define VCHI_MSG_RX_OVERRUN ++ ++/* How many transmit slots do we use. Generally don't need many, as the hardware driver ++ * underneath VCHI will usually have its own buffering. */ ++#ifndef VCHI_NUM_WRITE_SLOTS ++# define VCHI_NUM_WRITE_SLOTS 4 ++#endif ++ ++/* If a service has held or queued received messages in VCHI_XOFF_THRESHOLD or more slots, ++ * then it's taking up too much buffer space, and the peer service will be told to stop ++ * transmitting with an XOFF message. For this to be effective, the VCHI_NUM_READ_SLOTS ++ * needs to be considerably bigger than VCHI_NUM_WRITE_SLOTS, or the transmit latency ++ * is too high. */ ++#ifndef VCHI_XOFF_THRESHOLD ++# define VCHI_XOFF_THRESHOLD (VCHI_NUM_READ_SLOTS / 2) ++#endif ++ ++/* After we've sent an XOFF, the peer will be told to resume transmission once the local ++ * service has dequeued/released enough messages that it's now occupying ++ * VCHI_XON_THRESHOLD slots or fewer. */ ++#ifndef VCHI_XON_THRESHOLD ++# define VCHI_XON_THRESHOLD (VCHI_NUM_READ_SLOTS / 4) ++#endif ++ ++/* A size below which a bulk transfer omits the handshake completely and always goes ++ * via the message channel, if bulk auxiliary is being sent on that service. (The user ++ * can guarantee this by enabling unaligned transmits). ++ * Not API. */ ++#ifndef VCHI_MIN_BULK_SIZE ++# define VCHI_MIN_BULK_SIZE ( VCHI_MAX_MSG_SIZE / 2 < 4096 ? VCHI_MAX_MSG_SIZE / 2 : 4096 ) ++#endif ++ ++/* Maximum size of bulk transmission chunks, for each interface type. A trade-off between ++ * speed and latency; the smaller the chunk size the better change of messages and other ++ * bulk transmissions getting in when big bulk transfers are happening. Set to 0 to not ++ * break transmissions into chunks. ++ */ ++#ifndef VCHI_MAX_BULK_CHUNK_SIZE_MPHI ++# define VCHI_MAX_BULK_CHUNK_SIZE_MPHI (16 * 1024) ++#endif ++ ++/* NB Chunked CCP2 transmissions violate the letter of the CCP2 spec by using "JPEG8" mode ++ * with multiple-line frames. Only use if the receiver can cope. */ ++#ifndef VCHI_MAX_BULK_CHUNK_SIZE_CCP2 ++# define VCHI_MAX_BULK_CHUNK_SIZE_CCP2 0 ++#endif ++ ++/* How many TX messages can we have pending in our transmit slots. Once exhausted, ++ * vchi_msg_queue will be blocked. */ ++#ifndef VCHI_TX_MSG_QUEUE_SIZE ++# define VCHI_TX_MSG_QUEUE_SIZE 256 ++#endif ++ ++/* How many RX messages can we have parsed in the receive slots. Once exhausted, parsing ++ * will be suspended until older messages are dequeued/released. */ ++#ifndef VCHI_RX_MSG_QUEUE_SIZE ++# define VCHI_RX_MSG_QUEUE_SIZE 256 ++#endif ++ ++/* Really should be able to cope if we run out of received message descriptors, by ++ * suspending parsing as the comment above says, but we don't. This sweeps the issue ++ * under the carpet. */ ++#if VCHI_RX_MSG_QUEUE_SIZE < (VCHI_MAX_MSG_SIZE/16 + 1) * VCHI_NUM_READ_SLOTS ++# undef VCHI_RX_MSG_QUEUE_SIZE ++# define VCHI_RX_MSG_QUEUE_SIZE (VCHI_MAX_MSG_SIZE/16 + 1) * VCHI_NUM_READ_SLOTS ++#endif ++ ++/* How many bulk transmits can we have pending. Once exhausted, vchi_bulk_queue_transmit ++ * will be blocked. */ ++#ifndef VCHI_TX_BULK_QUEUE_SIZE ++# define VCHI_TX_BULK_QUEUE_SIZE 64 ++#endif ++ ++/* How many bulk receives can we have pending. Once exhausted, vchi_bulk_queue_receive ++ * will be blocked. */ ++#ifndef VCHI_RX_BULK_QUEUE_SIZE ++# define VCHI_RX_BULK_QUEUE_SIZE 64 ++#endif ++ ++/* A limit on how many outstanding bulk requests we expect the peer to give us. If ++ * the peer asks for more than this, VCHI will fail and assert. The number is determined ++ * by the peer's hardware - it's the number of outstanding requests that can be queued ++ * on all bulk channels. VC3's MPHI peripheral allows 16. */ ++#ifndef VCHI_MAX_PEER_BULK_REQUESTS ++# define VCHI_MAX_PEER_BULK_REQUESTS 32 ++#endif ++ ++/* Define VCHI_CCP2TX_MANUAL_POWER if the host tells us when to turn the CCP2 ++ * transmitter on and off. ++ */ ++/*#define VCHI_CCP2TX_MANUAL_POWER*/ ++ ++#ifndef VCHI_CCP2TX_MANUAL_POWER ++ ++/* Timeout (in milliseconds) for putting the CCP2TX interface into IDLE state. Set ++ * negative for no IDLE. ++ */ ++# ifndef VCHI_CCP2TX_IDLE_TIMEOUT ++# define VCHI_CCP2TX_IDLE_TIMEOUT 5 ++# endif ++ ++/* Timeout (in milliseconds) for putting the CCP2TX interface into OFF state. Set ++ * negative for no OFF. ++ */ ++# ifndef VCHI_CCP2TX_OFF_TIMEOUT ++# define VCHI_CCP2TX_OFF_TIMEOUT 1000 ++# endif ++ ++#endif /* VCHI_CCP2TX_MANUAL_POWER */ ++ ++#endif /* VCHI_CFG_H_ */ ++ ++/****************************** End of file **********************************/ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_cfg_internal.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_cfg_internal.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,71 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHI_CFG_INTERNAL_H_ ++#define VCHI_CFG_INTERNAL_H_ ++ ++/**************************************************************************************** ++ * Control optimisation attempts. ++ ***************************************************************************************/ ++ ++// Don't use lots of short-term locks - use great long ones, reducing the overall locks-per-second ++#define VCHI_COARSE_LOCKING ++ ++// Avoid lock then unlock on exit from blocking queue operations (msg tx, bulk rx/tx) ++// (only relevant if VCHI_COARSE_LOCKING) ++#define VCHI_ELIDE_BLOCK_EXIT_LOCK ++ ++// Avoid lock on non-blocking peek ++// (only relevant if VCHI_COARSE_LOCKING) ++#define VCHI_AVOID_PEEK_LOCK ++ ++// Use one slot-handler thread per connection, rather than 1 thread dealing with all connections in rotation. ++#define VCHI_MULTIPLE_HANDLER_THREADS ++ ++// Put free descriptors onto the head of the free queue, rather than the tail, so that we don't thrash ++// our way through the pool of descriptors. ++#define VCHI_PUSH_FREE_DESCRIPTORS_ONTO_HEAD ++ ++// Don't issue a MSG_AVAILABLE callback for every single message. Possibly only safe if VCHI_COARSE_LOCKING. ++#define VCHI_FEWER_MSG_AVAILABLE_CALLBACKS ++ ++// Don't use message descriptors for TX messages that don't need them ++#define VCHI_MINIMISE_TX_MSG_DESCRIPTORS ++ ++// Nano-locks for multiqueue ++//#define VCHI_MQUEUE_NANOLOCKS ++ ++// Lock-free(er) dequeuing ++//#define VCHI_RX_NANOLOCKS ++ ++#endif /*VCHI_CFG_INTERNAL_H_*/ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_common.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_common.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,163 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHI_COMMON_H_ ++#define VCHI_COMMON_H_ ++ ++ ++//flags used when sending messages (must be bitmapped) ++typedef enum ++{ ++ VCHI_FLAGS_NONE = 0x0, ++ VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE = 0x1, // waits for message to be received, or sent (NB. not the same as being seen on other side) ++ VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE = 0x2, // run a callback when message sent ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED = 0x4, // return once the transfer is in a queue ready to go ++ VCHI_FLAGS_ALLOW_PARTIAL = 0x8, ++ VCHI_FLAGS_BLOCK_UNTIL_DATA_READ = 0x10, ++ VCHI_FLAGS_CALLBACK_WHEN_DATA_READ = 0x20, ++ ++ VCHI_FLAGS_ALIGN_SLOT = 0x000080, // internal use only ++ VCHI_FLAGS_BULK_AUX_QUEUED = 0x010000, // internal use only ++ VCHI_FLAGS_BULK_AUX_COMPLETE = 0x020000, // internal use only ++ VCHI_FLAGS_BULK_DATA_QUEUED = 0x040000, // internal use only ++ VCHI_FLAGS_BULK_DATA_COMPLETE = 0x080000, // internal use only ++ VCHI_FLAGS_INTERNAL = 0xFF0000 ++} VCHI_FLAGS_T; ++ ++// constants for vchi_crc_control() ++typedef enum { ++ VCHI_CRC_NOTHING = -1, ++ VCHI_CRC_PER_SERVICE = 0, ++ VCHI_CRC_EVERYTHING = 1, ++} VCHI_CRC_CONTROL_T; ++ ++//callback reasons when an event occurs on a service ++typedef enum ++{ ++ VCHI_CALLBACK_REASON_MIN, ++ ++ //This indicates that there is data available ++ //handle is the msg id that was transmitted with the data ++ // When a message is received and there was no FULL message available previously, send callback ++ // Tasks get kicked by the callback, reset their event and try and read from the fifo until it fails ++ VCHI_CALLBACK_MSG_AVAILABLE, ++ VCHI_CALLBACK_MSG_SENT, ++ VCHI_CALLBACK_MSG_SPACE_AVAILABLE, // XXX not yet implemented ++ ++ // This indicates that a transfer from the other side has completed ++ VCHI_CALLBACK_BULK_RECEIVED, ++ //This indicates that data queued up to be sent has now gone ++ //handle is the msg id that was used when sending the data ++ VCHI_CALLBACK_BULK_SENT, ++ VCHI_CALLBACK_BULK_RX_SPACE_AVAILABLE, // XXX not yet implemented ++ VCHI_CALLBACK_BULK_TX_SPACE_AVAILABLE, // XXX not yet implemented ++ ++ VCHI_CALLBACK_SERVICE_CLOSED, ++ ++ // this side has sent XOFF to peer due to lack of data consumption by service ++ // (suggests the service may need to take some recovery action if it has ++ // been deliberately holding off consuming data) ++ VCHI_CALLBACK_SENT_XOFF, ++ VCHI_CALLBACK_SENT_XON, ++ ++ // indicates that a bulk transfer has finished reading the source buffer ++ VCHI_CALLBACK_BULK_DATA_READ, ++ ++ // power notification events (currently host side only) ++ VCHI_CALLBACK_PEER_OFF, ++ VCHI_CALLBACK_PEER_SUSPENDED, ++ VCHI_CALLBACK_PEER_ON, ++ VCHI_CALLBACK_PEER_RESUMED, ++ VCHI_CALLBACK_FORCED_POWER_OFF, ++ ++#ifdef USE_VCHIQ_ARM ++ // some extra notifications provided by vchiq_arm ++ VCHI_CALLBACK_SERVICE_OPENED, ++ VCHI_CALLBACK_BULK_RECEIVE_ABORTED, ++ VCHI_CALLBACK_BULK_TRANSMIT_ABORTED, ++#endif ++ ++ VCHI_CALLBACK_REASON_MAX ++} VCHI_CALLBACK_REASON_T; ++ ++//Calback used by all services / bulk transfers ++typedef void (*VCHI_CALLBACK_T)( void *callback_param, //my service local param ++ VCHI_CALLBACK_REASON_T reason, ++ void *handle ); //for transmitting msg's only ++ ++ ++ ++/* ++ * Define vector struct for scatter-gather (vector) operations ++ * Vectors can be nested - if a vector element has negative length, then ++ * the data pointer is treated as pointing to another vector array, with ++ * '-vec_len' elements. Thus to append a header onto an existing vector, ++ * you can do this: ++ * ++ * void foo(const VCHI_MSG_VECTOR_T *v, int n) ++ * { ++ * VCHI_MSG_VECTOR_T nv[2]; ++ * nv[0].vec_base = my_header; ++ * nv[0].vec_len = sizeof my_header; ++ * nv[1].vec_base = v; ++ * nv[1].vec_len = -n; ++ * ... ++ * ++ */ ++typedef struct vchi_msg_vector { ++ const void *vec_base; ++ int32_t vec_len; ++} VCHI_MSG_VECTOR_T; ++ ++// Opaque type for a connection API ++typedef struct opaque_vchi_connection_api_t VCHI_CONNECTION_API_T; ++ ++// Opaque type for a message driver ++typedef struct opaque_vchi_message_driver_t VCHI_MESSAGE_DRIVER_T; ++ ++ ++// Iterator structure for reading ahead through received message queue. Allocated by client, ++// initialised by vchi_msg_look_ahead. Fields are for internal VCHI use only. ++// Iterates over messages in queue at the instant of the call to vchi_msg_lookahead - ++// will not proceed to messages received since. Behaviour is undefined if an iterator ++// is used again after messages for that service are removed/dequeued by any ++// means other than vchi_msg_iter_... calls on the iterator itself. ++typedef struct { ++ struct opaque_vchi_service_t *service; ++ void *last; ++ void *next; ++ void *remove; ++} VCHI_MSG_ITER_T; ++ ++ ++#endif // VCHI_COMMON_H_ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_mh.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchi/vchi_mh.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,42 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHI_MH_H_ ++#define VCHI_MH_H_ ++ ++#include ++ ++typedef int32_t VCHI_MEM_HANDLE_T; ++#define VCHI_MEM_HANDLE_INVALID 0 ++ ++#endif +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,41 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHIQ_VCHIQ_H ++#define VCHIQ_VCHIQ_H ++ ++#include "vchiq_if.h" ++#include "vchiq_util.h" ++ ++#endif ++ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,42 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHIQ_2835_H ++#define VCHIQ_2835_H ++ ++#include "vchiq_pagelist.h" ++ ++#define VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX 0 ++#define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1 ++ ++#endif /* VCHIQ_2835_H */ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,538 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) ++ ++#define VCHIQ_DOORBELL_IRQ IRQ_ARM_DOORBELL_0 ++#define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) ++ ++#include "vchiq_arm.h" ++#include "vchiq_2835.h" ++#include "vchiq_connected.h" ++ ++#define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) ++ ++typedef struct vchiq_2835_state_struct { ++ int inited; ++ VCHIQ_ARM_STATE_T arm_state; ++} VCHIQ_2835_ARM_STATE_T; ++ ++static char *g_slot_mem; ++static int g_slot_mem_size; ++dma_addr_t g_slot_phys; ++static FRAGMENTS_T *g_fragments_base; ++static FRAGMENTS_T *g_free_fragments; ++struct semaphore g_free_fragments_sema; ++ ++extern int vchiq_arm_log_level; ++ ++static DEFINE_SEMAPHORE(g_free_fragments_mutex); ++ ++static irqreturn_t ++vchiq_doorbell_irq(int irq, void *dev_id); ++ ++static int ++create_pagelist(char __user *buf, size_t count, unsigned short type, ++ struct task_struct *task, PAGELIST_T ** ppagelist); ++ ++static void ++free_pagelist(PAGELIST_T *pagelist, int actual); ++ ++int __init ++vchiq_platform_init(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; ++ int frag_mem_size; ++ int err; ++ int i; ++ ++ /* Allocate space for the channels in coherent memory */ ++ g_slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); ++ frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); ++ ++ g_slot_mem = dma_alloc_coherent(NULL, g_slot_mem_size + frag_mem_size, ++ &g_slot_phys, GFP_ATOMIC); ++ ++ if (!g_slot_mem) { ++ vchiq_log_error(vchiq_arm_log_level, ++ "Unable to allocate channel memory"); ++ err = -ENOMEM; ++ goto failed_alloc; ++ } ++ ++ WARN_ON(((int)g_slot_mem & (PAGE_SIZE - 1)) != 0); ++ ++ vchiq_slot_zero = vchiq_init_slots(g_slot_mem, g_slot_mem_size); ++ if (!vchiq_slot_zero) { ++ err = -EINVAL; ++ goto failed_init_slots; ++ } ++ ++ vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = ++ (int)g_slot_phys + g_slot_mem_size; ++ vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = ++ MAX_FRAGMENTS; ++ ++ g_fragments_base = (FRAGMENTS_T *)(g_slot_mem + g_slot_mem_size); ++ g_slot_mem_size += frag_mem_size; ++ ++ g_free_fragments = g_fragments_base; ++ for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { ++ *(FRAGMENTS_T **)&g_fragments_base[i] = ++ &g_fragments_base[i + 1]; ++ } ++ *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; ++ sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); ++ ++ if (vchiq_init_state(state, vchiq_slot_zero, 0/*slave*/) != ++ VCHIQ_SUCCESS) { ++ err = -EINVAL; ++ goto failed_vchiq_init; ++ } ++ ++ err = request_irq(VCHIQ_DOORBELL_IRQ, vchiq_doorbell_irq, ++ IRQF_IRQPOLL, "VCHIQ doorbell", ++ state); ++ if (err < 0) { ++ vchiq_log_error(vchiq_arm_log_level, "%s: failed to register " ++ "irq=%d err=%d", __func__, ++ VCHIQ_DOORBELL_IRQ, err); ++ goto failed_request_irq; ++ } ++ ++ /* Send the base address of the slots to VideoCore */ ++ ++ dsb(); /* Ensure all writes have completed */ ++ ++ bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)g_slot_phys); ++ ++ vchiq_log_info(vchiq_arm_log_level, ++ "vchiq_init - done (slots %x, phys %x)", ++ (unsigned int)vchiq_slot_zero, g_slot_phys); ++ ++ vchiq_call_connected_callbacks(); ++ ++ return 0; ++ ++failed_request_irq: ++failed_vchiq_init: ++failed_init_slots: ++ dma_free_coherent(NULL, g_slot_mem_size, g_slot_mem, g_slot_phys); ++ ++failed_alloc: ++ return err; ++} ++ ++void __exit ++vchiq_platform_exit(VCHIQ_STATE_T *state) ++{ ++ free_irq(VCHIQ_DOORBELL_IRQ, state); ++ dma_free_coherent(NULL, g_slot_mem_size, ++ g_slot_mem, g_slot_phys); ++} ++ ++ ++VCHIQ_STATUS_T ++vchiq_platform_init_state(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ state->platform_state = kzalloc(sizeof(VCHIQ_2835_ARM_STATE_T), GFP_KERNEL); ++ ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 1; ++ status = vchiq_arm_init_state(state, &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state); ++ if(status != VCHIQ_SUCCESS) ++ { ++ ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 0; ++ } ++ return status; ++} ++ ++VCHIQ_ARM_STATE_T* ++vchiq_platform_get_arm_state(VCHIQ_STATE_T *state) ++{ ++ if(!((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited) ++ { ++ BUG(); ++ } ++ return &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state; ++} ++ ++void ++remote_event_signal(REMOTE_EVENT_T *event) ++{ ++ wmb(); ++ ++ event->fired = 1; ++ ++ dsb(); /* data barrier operation */ ++ ++ if (event->armed) { ++ /* trigger vc interrupt */ ++ ++ writel(0, __io_address(ARM_0_BELL2)); ++ } ++} ++ ++int ++vchiq_copy_from_user(void *dst, const void *src, int size) ++{ ++ if ((uint32_t)src < TASK_SIZE) { ++ return copy_from_user(dst, src, size); ++ } else { ++ memcpy(dst, src, size); ++ return 0; ++ } ++} ++ ++VCHIQ_STATUS_T ++vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, VCHI_MEM_HANDLE_T memhandle, ++ void *offset, int size, int dir) ++{ ++ PAGELIST_T *pagelist; ++ int ret; ++ ++ WARN_ON(memhandle != VCHI_MEM_HANDLE_INVALID); ++ ++ ret = create_pagelist((char __user *)offset, size, ++ (dir == VCHIQ_BULK_RECEIVE) ++ ? PAGELIST_READ ++ : PAGELIST_WRITE, ++ current, ++ &pagelist); ++ if (ret != 0) ++ return VCHIQ_ERROR; ++ ++ bulk->handle = memhandle; ++ bulk->data = VCHIQ_ARM_ADDRESS(pagelist); ++ ++ /* Store the pagelist address in remote_data, which isn't used by the ++ slave. */ ++ bulk->remote_data = pagelist; ++ ++ return VCHIQ_SUCCESS; ++} ++ ++void ++vchiq_complete_bulk(VCHIQ_BULK_T *bulk) ++{ ++ if (bulk && bulk->remote_data && bulk->actual) ++ free_pagelist((PAGELIST_T *)bulk->remote_data, bulk->actual); ++} ++ ++void ++vchiq_transfer_bulk(VCHIQ_BULK_T *bulk) ++{ ++ /* ++ * This should only be called on the master (VideoCore) side, but ++ * provide an implementation to avoid the need for ifdefery. ++ */ ++ BUG(); ++} ++ ++void ++vchiq_dump_platform_state(void *dump_context) ++{ ++ char buf[80]; ++ int len; ++ len = snprintf(buf, sizeof(buf), ++ " Platform: 2835 (VC master)"); ++ vchiq_dump(dump_context, buf, len + 1); ++} ++ ++VCHIQ_STATUS_T ++vchiq_platform_suspend(VCHIQ_STATE_T *state) ++{ ++ return VCHIQ_ERROR; ++} ++ ++VCHIQ_STATUS_T ++vchiq_platform_resume(VCHIQ_STATE_T *state) ++{ ++ return VCHIQ_SUCCESS; ++} ++ ++void ++vchiq_platform_paused(VCHIQ_STATE_T *state) ++{ ++} ++ ++void ++vchiq_platform_resumed(VCHIQ_STATE_T *state) ++{ ++} ++ ++int ++vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state) ++{ ++ return 1; // autosuspend not supported - videocore always wanted ++} ++ ++int ++vchiq_platform_use_suspend_timer(void) ++{ ++ return 0; ++} ++void ++vchiq_dump_platform_use_state(VCHIQ_STATE_T *state) ++{ ++ vchiq_log_info((vchiq_arm_log_level>=VCHIQ_LOG_INFO),"Suspend timer not in use"); ++} ++void ++vchiq_platform_handle_timeout(VCHIQ_STATE_T *state) ++{ ++ (void)state; ++} ++/* ++ * Local functions ++ */ ++ ++static irqreturn_t ++vchiq_doorbell_irq(int irq, void *dev_id) ++{ ++ VCHIQ_STATE_T *state = dev_id; ++ irqreturn_t ret = IRQ_NONE; ++ unsigned int status; ++ ++ /* Read (and clear) the doorbell */ ++ status = readl(__io_address(ARM_0_BELL0)); ++ ++ if (status & 0x4) { /* Was the doorbell rung? */ ++ remote_event_pollall(state); ++ ret = IRQ_HANDLED; ++ } ++ ++ return ret; ++} ++ ++/* There is a potential problem with partial cache lines (pages?) ++** at the ends of the block when reading. If the CPU accessed anything in ++** the same line (page?) then it may have pulled old data into the cache, ++** obscuring the new data underneath. We can solve this by transferring the ++** partial cache lines separately, and allowing the ARM to copy into the ++** cached area. ++ ++** N.B. This implementation plays slightly fast and loose with the Linux ++** driver programming rules, e.g. its use of __virt_to_bus instead of ++** dma_map_single, but it isn't a multi-platform driver and it benefits ++** from increased speed as a result. ++*/ ++ ++static int ++create_pagelist(char __user *buf, size_t count, unsigned short type, ++ struct task_struct *task, PAGELIST_T ** ppagelist) ++{ ++ PAGELIST_T *pagelist; ++ struct page **pages; ++ struct page *page; ++ unsigned long *addrs; ++ unsigned int num_pages, offset, i; ++ char *addr, *base_addr, *next_addr; ++ int run, addridx, actual_pages; ++ ++ offset = (unsigned int)buf & (PAGE_SIZE - 1); ++ num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE; ++ ++ *ppagelist = NULL; ++ ++ /* Allocate enough storage to hold the page pointers and the page ++ ** list ++ */ ++ pagelist = kmalloc(sizeof(PAGELIST_T) + ++ (num_pages * sizeof(unsigned long)) + ++ (num_pages * sizeof(pages[0])), ++ GFP_KERNEL); ++ ++ vchiq_log_trace(vchiq_arm_log_level, ++ "create_pagelist - %x", (unsigned int)pagelist); ++ if (!pagelist) ++ return -ENOMEM; ++ ++ addrs = pagelist->addrs; ++ pages = (struct page **)(addrs + num_pages); ++ ++ down_read(&task->mm->mmap_sem); ++ actual_pages = get_user_pages(task, task->mm, ++ (unsigned long)buf & ~(PAGE_SIZE - 1), num_pages, ++ (type == PAGELIST_READ) /*Write */ , 0 /*Force */ , ++ pages, NULL /*vmas */); ++ up_read(&task->mm->mmap_sem); ++ ++ if (actual_pages != num_pages) ++ { ++ /* This is probably due to the process being killed */ ++ while (actual_pages > 0) ++ { ++ actual_pages--; ++ page_cache_release(pages[actual_pages]); ++ } ++ kfree(pagelist); ++ if (actual_pages == 0) ++ actual_pages = -ENOMEM; ++ return actual_pages; ++ } ++ ++ pagelist->length = count; ++ pagelist->type = type; ++ pagelist->offset = offset; ++ ++ /* Group the pages into runs of contiguous pages */ ++ ++ base_addr = VCHIQ_ARM_ADDRESS(page_address(pages[0])); ++ next_addr = base_addr + PAGE_SIZE; ++ addridx = 0; ++ run = 0; ++ ++ for (i = 1; i < num_pages; i++) { ++ addr = VCHIQ_ARM_ADDRESS(page_address(pages[i])); ++ if ((addr == next_addr) && (run < (PAGE_SIZE - 1))) { ++ next_addr += PAGE_SIZE; ++ run++; ++ } else { ++ addrs[addridx] = (unsigned long)base_addr + run; ++ addridx++; ++ base_addr = addr; ++ next_addr = addr + PAGE_SIZE; ++ run = 0; ++ } ++ } ++ ++ addrs[addridx] = (unsigned long)base_addr + run; ++ addridx++; ++ ++ /* Partial cache lines (fragments) require special measures */ ++ if ((type == PAGELIST_READ) && ++ ((pagelist->offset & (CACHE_LINE_SIZE - 1)) || ++ ((pagelist->offset + pagelist->length) & ++ (CACHE_LINE_SIZE - 1)))) { ++ FRAGMENTS_T *fragments; ++ ++ if (down_interruptible(&g_free_fragments_sema) != 0) { ++ kfree(pagelist); ++ return -EINTR; ++ } ++ ++ WARN_ON(g_free_fragments == NULL); ++ ++ down(&g_free_fragments_mutex); ++ fragments = (FRAGMENTS_T *) g_free_fragments; ++ WARN_ON(fragments == NULL); ++ g_free_fragments = *(FRAGMENTS_T **) g_free_fragments; ++ up(&g_free_fragments_mutex); ++ pagelist->type = ++ PAGELIST_READ_WITH_FRAGMENTS + (fragments - ++ g_fragments_base); ++ } ++ ++ for (page = virt_to_page(pagelist); ++ page <= virt_to_page(addrs + num_pages - 1); page++) { ++ flush_dcache_page(page); ++ } ++ ++ *ppagelist = pagelist; ++ ++ return 0; ++} ++ ++static void ++free_pagelist(PAGELIST_T *pagelist, int actual) ++{ ++ struct page **pages; ++ unsigned int num_pages, i; ++ ++ vchiq_log_trace(vchiq_arm_log_level, ++ "free_pagelist - %x, %d", (unsigned int)pagelist, actual); ++ ++ num_pages = ++ (pagelist->length + pagelist->offset + PAGE_SIZE - 1) / ++ PAGE_SIZE; ++ ++ pages = (struct page **)(pagelist->addrs + num_pages); ++ ++ /* Deal with any partial cache lines (fragments) */ ++ if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) { ++ FRAGMENTS_T *fragments = g_fragments_base + ++ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS); ++ int head_bytes, tail_bytes; ++ head_bytes = (CACHE_LINE_SIZE - pagelist->offset) & ++ (CACHE_LINE_SIZE - 1); ++ tail_bytes = (pagelist->offset + actual) & ++ (CACHE_LINE_SIZE - 1); ++ ++ if ((actual >= 0) && (head_bytes != 0)) { ++ if (head_bytes > actual) ++ head_bytes = actual; ++ ++ memcpy((char *)page_address(pages[0]) + ++ pagelist->offset, ++ fragments->headbuf, ++ head_bytes); ++ } ++ if ((actual >= 0) && (head_bytes < actual) && ++ (tail_bytes != 0)) { ++ memcpy((char *)page_address(pages[num_pages - 1]) + ++ ((pagelist->offset + actual) & ++ (PAGE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)), ++ fragments->tailbuf, tail_bytes); ++ } ++ ++ down(&g_free_fragments_mutex); ++ *(FRAGMENTS_T **) fragments = g_free_fragments; ++ g_free_fragments = fragments; ++ up(&g_free_fragments_mutex); ++ up(&g_free_fragments_sema); ++ } ++ ++ for (i = 0; i < num_pages; i++) { ++ if (pagelist->type != PAGELIST_WRITE) ++ set_page_dirty(pages[i]); ++ page_cache_release(pages[i]); ++ } ++ ++ kfree(pagelist); ++} +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,2813 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "vchiq_core.h" ++#include "vchiq_ioctl.h" ++#include "vchiq_arm.h" ++ ++#define DEVICE_NAME "vchiq" ++ ++/* Override the default prefix, which would be vchiq_arm (from the filename) */ ++#undef MODULE_PARAM_PREFIX ++#define MODULE_PARAM_PREFIX DEVICE_NAME "." ++ ++#define VCHIQ_MINOR 0 ++ ++/* Some per-instance constants */ ++#define MAX_COMPLETIONS 16 ++#define MAX_SERVICES 64 ++#define MAX_ELEMENTS 8 ++#define MSG_QUEUE_SIZE 64 ++ ++#define KEEPALIVE_VER 1 ++#define KEEPALIVE_VER_MIN KEEPALIVE_VER ++ ++/* Run time control of log level, based on KERN_XXX level. */ ++int vchiq_arm_log_level = VCHIQ_LOG_DEFAULT; ++int vchiq_susp_log_level = VCHIQ_LOG_ERROR; ++ ++#define SUSPEND_TIMER_TIMEOUT_MS 100 ++#define SUSPEND_RETRY_TIMER_TIMEOUT_MS 1000 ++ ++#define VC_SUSPEND_NUM_OFFSET 3 /* number of values before idle which are -ve */ ++static const char *const suspend_state_names[] = { ++ "VC_SUSPEND_FORCE_CANCELED", ++ "VC_SUSPEND_REJECTED", ++ "VC_SUSPEND_FAILED", ++ "VC_SUSPEND_IDLE", ++ "VC_SUSPEND_REQUESTED", ++ "VC_SUSPEND_IN_PROGRESS", ++ "VC_SUSPEND_SUSPENDED" ++}; ++#define VC_RESUME_NUM_OFFSET 1 /* number of values before idle which are -ve */ ++static const char *const resume_state_names[] = { ++ "VC_RESUME_FAILED", ++ "VC_RESUME_IDLE", ++ "VC_RESUME_REQUESTED", ++ "VC_RESUME_IN_PROGRESS", ++ "VC_RESUME_RESUMED" ++}; ++/* The number of times we allow force suspend to timeout before actually ++** _forcing_ suspend. This is to cater for SW which fails to release vchiq ++** correctly - we don't want to prevent ARM suspend indefinitely in this case. ++*/ ++#define FORCE_SUSPEND_FAIL_MAX 8 ++ ++/* The time in ms allowed for videocore to go idle when force suspend has been ++ * requested */ ++#define FORCE_SUSPEND_TIMEOUT_MS 200 ++ ++ ++static void suspend_timer_callback(unsigned long context); ++static int vchiq_proc_add_instance(VCHIQ_INSTANCE_T instance); ++static void vchiq_proc_remove_instance(VCHIQ_INSTANCE_T instance); ++ ++ ++typedef struct user_service_struct { ++ VCHIQ_SERVICE_T *service; ++ void *userdata; ++ VCHIQ_INSTANCE_T instance; ++ int is_vchi; ++ int dequeue_pending; ++ int message_available_pos; ++ int msg_insert; ++ int msg_remove; ++ struct semaphore insert_event; ++ struct semaphore remove_event; ++ VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE]; ++} USER_SERVICE_T; ++ ++struct bulk_waiter_node { ++ struct bulk_waiter bulk_waiter; ++ int pid; ++ struct list_head list; ++}; ++ ++struct vchiq_instance_struct { ++ VCHIQ_STATE_T *state; ++ VCHIQ_COMPLETION_DATA_T completions[MAX_COMPLETIONS]; ++ int completion_insert; ++ int completion_remove; ++ struct semaphore insert_event; ++ struct semaphore remove_event; ++ struct mutex completion_mutex; ++ ++ int connected; ++ int closing; ++ int pid; ++ int mark; ++ ++ struct list_head bulk_waiter_list; ++ struct mutex bulk_waiter_list_mutex; ++ ++ struct proc_dir_entry *proc_entry; ++}; ++ ++typedef struct dump_context_struct { ++ char __user *buf; ++ size_t actual; ++ size_t space; ++ loff_t offset; ++} DUMP_CONTEXT_T; ++ ++static struct cdev vchiq_cdev; ++static dev_t vchiq_devid; ++static VCHIQ_STATE_T g_state; ++static struct class *vchiq_class; ++static struct device *vchiq_dev; ++static DEFINE_SPINLOCK(msg_queue_spinlock); ++ ++static const char *const ioctl_names[] = { ++ "CONNECT", ++ "SHUTDOWN", ++ "CREATE_SERVICE", ++ "REMOVE_SERVICE", ++ "QUEUE_MESSAGE", ++ "QUEUE_BULK_TRANSMIT", ++ "QUEUE_BULK_RECEIVE", ++ "AWAIT_COMPLETION", ++ "DEQUEUE_MESSAGE", ++ "GET_CLIENT_ID", ++ "GET_CONFIG", ++ "CLOSE_SERVICE", ++ "USE_SERVICE", ++ "RELEASE_SERVICE", ++ "SET_SERVICE_OPTION", ++ "DUMP_PHYS_MEM" ++}; ++ ++vchiq_static_assert((sizeof(ioctl_names)/sizeof(ioctl_names[0])) == ++ (VCHIQ_IOC_MAX + 1)); ++ ++static void ++dump_phys_mem(void *virt_addr, uint32_t num_bytes); ++ ++/**************************************************************************** ++* ++* add_completion ++* ++***************************************************************************/ ++ ++static VCHIQ_STATUS_T ++add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, ++ VCHIQ_HEADER_T *header, USER_SERVICE_T *user_service, ++ void *bulk_userdata) ++{ ++ VCHIQ_COMPLETION_DATA_T *completion; ++ DEBUG_INITIALISE(g_state.local) ++ ++ while (instance->completion_insert == ++ (instance->completion_remove + MAX_COMPLETIONS)) { ++ /* Out of space - wait for the client */ ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ vchiq_log_trace(vchiq_arm_log_level, ++ "add_completion - completion queue full"); ++ DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); ++ if (down_interruptible(&instance->remove_event) != 0) { ++ vchiq_log_info(vchiq_arm_log_level, ++ "service_callback interrupted"); ++ return VCHIQ_RETRY; ++ } else if (instance->closing) { ++ vchiq_log_info(vchiq_arm_log_level, ++ "service_callback closing"); ++ return VCHIQ_ERROR; ++ } ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ } ++ ++ completion = ++ &instance->completions[instance->completion_insert & ++ (MAX_COMPLETIONS - 1)]; ++ ++ completion->header = header; ++ completion->reason = reason; ++ /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */ ++ completion->service_userdata = user_service->service; ++ completion->bulk_userdata = bulk_userdata; ++ ++ if (reason == VCHIQ_SERVICE_CLOSED) ++ /* Take an extra reference, to be held until ++ this CLOSED notification is delivered. */ ++ lock_service(user_service->service); ++ ++ /* A write barrier is needed here to ensure that the entire completion ++ record is written out before the insert point. */ ++ wmb(); ++ ++ if (reason == VCHIQ_MESSAGE_AVAILABLE) ++ user_service->message_available_pos = ++ instance->completion_insert; ++ instance->completion_insert++; ++ ++ up(&instance->insert_event); ++ ++ return VCHIQ_SUCCESS; ++} ++ ++/**************************************************************************** ++* ++* service_callback ++* ++***************************************************************************/ ++ ++static VCHIQ_STATUS_T ++service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, ++ VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata) ++{ ++ /* How do we ensure the callback goes to the right client? ++ ** The service_user data points to a USER_SERVICE_T record containing ++ ** the original callback and the user state structure, which contains a ++ ** circular buffer for completion records. ++ */ ++ USER_SERVICE_T *user_service; ++ VCHIQ_SERVICE_T *service; ++ VCHIQ_INSTANCE_T instance; ++ DEBUG_INITIALISE(g_state.local) ++ ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ ++ service = handle_to_service(handle); ++ BUG_ON(!service); ++ user_service = (USER_SERVICE_T *)service->base.userdata; ++ instance = user_service->instance; ++ ++ if (!instance || instance->closing) ++ return VCHIQ_SUCCESS; ++ ++ vchiq_log_trace(vchiq_arm_log_level, ++ "service_callback - service %lx(%d), reason %d, header %lx, " ++ "instance %lx, bulk_userdata %lx", ++ (unsigned long)user_service, ++ service->localport, ++ reason, (unsigned long)header, ++ (unsigned long)instance, (unsigned long)bulk_userdata); ++ ++ if (header && user_service->is_vchi) { ++ spin_lock(&msg_queue_spinlock); ++ while (user_service->msg_insert == ++ (user_service->msg_remove + MSG_QUEUE_SIZE)) { ++ spin_unlock(&msg_queue_spinlock); ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ DEBUG_COUNT(MSG_QUEUE_FULL_COUNT); ++ vchiq_log_trace(vchiq_arm_log_level, ++ "service_callback - msg queue full"); ++ /* If there is no MESSAGE_AVAILABLE in the completion ++ ** queue, add one ++ */ ++ if ((user_service->message_available_pos - ++ instance->completion_remove) < 0) { ++ VCHIQ_STATUS_T status; ++ vchiq_log_info(vchiq_arm_log_level, ++ "Inserting extra MESSAGE_AVAILABLE"); ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ status = add_completion(instance, reason, ++ NULL, user_service, bulk_userdata); ++ if (status != VCHIQ_SUCCESS) { ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ return status; ++ } ++ } ++ ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ if (down_interruptible(&user_service->remove_event) ++ != 0) { ++ vchiq_log_info(vchiq_arm_log_level, ++ "service_callback interrupted"); ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ return VCHIQ_RETRY; ++ } else if (instance->closing) { ++ vchiq_log_info(vchiq_arm_log_level, ++ "service_callback closing"); ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ return VCHIQ_ERROR; ++ } ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ spin_lock(&msg_queue_spinlock); ++ } ++ ++ user_service->msg_queue[user_service->msg_insert & ++ (MSG_QUEUE_SIZE - 1)] = header; ++ user_service->msg_insert++; ++ spin_unlock(&msg_queue_spinlock); ++ ++ up(&user_service->insert_event); ++ ++ /* If there is a thread waiting in DEQUEUE_MESSAGE, or if ++ ** there is a MESSAGE_AVAILABLE in the completion queue then ++ ** bypass the completion queue. ++ */ ++ if (((user_service->message_available_pos - ++ instance->completion_remove) >= 0) || ++ user_service->dequeue_pending) { ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ user_service->dequeue_pending = 0; ++ return VCHIQ_SUCCESS; ++ } ++ ++ header = NULL; ++ } ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ ++ return add_completion(instance, reason, header, user_service, ++ bulk_userdata); ++} ++ ++/**************************************************************************** ++* ++* user_service_free ++* ++***************************************************************************/ ++static void ++user_service_free(void *userdata) ++{ ++ kfree(userdata); ++} ++ ++/**************************************************************************** ++* ++* vchiq_ioctl ++* ++***************************************************************************/ ++ ++static long ++vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ VCHIQ_INSTANCE_T instance = file->private_data; ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ VCHIQ_SERVICE_T *service = NULL; ++ long ret = 0; ++ int i, rc; ++ DEBUG_INITIALISE(g_state.local) ++ ++ vchiq_log_trace(vchiq_arm_log_level, ++ "vchiq_ioctl - instance %x, cmd %s, arg %lx", ++ (unsigned int)instance, ++ ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && ++ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ? ++ ioctl_names[_IOC_NR(cmd)] : "", arg); ++ ++ switch (cmd) { ++ case VCHIQ_IOC_SHUTDOWN: ++ if (!instance->connected) ++ break; ++ ++ /* Remove all services */ ++ i = 0; ++ while ((service = next_service_by_instance(instance->state, ++ instance, &i)) != NULL) { ++ status = vchiq_remove_service(service->handle); ++ unlock_service(service); ++ if (status != VCHIQ_SUCCESS) ++ break; ++ } ++ service = NULL; ++ ++ if (status == VCHIQ_SUCCESS) { ++ /* Wake the completion thread and ask it to exit */ ++ instance->closing = 1; ++ up(&instance->insert_event); ++ } ++ ++ break; ++ ++ case VCHIQ_IOC_CONNECT: ++ if (instance->connected) { ++ ret = -EINVAL; ++ break; ++ } ++ rc = mutex_lock_interruptible(&instance->state->mutex); ++ if (rc != 0) { ++ vchiq_log_error(vchiq_arm_log_level, ++ "vchiq: connect: could not lock mutex for " ++ "state %d: %d", ++ instance->state->id, rc); ++ ret = -EINTR; ++ break; ++ } ++ status = vchiq_connect_internal(instance->state, instance); ++ mutex_unlock(&instance->state->mutex); ++ ++ if (status == VCHIQ_SUCCESS) ++ instance->connected = 1; ++ else ++ vchiq_log_error(vchiq_arm_log_level, ++ "vchiq: could not connect: %d", status); ++ break; ++ ++ case VCHIQ_IOC_CREATE_SERVICE: { ++ VCHIQ_CREATE_SERVICE_T args; ++ USER_SERVICE_T *user_service = NULL; ++ void *userdata; ++ int srvstate; ++ ++ if (copy_from_user ++ (&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL); ++ if (!user_service) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (args.is_open) { ++ if (!instance->connected) { ++ ret = -ENOTCONN; ++ kfree(user_service); ++ break; ++ } ++ srvstate = VCHIQ_SRVSTATE_OPENING; ++ } else { ++ srvstate = ++ instance->connected ? ++ VCHIQ_SRVSTATE_LISTENING : ++ VCHIQ_SRVSTATE_HIDDEN; ++ } ++ ++ userdata = args.params.userdata; ++ args.params.callback = service_callback; ++ args.params.userdata = user_service; ++ service = vchiq_add_service_internal( ++ instance->state, ++ &args.params, srvstate, ++ instance, user_service_free); ++ ++ if (service != NULL) { ++ user_service->service = service; ++ user_service->userdata = userdata; ++ user_service->instance = instance; ++ user_service->is_vchi = args.is_vchi; ++ user_service->dequeue_pending = 0; ++ user_service->message_available_pos = ++ instance->completion_remove - 1; ++ user_service->msg_insert = 0; ++ user_service->msg_remove = 0; ++ sema_init(&user_service->insert_event, 0); ++ sema_init(&user_service->remove_event, 0); ++ ++ if (args.is_open) { ++ status = vchiq_open_service_internal ++ (service, instance->pid); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_remove_service(service->handle); ++ service = NULL; ++ ret = (status == VCHIQ_RETRY) ? ++ -EINTR : -EIO; ++ break; ++ } ++ } ++ ++ if (copy_to_user((void __user *) ++ &(((VCHIQ_CREATE_SERVICE_T __user *) ++ arg)->handle), ++ (const void *)&service->handle, ++ sizeof(service->handle)) != 0) { ++ ret = -EFAULT; ++ vchiq_remove_service(service->handle); ++ } ++ ++ service = NULL; ++ } else { ++ ret = -EEXIST; ++ kfree(user_service); ++ } ++ } break; ++ ++ case VCHIQ_IOC_CLOSE_SERVICE: { ++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg; ++ ++ service = find_service_for_instance(instance, handle); ++ if (service != NULL) ++ status = vchiq_close_service(service->handle); ++ else ++ ret = -EINVAL; ++ } break; ++ ++ case VCHIQ_IOC_REMOVE_SERVICE: { ++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg; ++ ++ service = find_service_for_instance(instance, handle); ++ if (service != NULL) ++ status = vchiq_remove_service(service->handle); ++ else ++ ret = -EINVAL; ++ } break; ++ ++ case VCHIQ_IOC_USE_SERVICE: ++ case VCHIQ_IOC_RELEASE_SERVICE: { ++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg; ++ ++ service = find_service_for_instance(instance, handle); ++ if (service != NULL) { ++ status = (cmd == VCHIQ_IOC_USE_SERVICE) ? ++ vchiq_use_service_internal(service) : ++ vchiq_release_service_internal(service); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s: cmd %s returned error %d for " ++ "service %c%c%c%c:%03d", ++ __func__, ++ (cmd == VCHIQ_IOC_USE_SERVICE) ? ++ "VCHIQ_IOC_USE_SERVICE" : ++ "VCHIQ_IOC_RELEASE_SERVICE", ++ status, ++ VCHIQ_FOURCC_AS_4CHARS( ++ service->base.fourcc), ++ service->client_id); ++ ret = -EINVAL; ++ } ++ } else ++ ret = -EINVAL; ++ } break; ++ ++ case VCHIQ_IOC_QUEUE_MESSAGE: { ++ VCHIQ_QUEUE_MESSAGE_T args; ++ if (copy_from_user ++ (&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ service = find_service_for_instance(instance, args.handle); ++ ++ if ((service != NULL) && (args.count <= MAX_ELEMENTS)) { ++ /* Copy elements into kernel space */ ++ VCHIQ_ELEMENT_T elements[MAX_ELEMENTS]; ++ if (copy_from_user(elements, args.elements, ++ args.count * sizeof(VCHIQ_ELEMENT_T)) == 0) ++ status = vchiq_queue_message ++ (args.handle, ++ elements, args.count); ++ else ++ ret = -EFAULT; ++ } else { ++ ret = -EINVAL; ++ } ++ } break; ++ ++ case VCHIQ_IOC_QUEUE_BULK_TRANSMIT: ++ case VCHIQ_IOC_QUEUE_BULK_RECEIVE: { ++ VCHIQ_QUEUE_BULK_TRANSFER_T args; ++ struct bulk_waiter_node *waiter = NULL; ++ VCHIQ_BULK_DIR_T dir = ++ (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ? ++ VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE; ++ ++ if (copy_from_user ++ (&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ service = find_service_for_instance(instance, args.handle); ++ if (!service) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (args.mode == VCHIQ_BULK_MODE_BLOCKING) { ++ waiter = kzalloc(sizeof(struct bulk_waiter_node), ++ GFP_KERNEL); ++ if (!waiter) { ++ ret = -ENOMEM; ++ break; ++ } ++ args.userdata = &waiter->bulk_waiter; ++ } else if (args.mode == VCHIQ_BULK_MODE_WAITING) { ++ struct list_head *pos; ++ mutex_lock(&instance->bulk_waiter_list_mutex); ++ list_for_each(pos, &instance->bulk_waiter_list) { ++ if (list_entry(pos, struct bulk_waiter_node, ++ list)->pid == current->pid) { ++ waiter = list_entry(pos, ++ struct bulk_waiter_node, ++ list); ++ list_del(pos); ++ break; ++ } ++ ++ } ++ mutex_unlock(&instance->bulk_waiter_list_mutex); ++ if (!waiter) { ++ vchiq_log_error(vchiq_arm_log_level, ++ "no bulk_waiter found for pid %d", ++ current->pid); ++ ret = -ESRCH; ++ break; ++ } ++ vchiq_log_info(vchiq_arm_log_level, ++ "found bulk_waiter %x for pid %d", ++ (unsigned int)waiter, current->pid); ++ args.userdata = &waiter->bulk_waiter; ++ } ++ status = vchiq_bulk_transfer ++ (args.handle, ++ VCHI_MEM_HANDLE_INVALID, ++ args.data, args.size, ++ args.userdata, args.mode, ++ dir); ++ if (!waiter) ++ break; ++ if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) || ++ !waiter->bulk_waiter.bulk) { ++ if (waiter->bulk_waiter.bulk) { ++ /* Cancel the signal when the transfer ++ ** completes. */ ++ spin_lock(&bulk_waiter_spinlock); ++ waiter->bulk_waiter.bulk->userdata = NULL; ++ spin_unlock(&bulk_waiter_spinlock); ++ } ++ kfree(waiter); ++ } else { ++ const VCHIQ_BULK_MODE_T mode_waiting = ++ VCHIQ_BULK_MODE_WAITING; ++ waiter->pid = current->pid; ++ mutex_lock(&instance->bulk_waiter_list_mutex); ++ list_add(&waiter->list, &instance->bulk_waiter_list); ++ mutex_unlock(&instance->bulk_waiter_list_mutex); ++ vchiq_log_info(vchiq_arm_log_level, ++ "saved bulk_waiter %x for pid %d", ++ (unsigned int)waiter, current->pid); ++ ++ if (copy_to_user((void __user *) ++ &(((VCHIQ_QUEUE_BULK_TRANSFER_T __user *) ++ arg)->mode), ++ (const void *)&mode_waiting, ++ sizeof(mode_waiting)) != 0) ++ ret = -EFAULT; ++ } ++ } break; ++ ++ case VCHIQ_IOC_AWAIT_COMPLETION: { ++ VCHIQ_AWAIT_COMPLETION_T args; ++ ++ DEBUG_TRACE(AWAIT_COMPLETION_LINE); ++ if (!instance->connected) { ++ ret = -ENOTCONN; ++ break; ++ } ++ ++ if (copy_from_user(&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ mutex_lock(&instance->completion_mutex); ++ ++ DEBUG_TRACE(AWAIT_COMPLETION_LINE); ++ while ((instance->completion_remove == ++ instance->completion_insert) ++ && !instance->closing) { ++ int rc; ++ DEBUG_TRACE(AWAIT_COMPLETION_LINE); ++ mutex_unlock(&instance->completion_mutex); ++ rc = down_interruptible(&instance->insert_event); ++ mutex_lock(&instance->completion_mutex); ++ if (rc != 0) { ++ DEBUG_TRACE(AWAIT_COMPLETION_LINE); ++ vchiq_log_info(vchiq_arm_log_level, ++ "AWAIT_COMPLETION interrupted"); ++ ret = -EINTR; ++ break; ++ } ++ } ++ DEBUG_TRACE(AWAIT_COMPLETION_LINE); ++ ++ /* A read memory barrier is needed to stop prefetch of a stale ++ ** completion record ++ */ ++ rmb(); ++ ++ if (ret == 0) { ++ int msgbufcount = args.msgbufcount; ++ for (ret = 0; ret < args.count; ret++) { ++ VCHIQ_COMPLETION_DATA_T *completion; ++ VCHIQ_SERVICE_T *service; ++ USER_SERVICE_T *user_service; ++ VCHIQ_HEADER_T *header; ++ if (instance->completion_remove == ++ instance->completion_insert) ++ break; ++ completion = &instance->completions[ ++ instance->completion_remove & ++ (MAX_COMPLETIONS - 1)]; ++ ++ service = completion->service_userdata; ++ user_service = service->base.userdata; ++ completion->service_userdata = ++ user_service->userdata; ++ ++ header = completion->header; ++ if (header) { ++ void __user *msgbuf; ++ int msglen; ++ ++ msglen = header->size + ++ sizeof(VCHIQ_HEADER_T); ++ /* This must be a VCHIQ-style service */ ++ if (args.msgbufsize < msglen) { ++ vchiq_log_error( ++ vchiq_arm_log_level, ++ "header %x: msgbufsize" ++ " %x < msglen %x", ++ (unsigned int)header, ++ args.msgbufsize, ++ msglen); ++ WARN(1, "invalid message " ++ "size\n"); ++ if (ret == 0) ++ ret = -EMSGSIZE; ++ break; ++ } ++ if (msgbufcount <= 0) ++ /* Stall here for lack of a ++ ** buffer for the message. */ ++ break; ++ /* Get the pointer from user space */ ++ msgbufcount--; ++ if (copy_from_user(&msgbuf, ++ (const void __user *) ++ &args.msgbufs[msgbufcount], ++ sizeof(msgbuf)) != 0) { ++ if (ret == 0) ++ ret = -EFAULT; ++ break; ++ } ++ ++ /* Copy the message to user space */ ++ if (copy_to_user(msgbuf, header, ++ msglen) != 0) { ++ if (ret == 0) ++ ret = -EFAULT; ++ break; ++ } ++ ++ /* Now it has been copied, the message ++ ** can be released. */ ++ vchiq_release_message(service->handle, ++ header); ++ ++ /* The completion must point to the ++ ** msgbuf. */ ++ completion->header = msgbuf; ++ } ++ ++ if (completion->reason == ++ VCHIQ_SERVICE_CLOSED) ++ unlock_service(service); ++ ++ if (copy_to_user((void __user *)( ++ (size_t)args.buf + ++ ret * sizeof(VCHIQ_COMPLETION_DATA_T)), ++ completion, ++ sizeof(VCHIQ_COMPLETION_DATA_T)) != 0) { ++ if (ret == 0) ++ ret = -EFAULT; ++ break; ++ } ++ ++ instance->completion_remove++; ++ } ++ ++ if (msgbufcount != args.msgbufcount) { ++ if (copy_to_user((void __user *) ++ &((VCHIQ_AWAIT_COMPLETION_T *)arg)-> ++ msgbufcount, ++ &msgbufcount, ++ sizeof(msgbufcount)) != 0) { ++ ret = -EFAULT; ++ } ++ } ++ } ++ ++ if (ret != 0) ++ up(&instance->remove_event); ++ mutex_unlock(&instance->completion_mutex); ++ DEBUG_TRACE(AWAIT_COMPLETION_LINE); ++ } break; ++ ++ case VCHIQ_IOC_DEQUEUE_MESSAGE: { ++ VCHIQ_DEQUEUE_MESSAGE_T args; ++ USER_SERVICE_T *user_service; ++ VCHIQ_HEADER_T *header; ++ ++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); ++ if (copy_from_user ++ (&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ service = find_service_for_instance(instance, args.handle); ++ if (!service) { ++ ret = -EINVAL; ++ break; ++ } ++ user_service = (USER_SERVICE_T *)service->base.userdata; ++ if (user_service->is_vchi == 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ spin_lock(&msg_queue_spinlock); ++ if (user_service->msg_remove == user_service->msg_insert) { ++ if (!args.blocking) { ++ spin_unlock(&msg_queue_spinlock); ++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); ++ ret = -EWOULDBLOCK; ++ break; ++ } ++ user_service->dequeue_pending = 1; ++ do { ++ spin_unlock(&msg_queue_spinlock); ++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); ++ if (down_interruptible( ++ &user_service->insert_event) != 0) { ++ vchiq_log_info(vchiq_arm_log_level, ++ "DEQUEUE_MESSAGE interrupted"); ++ ret = -EINTR; ++ break; ++ } ++ spin_lock(&msg_queue_spinlock); ++ } while (user_service->msg_remove == ++ user_service->msg_insert); ++ ++ if (ret) ++ break; ++ } ++ ++ BUG_ON((int)(user_service->msg_insert - ++ user_service->msg_remove) < 0); ++ ++ header = user_service->msg_queue[user_service->msg_remove & ++ (MSG_QUEUE_SIZE - 1)]; ++ user_service->msg_remove++; ++ spin_unlock(&msg_queue_spinlock); ++ ++ up(&user_service->remove_event); ++ if (header == NULL) ++ ret = -ENOTCONN; ++ else if (header->size <= args.bufsize) { ++ /* Copy to user space if msgbuf is not NULL */ ++ if ((args.buf == NULL) || ++ (copy_to_user((void __user *)args.buf, ++ header->data, ++ header->size) == 0)) { ++ ret = header->size; ++ vchiq_release_message( ++ service->handle, ++ header); ++ } else ++ ret = -EFAULT; ++ } else { ++ vchiq_log_error(vchiq_arm_log_level, ++ "header %x: bufsize %x < size %x", ++ (unsigned int)header, args.bufsize, ++ header->size); ++ WARN(1, "invalid size\n"); ++ ret = -EMSGSIZE; ++ } ++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); ++ } break; ++ ++ case VCHIQ_IOC_GET_CLIENT_ID: { ++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg; ++ ++ ret = vchiq_get_client_id(handle); ++ } break; ++ ++ case VCHIQ_IOC_GET_CONFIG: { ++ VCHIQ_GET_CONFIG_T args; ++ VCHIQ_CONFIG_T config; ++ ++ if (copy_from_user(&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ if (args.config_size > sizeof(config)) { ++ ret = -EINVAL; ++ break; ++ } ++ status = vchiq_get_config(instance, args.config_size, &config); ++ if (status == VCHIQ_SUCCESS) { ++ if (copy_to_user((void __user *)args.pconfig, ++ &config, args.config_size) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ } ++ } break; ++ ++ case VCHIQ_IOC_SET_SERVICE_OPTION: { ++ VCHIQ_SET_SERVICE_OPTION_T args; ++ ++ if (copy_from_user( ++ &args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ service = find_service_for_instance(instance, args.handle); ++ if (!service) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ status = vchiq_set_service_option( ++ args.handle, args.option, args.value); ++ } break; ++ ++ case VCHIQ_IOC_DUMP_PHYS_MEM: { ++ VCHIQ_DUMP_MEM_T args; ++ ++ if (copy_from_user ++ (&args, (const void __user *)arg, ++ sizeof(args)) != 0) { ++ ret = -EFAULT; ++ break; ++ } ++ dump_phys_mem(args.virt_addr, args.num_bytes); ++ } break; ++ ++ default: ++ ret = -ENOTTY; ++ break; ++ } ++ ++ if (service) ++ unlock_service(service); ++ ++ if (ret == 0) { ++ if (status == VCHIQ_ERROR) ++ ret = -EIO; ++ else if (status == VCHIQ_RETRY) ++ ret = -EINTR; ++ } ++ ++ if ((status == VCHIQ_SUCCESS) && (ret < 0) && (ret != -EINTR) && ++ (ret != -EWOULDBLOCK)) ++ vchiq_log_info(vchiq_arm_log_level, ++ " ioctl instance %lx, cmd %s -> status %d, %ld", ++ (unsigned long)instance, ++ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ? ++ ioctl_names[_IOC_NR(cmd)] : ++ "", ++ status, ret); ++ else ++ vchiq_log_trace(vchiq_arm_log_level, ++ " ioctl instance %lx, cmd %s -> status %d, %ld", ++ (unsigned long)instance, ++ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ? ++ ioctl_names[_IOC_NR(cmd)] : ++ "", ++ status, ret); ++ ++ return ret; ++} ++ ++/**************************************************************************** ++* ++* vchiq_open ++* ++***************************************************************************/ ++ ++static int ++vchiq_open(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode) & 0x0f; ++ vchiq_log_info(vchiq_arm_log_level, "vchiq_open"); ++ switch (dev) { ++ case VCHIQ_MINOR: { ++ int ret; ++ VCHIQ_STATE_T *state = vchiq_get_state(); ++ VCHIQ_INSTANCE_T instance; ++ ++ if (!state) { ++ vchiq_log_error(vchiq_arm_log_level, ++ "vchiq has no connection to VideoCore"); ++ return -ENOTCONN; ++ } ++ ++ instance = kzalloc(sizeof(*instance), GFP_KERNEL); ++ if (!instance) ++ return -ENOMEM; ++ ++ instance->state = state; ++ instance->pid = current->tgid; ++ ++ ret = vchiq_proc_add_instance(instance); ++ if (ret != 0) { ++ kfree(instance); ++ return ret; ++ } ++ ++ sema_init(&instance->insert_event, 0); ++ sema_init(&instance->remove_event, 0); ++ mutex_init(&instance->completion_mutex); ++ mutex_init(&instance->bulk_waiter_list_mutex); ++ INIT_LIST_HEAD(&instance->bulk_waiter_list); ++ ++ file->private_data = instance; ++ } break; ++ ++ default: ++ vchiq_log_error(vchiq_arm_log_level, ++ "Unknown minor device: %d", dev); ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vchiq_release ++* ++***************************************************************************/ ++ ++static int ++vchiq_release(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode) & 0x0f; ++ int ret = 0; ++ switch (dev) { ++ case VCHIQ_MINOR: { ++ VCHIQ_INSTANCE_T instance = file->private_data; ++ VCHIQ_STATE_T *state = vchiq_get_state(); ++ VCHIQ_SERVICE_T *service; ++ int i; ++ ++ vchiq_log_info(vchiq_arm_log_level, ++ "vchiq_release: instance=%lx", ++ (unsigned long)instance); ++ ++ if (!state) { ++ ret = -EPERM; ++ goto out; ++ } ++ ++ /* Ensure videocore is awake to allow termination. */ ++ vchiq_use_internal(instance->state, NULL, ++ USE_TYPE_VCHIQ); ++ ++ mutex_lock(&instance->completion_mutex); ++ ++ /* Wake the completion thread and ask it to exit */ ++ instance->closing = 1; ++ up(&instance->insert_event); ++ ++ mutex_unlock(&instance->completion_mutex); ++ ++ /* Wake the slot handler if the completion queue is full. */ ++ up(&instance->remove_event); ++ ++ /* Mark all services for termination... */ ++ i = 0; ++ while ((service = next_service_by_instance(state, instance, ++ &i)) != NULL) { ++ USER_SERVICE_T *user_service = service->base.userdata; ++ ++ /* Wake the slot handler if the msg queue is full. */ ++ up(&user_service->remove_event); ++ ++ vchiq_terminate_service_internal(service); ++ unlock_service(service); ++ } ++ ++ /* ...and wait for them to die */ ++ i = 0; ++ while ((service = next_service_by_instance(state, instance, &i)) ++ != NULL) { ++ USER_SERVICE_T *user_service = service->base.userdata; ++ ++ down(&service->remove_event); ++ ++ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); ++ ++ spin_lock(&msg_queue_spinlock); ++ ++ while (user_service->msg_remove != ++ user_service->msg_insert) { ++ VCHIQ_HEADER_T *header = user_service-> ++ msg_queue[user_service->msg_remove & ++ (MSG_QUEUE_SIZE - 1)]; ++ user_service->msg_remove++; ++ spin_unlock(&msg_queue_spinlock); ++ ++ if (header) ++ vchiq_release_message( ++ service->handle, ++ header); ++ spin_lock(&msg_queue_spinlock); ++ } ++ ++ spin_unlock(&msg_queue_spinlock); ++ ++ unlock_service(service); ++ } ++ ++ /* Release any closed services */ ++ while (instance->completion_remove != ++ instance->completion_insert) { ++ VCHIQ_COMPLETION_DATA_T *completion; ++ VCHIQ_SERVICE_T *service; ++ completion = &instance->completions[ ++ instance->completion_remove & ++ (MAX_COMPLETIONS - 1)]; ++ service = completion->service_userdata; ++ if (completion->reason == VCHIQ_SERVICE_CLOSED) ++ unlock_service(service); ++ instance->completion_remove++; ++ } ++ ++ /* Release the PEER service count. */ ++ vchiq_release_internal(instance->state, NULL); ++ ++ { ++ struct list_head *pos, *next; ++ list_for_each_safe(pos, next, ++ &instance->bulk_waiter_list) { ++ struct bulk_waiter_node *waiter; ++ waiter = list_entry(pos, ++ struct bulk_waiter_node, ++ list); ++ list_del(pos); ++ vchiq_log_info(vchiq_arm_log_level, ++ "bulk_waiter - cleaned up %x " ++ "for pid %d", ++ (unsigned int)waiter, waiter->pid); ++ kfree(waiter); ++ } ++ } ++ ++ vchiq_proc_remove_instance(instance); ++ ++ kfree(instance); ++ file->private_data = NULL; ++ } break; ++ ++ default: ++ vchiq_log_error(vchiq_arm_log_level, ++ "Unknown minor device: %d", dev); ++ ret = -ENXIO; ++ } ++ ++out: ++ return ret; ++} ++ ++/**************************************************************************** ++* ++* vchiq_dump ++* ++***************************************************************************/ ++ ++void ++vchiq_dump(void *dump_context, const char *str, int len) ++{ ++ DUMP_CONTEXT_T *context = (DUMP_CONTEXT_T *)dump_context; ++ ++ if (context->actual < context->space) { ++ int copy_bytes; ++ if (context->offset > 0) { ++ int skip_bytes = min(len, (int)context->offset); ++ str += skip_bytes; ++ len -= skip_bytes; ++ context->offset -= skip_bytes; ++ if (context->offset > 0) ++ return; ++ } ++ copy_bytes = min(len, (int)(context->space - context->actual)); ++ if (copy_bytes == 0) ++ return; ++ if (copy_to_user(context->buf + context->actual, str, ++ copy_bytes)) ++ context->actual = -EFAULT; ++ context->actual += copy_bytes; ++ len -= copy_bytes; ++ ++ /* If tne terminating NUL is included in the length, then it ++ ** marks the end of a line and should be replaced with a ++ ** carriage return. */ ++ if ((len == 0) && (str[copy_bytes - 1] == '\0')) { ++ char cr = '\n'; ++ if (copy_to_user(context->buf + context->actual - 1, ++ &cr, 1)) ++ context->actual = -EFAULT; ++ } ++ } ++} ++ ++/**************************************************************************** ++* ++* vchiq_dump_platform_instance_state ++* ++***************************************************************************/ ++ ++void ++vchiq_dump_platform_instances(void *dump_context) ++{ ++ VCHIQ_STATE_T *state = vchiq_get_state(); ++ char buf[80]; ++ int len; ++ int i; ++ ++ /* There is no list of instances, so instead scan all services, ++ marking those that have been dumped. */ ++ ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *service = state->services[i]; ++ VCHIQ_INSTANCE_T instance; ++ ++ if (service && (service->base.callback == service_callback)) { ++ instance = service->instance; ++ if (instance) ++ instance->mark = 0; ++ } ++ } ++ ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *service = state->services[i]; ++ VCHIQ_INSTANCE_T instance; ++ ++ if (service && (service->base.callback == service_callback)) { ++ instance = service->instance; ++ if (instance && !instance->mark) { ++ len = snprintf(buf, sizeof(buf), ++ "Instance %x: pid %d,%s completions " ++ "%d/%d", ++ (unsigned int)instance, instance->pid, ++ instance->connected ? " connected, " : ++ "", ++ instance->completion_insert - ++ instance->completion_remove, ++ MAX_COMPLETIONS); ++ ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ instance->mark = 1; ++ } ++ } ++ } ++} ++ ++/**************************************************************************** ++* ++* vchiq_dump_platform_service_state ++* ++***************************************************************************/ ++ ++void ++vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service) ++{ ++ USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata; ++ char buf[80]; ++ int len; ++ ++ len = snprintf(buf, sizeof(buf), " instance %x", ++ (unsigned int)service->instance); ++ ++ if ((service->base.callback == service_callback) && ++ user_service->is_vchi) { ++ len += snprintf(buf + len, sizeof(buf) - len, ++ ", %d/%d messages", ++ user_service->msg_insert - user_service->msg_remove, ++ MSG_QUEUE_SIZE); ++ ++ if (user_service->dequeue_pending) ++ len += snprintf(buf + len, sizeof(buf) - len, ++ " (dequeue pending)"); ++ } ++ ++ vchiq_dump(dump_context, buf, len + 1); ++} ++ ++/**************************************************************************** ++* ++* dump_user_mem ++* ++***************************************************************************/ ++ ++static void ++dump_phys_mem(void *virt_addr, uint32_t num_bytes) ++{ ++ int rc; ++ uint8_t *end_virt_addr = virt_addr + num_bytes; ++ int num_pages; ++ int offset; ++ int end_offset; ++ int page_idx; ++ int prev_idx; ++ struct page *page; ++ struct page **pages; ++ uint8_t *kmapped_virt_ptr; ++ ++ /* Align virtAddr and endVirtAddr to 16 byte boundaries. */ ++ ++ virt_addr = (void *)((unsigned long)virt_addr & ~0x0fuL); ++ end_virt_addr = (void *)(((unsigned long)end_virt_addr + 15uL) & ++ ~0x0fuL); ++ ++ offset = (int)(long)virt_addr & (PAGE_SIZE - 1); ++ end_offset = (int)(long)end_virt_addr & (PAGE_SIZE - 1); ++ ++ num_pages = (offset + num_bytes + PAGE_SIZE - 1) / PAGE_SIZE; ++ ++ pages = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL); ++ if (pages == NULL) { ++ vchiq_log_error(vchiq_arm_log_level, ++ "Unable to allocation memory for %d pages\n", ++ num_pages); ++ return; ++ } ++ ++ down_read(¤t->mm->mmap_sem); ++ rc = get_user_pages(current, /* task */ ++ current->mm, /* mm */ ++ (unsigned long)virt_addr, /* start */ ++ num_pages, /* len */ ++ 0, /* write */ ++ 0, /* force */ ++ pages, /* pages (array of page pointers) */ ++ NULL); /* vmas */ ++ up_read(¤t->mm->mmap_sem); ++ ++ prev_idx = -1; ++ page = NULL; ++ ++ while (offset < end_offset) { ++ ++ int page_offset = offset % PAGE_SIZE; ++ page_idx = offset / PAGE_SIZE; ++ ++ if (page_idx != prev_idx) { ++ ++ if (page != NULL) ++ kunmap(page); ++ page = pages[page_idx]; ++ kmapped_virt_ptr = kmap(page); ++ ++ prev_idx = page_idx; ++ } ++ ++ if (vchiq_arm_log_level >= VCHIQ_LOG_TRACE) ++ vchiq_log_dump_mem("ph", ++ (uint32_t)(unsigned long)&kmapped_virt_ptr[ ++ page_offset], ++ &kmapped_virt_ptr[page_offset], 16); ++ ++ offset += 16; ++ } ++ if (page != NULL) ++ kunmap(page); ++ ++ for (page_idx = 0; page_idx < num_pages; page_idx++) ++ page_cache_release(pages[page_idx]); ++ ++ kfree(pages); ++} ++ ++/**************************************************************************** ++* ++* vchiq_read ++* ++***************************************************************************/ ++ ++static ssize_t ++vchiq_read(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ DUMP_CONTEXT_T context; ++ context.buf = buf; ++ context.actual = 0; ++ context.space = count; ++ context.offset = *ppos; ++ ++ vchiq_dump_state(&context, &g_state); ++ ++ *ppos += context.actual; ++ ++ return context.actual; ++} ++ ++VCHIQ_STATE_T * ++vchiq_get_state(void) ++{ ++ ++ if (g_state.remote == NULL) ++ printk(KERN_ERR "%s: g_state.remote == NULL\n", __func__); ++ else if (g_state.remote->initialised != 1) ++ printk(KERN_NOTICE "%s: g_state.remote->initialised != 1 (%d)\n", ++ __func__, g_state.remote->initialised); ++ ++ return ((g_state.remote != NULL) && ++ (g_state.remote->initialised == 1)) ? &g_state : NULL; ++} ++ ++static const struct file_operations ++vchiq_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = vchiq_ioctl, ++ .open = vchiq_open, ++ .release = vchiq_release, ++ .read = vchiq_read ++}; ++ ++/* ++ * Autosuspend related functionality ++ */ ++ ++int ++vchiq_videocore_wanted(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ if (!arm_state) ++ /* autosuspend not supported - always return wanted */ ++ return 1; ++ else if (arm_state->blocked_count) ++ return 1; ++ else if (!arm_state->videocore_use_count) ++ /* usage count zero - check for override unless we're forcing */ ++ if (arm_state->resume_blocked) ++ return 0; ++ else ++ return vchiq_platform_videocore_wanted(state); ++ else ++ /* non-zero usage count - videocore still required */ ++ return 1; ++} ++ ++static VCHIQ_STATUS_T ++vchiq_keepalive_vchiq_callback(VCHIQ_REASON_T reason, ++ VCHIQ_HEADER_T *header, ++ VCHIQ_SERVICE_HANDLE_T service_user, ++ void *bulk_user) ++{ ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s callback reason %d", __func__, reason); ++ return 0; ++} ++ ++static int ++vchiq_keepalive_thread_func(void *v) ++{ ++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v; ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ ++ VCHIQ_STATUS_T status; ++ VCHIQ_INSTANCE_T instance; ++ VCHIQ_SERVICE_HANDLE_T ka_handle; ++ ++ VCHIQ_SERVICE_PARAMS_T params = { ++ .fourcc = VCHIQ_MAKE_FOURCC('K', 'E', 'E', 'P'), ++ .callback = vchiq_keepalive_vchiq_callback, ++ .version = KEEPALIVE_VER, ++ .version_min = KEEPALIVE_VER_MIN ++ }; ++ ++ status = vchiq_initialise(&instance); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s vchiq_initialise failed %d", __func__, status); ++ goto exit; ++ } ++ ++ status = vchiq_connect(instance); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s vchiq_connect failed %d", __func__, status); ++ goto shutdown; ++ } ++ ++ status = vchiq_add_service(instance, ¶ms, &ka_handle); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s vchiq_open_service failed %d", __func__, status); ++ goto shutdown; ++ } ++ ++ while (1) { ++ long rc = 0, uc = 0; ++ if (wait_for_completion_interruptible(&arm_state->ka_evt) ++ != 0) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s interrupted", __func__); ++ flush_signals(current); ++ continue; ++ } ++ ++ /* read and clear counters. Do release_count then use_count to ++ * prevent getting more releases than uses */ ++ rc = atomic_xchg(&arm_state->ka_release_count, 0); ++ uc = atomic_xchg(&arm_state->ka_use_count, 0); ++ ++ /* Call use/release service the requisite number of times. ++ * Process use before release so use counts don't go negative */ ++ while (uc--) { ++ atomic_inc(&arm_state->ka_use_ack_count); ++ status = vchiq_use_service(ka_handle); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s vchiq_use_service error %d", ++ __func__, status); ++ } ++ } ++ while (rc--) { ++ status = vchiq_release_service(ka_handle); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s vchiq_release_service error %d", ++ __func__, status); ++ } ++ } ++ } ++ ++shutdown: ++ vchiq_shutdown(instance); ++exit: ++ return 0; ++} ++ ++ ++ ++VCHIQ_STATUS_T ++vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ ++ if (arm_state) { ++ rwlock_init(&arm_state->susp_res_lock); ++ ++ init_completion(&arm_state->ka_evt); ++ atomic_set(&arm_state->ka_use_count, 0); ++ atomic_set(&arm_state->ka_use_ack_count, 0); ++ atomic_set(&arm_state->ka_release_count, 0); ++ ++ init_completion(&arm_state->vc_suspend_complete); ++ ++ init_completion(&arm_state->vc_resume_complete); ++ /* Initialise to 'done' state. We only want to block on resume ++ * completion while videocore is suspended. */ ++ set_resume_state(arm_state, VC_RESUME_RESUMED); ++ ++ init_completion(&arm_state->resume_blocker); ++ /* Initialise to 'done' state. We only want to block on this ++ * completion while resume is blocked */ ++ complete_all(&arm_state->resume_blocker); ++ ++ init_completion(&arm_state->blocked_blocker); ++ /* Initialise to 'done' state. We only want to block on this ++ * completion while things are waiting on the resume blocker */ ++ complete_all(&arm_state->blocked_blocker); ++ ++ arm_state->suspend_timer_timeout = SUSPEND_TIMER_TIMEOUT_MS; ++ arm_state->suspend_timer_running = 0; ++ init_timer(&arm_state->suspend_timer); ++ arm_state->suspend_timer.data = (unsigned long)(state); ++ arm_state->suspend_timer.function = suspend_timer_callback; ++ ++ arm_state->first_connect = 0; ++ ++ } ++ return status; ++} ++ ++/* ++** Functions to modify the state variables; ++** set_suspend_state ++** set_resume_state ++** ++** There are more state variables than we might like, so ensure they remain in ++** step. Suspend and resume state are maintained separately, since most of ++** these state machines can operate independently. However, there are a few ++** states where state transitions in one state machine cause a reset to the ++** other state machine. In addition, there are some completion events which ++** need to occur on state machine reset and end-state(s), so these are also ++** dealt with in these functions. ++** ++** In all states we set the state variable according to the input, but in some ++** cases we perform additional steps outlined below; ++** ++** VC_SUSPEND_IDLE - Initialise the suspend completion at the same time. ++** The suspend completion is completed after any suspend ++** attempt. When we reset the state machine we also reset ++** the completion. This reset occurs when videocore is ++** resumed, and also if we initiate suspend after a suspend ++** failure. ++** ++** VC_SUSPEND_IN_PROGRESS - This state is considered the point of no return for ++** suspend - ie from this point on we must try to suspend ++** before resuming can occur. We therefore also reset the ++** resume state machine to VC_RESUME_IDLE in this state. ++** ++** VC_SUSPEND_SUSPENDED - Suspend has completed successfully. Also call ++** complete_all on the suspend completion to notify ++** anything waiting for suspend to happen. ++** ++** VC_SUSPEND_REJECTED - Videocore rejected suspend. Videocore will also ++** initiate resume, so no need to alter resume state. ++** We call complete_all on the suspend completion to notify ++** of suspend rejection. ++** ++** VC_SUSPEND_FAILED - We failed to initiate videocore suspend. We notify the ++** suspend completion and reset the resume state machine. ++** ++** VC_RESUME_IDLE - Initialise the resume completion at the same time. The ++** resume completion is in it's 'done' state whenever ++** videcore is running. Therfore, the VC_RESUME_IDLE state ++** implies that videocore is suspended. ++** Hence, any thread which needs to wait until videocore is ++** running can wait on this completion - it will only block ++** if videocore is suspended. ++** ++** VC_RESUME_RESUMED - Resume has completed successfully. Videocore is running. ++** Call complete_all on the resume completion to unblock ++** any threads waiting for resume. Also reset the suspend ++** state machine to it's idle state. ++** ++** VC_RESUME_FAILED - Currently unused - no mechanism to fail resume exists. ++*/ ++ ++inline void ++set_suspend_state(VCHIQ_ARM_STATE_T *arm_state, ++ enum vc_suspend_status new_state) ++{ ++ /* set the state in all cases */ ++ arm_state->vc_suspend_state = new_state; ++ ++ /* state specific additional actions */ ++ switch (new_state) { ++ case VC_SUSPEND_FORCE_CANCELED: ++ complete_all(&arm_state->vc_suspend_complete); ++ break; ++ case VC_SUSPEND_REJECTED: ++ complete_all(&arm_state->vc_suspend_complete); ++ break; ++ case VC_SUSPEND_FAILED: ++ complete_all(&arm_state->vc_suspend_complete); ++ arm_state->vc_resume_state = VC_RESUME_RESUMED; ++ complete_all(&arm_state->vc_resume_complete); ++ break; ++ case VC_SUSPEND_IDLE: ++ INIT_COMPLETION(arm_state->vc_suspend_complete); ++ break; ++ case VC_SUSPEND_REQUESTED: ++ break; ++ case VC_SUSPEND_IN_PROGRESS: ++ set_resume_state(arm_state, VC_RESUME_IDLE); ++ break; ++ case VC_SUSPEND_SUSPENDED: ++ complete_all(&arm_state->vc_suspend_complete); ++ break; ++ default: ++ BUG(); ++ break; ++ } ++} ++ ++inline void ++set_resume_state(VCHIQ_ARM_STATE_T *arm_state, ++ enum vc_resume_status new_state) ++{ ++ /* set the state in all cases */ ++ arm_state->vc_resume_state = new_state; ++ ++ /* state specific additional actions */ ++ switch (new_state) { ++ case VC_RESUME_FAILED: ++ break; ++ case VC_RESUME_IDLE: ++ INIT_COMPLETION(arm_state->vc_resume_complete); ++ break; ++ case VC_RESUME_REQUESTED: ++ break; ++ case VC_RESUME_IN_PROGRESS: ++ break; ++ case VC_RESUME_RESUMED: ++ complete_all(&arm_state->vc_resume_complete); ++ set_suspend_state(arm_state, VC_SUSPEND_IDLE); ++ break; ++ default: ++ BUG(); ++ break; ++ } ++} ++ ++ ++/* should be called with the write lock held */ ++inline void ++start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state) ++{ ++ del_timer(&arm_state->suspend_timer); ++ arm_state->suspend_timer.expires = jiffies + ++ msecs_to_jiffies(arm_state-> ++ suspend_timer_timeout); ++ add_timer(&arm_state->suspend_timer); ++ arm_state->suspend_timer_running = 1; ++} ++ ++/* should be called with the write lock held */ ++static inline void ++stop_suspend_timer(VCHIQ_ARM_STATE_T *arm_state) ++{ ++ if (arm_state->suspend_timer_running) { ++ del_timer(&arm_state->suspend_timer); ++ arm_state->suspend_timer_running = 0; ++ } ++} ++ ++static inline int ++need_resume(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ return (arm_state->vc_suspend_state > VC_SUSPEND_IDLE) && ++ (arm_state->vc_resume_state < VC_RESUME_REQUESTED) && ++ vchiq_videocore_wanted(state); ++} ++ ++static int ++block_resume(VCHIQ_ARM_STATE_T *arm_state) ++{ ++ int status = VCHIQ_SUCCESS; ++ const unsigned long timeout_val = ++ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS); ++ int resume_count = 0; ++ ++ /* Allow any threads which were blocked by the last force suspend to ++ * complete if they haven't already. Only give this one shot; if ++ * blocked_count is incremented after blocked_blocker is completed ++ * (which only happens when blocked_count hits 0) then those threads ++ * will have to wait until next time around */ ++ if (arm_state->blocked_count) { ++ INIT_COMPLETION(arm_state->blocked_blocker); ++ write_unlock_bh(&arm_state->susp_res_lock); ++ vchiq_log_info(vchiq_susp_log_level, "%s wait for previously " ++ "blocked clients", __func__); ++ if (wait_for_completion_interruptible_timeout( ++ &arm_state->blocked_blocker, timeout_val) ++ <= 0) { ++ vchiq_log_error(vchiq_susp_log_level, "%s wait for " ++ "previously blocked clients failed" , __func__); ++ status = VCHIQ_ERROR; ++ write_lock_bh(&arm_state->susp_res_lock); ++ goto out; ++ } ++ vchiq_log_info(vchiq_susp_log_level, "%s previously blocked " ++ "clients resumed", __func__); ++ write_lock_bh(&arm_state->susp_res_lock); ++ } ++ ++ /* We need to wait for resume to complete if it's in process */ ++ while (arm_state->vc_resume_state != VC_RESUME_RESUMED && ++ arm_state->vc_resume_state > VC_RESUME_IDLE) { ++ if (resume_count > 1) { ++ status = VCHIQ_ERROR; ++ vchiq_log_error(vchiq_susp_log_level, "%s waited too " ++ "many times for resume" , __func__); ++ goto out; ++ } ++ write_unlock_bh(&arm_state->susp_res_lock); ++ vchiq_log_info(vchiq_susp_log_level, "%s wait for resume", ++ __func__); ++ if (wait_for_completion_interruptible_timeout( ++ &arm_state->vc_resume_complete, timeout_val) ++ <= 0) { ++ vchiq_log_error(vchiq_susp_log_level, "%s wait for " ++ "resume failed (%s)", __func__, ++ resume_state_names[arm_state->vc_resume_state + ++ VC_RESUME_NUM_OFFSET]); ++ status = VCHIQ_ERROR; ++ write_lock_bh(&arm_state->susp_res_lock); ++ goto out; ++ } ++ vchiq_log_info(vchiq_susp_log_level, "%s resumed", __func__); ++ write_lock_bh(&arm_state->susp_res_lock); ++ resume_count++; ++ } ++ INIT_COMPLETION(arm_state->resume_blocker); ++ arm_state->resume_blocked = 1; ++ ++out: ++ return status; ++} ++ ++static inline void ++unblock_resume(VCHIQ_ARM_STATE_T *arm_state) ++{ ++ complete_all(&arm_state->resume_blocker); ++ arm_state->resume_blocked = 0; ++} ++ ++/* Initiate suspend via slot handler. Should be called with the write lock ++ * held */ ++VCHIQ_STATUS_T ++vchiq_arm_vcsuspend(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_ERROR; ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ status = VCHIQ_SUCCESS; ++ ++ ++ switch (arm_state->vc_suspend_state) { ++ case VC_SUSPEND_REQUESTED: ++ vchiq_log_info(vchiq_susp_log_level, "%s: suspend already " ++ "requested", __func__); ++ break; ++ case VC_SUSPEND_IN_PROGRESS: ++ vchiq_log_info(vchiq_susp_log_level, "%s: suspend already in " ++ "progress", __func__); ++ break; ++ ++ default: ++ /* We don't expect to be in other states, so log but continue ++ * anyway */ ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s unexpected suspend state %s", __func__, ++ suspend_state_names[arm_state->vc_suspend_state + ++ VC_SUSPEND_NUM_OFFSET]); ++ /* fall through */ ++ case VC_SUSPEND_REJECTED: ++ case VC_SUSPEND_FAILED: ++ /* Ensure any idle state actions have been run */ ++ set_suspend_state(arm_state, VC_SUSPEND_IDLE); ++ /* fall through */ ++ case VC_SUSPEND_IDLE: ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s: suspending", __func__); ++ set_suspend_state(arm_state, VC_SUSPEND_REQUESTED); ++ /* kick the slot handler thread to initiate suspend */ ++ request_poll(state, NULL, 0); ++ break; ++ } ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, status); ++ return status; ++} ++ ++void ++vchiq_platform_check_suspend(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ int susp = 0; ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ if (arm_state->vc_suspend_state == VC_SUSPEND_REQUESTED && ++ arm_state->vc_resume_state == VC_RESUME_RESUMED) { ++ set_suspend_state(arm_state, VC_SUSPEND_IN_PROGRESS); ++ susp = 1; ++ } ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++ if (susp) ++ vchiq_platform_suspend(state); ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__); ++ return; ++} ++ ++ ++static void ++output_timeout_error(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ char service_err[50] = ""; ++ int vc_use_count = arm_state->videocore_use_count; ++ int active_services = state->unused_service; ++ int i; ++ ++ if (!arm_state->videocore_use_count) { ++ snprintf(service_err, 50, " Videocore usecount is 0"); ++ goto output_msg; ++ } ++ for (i = 0; i < active_services; i++) { ++ VCHIQ_SERVICE_T *service_ptr = state->services[i]; ++ if (service_ptr && service_ptr->service_use_count && ++ (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE)) { ++ snprintf(service_err, 50, " %c%c%c%c(%d) service has " ++ "use count %d%s", VCHIQ_FOURCC_AS_4CHARS( ++ service_ptr->base.fourcc), ++ service_ptr->client_id, ++ service_ptr->service_use_count, ++ service_ptr->service_use_count == ++ vc_use_count ? "" : " (+ more)"); ++ break; ++ } ++ } ++ ++output_msg: ++ vchiq_log_error(vchiq_susp_log_level, ++ "timed out waiting for vc suspend (%d).%s", ++ arm_state->autosuspend_override, service_err); ++ ++} ++ ++/* Try to get videocore into suspended state, regardless of autosuspend state. ++** We don't actually force suspend, since videocore may get into a bad state ++** if we force suspend at a bad time. Instead, we wait for autosuspend to ++** determine a good point to suspend. If this doesn't happen within 100ms we ++** report failure. ++** ++** Returns VCHIQ_SUCCESS if videocore suspended successfully, VCHIQ_RETRY if ++** videocore failed to suspend in time or VCHIQ_ERROR if interrupted. ++*/ ++VCHIQ_STATUS_T ++vchiq_arm_force_suspend(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ VCHIQ_STATUS_T status = VCHIQ_ERROR; ++ long rc = 0; ++ int repeat = -1; ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ ++ status = block_resume(arm_state); ++ if (status != VCHIQ_SUCCESS) ++ goto unlock; ++ if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) { ++ /* Already suspended - just block resume and exit */ ++ vchiq_log_info(vchiq_susp_log_level, "%s already suspended", ++ __func__); ++ status = VCHIQ_SUCCESS; ++ goto unlock; ++ } else if (arm_state->vc_suspend_state <= VC_SUSPEND_IDLE) { ++ /* initiate suspend immediately in the case that we're waiting ++ * for the timeout */ ++ stop_suspend_timer(arm_state); ++ if (!vchiq_videocore_wanted(state)) { ++ vchiq_log_info(vchiq_susp_log_level, "%s videocore " ++ "idle, initiating suspend", __func__); ++ status = vchiq_arm_vcsuspend(state); ++ } else if (arm_state->autosuspend_override < ++ FORCE_SUSPEND_FAIL_MAX) { ++ vchiq_log_info(vchiq_susp_log_level, "%s letting " ++ "videocore go idle", __func__); ++ status = VCHIQ_SUCCESS; ++ } else { ++ vchiq_log_warning(vchiq_susp_log_level, "%s failed too " ++ "many times - attempting suspend", __func__); ++ status = vchiq_arm_vcsuspend(state); ++ } ++ } else { ++ vchiq_log_info(vchiq_susp_log_level, "%s videocore suspend " ++ "in progress - wait for completion", __func__); ++ status = VCHIQ_SUCCESS; ++ } ++ ++ /* Wait for suspend to happen due to system idle (not forced..) */ ++ if (status != VCHIQ_SUCCESS) ++ goto unblock_resume; ++ ++ do { ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++ rc = wait_for_completion_interruptible_timeout( ++ &arm_state->vc_suspend_complete, ++ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS)); ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ if (rc < 0) { ++ vchiq_log_warning(vchiq_susp_log_level, "%s " ++ "interrupted waiting for suspend", __func__); ++ status = VCHIQ_ERROR; ++ goto unblock_resume; ++ } else if (rc == 0) { ++ if (arm_state->vc_suspend_state > VC_SUSPEND_IDLE) { ++ /* Repeat timeout once if in progress */ ++ if (repeat < 0) { ++ repeat = 1; ++ continue; ++ } ++ } ++ arm_state->autosuspend_override++; ++ output_timeout_error(state); ++ ++ status = VCHIQ_RETRY; ++ goto unblock_resume; ++ } ++ } while (0 < (repeat--)); ++ ++ /* Check and report state in case we need to abort ARM suspend */ ++ if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED) { ++ status = VCHIQ_RETRY; ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s videocore suspend failed (state %s)", __func__, ++ suspend_state_names[arm_state->vc_suspend_state + ++ VC_SUSPEND_NUM_OFFSET]); ++ /* Reset the state only if it's still in an error state. ++ * Something could have already initiated another suspend. */ ++ if (arm_state->vc_suspend_state < VC_SUSPEND_IDLE) ++ set_suspend_state(arm_state, VC_SUSPEND_IDLE); ++ ++ goto unblock_resume; ++ } ++ ++ /* successfully suspended - unlock and exit */ ++ goto unlock; ++ ++unblock_resume: ++ /* all error states need to unblock resume before exit */ ++ unblock_resume(arm_state); ++ ++unlock: ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, status); ++ return status; ++} ++ ++void ++vchiq_check_suspend(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED && ++ arm_state->first_connect && ++ !vchiq_videocore_wanted(state)) { ++ vchiq_arm_vcsuspend(state); ++ } ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__); ++ return; ++} ++ ++ ++int ++vchiq_arm_allow_resume(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ int resume = 0; ++ int ret = -1; ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ unblock_resume(arm_state); ++ resume = vchiq_check_resume(state); ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++ if (resume) { ++ if (wait_for_completion_interruptible( ++ &arm_state->vc_resume_complete) < 0) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s interrupted", __func__); ++ /* failed, cannot accurately derive suspend ++ * state, so exit early. */ ++ goto out; ++ } ++ } ++ ++ read_lock_bh(&arm_state->susp_res_lock); ++ if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) { ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s: Videocore remains suspended", __func__); ++ } else { ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s: Videocore resumed", __func__); ++ ret = 0; ++ } ++ read_unlock_bh(&arm_state->susp_res_lock); ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret); ++ return ret; ++} ++ ++/* This function should be called with the write lock held */ ++int ++vchiq_check_resume(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ int resume = 0; ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ if (need_resume(state)) { ++ set_resume_state(arm_state, VC_RESUME_REQUESTED); ++ request_poll(state, NULL, 0); ++ resume = 1; ++ } ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__); ++ return resume; ++} ++ ++void ++vchiq_platform_check_resume(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ int res = 0; ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ if (arm_state->wake_address == 0) { ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s: already awake", __func__); ++ goto unlock; ++ } ++ if (arm_state->vc_resume_state == VC_RESUME_IN_PROGRESS) { ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s: already resuming", __func__); ++ goto unlock; ++ } ++ ++ if (arm_state->vc_resume_state == VC_RESUME_REQUESTED) { ++ set_resume_state(arm_state, VC_RESUME_IN_PROGRESS); ++ res = 1; ++ } else ++ vchiq_log_trace(vchiq_susp_log_level, ++ "%s: not resuming (resume state %s)", __func__, ++ resume_state_names[arm_state->vc_resume_state + ++ VC_RESUME_NUM_OFFSET]); ++ ++unlock: ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++ if (res) ++ vchiq_platform_resume(state); ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__); ++ return; ++ ++} ++ ++ ++ ++VCHIQ_STATUS_T ++vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, ++ enum USE_TYPE_E use_type) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS; ++ char entity[16]; ++ int *entity_uc; ++ int local_uc, local_entity_uc; ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ if (use_type == USE_TYPE_VCHIQ) { ++ sprintf(entity, "VCHIQ: "); ++ entity_uc = &arm_state->peer_use_count; ++ } else if (service) { ++ sprintf(entity, "%c%c%c%c:%03d", ++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), ++ service->client_id); ++ entity_uc = &service->service_use_count; ++ } else { ++ vchiq_log_error(vchiq_susp_log_level, "%s null service " ++ "ptr", __func__); ++ ret = VCHIQ_ERROR; ++ goto out; ++ } ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ while (arm_state->resume_blocked) { ++ /* If we call 'use' while force suspend is waiting for suspend, ++ * then we're about to block the thread which the force is ++ * waiting to complete, so we're bound to just time out. In this ++ * case, set the suspend state such that the wait will be ++ * canceled, so we can complete as quickly as possible. */ ++ if (arm_state->resume_blocked && arm_state->vc_suspend_state == ++ VC_SUSPEND_IDLE) { ++ set_suspend_state(arm_state, VC_SUSPEND_FORCE_CANCELED); ++ break; ++ } ++ /* If suspend is already in progress then we need to block */ ++ if (!try_wait_for_completion(&arm_state->resume_blocker)) { ++ /* Indicate that there are threads waiting on the resume ++ * blocker. These need to be allowed to complete before ++ * a _second_ call to force suspend can complete, ++ * otherwise low priority threads might never actually ++ * continue */ ++ arm_state->blocked_count++; ++ write_unlock_bh(&arm_state->susp_res_lock); ++ vchiq_log_info(vchiq_susp_log_level, "%s %s resume " ++ "blocked - waiting...", __func__, entity); ++ if (wait_for_completion_killable( ++ &arm_state->resume_blocker) != 0) { ++ vchiq_log_error(vchiq_susp_log_level, "%s %s " ++ "wait for resume blocker interrupted", ++ __func__, entity); ++ ret = VCHIQ_ERROR; ++ write_lock_bh(&arm_state->susp_res_lock); ++ arm_state->blocked_count--; ++ write_unlock_bh(&arm_state->susp_res_lock); ++ goto out; ++ } ++ vchiq_log_info(vchiq_susp_log_level, "%s %s resume " ++ "unblocked", __func__, entity); ++ write_lock_bh(&arm_state->susp_res_lock); ++ if (--arm_state->blocked_count == 0) ++ complete_all(&arm_state->blocked_blocker); ++ } ++ } ++ ++ stop_suspend_timer(arm_state); ++ ++ local_uc = ++arm_state->videocore_use_count; ++ local_entity_uc = ++(*entity_uc); ++ ++ /* If there's a pending request which hasn't yet been serviced then ++ * just clear it. If we're past VC_SUSPEND_REQUESTED state then ++ * vc_resume_complete will block until we either resume or fail to ++ * suspend */ ++ if (arm_state->vc_suspend_state <= VC_SUSPEND_REQUESTED) ++ set_suspend_state(arm_state, VC_SUSPEND_IDLE); ++ ++ if ((use_type != USE_TYPE_SERVICE_NO_RESUME) && need_resume(state)) { ++ set_resume_state(arm_state, VC_RESUME_REQUESTED); ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s %s count %d, state count %d", ++ __func__, entity, local_entity_uc, local_uc); ++ request_poll(state, NULL, 0); ++ } else ++ vchiq_log_trace(vchiq_susp_log_level, ++ "%s %s count %d, state count %d", ++ __func__, entity, *entity_uc, local_uc); ++ ++ ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++ /* Completion is in a done state when we're not suspended, so this won't ++ * block for the non-suspended case. */ ++ if (!try_wait_for_completion(&arm_state->vc_resume_complete)) { ++ vchiq_log_info(vchiq_susp_log_level, "%s %s wait for resume", ++ __func__, entity); ++ if (wait_for_completion_killable( ++ &arm_state->vc_resume_complete) != 0) { ++ vchiq_log_error(vchiq_susp_log_level, "%s %s wait for " ++ "resume interrupted", __func__, entity); ++ ret = VCHIQ_ERROR; ++ goto out; ++ } ++ vchiq_log_info(vchiq_susp_log_level, "%s %s resumed", __func__, ++ entity); ++ } ++ ++ if (ret == VCHIQ_SUCCESS) { ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ long ack_cnt = atomic_xchg(&arm_state->ka_use_ack_count, 0); ++ while (ack_cnt && (status == VCHIQ_SUCCESS)) { ++ /* Send the use notify to videocore */ ++ status = vchiq_send_remote_use_active(state); ++ if (status == VCHIQ_SUCCESS) ++ ack_cnt--; ++ else ++ atomic_add(ack_cnt, ++ &arm_state->ka_use_ack_count); ++ } ++ } ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret); ++ return ret; ++} ++ ++VCHIQ_STATUS_T ++vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS; ++ char entity[16]; ++ int *entity_uc; ++ int local_uc, local_entity_uc; ++ ++ if (!arm_state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ if (service) { ++ sprintf(entity, "%c%c%c%c:%03d", ++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), ++ service->client_id); ++ entity_uc = &service->service_use_count; ++ } else { ++ sprintf(entity, "PEER: "); ++ entity_uc = &arm_state->peer_use_count; ++ } ++ ++ write_lock_bh(&arm_state->susp_res_lock); ++ if (!arm_state->videocore_use_count || !(*entity_uc)) { ++ /* Don't use BUG_ON - don't allow user thread to crash kernel */ ++ WARN_ON(!arm_state->videocore_use_count); ++ WARN_ON(!(*entity_uc)); ++ ret = VCHIQ_ERROR; ++ goto unlock; ++ } ++ local_uc = --arm_state->videocore_use_count; ++ local_entity_uc = --(*entity_uc); ++ ++ if (!vchiq_videocore_wanted(state)) { ++ if (vchiq_platform_use_suspend_timer() && ++ !arm_state->resume_blocked) { ++ /* Only use the timer if we're not trying to force ++ * suspend (=> resume_blocked) */ ++ start_suspend_timer(arm_state); ++ } else { ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s %s count %d, state count %d - suspending", ++ __func__, entity, *entity_uc, ++ arm_state->videocore_use_count); ++ vchiq_arm_vcsuspend(state); ++ } ++ } else ++ vchiq_log_trace(vchiq_susp_log_level, ++ "%s %s count %d, state count %d", ++ __func__, entity, *entity_uc, ++ arm_state->videocore_use_count); ++ ++unlock: ++ write_unlock_bh(&arm_state->susp_res_lock); ++ ++out: ++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret); ++ return ret; ++} ++ ++void ++vchiq_on_remote_use(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ atomic_inc(&arm_state->ka_use_count); ++ complete(&arm_state->ka_evt); ++} ++ ++void ++vchiq_on_remote_release(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ atomic_inc(&arm_state->ka_release_count); ++ complete(&arm_state->ka_evt); ++} ++ ++VCHIQ_STATUS_T ++vchiq_use_service_internal(VCHIQ_SERVICE_T *service) ++{ ++ return vchiq_use_internal(service->state, service, USE_TYPE_SERVICE); ++} ++ ++VCHIQ_STATUS_T ++vchiq_release_service_internal(VCHIQ_SERVICE_T *service) ++{ ++ return vchiq_release_internal(service->state, service); ++} ++ ++static void suspend_timer_callback(unsigned long context) ++{ ++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *)context; ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ if (!arm_state) ++ goto out; ++ vchiq_log_info(vchiq_susp_log_level, ++ "%s - suspend timer expired - check suspend", __func__); ++ vchiq_check_suspend(state); ++out: ++ return; ++} ++ ++VCHIQ_STATUS_T ++vchiq_use_service_no_resume(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_STATUS_T ret = VCHIQ_ERROR; ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ if (service) { ++ ret = vchiq_use_internal(service->state, service, ++ USE_TYPE_SERVICE_NO_RESUME); ++ unlock_service(service); ++ } ++ return ret; ++} ++ ++VCHIQ_STATUS_T ++vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_STATUS_T ret = VCHIQ_ERROR; ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ if (service) { ++ ret = vchiq_use_internal(service->state, service, ++ USE_TYPE_SERVICE); ++ unlock_service(service); ++ } ++ return ret; ++} ++ ++VCHIQ_STATUS_T ++vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_STATUS_T ret = VCHIQ_ERROR; ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ if (service) { ++ ret = vchiq_release_internal(service->state, service); ++ unlock_service(service); ++ } ++ return ret; ++} ++ ++void ++vchiq_dump_service_use_state(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ int i, j = 0; ++ /* Only dump 64 services */ ++ static const int local_max_services = 64; ++ /* If there's more than 64 services, only dump ones with ++ * non-zero counts */ ++ int only_nonzero = 0; ++ static const char *nz = "<-- preventing suspend"; ++ ++ enum vc_suspend_status vc_suspend_state; ++ enum vc_resume_status vc_resume_state; ++ int peer_count; ++ int vc_use_count; ++ int active_services; ++ struct service_data_struct { ++ int fourcc; ++ int clientid; ++ int use_count; ++ } service_data[local_max_services]; ++ ++ if (!arm_state) ++ return; ++ ++ read_lock_bh(&arm_state->susp_res_lock); ++ vc_suspend_state = arm_state->vc_suspend_state; ++ vc_resume_state = arm_state->vc_resume_state; ++ peer_count = arm_state->peer_use_count; ++ vc_use_count = arm_state->videocore_use_count; ++ active_services = state->unused_service; ++ if (active_services > local_max_services) ++ only_nonzero = 1; ++ ++ for (i = 0; (i < active_services) && (j < local_max_services); i++) { ++ VCHIQ_SERVICE_T *service_ptr = state->services[i]; ++ if (!service_ptr) ++ continue; ++ ++ if (only_nonzero && !service_ptr->service_use_count) ++ continue; ++ ++ if (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE) { ++ service_data[j].fourcc = service_ptr->base.fourcc; ++ service_data[j].clientid = service_ptr->client_id; ++ service_data[j++].use_count = service_ptr-> ++ service_use_count; ++ } ++ } ++ ++ read_unlock_bh(&arm_state->susp_res_lock); ++ ++ vchiq_log_warning(vchiq_susp_log_level, ++ "-- Videcore suspend state: %s --", ++ suspend_state_names[vc_suspend_state + VC_SUSPEND_NUM_OFFSET]); ++ vchiq_log_warning(vchiq_susp_log_level, ++ "-- Videcore resume state: %s --", ++ resume_state_names[vc_resume_state + VC_RESUME_NUM_OFFSET]); ++ ++ if (only_nonzero) ++ vchiq_log_warning(vchiq_susp_log_level, "Too many active " ++ "services (%d). Only dumping up to first %d services " ++ "with non-zero use-count", active_services, ++ local_max_services); ++ ++ for (i = 0; i < j; i++) { ++ vchiq_log_warning(vchiq_susp_log_level, ++ "----- %c%c%c%c:%d service count %d %s", ++ VCHIQ_FOURCC_AS_4CHARS(service_data[i].fourcc), ++ service_data[i].clientid, ++ service_data[i].use_count, ++ service_data[i].use_count ? nz : ""); ++ } ++ vchiq_log_warning(vchiq_susp_log_level, ++ "----- VCHIQ use count count %d", peer_count); ++ vchiq_log_warning(vchiq_susp_log_level, ++ "--- Overall vchiq instance use count %d", vc_use_count); ++ ++ vchiq_dump_platform_use_state(state); ++} ++ ++VCHIQ_STATUS_T ++vchiq_check_service(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_ARM_STATE_T *arm_state; ++ VCHIQ_STATUS_T ret = VCHIQ_ERROR; ++ ++ if (!service || !service->state) ++ goto out; ++ ++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__); ++ ++ arm_state = vchiq_platform_get_arm_state(service->state); ++ ++ read_lock_bh(&arm_state->susp_res_lock); ++ if (service->service_use_count) ++ ret = VCHIQ_SUCCESS; ++ read_unlock_bh(&arm_state->susp_res_lock); ++ ++ if (ret == VCHIQ_ERROR) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "%s ERROR - %c%c%c%c:%d service count %d, " ++ "state count %d, videocore suspend state %s", __func__, ++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), ++ service->client_id, service->service_use_count, ++ arm_state->videocore_use_count, ++ suspend_state_names[arm_state->vc_suspend_state + ++ VC_SUSPEND_NUM_OFFSET]); ++ vchiq_dump_service_use_state(service->state); ++ } ++out: ++ return ret; ++} ++ ++/* stub functions */ ++void vchiq_on_remote_use_active(VCHIQ_STATE_T *state) ++{ ++ (void)state; ++} ++ ++void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, ++ VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate) ++{ ++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state); ++ vchiq_log_info(vchiq_susp_log_level, "%d: %s->%s", state->id, ++ get_conn_state_name(oldstate), get_conn_state_name(newstate)); ++ if (state->conn_state == VCHIQ_CONNSTATE_CONNECTED) { ++ write_lock_bh(&arm_state->susp_res_lock); ++ if (!arm_state->first_connect) { ++ char threadname[10]; ++ arm_state->first_connect = 1; ++ write_unlock_bh(&arm_state->susp_res_lock); ++ snprintf(threadname, sizeof(threadname), "VCHIQka-%d", ++ state->id); ++ arm_state->ka_thread = kthread_create( ++ &vchiq_keepalive_thread_func, ++ (void *)state, ++ threadname); ++ if (arm_state->ka_thread == NULL) { ++ vchiq_log_error(vchiq_susp_log_level, ++ "vchiq: FATAL: couldn't create thread %s", ++ threadname); ++ } else { ++ wake_up_process(arm_state->ka_thread); ++ } ++ } else ++ write_unlock_bh(&arm_state->susp_res_lock); ++ } ++} ++ ++ ++/**************************************************************************** ++* ++* vchiq_init - called when the module is loaded. ++* ++***************************************************************************/ ++ ++static int __init ++vchiq_init(void) ++{ ++ int err; ++ void *ptr_err; ++ ++ /* create proc entries */ ++ err = vchiq_proc_init(); ++ if (err != 0) ++ goto failed_proc_init; ++ ++ err = alloc_chrdev_region(&vchiq_devid, VCHIQ_MINOR, 1, DEVICE_NAME); ++ if (err != 0) { ++ vchiq_log_error(vchiq_arm_log_level, ++ "Unable to allocate device number"); ++ goto failed_alloc_chrdev; ++ } ++ cdev_init(&vchiq_cdev, &vchiq_fops); ++ vchiq_cdev.owner = THIS_MODULE; ++ err = cdev_add(&vchiq_cdev, vchiq_devid, 1); ++ if (err != 0) { ++ vchiq_log_error(vchiq_arm_log_level, ++ "Unable to register device"); ++ goto failed_cdev_add; ++ } ++ ++ /* create sysfs entries */ ++ vchiq_class = class_create(THIS_MODULE, DEVICE_NAME); ++ ptr_err = vchiq_class; ++ if (IS_ERR(ptr_err)) ++ goto failed_class_create; ++ ++ vchiq_dev = device_create(vchiq_class, NULL, ++ vchiq_devid, NULL, "vchiq"); ++ ptr_err = vchiq_dev; ++ if (IS_ERR(ptr_err)) ++ goto failed_device_create; ++ ++ err = vchiq_platform_init(&g_state); ++ if (err != 0) ++ goto failed_platform_init; ++ ++ vchiq_log_info(vchiq_arm_log_level, ++ "vchiq: initialised - version %d (min %d), device %d.%d", ++ VCHIQ_VERSION, VCHIQ_VERSION_MIN, ++ MAJOR(vchiq_devid), MINOR(vchiq_devid)); ++ ++ return 0; ++ ++failed_platform_init: ++ device_destroy(vchiq_class, vchiq_devid); ++failed_device_create: ++ class_destroy(vchiq_class); ++failed_class_create: ++ cdev_del(&vchiq_cdev); ++ err = PTR_ERR(ptr_err); ++failed_cdev_add: ++ unregister_chrdev_region(vchiq_devid, 1); ++failed_alloc_chrdev: ++ vchiq_proc_deinit(); ++failed_proc_init: ++ vchiq_log_warning(vchiq_arm_log_level, "could not load vchiq"); ++ return err; ++} ++ ++static int vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance) ++{ ++ VCHIQ_SERVICE_T *service; ++ int use_count = 0, i; ++ i = 0; ++ while ((service = next_service_by_instance(instance->state, ++ instance, &i)) != NULL) { ++ use_count += service->service_use_count; ++ unlock_service(service); ++ } ++ return use_count; ++} ++ ++/* read the per-process use-count */ ++static int proc_read_use_count(char *page, char **start, ++ off_t off, int count, ++ int *eof, void *data) ++{ ++ VCHIQ_INSTANCE_T instance = data; ++ int len, use_count; ++ ++ use_count = vchiq_instance_get_use_count(instance); ++ len = snprintf(page+off, count, "%d\n", use_count); ++ ++ return len; ++} ++ ++/* add an instance (process) to the proc entries */ ++static int vchiq_proc_add_instance(VCHIQ_INSTANCE_T instance) ++{ ++#if 1 ++ return 0; ++#else ++ char pidstr[32]; ++ struct proc_dir_entry *top, *use_count; ++ struct proc_dir_entry *clients = vchiq_clients_top(); ++ int pid = instance->pid; ++ ++ snprintf(pidstr, sizeof(pidstr), "%d", pid); ++ top = proc_mkdir(pidstr, clients); ++ if (!top) ++ goto fail_top; ++ ++ use_count = create_proc_read_entry("use_count", ++ 0444, top, ++ proc_read_use_count, ++ instance); ++ if (!use_count) ++ goto fail_use_count; ++ ++ instance->proc_entry = top; ++ ++ return 0; ++ ++fail_use_count: ++ remove_proc_entry(top->name, clients); ++fail_top: ++ return -ENOMEM; ++#endif ++} ++ ++static void vchiq_proc_remove_instance(VCHIQ_INSTANCE_T instance) ++{ ++#if 0 ++ struct proc_dir_entry *clients = vchiq_clients_top(); ++ remove_proc_entry("use_count", instance->proc_entry); ++ remove_proc_entry(instance->proc_entry->name, clients); ++#endif ++} ++ ++/**************************************************************************** ++* ++* vchiq_exit - called when the module is unloaded. ++* ++***************************************************************************/ ++ ++static void __exit ++vchiq_exit(void) ++{ ++ vchiq_platform_exit(&g_state); ++ device_destroy(vchiq_class, vchiq_devid); ++ class_destroy(vchiq_class); ++ cdev_del(&vchiq_cdev); ++ unregister_chrdev_region(vchiq_devid, 1); ++} ++ ++module_init(vchiq_init); ++module_exit(vchiq_exit); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Broadcom Corporation"); +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,212 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHIQ_ARM_H ++#define VCHIQ_ARM_H ++ ++#include ++#include ++#include ++#include "vchiq_core.h" ++ ++ ++enum vc_suspend_status { ++ VC_SUSPEND_FORCE_CANCELED = -3, /* Force suspend canceled, too busy */ ++ VC_SUSPEND_REJECTED = -2, /* Videocore rejected suspend request */ ++ VC_SUSPEND_FAILED = -1, /* Videocore suspend failed */ ++ VC_SUSPEND_IDLE = 0, /* VC active, no suspend actions */ ++ VC_SUSPEND_REQUESTED, /* User has requested suspend */ ++ VC_SUSPEND_IN_PROGRESS, /* Slot handler has recvd suspend request */ ++ VC_SUSPEND_SUSPENDED /* Videocore suspend succeeded */ ++}; ++ ++enum vc_resume_status { ++ VC_RESUME_FAILED = -1, /* Videocore resume failed */ ++ VC_RESUME_IDLE = 0, /* VC suspended, no resume actions */ ++ VC_RESUME_REQUESTED, /* User has requested resume */ ++ VC_RESUME_IN_PROGRESS, /* Slot handler has received resume request */ ++ VC_RESUME_RESUMED /* Videocore resumed successfully (active) */ ++}; ++ ++ ++enum USE_TYPE_E { ++ USE_TYPE_SERVICE, ++ USE_TYPE_SERVICE_NO_RESUME, ++ USE_TYPE_VCHIQ ++}; ++ ++ ++ ++typedef struct vchiq_arm_state_struct { ++ /* Keepalive-related data */ ++ struct task_struct *ka_thread; ++ struct completion ka_evt; ++ atomic_t ka_use_count; ++ atomic_t ka_use_ack_count; ++ atomic_t ka_release_count; ++ ++ struct completion vc_suspend_complete; ++ struct completion vc_resume_complete; ++ ++ rwlock_t susp_res_lock; ++ enum vc_suspend_status vc_suspend_state; ++ enum vc_resume_status vc_resume_state; ++ ++ unsigned int wake_address; ++ ++ struct timer_list suspend_timer; ++ int suspend_timer_timeout; ++ int suspend_timer_running; ++ ++ /* Global use count for videocore. ++ ** This is equal to the sum of the use counts for all services. When ++ ** this hits zero the videocore suspend procedure will be initiated. ++ */ ++ int videocore_use_count; ++ ++ /* Use count to track requests from videocore peer. ++ ** This use count is not associated with a service, so needs to be ++ ** tracked separately with the state. ++ */ ++ int peer_use_count; ++ ++ /* Flag to indicate whether resume is blocked. This happens when the ++ ** ARM is suspending ++ */ ++ struct completion resume_blocker; ++ int resume_blocked; ++ struct completion blocked_blocker; ++ int blocked_count; ++ ++ int autosuspend_override; ++ ++ /* Flag to indicate that the first vchiq connect has made it through. ++ ** This means that both sides should be fully ready, and we should ++ ** be able to suspend after this point. ++ */ ++ int first_connect; ++ ++ unsigned long long suspend_start_time; ++ unsigned long long sleep_start_time; ++ unsigned long long resume_start_time; ++ unsigned long long last_wake_time; ++ ++} VCHIQ_ARM_STATE_T; ++ ++extern int vchiq_arm_log_level; ++extern int vchiq_susp_log_level; ++ ++extern int __init ++vchiq_platform_init(VCHIQ_STATE_T *state); ++ ++extern void __exit ++vchiq_platform_exit(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATE_T * ++vchiq_get_state(void); ++ ++extern VCHIQ_STATUS_T ++vchiq_arm_vcsuspend(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_arm_force_suspend(VCHIQ_STATE_T *state); ++ ++extern int ++vchiq_arm_allow_resume(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_arm_vcresume(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state); ++ ++extern int ++vchiq_check_resume(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_check_suspend(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle); ++ ++extern VCHIQ_STATUS_T ++vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle); ++ ++extern VCHIQ_STATUS_T ++vchiq_check_service(VCHIQ_SERVICE_T *service); ++ ++extern VCHIQ_STATUS_T ++vchiq_platform_suspend(VCHIQ_STATE_T *state); ++ ++extern int ++vchiq_platform_videocore_wanted(VCHIQ_STATE_T *state); ++ ++extern int ++vchiq_platform_use_suspend_timer(void); ++ ++extern void ++vchiq_dump_platform_use_state(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_dump_service_use_state(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_ARM_STATE_T* ++vchiq_platform_get_arm_state(VCHIQ_STATE_T *state); ++ ++extern int ++vchiq_videocore_wanted(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, ++ enum USE_TYPE_E use_type); ++extern VCHIQ_STATUS_T ++vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service); ++ ++void ++set_suspend_state(VCHIQ_ARM_STATE_T *arm_state, ++ enum vc_suspend_status new_state); ++ ++void ++set_resume_state(VCHIQ_ARM_STATE_T *arm_state, ++ enum vc_resume_status new_state); ++ ++void ++start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state); ++ ++extern int vchiq_proc_init(void); ++extern void vchiq_proc_deinit(void); ++extern struct proc_dir_entry *vchiq_proc_top(void); ++extern struct proc_dir_entry *vchiq_clients_top(void); ++ ++ ++#endif /* VCHIQ_ARM_H */ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_build_info.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_build_info.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,37 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++const char *vchiq_get_build_hostname(void); ++const char *vchiq_get_build_version(void); ++const char *vchiq_get_build_time(void); ++const char *vchiq_get_build_date(void); +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,60 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHIQ_CFG_H ++#define VCHIQ_CFG_H ++ ++#define VCHIQ_MAGIC VCHIQ_MAKE_FOURCC('V', 'C', 'H', 'I') ++/* The version of VCHIQ - change with any non-trivial change */ ++#define VCHIQ_VERSION 6 ++/* The minimum compatible version - update to match VCHIQ_VERSION with any ++** incompatible change */ ++#define VCHIQ_VERSION_MIN 3 ++ ++#define VCHIQ_MAX_STATES 1 ++#define VCHIQ_MAX_SERVICES 4096 ++#define VCHIQ_MAX_SLOTS 128 ++#define VCHIQ_MAX_SLOTS_PER_SIDE 64 ++ ++#define VCHIQ_NUM_CURRENT_BULKS 32 ++#define VCHIQ_NUM_SERVICE_BULKS 4 ++ ++#ifndef VCHIQ_ENABLE_DEBUG ++#define VCHIQ_ENABLE_DEBUG 1 ++#endif ++ ++#ifndef VCHIQ_ENABLE_STATS ++#define VCHIQ_ENABLE_STATS 1 ++#endif ++ ++#endif /* VCHIQ_CFG_H */ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,119 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "vchiq_connected.h" ++#include "vchiq_core.h" ++#include ++#include ++ ++#define MAX_CALLBACKS 10 ++ ++static int g_connected; ++static int g_num_deferred_callbacks; ++static VCHIQ_CONNECTED_CALLBACK_T g_deferred_callback[MAX_CALLBACKS]; ++static int g_once_init; ++static struct mutex g_connected_mutex; ++ ++/**************************************************************************** ++* ++* Function to initialize our lock. ++* ++***************************************************************************/ ++ ++static void connected_init(void) ++{ ++ if (!g_once_init) { ++ mutex_init(&g_connected_mutex); ++ g_once_init = 1; ++ } ++} ++ ++/**************************************************************************** ++* ++* This function is used to defer initialization until the vchiq stack is ++* initialized. If the stack is already initialized, then the callback will ++* be made immediately, otherwise it will be deferred until ++* vchiq_call_connected_callbacks is called. ++* ++***************************************************************************/ ++ ++void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback) ++{ ++ connected_init(); ++ ++ if (mutex_lock_interruptible(&g_connected_mutex) != 0) ++ return; ++ ++ if (g_connected) ++ /* We're already connected. Call the callback immediately. */ ++ ++ callback(); ++ else { ++ if (g_num_deferred_callbacks >= MAX_CALLBACKS) ++ vchiq_log_error(vchiq_core_log_level, ++ "There already %d callback registered - " ++ "please increase MAX_CALLBACKS", ++ g_num_deferred_callbacks); ++ else { ++ g_deferred_callback[g_num_deferred_callbacks] = ++ callback; ++ g_num_deferred_callbacks++; ++ } ++ } ++ mutex_unlock(&g_connected_mutex); ++} ++ ++/**************************************************************************** ++* ++* This function is called by the vchiq stack once it has been connected to ++* the videocore and clients can start to use the stack. ++* ++***************************************************************************/ ++ ++void vchiq_call_connected_callbacks(void) ++{ ++ int i; ++ ++ connected_init(); ++ ++ if (mutex_lock_interruptible(&g_connected_mutex) != 0) ++ return; ++ ++ for (i = 0; i < g_num_deferred_callbacks; i++) ++ g_deferred_callback[i](); ++ ++ g_num_deferred_callbacks = 0; ++ g_connected = 1; ++ mutex_unlock(&g_connected_mutex); ++} ++EXPORT_SYMBOL(vchiq_add_connected_callback); +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,51 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHIQ_CONNECTED_H ++#define VCHIQ_CONNECTED_H ++ ++/* ---- Include Files ----------------------------------------------------- */ ++ ++/* ---- Constants and Types ---------------------------------------------- */ ++ ++typedef void (*VCHIQ_CONNECTED_CALLBACK_T)(void); ++ ++/* ---- Variable Externs ------------------------------------------------- */ ++ ++/* ---- Function Prototypes ---------------------------------------------- */ ++ ++void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback); ++void vchiq_call_connected_callbacks(void); ++ ++#endif /* VCHIQ_CONNECTED_H */ ++ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,3824 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "vchiq_core.h" ++ ++#define VCHIQ_SLOT_HANDLER_STACK 8192 ++ ++#define HANDLE_STATE_SHIFT 12 ++ ++#define SLOT_INFO_FROM_INDEX(state, index) (state->slot_info + (index)) ++#define SLOT_DATA_FROM_INDEX(state, index) (state->slot_data + (index)) ++#define SLOT_INDEX_FROM_DATA(state, data) \ ++ (((unsigned int)((char *)data - (char *)state->slot_data)) / \ ++ VCHIQ_SLOT_SIZE) ++#define SLOT_INDEX_FROM_INFO(state, info) \ ++ ((unsigned int)(info - state->slot_info)) ++#define SLOT_QUEUE_INDEX_FROM_POS(pos) \ ++ ((int)((unsigned int)(pos) / VCHIQ_SLOT_SIZE)) ++ ++ ++#define BULK_INDEX(x) (x & (VCHIQ_NUM_SERVICE_BULKS - 1)) ++ ++ ++struct vchiq_open_payload { ++ int fourcc; ++ int client_id; ++ short version; ++ short version_min; ++}; ++ ++struct vchiq_openack_payload { ++ short version; ++}; ++ ++/* we require this for consistency between endpoints */ ++vchiq_static_assert(sizeof(VCHIQ_HEADER_T) == 8); ++vchiq_static_assert(IS_POW2(sizeof(VCHIQ_HEADER_T))); ++vchiq_static_assert(IS_POW2(VCHIQ_NUM_CURRENT_BULKS)); ++vchiq_static_assert(IS_POW2(VCHIQ_NUM_SERVICE_BULKS)); ++vchiq_static_assert(IS_POW2(VCHIQ_MAX_SERVICES)); ++vchiq_static_assert(VCHIQ_VERSION >= VCHIQ_VERSION_MIN); ++ ++/* Run time control of log level, based on KERN_XXX level. */ ++int vchiq_core_log_level = VCHIQ_LOG_DEFAULT; ++int vchiq_core_msg_log_level = VCHIQ_LOG_DEFAULT; ++int vchiq_sync_log_level = VCHIQ_LOG_DEFAULT; ++ ++static atomic_t pause_bulks_count = ATOMIC_INIT(0); ++ ++static DEFINE_SPINLOCK(service_spinlock); ++DEFINE_SPINLOCK(bulk_waiter_spinlock); ++DEFINE_SPINLOCK(quota_spinlock); ++ ++VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES]; ++static unsigned int handle_seq; ++ ++static const char *const srvstate_names[] = { ++ "FREE", ++ "HIDDEN", ++ "LISTENING", ++ "OPENING", ++ "OPEN", ++ "OPENSYNC", ++ "CLOSESENT", ++ "CLOSERECVD", ++ "CLOSEWAIT", ++ "CLOSED" ++}; ++ ++static const char *const reason_names[] = { ++ "SERVICE_OPENED", ++ "SERVICE_CLOSED", ++ "MESSAGE_AVAILABLE", ++ "BULK_TRANSMIT_DONE", ++ "BULK_RECEIVE_DONE", ++ "BULK_TRANSMIT_ABORTED", ++ "BULK_RECEIVE_ABORTED" ++}; ++ ++static const char *const conn_state_names[] = { ++ "DISCONNECTED", ++ "CONNECTING", ++ "CONNECTED", ++ "PAUSING", ++ "PAUSE_SENT", ++ "PAUSED", ++ "RESUMING", ++ "PAUSE_TIMEOUT", ++ "RESUME_TIMEOUT" ++}; ++ ++ ++static void ++release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header); ++ ++static const char *msg_type_str(unsigned int msg_type) ++{ ++ switch (msg_type) { ++ case VCHIQ_MSG_PADDING: return "PADDING"; ++ case VCHIQ_MSG_CONNECT: return "CONNECT"; ++ case VCHIQ_MSG_OPEN: return "OPEN"; ++ case VCHIQ_MSG_OPENACK: return "OPENACK"; ++ case VCHIQ_MSG_CLOSE: return "CLOSE"; ++ case VCHIQ_MSG_DATA: return "DATA"; ++ case VCHIQ_MSG_BULK_RX: return "BULK_RX"; ++ case VCHIQ_MSG_BULK_TX: return "BULK_TX"; ++ case VCHIQ_MSG_BULK_RX_DONE: return "BULK_RX_DONE"; ++ case VCHIQ_MSG_BULK_TX_DONE: return "BULK_TX_DONE"; ++ case VCHIQ_MSG_PAUSE: return "PAUSE"; ++ case VCHIQ_MSG_RESUME: return "RESUME"; ++ case VCHIQ_MSG_REMOTE_USE: return "REMOTE_USE"; ++ case VCHIQ_MSG_REMOTE_RELEASE: return "REMOTE_RELEASE"; ++ case VCHIQ_MSG_REMOTE_USE_ACTIVE: return "REMOTE_USE_ACTIVE"; ++ } ++ return "???"; ++} ++ ++static inline void ++vchiq_set_service_state(VCHIQ_SERVICE_T *service, int newstate) ++{ ++ vchiq_log_info(vchiq_core_log_level, "%d: srv:%d %s->%s", ++ service->state->id, service->localport, ++ srvstate_names[service->srvstate], ++ srvstate_names[newstate]); ++ service->srvstate = newstate; ++} ++ ++VCHIQ_SERVICE_T * ++find_service_by_handle(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_SERVICE_T *service; ++ ++ spin_lock(&service_spinlock); ++ service = handle_to_service(handle); ++ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE) && ++ (service->handle == handle)) { ++ BUG_ON(service->ref_count == 0); ++ service->ref_count++; ++ } else ++ service = NULL; ++ spin_unlock(&service_spinlock); ++ ++ if (!service) ++ vchiq_log_info(vchiq_core_log_level, ++ "Invalid service handle 0x%x", handle); ++ ++ return service; ++} ++ ++VCHIQ_SERVICE_T * ++find_service_by_port(VCHIQ_STATE_T *state, int localport) ++{ ++ VCHIQ_SERVICE_T *service = NULL; ++ if ((unsigned int)localport <= VCHIQ_PORT_MAX) { ++ spin_lock(&service_spinlock); ++ service = state->services[localport]; ++ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE)) { ++ BUG_ON(service->ref_count == 0); ++ service->ref_count++; ++ } else ++ service = NULL; ++ spin_unlock(&service_spinlock); ++ } ++ ++ if (!service) ++ vchiq_log_info(vchiq_core_log_level, ++ "Invalid port %d", localport); ++ ++ return service; ++} ++ ++VCHIQ_SERVICE_T * ++find_service_for_instance(VCHIQ_INSTANCE_T instance, ++ VCHIQ_SERVICE_HANDLE_T handle) { ++ VCHIQ_SERVICE_T *service; ++ ++ spin_lock(&service_spinlock); ++ service = handle_to_service(handle); ++ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE) && ++ (service->handle == handle) && ++ (service->instance == instance)) { ++ BUG_ON(service->ref_count == 0); ++ service->ref_count++; ++ } else ++ service = NULL; ++ spin_unlock(&service_spinlock); ++ ++ if (!service) ++ vchiq_log_info(vchiq_core_log_level, ++ "Invalid service handle 0x%x", handle); ++ ++ return service; ++} ++ ++VCHIQ_SERVICE_T * ++next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance, ++ int *pidx) ++{ ++ VCHIQ_SERVICE_T *service = NULL; ++ int idx = *pidx; ++ ++ spin_lock(&service_spinlock); ++ while (idx < state->unused_service) { ++ VCHIQ_SERVICE_T *srv = state->services[idx++]; ++ if (srv && (srv->srvstate != VCHIQ_SRVSTATE_FREE) && ++ (srv->instance == instance)) { ++ service = srv; ++ BUG_ON(service->ref_count == 0); ++ service->ref_count++; ++ break; ++ } ++ } ++ spin_unlock(&service_spinlock); ++ ++ *pidx = idx; ++ ++ return service; ++} ++ ++void ++lock_service(VCHIQ_SERVICE_T *service) ++{ ++ spin_lock(&service_spinlock); ++ BUG_ON(!service || (service->ref_count == 0)); ++ if (service) ++ service->ref_count++; ++ spin_unlock(&service_spinlock); ++} ++ ++void ++unlock_service(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_STATE_T *state = service->state; ++ spin_lock(&service_spinlock); ++ BUG_ON(!service || (service->ref_count == 0)); ++ if (service && service->ref_count) { ++ service->ref_count--; ++ if (!service->ref_count) { ++ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); ++ state->services[service->localport] = NULL; ++ } else ++ service = NULL; ++ } ++ spin_unlock(&service_spinlock); ++ ++ if (service && service->userdata_term) ++ service->userdata_term(service->base.userdata); ++ ++ kfree(service); ++} ++ ++int ++vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ int id; ++ ++ id = service ? service->client_id : 0; ++ if (service) ++ unlock_service(service); ++ ++ return id; ++} ++ ++void * ++vchiq_get_service_userdata(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_SERVICE_T *service = handle_to_service(handle); ++ ++ return service ? service->base.userdata : NULL; ++} ++ ++int ++vchiq_get_service_fourcc(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_SERVICE_T *service = handle_to_service(handle); ++ ++ return service ? service->base.fourcc : 0; ++} ++ ++static void ++mark_service_closing_internal(VCHIQ_SERVICE_T *service, int sh_thread) ++{ ++ VCHIQ_STATE_T *state = service->state; ++ VCHIQ_SERVICE_QUOTA_T *service_quota; ++ ++ service->closing = 1; ++ ++ /* Synchronise with other threads. */ ++ mutex_lock(&state->recycle_mutex); ++ mutex_unlock(&state->recycle_mutex); ++ if (!sh_thread || (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT)) { ++ /* If we're pausing then the slot_mutex is held until resume ++ * by the slot handler. Therefore don't try to acquire this ++ * mutex if we're the slot handler and in the pause sent state. ++ * We don't need to in this case anyway. */ ++ mutex_lock(&state->slot_mutex); ++ mutex_unlock(&state->slot_mutex); ++ } ++ ++ /* Unblock any sending thread. */ ++ service_quota = &state->service_quotas[service->localport]; ++ up(&service_quota->quota_event); ++} ++ ++static void ++mark_service_closing(VCHIQ_SERVICE_T *service) ++{ ++ mark_service_closing_internal(service, 0); ++} ++ ++static inline VCHIQ_STATUS_T ++make_service_callback(VCHIQ_SERVICE_T *service, VCHIQ_REASON_T reason, ++ VCHIQ_HEADER_T *header, void *bulk_userdata) ++{ ++ VCHIQ_STATUS_T status; ++ vchiq_log_trace(vchiq_core_log_level, "%d: callback:%d (%s, %x, %x)", ++ service->state->id, service->localport, reason_names[reason], ++ (unsigned int)header, (unsigned int)bulk_userdata); ++ status = service->base.callback(reason, header, service->handle, ++ bulk_userdata); ++ if (status == VCHIQ_ERROR) { ++ vchiq_log_warning(vchiq_core_log_level, ++ "%d: ignoring ERROR from callback to service %x", ++ service->state->id, service->handle); ++ status = VCHIQ_SUCCESS; ++ } ++ return status; ++} ++ ++inline void ++vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate) ++{ ++ VCHIQ_CONNSTATE_T oldstate = state->conn_state; ++ vchiq_log_info(vchiq_core_log_level, "%d: %s->%s", state->id, ++ conn_state_names[oldstate], ++ conn_state_names[newstate]); ++ state->conn_state = newstate; ++ vchiq_platform_conn_state_changed(state, oldstate, newstate); ++} ++ ++static inline void ++remote_event_create(REMOTE_EVENT_T *event) ++{ ++ event->armed = 0; ++ /* Don't clear the 'fired' flag because it may already have been set ++ ** by the other side. */ ++ sema_init(event->event, 0); ++} ++ ++static inline void ++remote_event_destroy(REMOTE_EVENT_T *event) ++{ ++ (void)event; ++} ++ ++static inline int ++remote_event_wait(REMOTE_EVENT_T *event) ++{ ++ if (!event->fired) { ++ event->armed = 1; ++ dsb(); ++ if (!event->fired) { ++ if (down_interruptible(event->event) != 0) { ++ event->armed = 0; ++ return 0; ++ } ++ } ++ event->armed = 0; ++ wmb(); ++ } ++ ++ event->fired = 0; ++ return 1; ++} ++ ++static inline void ++remote_event_signal_local(REMOTE_EVENT_T *event) ++{ ++ event->armed = 0; ++ up(event->event); ++} ++ ++static inline void ++remote_event_poll(REMOTE_EVENT_T *event) ++{ ++ if (event->fired && event->armed) ++ remote_event_signal_local(event); ++} ++ ++void ++remote_event_pollall(VCHIQ_STATE_T *state) ++{ ++ remote_event_poll(&state->local->sync_trigger); ++ remote_event_poll(&state->local->sync_release); ++ remote_event_poll(&state->local->trigger); ++ remote_event_poll(&state->local->recycle); ++} ++ ++/* Round up message sizes so that any space at the end of a slot is always big ++** enough for a header. This relies on header size being a power of two, which ++** has been verified earlier by a static assertion. */ ++ ++static inline unsigned int ++calc_stride(unsigned int size) ++{ ++ /* Allow room for the header */ ++ size += sizeof(VCHIQ_HEADER_T); ++ ++ /* Round up */ ++ return (size + sizeof(VCHIQ_HEADER_T) - 1) & ~(sizeof(VCHIQ_HEADER_T) ++ - 1); ++} ++ ++/* Called by the slot handler thread */ ++static VCHIQ_SERVICE_T * ++get_listening_service(VCHIQ_STATE_T *state, int fourcc) ++{ ++ int i; ++ ++ WARN_ON(fourcc == VCHIQ_FOURCC_INVALID); ++ ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *service = state->services[i]; ++ if (service && ++ (service->public_fourcc == fourcc) && ++ ((service->srvstate == VCHIQ_SRVSTATE_LISTENING) || ++ ((service->srvstate == VCHIQ_SRVSTATE_OPEN) && ++ (service->remoteport == VCHIQ_PORT_FREE)))) { ++ lock_service(service); ++ return service; ++ } ++ } ++ ++ return NULL; ++} ++ ++/* Called by the slot handler thread */ ++static VCHIQ_SERVICE_T * ++get_connected_service(VCHIQ_STATE_T *state, unsigned int port) ++{ ++ int i; ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *service = state->services[i]; ++ if (service && (service->srvstate == VCHIQ_SRVSTATE_OPEN) ++ && (service->remoteport == port)) { ++ lock_service(service); ++ return service; ++ } ++ } ++ return NULL; ++} ++ ++inline void ++request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type) ++{ ++ uint32_t value; ++ ++ if (service) { ++ do { ++ value = atomic_read(&service->poll_flags); ++ } while (atomic_cmpxchg(&service->poll_flags, value, ++ value | (1 << poll_type)) != value); ++ ++ do { ++ value = atomic_read(&state->poll_services[ ++ service->localport>>5]); ++ } while (atomic_cmpxchg( ++ &state->poll_services[service->localport>>5], ++ value, value | (1 << (service->localport & 0x1f))) ++ != value); ++ } ++ ++ state->poll_needed = 1; ++ wmb(); ++ ++ /* ... and ensure the slot handler runs. */ ++ remote_event_signal_local(&state->local->trigger); ++} ++ ++/* Called from queue_message, by the slot handler and application threads, ++** with slot_mutex held */ ++static VCHIQ_HEADER_T * ++reserve_space(VCHIQ_STATE_T *state, int space, int is_blocking) ++{ ++ VCHIQ_SHARED_STATE_T *local = state->local; ++ int tx_pos = state->local_tx_pos; ++ int slot_space = VCHIQ_SLOT_SIZE - (tx_pos & VCHIQ_SLOT_MASK); ++ ++ if (space > slot_space) { ++ VCHIQ_HEADER_T *header; ++ /* Fill the remaining space with padding */ ++ WARN_ON(state->tx_data == NULL); ++ header = (VCHIQ_HEADER_T *) ++ (state->tx_data + (tx_pos & VCHIQ_SLOT_MASK)); ++ header->msgid = VCHIQ_MSGID_PADDING; ++ header->size = slot_space - sizeof(VCHIQ_HEADER_T); ++ ++ tx_pos += slot_space; ++ } ++ ++ /* If necessary, get the next slot. */ ++ if ((tx_pos & VCHIQ_SLOT_MASK) == 0) { ++ int slot_index; ++ ++ /* If there is no free slot... */ ++ ++ if (down_trylock(&state->slot_available_event) != 0) { ++ /* ...wait for one. */ ++ ++ VCHIQ_STATS_INC(state, slot_stalls); ++ ++ /* But first, flush through the last slot. */ ++ state->local_tx_pos = tx_pos; ++ local->tx_pos = tx_pos; ++ remote_event_signal(&state->remote->trigger); ++ ++ if (!is_blocking || ++ (down_interruptible( ++ &state->slot_available_event) != 0)) ++ return NULL; /* No space available */ ++ } ++ ++ BUG_ON(tx_pos == ++ (state->slot_queue_available * VCHIQ_SLOT_SIZE)); ++ ++ slot_index = local->slot_queue[ ++ SLOT_QUEUE_INDEX_FROM_POS(tx_pos) & ++ VCHIQ_SLOT_QUEUE_MASK]; ++ state->tx_data = ++ (char *)SLOT_DATA_FROM_INDEX(state, slot_index); ++ } ++ ++ state->local_tx_pos = tx_pos + space; ++ ++ return (VCHIQ_HEADER_T *)(state->tx_data + (tx_pos & VCHIQ_SLOT_MASK)); ++} ++ ++/* Called by the recycle thread. */ ++static void ++process_free_queue(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_SHARED_STATE_T *local = state->local; ++ BITSET_T service_found[BITSET_SIZE(VCHIQ_MAX_SERVICES)]; ++ int slot_queue_available; ++ ++ /* Use a read memory barrier to ensure that any state that may have ++ ** been modified by another thread is not masked by stale prefetched ++ ** values. */ ++ rmb(); ++ ++ /* Find slots which have been freed by the other side, and return them ++ ** to the available queue. */ ++ slot_queue_available = state->slot_queue_available; ++ ++ while (slot_queue_available != local->slot_queue_recycle) { ++ unsigned int pos; ++ int slot_index = local->slot_queue[slot_queue_available++ & ++ VCHIQ_SLOT_QUEUE_MASK]; ++ char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index); ++ int data_found = 0; ++ ++ vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%x %x %x", ++ state->id, slot_index, (unsigned int)data, ++ local->slot_queue_recycle, slot_queue_available); ++ ++ /* Initialise the bitmask for services which have used this ++ ** slot */ ++ BITSET_ZERO(service_found); ++ ++ pos = 0; ++ ++ while (pos < VCHIQ_SLOT_SIZE) { ++ VCHIQ_HEADER_T *header = ++ (VCHIQ_HEADER_T *)(data + pos); ++ int msgid = header->msgid; ++ if (VCHIQ_MSG_TYPE(msgid) == VCHIQ_MSG_DATA) { ++ int port = VCHIQ_MSG_SRCPORT(msgid); ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &state->service_quotas[port]; ++ int count; ++ spin_lock("a_spinlock); ++ count = service_quota->message_use_count; ++ if (count > 0) ++ service_quota->message_use_count = ++ count - 1; ++ spin_unlock("a_spinlock); ++ ++ if (count == service_quota->message_quota) ++ /* Signal the service that it ++ ** has dropped below its quota ++ */ ++ up(&service_quota->quota_event); ++ else if (count == 0) { ++ vchiq_log_error(vchiq_core_log_level, ++ "service %d " ++ "message_use_count=%d " ++ "(header %x, msgid %x, " ++ "header->msgid %x, " ++ "header->size %x)", ++ port, ++ service_quota-> ++ message_use_count, ++ (unsigned int)header, msgid, ++ header->msgid, ++ header->size); ++ WARN(1, "invalid message use count\n"); ++ } ++ if (!BITSET_IS_SET(service_found, port)) { ++ /* Set the found bit for this service */ ++ BITSET_SET(service_found, port); ++ ++ spin_lock("a_spinlock); ++ count = service_quota->slot_use_count; ++ if (count > 0) ++ service_quota->slot_use_count = ++ count - 1; ++ spin_unlock("a_spinlock); ++ ++ if (count > 0) { ++ /* Signal the service in case ++ ** it has dropped below its ++ ** quota */ ++ up(&service_quota->quota_event); ++ vchiq_log_trace( ++ vchiq_core_log_level, ++ "%d: pfq:%d %x@%x - " ++ "slot_use->%d", ++ state->id, port, ++ header->size, ++ (unsigned int)header, ++ count - 1); ++ } else { ++ vchiq_log_error( ++ vchiq_core_log_level, ++ "service %d " ++ "slot_use_count" ++ "=%d (header %x" ++ ", msgid %x, " ++ "header->msgid" ++ " %x, header->" ++ "size %x)", ++ port, count, ++ (unsigned int)header, ++ msgid, ++ header->msgid, ++ header->size); ++ WARN(1, "bad slot use count\n"); ++ } ++ } ++ ++ data_found = 1; ++ } ++ ++ pos += calc_stride(header->size); ++ if (pos > VCHIQ_SLOT_SIZE) { ++ vchiq_log_error(vchiq_core_log_level, ++ "pfq - pos %x: header %x, msgid %x, " ++ "header->msgid %x, header->size %x", ++ pos, (unsigned int)header, msgid, ++ header->msgid, header->size); ++ WARN(1, "invalid slot position\n"); ++ } ++ } ++ ++ if (data_found) { ++ int count; ++ spin_lock("a_spinlock); ++ count = state->data_use_count; ++ if (count > 0) ++ state->data_use_count = ++ count - 1; ++ spin_unlock("a_spinlock); ++ if (count == state->data_quota) ++ up(&state->data_quota_event); ++ } ++ ++ state->slot_queue_available = slot_queue_available; ++ up(&state->slot_available_event); ++ } ++} ++ ++/* Called by the slot handler and application threads */ ++static VCHIQ_STATUS_T ++queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, ++ int msgid, const VCHIQ_ELEMENT_T *elements, ++ int count, int size, int is_blocking) ++{ ++ VCHIQ_SHARED_STATE_T *local; ++ VCHIQ_SERVICE_QUOTA_T *service_quota = NULL; ++ VCHIQ_HEADER_T *header; ++ int type = VCHIQ_MSG_TYPE(msgid); ++ ++ unsigned int stride; ++ ++ local = state->local; ++ ++ stride = calc_stride(size); ++ ++ WARN_ON(!(stride <= VCHIQ_SLOT_SIZE)); ++ ++ if ((type != VCHIQ_MSG_RESUME) && ++ (mutex_lock_interruptible(&state->slot_mutex) != 0)) ++ return VCHIQ_RETRY; ++ ++ if (type == VCHIQ_MSG_DATA) { ++ int tx_end_index; ++ ++ BUG_ON(!service); ++ ++ if (service->closing) { ++ /* The service has been closed */ ++ mutex_unlock(&state->slot_mutex); ++ return VCHIQ_ERROR; ++ } ++ ++ service_quota = &state->service_quotas[service->localport]; ++ ++ spin_lock("a_spinlock); ++ ++ /* Ensure this service doesn't use more than its quota of ++ ** messages or slots */ ++ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS( ++ state->local_tx_pos + stride - 1); ++ ++ /* Ensure data messages don't use more than their quota of ++ ** slots */ ++ while ((tx_end_index != state->previous_data_index) && ++ (state->data_use_count == state->data_quota)) { ++ VCHIQ_STATS_INC(state, data_stalls); ++ spin_unlock("a_spinlock); ++ mutex_unlock(&state->slot_mutex); ++ ++ if (down_interruptible(&state->data_quota_event) ++ != 0) ++ return VCHIQ_RETRY; ++ ++ mutex_lock(&state->slot_mutex); ++ spin_lock("a_spinlock); ++ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS( ++ state->local_tx_pos + stride - 1); ++ if ((tx_end_index == state->previous_data_index) || ++ (state->data_use_count < state->data_quota)) { ++ /* Pass the signal on to other waiters */ ++ up(&state->data_quota_event); ++ break; ++ } ++ } ++ ++ while ((service_quota->message_use_count == ++ service_quota->message_quota) || ++ ((tx_end_index != service_quota->previous_tx_index) && ++ (service_quota->slot_use_count == ++ service_quota->slot_quota))) { ++ spin_unlock("a_spinlock); ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: qm:%d %s,%x - quota stall " ++ "(msg %d, slot %d)", ++ state->id, service->localport, ++ msg_type_str(type), size, ++ service_quota->message_use_count, ++ service_quota->slot_use_count); ++ VCHIQ_SERVICE_STATS_INC(service, quota_stalls); ++ mutex_unlock(&state->slot_mutex); ++ if (down_interruptible(&service_quota->quota_event) ++ != 0) ++ return VCHIQ_RETRY; ++ if (service->closing) ++ return VCHIQ_ERROR; ++ if (mutex_lock_interruptible(&state->slot_mutex) != 0) ++ return VCHIQ_RETRY; ++ if (service->srvstate != VCHIQ_SRVSTATE_OPEN) { ++ /* The service has been closed */ ++ mutex_unlock(&state->slot_mutex); ++ return VCHIQ_ERROR; ++ } ++ spin_lock("a_spinlock); ++ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS( ++ state->local_tx_pos + stride - 1); ++ } ++ ++ spin_unlock("a_spinlock); ++ } ++ ++ header = reserve_space(state, stride, is_blocking); ++ ++ if (!header) { ++ if (service) ++ VCHIQ_SERVICE_STATS_INC(service, slot_stalls); ++ mutex_unlock(&state->slot_mutex); ++ return VCHIQ_RETRY; ++ } ++ ++ if (type == VCHIQ_MSG_DATA) { ++ int i, pos; ++ int tx_end_index; ++ int slot_use_count; ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: qm %s@%x,%x (%d->%d)", ++ state->id, ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), ++ (unsigned int)header, size, ++ VCHIQ_MSG_SRCPORT(msgid), ++ VCHIQ_MSG_DSTPORT(msgid)); ++ ++ BUG_ON(!service); ++ ++ for (i = 0, pos = 0; i < (unsigned int)count; ++ pos += elements[i++].size) ++ if (elements[i].size) { ++ if (vchiq_copy_from_user ++ (header->data + pos, elements[i].data, ++ (size_t) elements[i].size) != ++ VCHIQ_SUCCESS) { ++ mutex_unlock(&state->slot_mutex); ++ VCHIQ_SERVICE_STATS_INC(service, ++ error_count); ++ return VCHIQ_ERROR; ++ } ++ if (i == 0) { ++ if (vchiq_core_msg_log_level >= ++ VCHIQ_LOG_INFO) ++ vchiq_log_dump_mem("Sent", 0, ++ header->data + pos, ++ min(64u, ++ elements[0].size)); ++ } ++ } ++ ++ spin_lock("a_spinlock); ++ service_quota->message_use_count++; ++ ++ tx_end_index = ++ SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos - 1); ++ ++ /* If this transmission can't fit in the last slot used by any ++ ** service, the data_use_count must be increased. */ ++ if (tx_end_index != state->previous_data_index) { ++ state->previous_data_index = tx_end_index; ++ state->data_use_count++; ++ } ++ ++ /* If this isn't the same slot last used by this service, ++ ** the service's slot_use_count must be increased. */ ++ if (tx_end_index != service_quota->previous_tx_index) { ++ service_quota->previous_tx_index = tx_end_index; ++ slot_use_count = ++service_quota->slot_use_count; ++ } else { ++ slot_use_count = 0; ++ } ++ ++ spin_unlock("a_spinlock); ++ ++ if (slot_use_count) ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: qm:%d %s,%x - slot_use->%d (hdr %p)", ++ state->id, service->localport, ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), size, ++ slot_use_count, header); ++ ++ VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); ++ VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); ++ } else { ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: qm %s@%x,%x (%d->%d)", state->id, ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), ++ (unsigned int)header, size, ++ VCHIQ_MSG_SRCPORT(msgid), ++ VCHIQ_MSG_DSTPORT(msgid)); ++ if (size != 0) { ++ WARN_ON(!((count == 1) && (size == elements[0].size))); ++ memcpy(header->data, elements[0].data, ++ elements[0].size); ++ } ++ VCHIQ_STATS_INC(state, ctrl_tx_count); ++ } ++ ++ header->msgid = msgid; ++ header->size = size; ++ ++ { ++ int svc_fourcc; ++ ++ svc_fourcc = service ++ ? service->base.fourcc ++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); ++ ++ vchiq_log_info(vchiq_core_msg_log_level, ++ "Sent Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d", ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), ++ VCHIQ_MSG_TYPE(msgid), ++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), ++ VCHIQ_MSG_SRCPORT(msgid), ++ VCHIQ_MSG_DSTPORT(msgid), ++ size); ++ } ++ ++ /* Make sure the new header is visible to the peer. */ ++ wmb(); ++ ++ /* Make the new tx_pos visible to the peer. */ ++ local->tx_pos = state->local_tx_pos; ++ wmb(); ++ ++ if (service && (type == VCHIQ_MSG_CLOSE)) ++ vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT); ++ ++ if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE) ++ mutex_unlock(&state->slot_mutex); ++ ++ remote_event_signal(&state->remote->trigger); ++ ++ return VCHIQ_SUCCESS; ++} ++ ++/* Called by the slot handler and application threads */ ++static VCHIQ_STATUS_T ++queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, ++ int msgid, const VCHIQ_ELEMENT_T *elements, ++ int count, int size, int is_blocking) ++{ ++ VCHIQ_SHARED_STATE_T *local; ++ VCHIQ_HEADER_T *header; ++ ++ local = state->local; ++ ++ if ((VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_RESUME) && ++ (mutex_lock_interruptible(&state->sync_mutex) != 0)) ++ return VCHIQ_RETRY; ++ ++ remote_event_wait(&local->sync_release); ++ ++ rmb(); ++ ++ header = (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, ++ local->slot_sync); ++ ++ { ++ int oldmsgid = header->msgid; ++ if (oldmsgid != VCHIQ_MSGID_PADDING) ++ vchiq_log_error(vchiq_core_log_level, ++ "%d: qms - msgid %x, not PADDING", ++ state->id, oldmsgid); ++ } ++ ++ if (service) { ++ int i, pos; ++ ++ vchiq_log_info(vchiq_sync_log_level, ++ "%d: qms %s@%x,%x (%d->%d)", state->id, ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), ++ (unsigned int)header, size, ++ VCHIQ_MSG_SRCPORT(msgid), ++ VCHIQ_MSG_DSTPORT(msgid)); ++ ++ for (i = 0, pos = 0; i < (unsigned int)count; ++ pos += elements[i++].size) ++ if (elements[i].size) { ++ if (vchiq_copy_from_user ++ (header->data + pos, elements[i].data, ++ (size_t) elements[i].size) != ++ VCHIQ_SUCCESS) { ++ mutex_unlock(&state->sync_mutex); ++ VCHIQ_SERVICE_STATS_INC(service, ++ error_count); ++ return VCHIQ_ERROR; ++ } ++ if (i == 0) { ++ if (vchiq_sync_log_level >= ++ VCHIQ_LOG_TRACE) ++ vchiq_log_dump_mem("Sent Sync", ++ 0, header->data + pos, ++ min(64u, ++ elements[0].size)); ++ } ++ } ++ ++ VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); ++ VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); ++ } else { ++ vchiq_log_info(vchiq_sync_log_level, ++ "%d: qms %s@%x,%x (%d->%d)", state->id, ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), ++ (unsigned int)header, size, ++ VCHIQ_MSG_SRCPORT(msgid), ++ VCHIQ_MSG_DSTPORT(msgid)); ++ if (size != 0) { ++ WARN_ON(!((count == 1) && (size == elements[0].size))); ++ memcpy(header->data, elements[0].data, ++ elements[0].size); ++ } ++ VCHIQ_STATS_INC(state, ctrl_tx_count); ++ } ++ ++ header->size = size; ++ header->msgid = msgid; ++ ++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) { ++ int svc_fourcc; ++ ++ svc_fourcc = service ++ ? service->base.fourcc ++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); ++ ++ vchiq_log_trace(vchiq_sync_log_level, ++ "Sent Sync Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d", ++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), ++ VCHIQ_MSG_TYPE(msgid), ++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), ++ VCHIQ_MSG_SRCPORT(msgid), ++ VCHIQ_MSG_DSTPORT(msgid), ++ size); ++ } ++ ++ /* Make sure the new header is visible to the peer. */ ++ wmb(); ++ ++ remote_event_signal(&state->remote->sync_trigger); ++ ++ if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE) ++ mutex_unlock(&state->sync_mutex); ++ ++ return VCHIQ_SUCCESS; ++} ++ ++static inline void ++claim_slot(VCHIQ_SLOT_INFO_T *slot) ++{ ++ slot->use_count++; ++} ++ ++static void ++release_slot(VCHIQ_STATE_T *state, VCHIQ_SLOT_INFO_T *slot_info, ++ VCHIQ_HEADER_T *header, VCHIQ_SERVICE_T *service) ++{ ++ int release_count; ++ ++ mutex_lock(&state->recycle_mutex); ++ ++ if (header) { ++ int msgid = header->msgid; ++ if (((msgid & VCHIQ_MSGID_CLAIMED) == 0) || ++ (service && service->closing)) { ++ mutex_unlock(&state->recycle_mutex); ++ return; ++ } ++ ++ /* Rewrite the message header to prevent a double ++ ** release */ ++ header->msgid = msgid & ~VCHIQ_MSGID_CLAIMED; ++ } ++ ++ release_count = slot_info->release_count; ++ slot_info->release_count = ++release_count; ++ ++ if (release_count == slot_info->use_count) { ++ int slot_queue_recycle; ++ /* Add to the freed queue */ ++ ++ /* A read barrier is necessary here to prevent speculative ++ ** fetches of remote->slot_queue_recycle from overtaking the ++ ** mutex. */ ++ rmb(); ++ ++ slot_queue_recycle = state->remote->slot_queue_recycle; ++ state->remote->slot_queue[slot_queue_recycle & ++ VCHIQ_SLOT_QUEUE_MASK] = ++ SLOT_INDEX_FROM_INFO(state, slot_info); ++ state->remote->slot_queue_recycle = slot_queue_recycle + 1; ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: release_slot %d - recycle->%x", ++ state->id, SLOT_INDEX_FROM_INFO(state, slot_info), ++ state->remote->slot_queue_recycle); ++ ++ /* A write barrier is necessary, but remote_event_signal ++ ** contains one. */ ++ remote_event_signal(&state->remote->recycle); ++ } ++ ++ mutex_unlock(&state->recycle_mutex); ++} ++ ++/* Called by the slot handler - don't hold the bulk mutex */ ++static VCHIQ_STATUS_T ++notify_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue, ++ int retry_poll) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: nb:%d %cx - p=%x rn=%x r=%x", ++ service->state->id, service->localport, ++ (queue == &service->bulk_tx) ? 't' : 'r', ++ queue->process, queue->remote_notify, queue->remove); ++ ++ if (service->state->is_master) { ++ while (queue->remote_notify != queue->process) { ++ VCHIQ_BULK_T *bulk = ++ &queue->bulks[BULK_INDEX(queue->remote_notify)]; ++ int msgtype = (bulk->dir == VCHIQ_BULK_TRANSMIT) ? ++ VCHIQ_MSG_BULK_RX_DONE : VCHIQ_MSG_BULK_TX_DONE; ++ int msgid = VCHIQ_MAKE_MSG(msgtype, service->localport, ++ service->remoteport); ++ VCHIQ_ELEMENT_T element = { &bulk->actual, 4 }; ++ /* Only reply to non-dummy bulk requests */ ++ if (bulk->remote_data) { ++ status = queue_message(service->state, NULL, ++ msgid, &element, 1, 4, 0); ++ if (status != VCHIQ_SUCCESS) ++ break; ++ } ++ queue->remote_notify++; ++ } ++ } else { ++ queue->remote_notify = queue->process; ++ } ++ ++ if (status == VCHIQ_SUCCESS) { ++ while (queue->remove != queue->remote_notify) { ++ VCHIQ_BULK_T *bulk = ++ &queue->bulks[BULK_INDEX(queue->remove)]; ++ ++ /* Only generate callbacks for non-dummy bulk ++ ** requests, and non-terminated services */ ++ if (bulk->data && service->instance) { ++ if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) { ++ if (bulk->dir == VCHIQ_BULK_TRANSMIT) { ++ VCHIQ_SERVICE_STATS_INC(service, ++ bulk_tx_count); ++ VCHIQ_SERVICE_STATS_ADD(service, ++ bulk_tx_bytes, ++ bulk->actual); ++ } else { ++ VCHIQ_SERVICE_STATS_INC(service, ++ bulk_rx_count); ++ VCHIQ_SERVICE_STATS_ADD(service, ++ bulk_rx_bytes, ++ bulk->actual); ++ } ++ } else { ++ VCHIQ_SERVICE_STATS_INC(service, ++ bulk_aborted_count); ++ } ++ if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) { ++ struct bulk_waiter *waiter; ++ spin_lock(&bulk_waiter_spinlock); ++ waiter = bulk->userdata; ++ if (waiter) { ++ waiter->actual = bulk->actual; ++ up(&waiter->event); ++ } ++ spin_unlock(&bulk_waiter_spinlock); ++ } else if (bulk->mode == ++ VCHIQ_BULK_MODE_CALLBACK) { ++ VCHIQ_REASON_T reason = (bulk->dir == ++ VCHIQ_BULK_TRANSMIT) ? ++ ((bulk->actual == ++ VCHIQ_BULK_ACTUAL_ABORTED) ? ++ VCHIQ_BULK_TRANSMIT_ABORTED : ++ VCHIQ_BULK_TRANSMIT_DONE) : ++ ((bulk->actual == ++ VCHIQ_BULK_ACTUAL_ABORTED) ? ++ VCHIQ_BULK_RECEIVE_ABORTED : ++ VCHIQ_BULK_RECEIVE_DONE); ++ status = make_service_callback(service, ++ reason, NULL, bulk->userdata); ++ if (status == VCHIQ_RETRY) ++ break; ++ } ++ } ++ ++ queue->remove++; ++ up(&service->bulk_remove_event); ++ } ++ if (!retry_poll) ++ status = VCHIQ_SUCCESS; ++ } ++ ++ if (status == VCHIQ_RETRY) ++ request_poll(service->state, service, ++ (queue == &service->bulk_tx) ? ++ VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY); ++ ++ return status; ++} ++ ++/* Called by the slot handler thread */ ++static void ++poll_services(VCHIQ_STATE_T *state) ++{ ++ int group, i; ++ ++ for (group = 0; group < BITSET_SIZE(state->unused_service); group++) { ++ uint32_t flags; ++ flags = atomic_xchg(&state->poll_services[group], 0); ++ for (i = 0; flags; i++) { ++ if (flags & (1 << i)) { ++ VCHIQ_SERVICE_T *service = ++ find_service_by_port(state, ++ (group<<5) + i); ++ uint32_t service_flags; ++ flags &= ~(1 << i); ++ if (!service) ++ continue; ++ service_flags = ++ atomic_xchg(&service->poll_flags, 0); ++ if (service_flags & ++ (1 << VCHIQ_POLL_REMOVE)) { ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: ps - remove %d<->%d", ++ state->id, service->localport, ++ service->remoteport); ++ ++ /* Make it look like a client, because ++ it must be removed and not left in ++ the LISTENING state. */ ++ service->public_fourcc = ++ VCHIQ_FOURCC_INVALID; ++ ++ if (vchiq_close_service_internal( ++ service, 0/*!close_recvd*/) != ++ VCHIQ_SUCCESS) ++ request_poll(state, service, ++ VCHIQ_POLL_REMOVE); ++ } else if (service_flags & ++ (1 << VCHIQ_POLL_TERMINATE)) { ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: ps - terminate %d<->%d", ++ state->id, service->localport, ++ service->remoteport); ++ if (vchiq_close_service_internal( ++ service, 0/*!close_recvd*/) != ++ VCHIQ_SUCCESS) ++ request_poll(state, service, ++ VCHIQ_POLL_TERMINATE); ++ } ++ if (service_flags & (1 << VCHIQ_POLL_TXNOTIFY)) ++ notify_bulks(service, ++ &service->bulk_tx, ++ 1/*retry_poll*/); ++ if (service_flags & (1 << VCHIQ_POLL_RXNOTIFY)) ++ notify_bulks(service, ++ &service->bulk_rx, ++ 1/*retry_poll*/); ++ unlock_service(service); ++ } ++ } ++ } ++} ++ ++/* Called by the slot handler or application threads, holding the bulk mutex. */ ++static int ++resolve_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue) ++{ ++ VCHIQ_STATE_T *state = service->state; ++ int resolved = 0; ++ int rc; ++ ++ while ((queue->process != queue->local_insert) && ++ (queue->process != queue->remote_insert)) { ++ VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)]; ++ ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: rb:%d %cx - li=%x ri=%x p=%x", ++ state->id, service->localport, ++ (queue == &service->bulk_tx) ? 't' : 'r', ++ queue->local_insert, queue->remote_insert, ++ queue->process); ++ ++ WARN_ON(!((int)(queue->local_insert - queue->process) > 0)); ++ WARN_ON(!((int)(queue->remote_insert - queue->process) > 0)); ++ ++ rc = mutex_lock_interruptible(&state->bulk_transfer_mutex); ++ if (rc != 0) ++ break; ++ ++ vchiq_transfer_bulk(bulk); ++ mutex_unlock(&state->bulk_transfer_mutex); ++ ++ if (vchiq_core_msg_log_level >= VCHIQ_LOG_INFO) { ++ const char *header = (queue == &service->bulk_tx) ? ++ "Send Bulk to" : "Recv Bulk from"; ++ if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) ++ vchiq_log_info(vchiq_core_msg_log_level, ++ "%s %c%c%c%c d:%d len:%d %x<->%x", ++ header, ++ VCHIQ_FOURCC_AS_4CHARS( ++ service->base.fourcc), ++ service->remoteport, ++ bulk->size, ++ (unsigned int)bulk->data, ++ (unsigned int)bulk->remote_data); ++ else ++ vchiq_log_info(vchiq_core_msg_log_level, ++ "%s %c%c%c%c d:%d ABORTED - tx len:%d," ++ " rx len:%d %x<->%x", ++ header, ++ VCHIQ_FOURCC_AS_4CHARS( ++ service->base.fourcc), ++ service->remoteport, ++ bulk->size, ++ bulk->remote_size, ++ (unsigned int)bulk->data, ++ (unsigned int)bulk->remote_data); ++ } ++ ++ vchiq_complete_bulk(bulk); ++ queue->process++; ++ resolved++; ++ } ++ return resolved; ++} ++ ++/* Called with the bulk_mutex held */ ++static void ++abort_outstanding_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue) ++{ ++ int is_tx = (queue == &service->bulk_tx); ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: aob:%d %cx - li=%x ri=%x p=%x", ++ service->state->id, service->localport, is_tx ? 't' : 'r', ++ queue->local_insert, queue->remote_insert, queue->process); ++ ++ WARN_ON(!((int)(queue->local_insert - queue->process) >= 0)); ++ WARN_ON(!((int)(queue->remote_insert - queue->process) >= 0)); ++ ++ while ((queue->process != queue->local_insert) || ++ (queue->process != queue->remote_insert)) { ++ VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)]; ++ ++ if (queue->process == queue->remote_insert) { ++ /* fabricate a matching dummy bulk */ ++ bulk->remote_data = NULL; ++ bulk->remote_size = 0; ++ queue->remote_insert++; ++ } ++ ++ if (queue->process != queue->local_insert) { ++ vchiq_complete_bulk(bulk); ++ ++ vchiq_log_info(vchiq_core_msg_log_level, ++ "%s %c%c%c%c d:%d ABORTED - tx len:%d, " ++ "rx len:%d", ++ is_tx ? "Send Bulk to" : "Recv Bulk from", ++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), ++ service->remoteport, ++ bulk->size, ++ bulk->remote_size); ++ } else { ++ /* fabricate a matching dummy bulk */ ++ bulk->data = NULL; ++ bulk->size = 0; ++ bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED; ++ bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT : ++ VCHIQ_BULK_RECEIVE; ++ queue->local_insert++; ++ } ++ ++ queue->process++; ++ } ++} ++ ++/* Called from the slot handler thread */ ++static void ++pause_bulks(VCHIQ_STATE_T *state) ++{ ++ if (unlikely(atomic_inc_return(&pause_bulks_count) != 1)) { ++ WARN_ON_ONCE(1); ++ atomic_set(&pause_bulks_count, 1); ++ return; ++ } ++ ++ /* Block bulk transfers from all services */ ++ mutex_lock(&state->bulk_transfer_mutex); ++} ++ ++/* Called from the slot handler thread */ ++static void ++resume_bulks(VCHIQ_STATE_T *state) ++{ ++ int i; ++ if (unlikely(atomic_dec_return(&pause_bulks_count) != 0)) { ++ WARN_ON_ONCE(1); ++ atomic_set(&pause_bulks_count, 0); ++ return; ++ } ++ ++ /* Allow bulk transfers from all services */ ++ mutex_unlock(&state->bulk_transfer_mutex); ++ ++ if (state->deferred_bulks == 0) ++ return; ++ ++ /* Deal with any bulks which had to be deferred due to being in ++ * paused state. Don't try to match up to number of deferred bulks ++ * in case we've had something come and close the service in the ++ * interim - just process all bulk queues for all services */ ++ vchiq_log_info(vchiq_core_log_level, "%s: processing %d deferred bulks", ++ __func__, state->deferred_bulks); ++ ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *service = state->services[i]; ++ int resolved_rx = 0; ++ int resolved_tx = 0; ++ if (!service || (service->srvstate != VCHIQ_SRVSTATE_OPEN)) ++ continue; ++ ++ mutex_lock(&service->bulk_mutex); ++ resolved_rx = resolve_bulks(service, &service->bulk_rx); ++ resolved_tx = resolve_bulks(service, &service->bulk_tx); ++ mutex_unlock(&service->bulk_mutex); ++ if (resolved_rx) ++ notify_bulks(service, &service->bulk_rx, 1); ++ if (resolved_tx) ++ notify_bulks(service, &service->bulk_tx, 1); ++ } ++ state->deferred_bulks = 0; ++} ++ ++static int ++parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) ++{ ++ VCHIQ_SERVICE_T *service = NULL; ++ int msgid, size; ++ int type; ++ unsigned int localport, remoteport; ++ ++ msgid = header->msgid; ++ size = header->size; ++ type = VCHIQ_MSG_TYPE(msgid); ++ localport = VCHIQ_MSG_DSTPORT(msgid); ++ remoteport = VCHIQ_MSG_SRCPORT(msgid); ++ if (size >= sizeof(struct vchiq_open_payload)) { ++ const struct vchiq_open_payload *payload = ++ (struct vchiq_open_payload *)header->data; ++ unsigned int fourcc; ++ ++ fourcc = payload->fourcc; ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: prs OPEN@%x (%d->'%c%c%c%c')", ++ state->id, (unsigned int)header, ++ localport, ++ VCHIQ_FOURCC_AS_4CHARS(fourcc)); ++ ++ service = get_listening_service(state, fourcc); ++ ++ if (service) { ++ /* A matching service exists */ ++ short version = payload->version; ++ short version_min = payload->version_min; ++ if ((service->version < version_min) || ++ (version < service->version_min)) { ++ /* Version mismatch */ ++ vchiq_loud_error_header(); ++ vchiq_loud_error("%d: service %d (%c%c%c%c) " ++ "version mismatch - local (%d, min %d)" ++ " vs. remote (%d, min %d)", ++ state->id, service->localport, ++ VCHIQ_FOURCC_AS_4CHARS(fourcc), ++ service->version, service->version_min, ++ version, version_min); ++ vchiq_loud_error_footer(); ++ unlock_service(service); ++ service = NULL; ++ goto fail_open; ++ } ++ service->peer_version = version; ++ ++ if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) { ++ struct vchiq_openack_payload ack_payload = { ++ service->version ++ }; ++ VCHIQ_ELEMENT_T body = { ++ &ack_payload, ++ sizeof(ack_payload) ++ }; ++ ++ /* Acknowledge the OPEN */ ++ if (service->sync) { ++ if (queue_message_sync(state, NULL, ++ VCHIQ_MAKE_MSG( ++ VCHIQ_MSG_OPENACK, ++ service->localport, ++ remoteport), ++ &body, 1, sizeof(ack_payload), ++ 0) == VCHIQ_RETRY) ++ goto bail_not_ready; ++ } else { ++ if (queue_message(state, NULL, ++ VCHIQ_MAKE_MSG( ++ VCHIQ_MSG_OPENACK, ++ service->localport, ++ remoteport), ++ &body, 1, sizeof(ack_payload), ++ 0) == VCHIQ_RETRY) ++ goto bail_not_ready; ++ } ++ ++ /* The service is now open */ ++ vchiq_set_service_state(service, ++ service->sync ? VCHIQ_SRVSTATE_OPENSYNC ++ : VCHIQ_SRVSTATE_OPEN); ++ } ++ ++ service->remoteport = remoteport; ++ service->client_id = ((int *)header->data)[1]; ++ if (make_service_callback(service, VCHIQ_SERVICE_OPENED, ++ NULL, NULL) == VCHIQ_RETRY) { ++ /* Bail out if not ready */ ++ service->remoteport = VCHIQ_PORT_FREE; ++ goto bail_not_ready; ++ } ++ ++ /* Success - the message has been dealt with */ ++ unlock_service(service); ++ return 1; ++ } ++ } ++ ++fail_open: ++ /* No available service, or an invalid request - send a CLOSE */ ++ if (queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, VCHIQ_MSG_SRCPORT(msgid)), ++ NULL, 0, 0, 0) == VCHIQ_RETRY) ++ goto bail_not_ready; ++ ++ return 1; ++ ++bail_not_ready: ++ if (service) ++ unlock_service(service); ++ ++ return 0; ++} ++ ++/* Called by the slot handler thread */ ++static void ++parse_rx_slots(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_SHARED_STATE_T *remote = state->remote; ++ VCHIQ_SERVICE_T *service = NULL; ++ int tx_pos; ++ DEBUG_INITIALISE(state->local) ++ ++ tx_pos = remote->tx_pos; ++ ++ while (state->rx_pos != tx_pos) { ++ VCHIQ_HEADER_T *header; ++ int msgid, size; ++ int type; ++ unsigned int localport, remoteport; ++ ++ DEBUG_TRACE(PARSE_LINE); ++ if (!state->rx_data) { ++ int rx_index; ++ WARN_ON(!((state->rx_pos & VCHIQ_SLOT_MASK) == 0)); ++ rx_index = remote->slot_queue[ ++ SLOT_QUEUE_INDEX_FROM_POS(state->rx_pos) & ++ VCHIQ_SLOT_QUEUE_MASK]; ++ state->rx_data = (char *)SLOT_DATA_FROM_INDEX(state, ++ rx_index); ++ state->rx_info = SLOT_INFO_FROM_INDEX(state, rx_index); ++ ++ /* Initialise use_count to one, and increment ++ ** release_count at the end of the slot to avoid ++ ** releasing the slot prematurely. */ ++ state->rx_info->use_count = 1; ++ state->rx_info->release_count = 0; ++ } ++ ++ header = (VCHIQ_HEADER_T *)(state->rx_data + ++ (state->rx_pos & VCHIQ_SLOT_MASK)); ++ DEBUG_VALUE(PARSE_HEADER, (int)header); ++ msgid = header->msgid; ++ DEBUG_VALUE(PARSE_MSGID, msgid); ++ size = header->size; ++ type = VCHIQ_MSG_TYPE(msgid); ++ localport = VCHIQ_MSG_DSTPORT(msgid); ++ remoteport = VCHIQ_MSG_SRCPORT(msgid); ++ ++ if (type != VCHIQ_MSG_DATA) ++ VCHIQ_STATS_INC(state, ctrl_rx_count); ++ ++ switch (type) { ++ case VCHIQ_MSG_OPENACK: ++ case VCHIQ_MSG_CLOSE: ++ case VCHIQ_MSG_DATA: ++ case VCHIQ_MSG_BULK_RX: ++ case VCHIQ_MSG_BULK_TX: ++ case VCHIQ_MSG_BULK_RX_DONE: ++ case VCHIQ_MSG_BULK_TX_DONE: ++ service = find_service_by_port(state, localport); ++ if ((!service || service->remoteport != remoteport) && ++ (localport == 0) && ++ (type == VCHIQ_MSG_CLOSE)) { ++ /* This could be a CLOSE from a client which ++ hadn't yet received the OPENACK - look for ++ the connected service */ ++ if (service) ++ unlock_service(service); ++ service = get_connected_service(state, ++ remoteport); ++ if (service) ++ vchiq_log_warning(vchiq_core_log_level, ++ "%d: prs %s@%x (%d->%d) - " ++ "found connected service %d", ++ state->id, msg_type_str(type), ++ (unsigned int)header, ++ remoteport, localport, ++ service->localport); ++ } ++ ++ if (!service) { ++ vchiq_log_error(vchiq_core_log_level, ++ "%d: prs %s@%x (%d->%d) - " ++ "invalid/closed service %d", ++ state->id, msg_type_str(type), ++ (unsigned int)header, ++ remoteport, localport, localport); ++ goto skip_message; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ if (vchiq_core_msg_log_level >= VCHIQ_LOG_INFO) { ++ int svc_fourcc; ++ ++ svc_fourcc = service ++ ? service->base.fourcc ++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); ++ vchiq_log_info(vchiq_core_msg_log_level, ++ "Rcvd Msg %s(%u) from %c%c%c%c s:%d d:%d " ++ "len:%d", ++ msg_type_str(type), type, ++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), ++ remoteport, localport, size); ++ if (size > 0) ++ vchiq_log_dump_mem("Rcvd", 0, header->data, ++ min(64, size)); ++ } ++ ++ if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size) ++ > VCHIQ_SLOT_SIZE) { ++ vchiq_log_error(vchiq_core_log_level, ++ "header %x (msgid %x) - size %x too big for " ++ "slot", ++ (unsigned int)header, (unsigned int)msgid, ++ (unsigned int)size); ++ WARN(1, "oversized for slot\n"); ++ } ++ ++ switch (type) { ++ case VCHIQ_MSG_OPEN: ++ WARN_ON(!(VCHIQ_MSG_DSTPORT(msgid) == 0)); ++ if (!parse_open(state, header)) ++ goto bail_not_ready; ++ break; ++ case VCHIQ_MSG_OPENACK: ++ if (size >= sizeof(struct vchiq_openack_payload)) { ++ const struct vchiq_openack_payload *payload = ++ (struct vchiq_openack_payload *) ++ header->data; ++ service->peer_version = payload->version; ++ } ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: prs OPENACK@%x,%x (%d->%d) v:%d", ++ state->id, (unsigned int)header, size, ++ remoteport, localport, service->peer_version); ++ if (service->srvstate == ++ VCHIQ_SRVSTATE_OPENING) { ++ service->remoteport = remoteport; ++ vchiq_set_service_state(service, ++ VCHIQ_SRVSTATE_OPEN); ++ up(&service->remove_event); ++ } else ++ vchiq_log_error(vchiq_core_log_level, ++ "OPENACK received in state %s", ++ srvstate_names[service->srvstate]); ++ break; ++ case VCHIQ_MSG_CLOSE: ++ WARN_ON(size != 0); /* There should be no data */ ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: prs CLOSE@%x (%d->%d)", ++ state->id, (unsigned int)header, ++ remoteport, localport); ++ ++ mark_service_closing_internal(service, 1); ++ ++ if (vchiq_close_service_internal(service, ++ 1/*close_recvd*/) == VCHIQ_RETRY) ++ goto bail_not_ready; ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "Close Service %c%c%c%c s:%u d:%d", ++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), ++ service->localport, ++ service->remoteport); ++ break; ++ case VCHIQ_MSG_DATA: ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: prs DATA@%x,%x (%d->%d)", ++ state->id, (unsigned int)header, size, ++ remoteport, localport); ++ ++ if ((service->remoteport == remoteport) ++ && (service->srvstate == ++ VCHIQ_SRVSTATE_OPEN)) { ++ header->msgid = msgid | VCHIQ_MSGID_CLAIMED; ++ claim_slot(state->rx_info); ++ DEBUG_TRACE(PARSE_LINE); ++ if (make_service_callback(service, ++ VCHIQ_MESSAGE_AVAILABLE, header, ++ NULL) == VCHIQ_RETRY) { ++ DEBUG_TRACE(PARSE_LINE); ++ goto bail_not_ready; ++ } ++ VCHIQ_SERVICE_STATS_INC(service, ctrl_rx_count); ++ VCHIQ_SERVICE_STATS_ADD(service, ctrl_rx_bytes, ++ size); ++ } else { ++ VCHIQ_STATS_INC(state, error_count); ++ } ++ break; ++ case VCHIQ_MSG_CONNECT: ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: prs CONNECT@%x", ++ state->id, (unsigned int)header); ++ up(&state->connect); ++ break; ++ case VCHIQ_MSG_BULK_RX: ++ case VCHIQ_MSG_BULK_TX: { ++ VCHIQ_BULK_QUEUE_T *queue; ++ WARN_ON(!state->is_master); ++ queue = (type == VCHIQ_MSG_BULK_RX) ? ++ &service->bulk_tx : &service->bulk_rx; ++ if ((service->remoteport == remoteport) ++ && (service->srvstate == ++ VCHIQ_SRVSTATE_OPEN)) { ++ VCHIQ_BULK_T *bulk; ++ int resolved = 0; ++ ++ DEBUG_TRACE(PARSE_LINE); ++ if (mutex_lock_interruptible( ++ &service->bulk_mutex) != 0) { ++ DEBUG_TRACE(PARSE_LINE); ++ goto bail_not_ready; ++ } ++ ++ WARN_ON(!(queue->remote_insert < queue->remove + ++ VCHIQ_NUM_SERVICE_BULKS)); ++ bulk = &queue->bulks[ ++ BULK_INDEX(queue->remote_insert)]; ++ bulk->remote_data = ++ (void *)((int *)header->data)[0]; ++ bulk->remote_size = ((int *)header->data)[1]; ++ wmb(); ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: prs %s@%x (%d->%d) %x@%x", ++ state->id, msg_type_str(type), ++ (unsigned int)header, ++ remoteport, localport, ++ bulk->remote_size, ++ (unsigned int)bulk->remote_data); ++ ++ queue->remote_insert++; ++ ++ if (atomic_read(&pause_bulks_count)) { ++ state->deferred_bulks++; ++ vchiq_log_info(vchiq_core_log_level, ++ "%s: deferring bulk (%d)", ++ __func__, ++ state->deferred_bulks); ++ if (state->conn_state != ++ VCHIQ_CONNSTATE_PAUSE_SENT) ++ vchiq_log_error( ++ vchiq_core_log_level, ++ "%s: bulks paused in " ++ "unexpected state %s", ++ __func__, ++ conn_state_names[ ++ state->conn_state]); ++ } else if (state->conn_state == ++ VCHIQ_CONNSTATE_CONNECTED) { ++ DEBUG_TRACE(PARSE_LINE); ++ resolved = resolve_bulks(service, ++ queue); ++ } ++ ++ mutex_unlock(&service->bulk_mutex); ++ if (resolved) ++ notify_bulks(service, queue, ++ 1/*retry_poll*/); ++ } ++ } break; ++ case VCHIQ_MSG_BULK_RX_DONE: ++ case VCHIQ_MSG_BULK_TX_DONE: ++ WARN_ON(state->is_master); ++ if ((service->remoteport == remoteport) ++ && (service->srvstate != ++ VCHIQ_SRVSTATE_FREE)) { ++ VCHIQ_BULK_QUEUE_T *queue; ++ VCHIQ_BULK_T *bulk; ++ ++ queue = (type == VCHIQ_MSG_BULK_RX_DONE) ? ++ &service->bulk_rx : &service->bulk_tx; ++ ++ DEBUG_TRACE(PARSE_LINE); ++ if (mutex_lock_interruptible( ++ &service->bulk_mutex) != 0) { ++ DEBUG_TRACE(PARSE_LINE); ++ goto bail_not_ready; ++ } ++ if ((int)(queue->remote_insert - ++ queue->local_insert) >= 0) { ++ vchiq_log_error(vchiq_core_log_level, ++ "%d: prs %s@%x (%d->%d) " ++ "unexpected (ri=%d,li=%d)", ++ state->id, msg_type_str(type), ++ (unsigned int)header, ++ remoteport, localport, ++ queue->remote_insert, ++ queue->local_insert); ++ mutex_unlock(&service->bulk_mutex); ++ break; ++ } ++ ++ BUG_ON(queue->process == queue->local_insert); ++ BUG_ON(queue->process != queue->remote_insert); ++ ++ bulk = &queue->bulks[ ++ BULK_INDEX(queue->remote_insert)]; ++ bulk->actual = *(int *)header->data; ++ queue->remote_insert++; ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: prs %s@%x (%d->%d) %x@%x", ++ state->id, msg_type_str(type), ++ (unsigned int)header, ++ remoteport, localport, ++ bulk->actual, (unsigned int)bulk->data); ++ ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: prs:%d %cx li=%x ri=%x p=%x", ++ state->id, localport, ++ (type == VCHIQ_MSG_BULK_RX_DONE) ? ++ 'r' : 't', ++ queue->local_insert, ++ queue->remote_insert, queue->process); ++ ++ DEBUG_TRACE(PARSE_LINE); ++ WARN_ON(queue->process == queue->local_insert); ++ vchiq_complete_bulk(bulk); ++ queue->process++; ++ mutex_unlock(&service->bulk_mutex); ++ DEBUG_TRACE(PARSE_LINE); ++ notify_bulks(service, queue, 1/*retry_poll*/); ++ DEBUG_TRACE(PARSE_LINE); ++ } ++ break; ++ case VCHIQ_MSG_PADDING: ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: prs PADDING@%x,%x", ++ state->id, (unsigned int)header, size); ++ break; ++ case VCHIQ_MSG_PAUSE: ++ /* If initiated, signal the application thread */ ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: prs PAUSE@%x,%x", ++ state->id, (unsigned int)header, size); ++ if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) { ++ vchiq_log_error(vchiq_core_log_level, ++ "%d: PAUSE received in state PAUSED", ++ state->id); ++ break; ++ } ++ if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT) { ++ /* Send a PAUSE in response */ ++ if (queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0), ++ NULL, 0, 0, 0) == VCHIQ_RETRY) ++ goto bail_not_ready; ++ if (state->is_master) ++ pause_bulks(state); ++ } ++ /* At this point slot_mutex is held */ ++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED); ++ vchiq_platform_paused(state); ++ break; ++ case VCHIQ_MSG_RESUME: ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: prs RESUME@%x,%x", ++ state->id, (unsigned int)header, size); ++ /* Release the slot mutex */ ++ mutex_unlock(&state->slot_mutex); ++ if (state->is_master) ++ resume_bulks(state); ++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED); ++ vchiq_platform_resumed(state); ++ break; ++ ++ case VCHIQ_MSG_REMOTE_USE: ++ vchiq_on_remote_use(state); ++ break; ++ case VCHIQ_MSG_REMOTE_RELEASE: ++ vchiq_on_remote_release(state); ++ break; ++ case VCHIQ_MSG_REMOTE_USE_ACTIVE: ++ vchiq_on_remote_use_active(state); ++ break; ++ ++ default: ++ vchiq_log_error(vchiq_core_log_level, ++ "%d: prs invalid msgid %x@%x,%x", ++ state->id, msgid, (unsigned int)header, size); ++ WARN(1, "invalid message\n"); ++ break; ++ } ++ ++skip_message: ++ if (service) { ++ unlock_service(service); ++ service = NULL; ++ } ++ ++ state->rx_pos += calc_stride(size); ++ ++ DEBUG_TRACE(PARSE_LINE); ++ /* Perform some housekeeping when the end of the slot is ++ ** reached. */ ++ if ((state->rx_pos & VCHIQ_SLOT_MASK) == 0) { ++ /* Remove the extra reference count. */ ++ release_slot(state, state->rx_info, NULL, NULL); ++ state->rx_data = NULL; ++ } ++ } ++ ++bail_not_ready: ++ if (service) ++ unlock_service(service); ++} ++ ++/* Called by the slot handler thread */ ++static int ++slot_handler_func(void *v) ++{ ++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v; ++ VCHIQ_SHARED_STATE_T *local = state->local; ++ DEBUG_INITIALISE(local) ++ ++ while (1) { ++ DEBUG_COUNT(SLOT_HANDLER_COUNT); ++ DEBUG_TRACE(SLOT_HANDLER_LINE); ++ remote_event_wait(&local->trigger); ++ ++ rmb(); ++ ++ DEBUG_TRACE(SLOT_HANDLER_LINE); ++ if (state->poll_needed) { ++ /* Check if we need to suspend - may change our ++ * conn_state */ ++ vchiq_platform_check_suspend(state); ++ ++ state->poll_needed = 0; ++ ++ /* Handle service polling and other rare conditions here ++ ** out of the mainline code */ ++ switch (state->conn_state) { ++ case VCHIQ_CONNSTATE_CONNECTED: ++ /* Poll the services as requested */ ++ poll_services(state); ++ break; ++ ++ case VCHIQ_CONNSTATE_PAUSING: ++ if (state->is_master) ++ pause_bulks(state); ++ if (queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0), ++ NULL, 0, 0, 0) != VCHIQ_RETRY) { ++ vchiq_set_conn_state(state, ++ VCHIQ_CONNSTATE_PAUSE_SENT); ++ } else { ++ if (state->is_master) ++ resume_bulks(state); ++ /* Retry later */ ++ state->poll_needed = 1; ++ } ++ break; ++ ++ case VCHIQ_CONNSTATE_PAUSED: ++ vchiq_platform_resume(state); ++ break; ++ ++ case VCHIQ_CONNSTATE_RESUMING: ++ if (queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0), ++ NULL, 0, 0, 0) != VCHIQ_RETRY) { ++ if (state->is_master) ++ resume_bulks(state); ++ vchiq_set_conn_state(state, ++ VCHIQ_CONNSTATE_CONNECTED); ++ vchiq_platform_resumed(state); ++ } else { ++ /* This should really be impossible, ++ ** since the PAUSE should have flushed ++ ** through outstanding messages. */ ++ vchiq_log_error(vchiq_core_log_level, ++ "Failed to send RESUME " ++ "message"); ++ BUG(); ++ } ++ break; ++ ++ case VCHIQ_CONNSTATE_PAUSE_TIMEOUT: ++ case VCHIQ_CONNSTATE_RESUME_TIMEOUT: ++ vchiq_platform_handle_timeout(state); ++ break; ++ default: ++ break; ++ } ++ ++ ++ } ++ ++ DEBUG_TRACE(SLOT_HANDLER_LINE); ++ parse_rx_slots(state); ++ } ++ return 0; ++} ++ ++ ++/* Called by the recycle thread */ ++static int ++recycle_func(void *v) ++{ ++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v; ++ VCHIQ_SHARED_STATE_T *local = state->local; ++ ++ while (1) { ++ remote_event_wait(&local->recycle); ++ ++ process_free_queue(state); ++ } ++ return 0; ++} ++ ++ ++/* Called by the sync thread */ ++static int ++sync_func(void *v) ++{ ++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v; ++ VCHIQ_SHARED_STATE_T *local = state->local; ++ VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, ++ state->remote->slot_sync); ++ ++ while (1) { ++ VCHIQ_SERVICE_T *service; ++ int msgid, size; ++ int type; ++ unsigned int localport, remoteport; ++ ++ remote_event_wait(&local->sync_trigger); ++ ++ rmb(); ++ ++ msgid = header->msgid; ++ size = header->size; ++ type = VCHIQ_MSG_TYPE(msgid); ++ localport = VCHIQ_MSG_DSTPORT(msgid); ++ remoteport = VCHIQ_MSG_SRCPORT(msgid); ++ ++ service = find_service_by_port(state, localport); ++ ++ if (!service) { ++ vchiq_log_error(vchiq_sync_log_level, ++ "%d: sf %s@%x (%d->%d) - " ++ "invalid/closed service %d", ++ state->id, msg_type_str(type), ++ (unsigned int)header, ++ remoteport, localport, localport); ++ release_message_sync(state, header); ++ continue; ++ } ++ ++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) { ++ int svc_fourcc; ++ ++ svc_fourcc = service ++ ? service->base.fourcc ++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); ++ vchiq_log_trace(vchiq_sync_log_level, ++ "Rcvd Msg %s from %c%c%c%c s:%d d:%d len:%d", ++ msg_type_str(type), ++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), ++ remoteport, localport, size); ++ if (size > 0) ++ vchiq_log_dump_mem("Rcvd", 0, header->data, ++ min(64, size)); ++ } ++ ++ switch (type) { ++ case VCHIQ_MSG_OPENACK: ++ if (size >= sizeof(struct vchiq_openack_payload)) { ++ const struct vchiq_openack_payload *payload = ++ (struct vchiq_openack_payload *) ++ header->data; ++ service->peer_version = payload->version; ++ } ++ vchiq_log_info(vchiq_sync_log_level, ++ "%d: sf OPENACK@%x,%x (%d->%d) v:%d", ++ state->id, (unsigned int)header, size, ++ remoteport, localport, service->peer_version); ++ if (service->srvstate == VCHIQ_SRVSTATE_OPENING) { ++ service->remoteport = remoteport; ++ vchiq_set_service_state(service, ++ VCHIQ_SRVSTATE_OPENSYNC); ++ up(&service->remove_event); ++ } ++ release_message_sync(state, header); ++ break; ++ ++ case VCHIQ_MSG_DATA: ++ vchiq_log_trace(vchiq_sync_log_level, ++ "%d: sf DATA@%x,%x (%d->%d)", ++ state->id, (unsigned int)header, size, ++ remoteport, localport); ++ ++ if ((service->remoteport == remoteport) && ++ (service->srvstate == ++ VCHIQ_SRVSTATE_OPENSYNC)) { ++ if (make_service_callback(service, ++ VCHIQ_MESSAGE_AVAILABLE, header, ++ NULL) == VCHIQ_RETRY) ++ vchiq_log_error(vchiq_sync_log_level, ++ "synchronous callback to " ++ "service %d returns " ++ "VCHIQ_RETRY", ++ localport); ++ } ++ break; ++ ++ default: ++ vchiq_log_error(vchiq_sync_log_level, ++ "%d: sf unexpected msgid %x@%x,%x", ++ state->id, msgid, (unsigned int)header, size); ++ release_message_sync(state, header); ++ break; ++ } ++ ++ unlock_service(service); ++ } ++ ++ return 0; ++} ++ ++ ++static void ++init_bulk_queue(VCHIQ_BULK_QUEUE_T *queue) ++{ ++ queue->local_insert = 0; ++ queue->remote_insert = 0; ++ queue->process = 0; ++ queue->remote_notify = 0; ++ queue->remove = 0; ++} ++ ++ ++inline const char * ++get_conn_state_name(VCHIQ_CONNSTATE_T conn_state) ++{ ++ return conn_state_names[conn_state]; ++} ++ ++ ++VCHIQ_SLOT_ZERO_T * ++vchiq_init_slots(void *mem_base, int mem_size) ++{ ++ int mem_align = (VCHIQ_SLOT_SIZE - (int)mem_base) & VCHIQ_SLOT_MASK; ++ VCHIQ_SLOT_ZERO_T *slot_zero = ++ (VCHIQ_SLOT_ZERO_T *)((char *)mem_base + mem_align); ++ int num_slots = (mem_size - mem_align)/VCHIQ_SLOT_SIZE; ++ int first_data_slot = VCHIQ_SLOT_ZERO_SLOTS; ++ ++ /* Ensure there is enough memory to run an absolutely minimum system */ ++ num_slots -= first_data_slot; ++ ++ if (num_slots < 4) { ++ vchiq_log_error(vchiq_core_log_level, ++ "vchiq_init_slots - insufficient memory %x bytes", ++ mem_size); ++ return NULL; ++ } ++ ++ memset(slot_zero, 0, sizeof(VCHIQ_SLOT_ZERO_T)); ++ ++ slot_zero->magic = VCHIQ_MAGIC; ++ slot_zero->version = VCHIQ_VERSION; ++ slot_zero->version_min = VCHIQ_VERSION_MIN; ++ slot_zero->slot_zero_size = sizeof(VCHIQ_SLOT_ZERO_T); ++ slot_zero->slot_size = VCHIQ_SLOT_SIZE; ++ slot_zero->max_slots = VCHIQ_MAX_SLOTS; ++ slot_zero->max_slots_per_side = VCHIQ_MAX_SLOTS_PER_SIDE; ++ ++ slot_zero->master.slot_sync = first_data_slot; ++ slot_zero->master.slot_first = first_data_slot + 1; ++ slot_zero->master.slot_last = first_data_slot + (num_slots/2) - 1; ++ slot_zero->slave.slot_sync = first_data_slot + (num_slots/2); ++ slot_zero->slave.slot_first = first_data_slot + (num_slots/2) + 1; ++ slot_zero->slave.slot_last = first_data_slot + num_slots - 1; ++ ++ return slot_zero; ++} ++ ++VCHIQ_STATUS_T ++vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, ++ int is_master) ++{ ++ VCHIQ_SHARED_STATE_T *local; ++ VCHIQ_SHARED_STATE_T *remote; ++ VCHIQ_STATUS_T status; ++ char threadname[10]; ++ static int id; ++ int i; ++ ++ vchiq_log_warning(vchiq_core_log_level, ++ "%s: slot_zero = 0x%08lx, is_master = %d", ++ __func__, (unsigned long)slot_zero, is_master); ++ ++ /* Check the input configuration */ ++ ++ if (slot_zero->magic != VCHIQ_MAGIC) { ++ vchiq_loud_error_header(); ++ vchiq_loud_error("Invalid VCHIQ magic value found."); ++ vchiq_loud_error("slot_zero=%x: magic=%x (expected %x)", ++ (unsigned int)slot_zero, slot_zero->magic, VCHIQ_MAGIC); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ ++ if (slot_zero->version < VCHIQ_VERSION_MIN) { ++ vchiq_loud_error_header(); ++ vchiq_loud_error("Incompatible VCHIQ versions found."); ++ vchiq_loud_error("slot_zero=%x: VideoCore version=%d " ++ "(minimum %d)", ++ (unsigned int)slot_zero, slot_zero->version, ++ VCHIQ_VERSION_MIN); ++ vchiq_loud_error("Restart with a newer VideoCore image."); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ ++ if (VCHIQ_VERSION < slot_zero->version_min) { ++ vchiq_loud_error_header(); ++ vchiq_loud_error("Incompatible VCHIQ versions found."); ++ vchiq_loud_error("slot_zero=%x: version=%d (VideoCore " ++ "minimum %d)", ++ (unsigned int)slot_zero, VCHIQ_VERSION, ++ slot_zero->version_min); ++ vchiq_loud_error("Restart with a newer kernel."); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ ++ if ((slot_zero->slot_zero_size != sizeof(VCHIQ_SLOT_ZERO_T)) || ++ (slot_zero->slot_size != VCHIQ_SLOT_SIZE) || ++ (slot_zero->max_slots != VCHIQ_MAX_SLOTS) || ++ (slot_zero->max_slots_per_side != VCHIQ_MAX_SLOTS_PER_SIDE)) { ++ vchiq_loud_error_header(); ++ if (slot_zero->slot_zero_size != sizeof(VCHIQ_SLOT_ZERO_T)) ++ vchiq_loud_error("slot_zero=%x: slot_zero_size=%x " ++ "(expected %x)", ++ (unsigned int)slot_zero, ++ slot_zero->slot_zero_size, ++ sizeof(VCHIQ_SLOT_ZERO_T)); ++ if (slot_zero->slot_size != VCHIQ_SLOT_SIZE) ++ vchiq_loud_error("slot_zero=%x: slot_size=%d " ++ "(expected %d", ++ (unsigned int)slot_zero, slot_zero->slot_size, ++ VCHIQ_SLOT_SIZE); ++ if (slot_zero->max_slots != VCHIQ_MAX_SLOTS) ++ vchiq_loud_error("slot_zero=%x: max_slots=%d " ++ "(expected %d)", ++ (unsigned int)slot_zero, slot_zero->max_slots, ++ VCHIQ_MAX_SLOTS); ++ if (slot_zero->max_slots_per_side != VCHIQ_MAX_SLOTS_PER_SIDE) ++ vchiq_loud_error("slot_zero=%x: max_slots_per_side=%d " ++ "(expected %d)", ++ (unsigned int)slot_zero, ++ slot_zero->max_slots_per_side, ++ VCHIQ_MAX_SLOTS_PER_SIDE); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ ++ if (is_master) { ++ local = &slot_zero->master; ++ remote = &slot_zero->slave; ++ } else { ++ local = &slot_zero->slave; ++ remote = &slot_zero->master; ++ } ++ ++ if (local->initialised) { ++ vchiq_loud_error_header(); ++ if (remote->initialised) ++ vchiq_loud_error("local state has already been " ++ "initialised"); ++ else ++ vchiq_loud_error("master/slave mismatch - two %ss", ++ is_master ? "master" : "slave"); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ ++ memset(state, 0, sizeof(VCHIQ_STATE_T)); ++ ++ state->id = id++; ++ state->is_master = is_master; ++ ++ /* ++ initialize shared state pointers ++ */ ++ ++ state->local = local; ++ state->remote = remote; ++ state->slot_data = (VCHIQ_SLOT_T *)slot_zero; ++ ++ /* ++ initialize events and mutexes ++ */ ++ ++ sema_init(&state->connect, 0); ++ mutex_init(&state->mutex); ++ sema_init(&state->trigger_event, 0); ++ sema_init(&state->recycle_event, 0); ++ sema_init(&state->sync_trigger_event, 0); ++ sema_init(&state->sync_release_event, 0); ++ ++ mutex_init(&state->slot_mutex); ++ mutex_init(&state->recycle_mutex); ++ mutex_init(&state->sync_mutex); ++ mutex_init(&state->bulk_transfer_mutex); ++ ++ sema_init(&state->slot_available_event, 0); ++ sema_init(&state->slot_remove_event, 0); ++ sema_init(&state->data_quota_event, 0); ++ ++ state->slot_queue_available = 0; ++ ++ for (i = 0; i < VCHIQ_MAX_SERVICES; i++) { ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &state->service_quotas[i]; ++ sema_init(&service_quota->quota_event, 0); ++ } ++ ++ for (i = local->slot_first; i <= local->slot_last; i++) { ++ local->slot_queue[state->slot_queue_available++] = i; ++ up(&state->slot_available_event); ++ } ++ ++ state->default_slot_quota = state->slot_queue_available/2; ++ state->default_message_quota = ++ min((unsigned short)(state->default_slot_quota * 256), ++ (unsigned short)~0); ++ ++ state->previous_data_index = -1; ++ state->data_use_count = 0; ++ state->data_quota = state->slot_queue_available - 1; ++ ++ local->trigger.event = &state->trigger_event; ++ remote_event_create(&local->trigger); ++ local->tx_pos = 0; ++ ++ local->recycle.event = &state->recycle_event; ++ remote_event_create(&local->recycle); ++ local->slot_queue_recycle = state->slot_queue_available; ++ ++ local->sync_trigger.event = &state->sync_trigger_event; ++ remote_event_create(&local->sync_trigger); ++ ++ local->sync_release.event = &state->sync_release_event; ++ remote_event_create(&local->sync_release); ++ ++ /* At start-of-day, the slot is empty and available */ ++ ((VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid ++ = VCHIQ_MSGID_PADDING; ++ remote_event_signal_local(&local->sync_release); ++ ++ local->debug[DEBUG_ENTRIES] = DEBUG_MAX; ++ ++ status = vchiq_platform_init_state(state); ++ ++ /* ++ bring up slot handler thread ++ */ ++ snprintf(threadname, sizeof(threadname), "VCHIQ-%d", state->id); ++ state->slot_handler_thread = kthread_create(&slot_handler_func, ++ (void *)state, ++ threadname); ++ ++ if (state->slot_handler_thread == NULL) { ++ vchiq_loud_error_header(); ++ vchiq_loud_error("couldn't create thread %s", threadname); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ set_user_nice(state->slot_handler_thread, -19); ++ wake_up_process(state->slot_handler_thread); ++ ++ snprintf(threadname, sizeof(threadname), "VCHIQr-%d", state->id); ++ state->recycle_thread = kthread_create(&recycle_func, ++ (void *)state, ++ threadname); ++ if (state->recycle_thread == NULL) { ++ vchiq_loud_error_header(); ++ vchiq_loud_error("couldn't create thread %s", threadname); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ set_user_nice(state->recycle_thread, -19); ++ wake_up_process(state->recycle_thread); ++ ++ snprintf(threadname, sizeof(threadname), "VCHIQs-%d", state->id); ++ state->sync_thread = kthread_create(&sync_func, ++ (void *)state, ++ threadname); ++ if (state->sync_thread == NULL) { ++ vchiq_loud_error_header(); ++ vchiq_loud_error("couldn't create thread %s", threadname); ++ vchiq_loud_error_footer(); ++ return VCHIQ_ERROR; ++ } ++ set_user_nice(state->sync_thread, -20); ++ wake_up_process(state->sync_thread); ++ ++ BUG_ON(state->id >= VCHIQ_MAX_STATES); ++ vchiq_states[state->id] = state; ++ ++ /* Indicate readiness to the other side */ ++ local->initialised = 1; ++ ++ return status; ++} ++ ++/* Called from application thread when a client or server service is created. */ ++VCHIQ_SERVICE_T * ++vchiq_add_service_internal(VCHIQ_STATE_T *state, ++ const VCHIQ_SERVICE_PARAMS_T *params, int srvstate, ++ VCHIQ_INSTANCE_T instance, VCHIQ_USERDATA_TERM_T userdata_term) ++{ ++ VCHIQ_SERVICE_T *service; ++ ++ service = kmalloc(sizeof(VCHIQ_SERVICE_T), GFP_KERNEL); ++ if (service) { ++ service->base.fourcc = params->fourcc; ++ service->base.callback = params->callback; ++ service->base.userdata = params->userdata; ++ service->handle = VCHIQ_SERVICE_HANDLE_INVALID; ++ service->ref_count = 1; ++ service->srvstate = VCHIQ_SRVSTATE_FREE; ++ service->userdata_term = userdata_term; ++ service->localport = VCHIQ_PORT_FREE; ++ service->remoteport = VCHIQ_PORT_FREE; ++ ++ service->public_fourcc = (srvstate == VCHIQ_SRVSTATE_OPENING) ? ++ VCHIQ_FOURCC_INVALID : params->fourcc; ++ service->client_id = 0; ++ service->auto_close = 1; ++ service->sync = 0; ++ service->closing = 0; ++ atomic_set(&service->poll_flags, 0); ++ service->version = params->version; ++ service->version_min = params->version_min; ++ service->state = state; ++ service->instance = instance; ++ service->service_use_count = 0; ++ init_bulk_queue(&service->bulk_tx); ++ init_bulk_queue(&service->bulk_rx); ++ sema_init(&service->remove_event, 0); ++ sema_init(&service->bulk_remove_event, 0); ++ mutex_init(&service->bulk_mutex); ++ memset(&service->stats, 0, sizeof(service->stats)); ++ } else { ++ vchiq_log_error(vchiq_core_log_level, ++ "Out of memory"); ++ } ++ ++ if (service) { ++ VCHIQ_SERVICE_T **pservice = NULL; ++ int i; ++ ++ /* Although it is perfectly possible to use service_spinlock ++ ** to protect the creation of services, it is overkill as it ++ ** disables interrupts while the array is searched. ++ ** The only danger is of another thread trying to create a ++ ** service - service deletion is safe. ++ ** Therefore it is preferable to use state->mutex which, ++ ** although slower to claim, doesn't block interrupts while ++ ** it is held. ++ */ ++ ++ mutex_lock(&state->mutex); ++ ++ /* Prepare to use a previously unused service */ ++ if (state->unused_service < VCHIQ_MAX_SERVICES) ++ pservice = &state->services[state->unused_service]; ++ ++ if (srvstate == VCHIQ_SRVSTATE_OPENING) { ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *srv = state->services[i]; ++ if (!srv) { ++ pservice = &state->services[i]; ++ break; ++ } ++ } ++ } else { ++ for (i = (state->unused_service - 1); i >= 0; i--) { ++ VCHIQ_SERVICE_T *srv = state->services[i]; ++ if (!srv) ++ pservice = &state->services[i]; ++ else if ((srv->public_fourcc == params->fourcc) ++ && ((srv->instance != instance) || ++ (srv->base.callback != ++ params->callback))) { ++ /* There is another server using this ++ ** fourcc which doesn't match. */ ++ pservice = NULL; ++ break; ++ } ++ } ++ } ++ ++ if (pservice) { ++ service->localport = (pservice - state->services); ++ if (!handle_seq) ++ handle_seq = VCHIQ_MAX_STATES * ++ VCHIQ_MAX_SERVICES; ++ service->handle = handle_seq | ++ (state->id * VCHIQ_MAX_SERVICES) | ++ service->localport; ++ handle_seq += VCHIQ_MAX_STATES * VCHIQ_MAX_SERVICES; ++ *pservice = service; ++ if (pservice == &state->services[state->unused_service]) ++ state->unused_service++; ++ } ++ ++ mutex_unlock(&state->mutex); ++ ++ if (!pservice) { ++ kfree(service); ++ service = NULL; ++ } ++ } ++ ++ if (service) { ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &state->service_quotas[service->localport]; ++ service_quota->slot_quota = state->default_slot_quota; ++ service_quota->message_quota = state->default_message_quota; ++ if (service_quota->slot_use_count == 0) ++ service_quota->previous_tx_index = ++ SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos) ++ - 1; ++ ++ /* Bring this service online */ ++ vchiq_set_service_state(service, srvstate); ++ ++ vchiq_log_info(vchiq_core_msg_log_level, ++ "%s Service %c%c%c%c SrcPort:%d", ++ (srvstate == VCHIQ_SRVSTATE_OPENING) ++ ? "Open" : "Add", ++ VCHIQ_FOURCC_AS_4CHARS(params->fourcc), ++ service->localport); ++ } ++ ++ /* Don't unlock the service - leave it with a ref_count of 1. */ ++ ++ return service; ++} ++ ++VCHIQ_STATUS_T ++vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id) ++{ ++ struct vchiq_open_payload payload = { ++ service->base.fourcc, ++ client_id, ++ service->version, ++ service->version_min ++ }; ++ VCHIQ_ELEMENT_T body = { &payload, sizeof(payload) }; ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ ++ service->client_id = client_id; ++ vchiq_use_service_internal(service); ++ status = queue_message(service->state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_OPEN, service->localport, 0), ++ &body, 1, sizeof(payload), 1); ++ if (status == VCHIQ_SUCCESS) { ++ if (down_interruptible(&service->remove_event) != 0) { ++ status = VCHIQ_RETRY; ++ vchiq_release_service_internal(service); ++ } else if ((service->srvstate != VCHIQ_SRVSTATE_OPEN) && ++ (service->srvstate != VCHIQ_SRVSTATE_OPENSYNC)) { ++ if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) ++ vchiq_log_error(vchiq_core_log_level, ++ "%d: osi - srvstate = %s (ref %d)", ++ service->state->id, ++ srvstate_names[service->srvstate], ++ service->ref_count); ++ status = VCHIQ_ERROR; ++ VCHIQ_SERVICE_STATS_INC(service, error_count); ++ vchiq_release_service_internal(service); ++ } ++ } ++ return status; ++} ++ ++static void ++release_service_messages(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_STATE_T *state = service->state; ++ int slot_last = state->remote->slot_last; ++ int i; ++ ++ /* Release any claimed messages */ ++ for (i = state->remote->slot_first; i <= slot_last; i++) { ++ VCHIQ_SLOT_INFO_T *slot_info = ++ SLOT_INFO_FROM_INDEX(state, i); ++ if (slot_info->release_count != slot_info->use_count) { ++ char *data = ++ (char *)SLOT_DATA_FROM_INDEX(state, i); ++ unsigned int pos, end; ++ ++ end = VCHIQ_SLOT_SIZE; ++ if (data == state->rx_data) ++ /* This buffer is still being read from - stop ++ ** at the current read position */ ++ end = state->rx_pos & VCHIQ_SLOT_MASK; ++ ++ pos = 0; ++ ++ while (pos < end) { ++ VCHIQ_HEADER_T *header = ++ (VCHIQ_HEADER_T *)(data + pos); ++ int msgid = header->msgid; ++ int port = VCHIQ_MSG_DSTPORT(msgid); ++ if ((port == service->localport) && ++ (msgid & VCHIQ_MSGID_CLAIMED)) { ++ vchiq_log_info(vchiq_core_log_level, ++ " fsi - hdr %x", ++ (unsigned int)header); ++ release_slot(state, slot_info, header, ++ NULL); ++ } ++ pos += calc_stride(header->size); ++ if (pos > VCHIQ_SLOT_SIZE) { ++ vchiq_log_error(vchiq_core_log_level, ++ "fsi - pos %x: header %x, " ++ "msgid %x, header->msgid %x, " ++ "header->size %x", ++ pos, (unsigned int)header, ++ msgid, header->msgid, ++ header->size); ++ WARN(1, "invalid slot position\n"); ++ } ++ } ++ } ++ } ++} ++ ++static int ++do_abort_bulks(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_STATUS_T status; ++ ++ /* Abort any outstanding bulk transfers */ ++ if (mutex_lock_interruptible(&service->bulk_mutex) != 0) ++ return 0; ++ abort_outstanding_bulks(service, &service->bulk_tx); ++ abort_outstanding_bulks(service, &service->bulk_rx); ++ mutex_unlock(&service->bulk_mutex); ++ ++ status = notify_bulks(service, &service->bulk_tx, 0/*!retry_poll*/); ++ if (status == VCHIQ_SUCCESS) ++ status = notify_bulks(service, &service->bulk_rx, ++ 0/*!retry_poll*/); ++ return (status == VCHIQ_SUCCESS); ++} ++ ++static VCHIQ_STATUS_T ++close_service_complete(VCHIQ_SERVICE_T *service, int failstate) ++{ ++ VCHIQ_STATUS_T status; ++ int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID); ++ int newstate; ++ ++ switch (service->srvstate) { ++ case VCHIQ_SRVSTATE_OPEN: ++ case VCHIQ_SRVSTATE_CLOSESENT: ++ case VCHIQ_SRVSTATE_CLOSERECVD: ++ if (is_server) { ++ if (service->auto_close) { ++ service->client_id = 0; ++ service->remoteport = VCHIQ_PORT_FREE; ++ newstate = VCHIQ_SRVSTATE_LISTENING; ++ } else ++ newstate = VCHIQ_SRVSTATE_CLOSEWAIT; ++ } else ++ newstate = VCHIQ_SRVSTATE_CLOSED; ++ vchiq_set_service_state(service, newstate); ++ break; ++ case VCHIQ_SRVSTATE_LISTENING: ++ break; ++ default: ++ vchiq_log_error(vchiq_core_log_level, ++ "close_service_complete(%x) called in state %s", ++ service->handle, srvstate_names[service->srvstate]); ++ WARN(1, "close_service_complete in unexpected state\n"); ++ return VCHIQ_ERROR; ++ } ++ ++ status = make_service_callback(service, ++ VCHIQ_SERVICE_CLOSED, NULL, NULL); ++ ++ if (status != VCHIQ_RETRY) { ++ int uc = service->service_use_count; ++ int i; ++ /* Complete the close process */ ++ for (i = 0; i < uc; i++) ++ /* cater for cases where close is forced and the ++ ** client may not close all it's handles */ ++ vchiq_release_service_internal(service); ++ ++ service->client_id = 0; ++ service->remoteport = VCHIQ_PORT_FREE; ++ ++ if (service->srvstate == VCHIQ_SRVSTATE_CLOSED) ++ vchiq_free_service_internal(service); ++ else if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) { ++ if (is_server) ++ service->closing = 0; ++ ++ up(&service->remove_event); ++ } ++ } else ++ vchiq_set_service_state(service, failstate); ++ ++ return status; ++} ++ ++/* Called by the slot handler */ ++VCHIQ_STATUS_T ++vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd) ++{ ++ VCHIQ_STATE_T *state = service->state; ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID); ++ ++ vchiq_log_info(vchiq_core_log_level, "%d: csi:%d,%d (%s)", ++ service->state->id, service->localport, close_recvd, ++ srvstate_names[service->srvstate]); ++ ++ switch (service->srvstate) { ++ case VCHIQ_SRVSTATE_CLOSED: ++ case VCHIQ_SRVSTATE_HIDDEN: ++ case VCHIQ_SRVSTATE_LISTENING: ++ case VCHIQ_SRVSTATE_CLOSEWAIT: ++ if (close_recvd) ++ vchiq_log_error(vchiq_core_log_level, ++ "vchiq_close_service_internal(1) called " ++ "in state %s", ++ srvstate_names[service->srvstate]); ++ else if (is_server) { ++ if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) { ++ status = VCHIQ_ERROR; ++ } else { ++ service->client_id = 0; ++ service->remoteport = VCHIQ_PORT_FREE; ++ if (service->srvstate == ++ VCHIQ_SRVSTATE_CLOSEWAIT) ++ vchiq_set_service_state(service, ++ VCHIQ_SRVSTATE_LISTENING); ++ } ++ up(&service->remove_event); ++ } else ++ vchiq_free_service_internal(service); ++ break; ++ case VCHIQ_SRVSTATE_OPENING: ++ if (close_recvd) { ++ /* The open was rejected - tell the user */ ++ vchiq_set_service_state(service, ++ VCHIQ_SRVSTATE_CLOSEWAIT); ++ up(&service->remove_event); ++ } else { ++ /* Shutdown mid-open - let the other side know */ ++ status = queue_message(state, service, ++ VCHIQ_MAKE_MSG ++ (VCHIQ_MSG_CLOSE, ++ service->localport, ++ VCHIQ_MSG_DSTPORT(service->remoteport)), ++ NULL, 0, 0, 0); ++ } ++ break; ++ ++ case VCHIQ_SRVSTATE_OPENSYNC: ++ mutex_lock(&state->sync_mutex); ++ /* Drop through */ ++ ++ case VCHIQ_SRVSTATE_OPEN: ++ if (state->is_master || close_recvd) { ++ if (!do_abort_bulks(service)) ++ status = VCHIQ_RETRY; ++ } ++ ++ release_service_messages(service); ++ ++ if (status == VCHIQ_SUCCESS) ++ status = queue_message(state, service, ++ VCHIQ_MAKE_MSG ++ (VCHIQ_MSG_CLOSE, ++ service->localport, ++ VCHIQ_MSG_DSTPORT(service->remoteport)), ++ NULL, 0, 0, 0); ++ ++ if (status == VCHIQ_SUCCESS) { ++ if (!close_recvd) ++ break; ++ } else if (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC) { ++ mutex_unlock(&state->sync_mutex); ++ break; ++ } else ++ break; ++ ++ status = close_service_complete(service, ++ VCHIQ_SRVSTATE_CLOSERECVD); ++ break; ++ ++ case VCHIQ_SRVSTATE_CLOSESENT: ++ if (!close_recvd) ++ /* This happens when a process is killed mid-close */ ++ break; ++ ++ if (!state->is_master) { ++ if (!do_abort_bulks(service)) { ++ status = VCHIQ_RETRY; ++ break; ++ } ++ } ++ ++ if (status == VCHIQ_SUCCESS) ++ status = close_service_complete(service, ++ VCHIQ_SRVSTATE_CLOSERECVD); ++ break; ++ ++ case VCHIQ_SRVSTATE_CLOSERECVD: ++ if (!close_recvd && is_server) ++ /* Force into LISTENING mode */ ++ vchiq_set_service_state(service, ++ VCHIQ_SRVSTATE_LISTENING); ++ status = close_service_complete(service, ++ VCHIQ_SRVSTATE_CLOSERECVD); ++ break; ++ ++ default: ++ vchiq_log_error(vchiq_core_log_level, ++ "vchiq_close_service_internal(%d) called in state %s", ++ close_recvd, srvstate_names[service->srvstate]); ++ break; ++ } ++ ++ return status; ++} ++ ++/* Called from the application process upon process death */ ++void ++vchiq_terminate_service_internal(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_STATE_T *state = service->state; ++ ++ vchiq_log_info(vchiq_core_log_level, "%d: tsi - (%d<->%d)", ++ state->id, service->localport, service->remoteport); ++ ++ mark_service_closing(service); ++ ++ /* Mark the service for removal by the slot handler */ ++ request_poll(state, service, VCHIQ_POLL_REMOVE); ++} ++ ++/* Called from the slot handler */ ++void ++vchiq_free_service_internal(VCHIQ_SERVICE_T *service) ++{ ++ VCHIQ_STATE_T *state = service->state; ++ ++ vchiq_log_info(vchiq_core_log_level, "%d: fsi - (%d)", ++ state->id, service->localport); ++ ++ switch (service->srvstate) { ++ case VCHIQ_SRVSTATE_OPENING: ++ case VCHIQ_SRVSTATE_CLOSED: ++ case VCHIQ_SRVSTATE_HIDDEN: ++ case VCHIQ_SRVSTATE_LISTENING: ++ case VCHIQ_SRVSTATE_CLOSEWAIT: ++ break; ++ default: ++ vchiq_log_error(vchiq_core_log_level, ++ "%d: fsi - (%d) in state %s", ++ state->id, service->localport, ++ srvstate_names[service->srvstate]); ++ return; ++ } ++ ++ vchiq_set_service_state(service, VCHIQ_SRVSTATE_FREE); ++ ++ up(&service->remove_event); ++ ++ /* Release the initial lock */ ++ unlock_service(service); ++} ++ ++VCHIQ_STATUS_T ++vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance) ++{ ++ VCHIQ_SERVICE_T *service; ++ int i; ++ ++ /* Find all services registered to this client and enable them. */ ++ i = 0; ++ while ((service = next_service_by_instance(state, instance, ++ &i)) != NULL) { ++ if (service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ++ vchiq_set_service_state(service, ++ VCHIQ_SRVSTATE_LISTENING); ++ unlock_service(service); ++ } ++ ++ if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) { ++ if (queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0, ++ 0, 1) == VCHIQ_RETRY) ++ return VCHIQ_RETRY; ++ ++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTING); ++ } ++ ++ if (state->conn_state == VCHIQ_CONNSTATE_CONNECTING) { ++ if (down_interruptible(&state->connect) != 0) ++ return VCHIQ_RETRY; ++ ++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED); ++ up(&state->connect); ++ } ++ ++ return VCHIQ_SUCCESS; ++} ++ ++VCHIQ_STATUS_T ++vchiq_shutdown_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance) ++{ ++ VCHIQ_SERVICE_T *service; ++ int i; ++ ++ /* Find all services registered to this client and enable them. */ ++ i = 0; ++ while ((service = next_service_by_instance(state, instance, ++ &i)) != NULL) { ++ (void)vchiq_remove_service(service->handle); ++ unlock_service(service); ++ } ++ ++ return VCHIQ_SUCCESS; ++} ++ ++VCHIQ_STATUS_T ++vchiq_pause_internal(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ ++ switch (state->conn_state) { ++ case VCHIQ_CONNSTATE_CONNECTED: ++ /* Request a pause */ ++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSING); ++ request_poll(state, NULL, 0); ++ break; ++ default: ++ vchiq_log_error(vchiq_core_log_level, ++ "vchiq_pause_internal in state %s\n", ++ conn_state_names[state->conn_state]); ++ status = VCHIQ_ERROR; ++ VCHIQ_STATS_INC(state, error_count); ++ break; ++ } ++ ++ return status; ++} ++ ++VCHIQ_STATUS_T ++vchiq_resume_internal(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ ++ if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) { ++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_RESUMING); ++ request_poll(state, NULL, 0); ++ } else { ++ status = VCHIQ_ERROR; ++ VCHIQ_STATS_INC(state, error_count); ++ } ++ ++ return status; ++} ++ ++VCHIQ_STATUS_T ++vchiq_close_service(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ /* Unregister the service */ ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ ++ if (!service) ++ return VCHIQ_ERROR; ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: close_service:%d", ++ service->state->id, service->localport); ++ ++ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) || ++ (service->srvstate == VCHIQ_SRVSTATE_LISTENING) || ++ (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)) { ++ unlock_service(service); ++ return VCHIQ_ERROR; ++ } ++ ++ mark_service_closing(service); ++ ++ if (current == service->state->slot_handler_thread) { ++ status = vchiq_close_service_internal(service, ++ 0/*!close_recvd*/); ++ BUG_ON(status == VCHIQ_RETRY); ++ } else { ++ /* Mark the service for termination by the slot handler */ ++ request_poll(service->state, service, VCHIQ_POLL_TERMINATE); ++ } ++ ++ while (1) { ++ if (down_interruptible(&service->remove_event) != 0) { ++ status = VCHIQ_RETRY; ++ break; ++ } ++ ++ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) || ++ (service->srvstate == VCHIQ_SRVSTATE_LISTENING) || ++ (service->srvstate == VCHIQ_SRVSTATE_OPEN)) ++ break; ++ ++ vchiq_log_warning(vchiq_core_log_level, ++ "%d: close_service:%d - waiting in state %s", ++ service->state->id, service->localport, ++ srvstate_names[service->srvstate]); ++ } ++ ++ if ((status == VCHIQ_SUCCESS) && ++ (service->srvstate != VCHIQ_SRVSTATE_FREE) && ++ (service->srvstate != VCHIQ_SRVSTATE_LISTENING)) ++ status = VCHIQ_ERROR; ++ ++ unlock_service(service); ++ ++ return status; ++} ++ ++VCHIQ_STATUS_T ++vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ /* Unregister the service */ ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS; ++ ++ if (!service) ++ return VCHIQ_ERROR; ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: remove_service:%d", ++ service->state->id, service->localport); ++ ++ if (service->srvstate == VCHIQ_SRVSTATE_FREE) { ++ unlock_service(service); ++ return VCHIQ_ERROR; ++ } ++ ++ mark_service_closing(service); ++ ++ if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) || ++ (current == service->state->slot_handler_thread)) { ++ /* Make it look like a client, because it must be removed and ++ not left in the LISTENING state. */ ++ service->public_fourcc = VCHIQ_FOURCC_INVALID; ++ ++ status = vchiq_close_service_internal(service, ++ 0/*!close_recvd*/); ++ BUG_ON(status == VCHIQ_RETRY); ++ } else { ++ /* Mark the service for removal by the slot handler */ ++ request_poll(service->state, service, VCHIQ_POLL_REMOVE); ++ } ++ while (1) { ++ if (down_interruptible(&service->remove_event) != 0) { ++ status = VCHIQ_RETRY; ++ break; ++ } ++ ++ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) || ++ (service->srvstate == VCHIQ_SRVSTATE_OPEN)) ++ break; ++ ++ vchiq_log_warning(vchiq_core_log_level, ++ "%d: remove_service:%d - waiting in state %s", ++ service->state->id, service->localport, ++ srvstate_names[service->srvstate]); ++ } ++ ++ if ((status == VCHIQ_SUCCESS) && ++ (service->srvstate != VCHIQ_SRVSTATE_FREE)) ++ status = VCHIQ_ERROR; ++ ++ unlock_service(service); ++ ++ return status; ++} ++ ++ ++/* This function may be called by kernel threads or user threads. ++ * User threads may receive VCHIQ_RETRY to indicate that a signal has been ++ * received and the call should be retried after being returned to user ++ * context. ++ * When called in blocking mode, the userdata field points to a bulk_waiter ++ * structure. ++ */ ++VCHIQ_STATUS_T ++vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, ++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata, ++ VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir) ++{ ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ VCHIQ_BULK_QUEUE_T *queue; ++ VCHIQ_BULK_T *bulk; ++ VCHIQ_STATE_T *state; ++ struct bulk_waiter *bulk_waiter = NULL; ++ const char dir_char = (dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r'; ++ const int dir_msgtype = (dir == VCHIQ_BULK_TRANSMIT) ? ++ VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX; ++ VCHIQ_STATUS_T status = VCHIQ_ERROR; ++ ++ if (!service || ++ (service->srvstate != VCHIQ_SRVSTATE_OPEN) || ++ ((memhandle == VCHI_MEM_HANDLE_INVALID) && (offset == NULL)) || ++ (vchiq_check_service(service) != VCHIQ_SUCCESS)) ++ goto error_exit; ++ ++ switch (mode) { ++ case VCHIQ_BULK_MODE_NOCALLBACK: ++ case VCHIQ_BULK_MODE_CALLBACK: ++ break; ++ case VCHIQ_BULK_MODE_BLOCKING: ++ bulk_waiter = (struct bulk_waiter *)userdata; ++ sema_init(&bulk_waiter->event, 0); ++ bulk_waiter->actual = 0; ++ bulk_waiter->bulk = NULL; ++ break; ++ case VCHIQ_BULK_MODE_WAITING: ++ bulk_waiter = (struct bulk_waiter *)userdata; ++ bulk = bulk_waiter->bulk; ++ goto waiting; ++ default: ++ goto error_exit; ++ } ++ ++ state = service->state; ++ ++ queue = (dir == VCHIQ_BULK_TRANSMIT) ? ++ &service->bulk_tx : &service->bulk_rx; ++ ++ if (mutex_lock_interruptible(&service->bulk_mutex) != 0) { ++ status = VCHIQ_RETRY; ++ goto error_exit; ++ } ++ ++ if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS) { ++ VCHIQ_SERVICE_STATS_INC(service, bulk_stalls); ++ do { ++ mutex_unlock(&service->bulk_mutex); ++ if (down_interruptible(&service->bulk_remove_event) ++ != 0) { ++ status = VCHIQ_RETRY; ++ goto error_exit; ++ } ++ if (mutex_lock_interruptible(&service->bulk_mutex) ++ != 0) { ++ status = VCHIQ_RETRY; ++ goto error_exit; ++ } ++ } while (queue->local_insert == queue->remove + ++ VCHIQ_NUM_SERVICE_BULKS); ++ } ++ ++ bulk = &queue->bulks[BULK_INDEX(queue->local_insert)]; ++ ++ bulk->mode = mode; ++ bulk->dir = dir; ++ bulk->userdata = userdata; ++ bulk->size = size; ++ bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED; ++ ++ if (vchiq_prepare_bulk_data(bulk, memhandle, offset, size, dir) != ++ VCHIQ_SUCCESS) ++ goto unlock_error_exit; ++ ++ wmb(); ++ ++ vchiq_log_info(vchiq_core_log_level, ++ "%d: bt (%d->%d) %cx %x@%x %x", ++ state->id, ++ service->localport, service->remoteport, dir_char, ++ size, (unsigned int)bulk->data, (unsigned int)userdata); ++ ++ if (state->is_master) { ++ queue->local_insert++; ++ if (resolve_bulks(service, queue)) ++ request_poll(state, service, ++ (dir == VCHIQ_BULK_TRANSMIT) ? ++ VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY); ++ } else { ++ int payload[2] = { (int)bulk->data, bulk->size }; ++ VCHIQ_ELEMENT_T element = { payload, sizeof(payload) }; ++ ++ status = queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(dir_msgtype, ++ service->localport, service->remoteport), ++ &element, 1, sizeof(payload), 1); ++ if (status != VCHIQ_SUCCESS) { ++ vchiq_complete_bulk(bulk); ++ goto unlock_error_exit; ++ } ++ queue->local_insert++; ++ } ++ ++ mutex_unlock(&service->bulk_mutex); ++ ++ vchiq_log_trace(vchiq_core_log_level, ++ "%d: bt:%d %cx li=%x ri=%x p=%x", ++ state->id, ++ service->localport, dir_char, ++ queue->local_insert, queue->remote_insert, queue->process); ++ ++waiting: ++ unlock_service(service); ++ ++ status = VCHIQ_SUCCESS; ++ ++ if (bulk_waiter) { ++ bulk_waiter->bulk = bulk; ++ if (down_interruptible(&bulk_waiter->event) != 0) ++ status = VCHIQ_RETRY; ++ else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED) ++ status = VCHIQ_ERROR; ++ } ++ ++ return status; ++ ++unlock_error_exit: ++ mutex_unlock(&service->bulk_mutex); ++ ++error_exit: ++ if (service) ++ unlock_service(service); ++ return status; ++} ++ ++VCHIQ_STATUS_T ++vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T handle, ++ const VCHIQ_ELEMENT_T *elements, unsigned int count) ++{ ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ VCHIQ_STATUS_T status = VCHIQ_ERROR; ++ ++ unsigned int size = 0; ++ unsigned int i; ++ ++ if (!service || ++ (vchiq_check_service(service) != VCHIQ_SUCCESS)) ++ goto error_exit; ++ ++ for (i = 0; i < (unsigned int)count; i++) { ++ if (elements[i].size) { ++ if (elements[i].data == NULL) { ++ VCHIQ_SERVICE_STATS_INC(service, error_count); ++ goto error_exit; ++ } ++ size += elements[i].size; ++ } ++ } ++ ++ if (size > VCHIQ_MAX_MSG_SIZE) { ++ VCHIQ_SERVICE_STATS_INC(service, error_count); ++ goto error_exit; ++ } ++ ++ switch (service->srvstate) { ++ case VCHIQ_SRVSTATE_OPEN: ++ status = queue_message(service->state, service, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA, ++ service->localport, ++ service->remoteport), ++ elements, count, size, 1); ++ break; ++ case VCHIQ_SRVSTATE_OPENSYNC: ++ status = queue_message_sync(service->state, service, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA, ++ service->localport, ++ service->remoteport), ++ elements, count, size, 1); ++ break; ++ default: ++ status = VCHIQ_ERROR; ++ break; ++ } ++ ++error_exit: ++ if (service) ++ unlock_service(service); ++ ++ return status; ++} ++ ++void ++vchiq_release_message(VCHIQ_SERVICE_HANDLE_T handle, VCHIQ_HEADER_T *header) ++{ ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ VCHIQ_SHARED_STATE_T *remote; ++ VCHIQ_STATE_T *state; ++ int slot_index; ++ ++ if (!service) ++ return; ++ ++ state = service->state; ++ remote = state->remote; ++ ++ slot_index = SLOT_INDEX_FROM_DATA(state, (void *)header); ++ ++ if ((slot_index >= remote->slot_first) && ++ (slot_index <= remote->slot_last)) { ++ int msgid = header->msgid; ++ if (msgid & VCHIQ_MSGID_CLAIMED) { ++ VCHIQ_SLOT_INFO_T *slot_info = ++ SLOT_INFO_FROM_INDEX(state, slot_index); ++ ++ release_slot(state, slot_info, header, service); ++ } ++ } else if (slot_index == remote->slot_sync) ++ release_message_sync(state, header); ++ ++ unlock_service(service); ++} ++ ++static void ++release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) ++{ ++ header->msgid = VCHIQ_MSGID_PADDING; ++ wmb(); ++ remote_event_signal(&state->remote->sync_release); ++} ++ ++VCHIQ_STATUS_T ++vchiq_get_peer_version(VCHIQ_SERVICE_HANDLE_T handle, short *peer_version) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_ERROR; ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ ++ if (!service || ++ (vchiq_check_service(service) != VCHIQ_SUCCESS) || ++ !peer_version) ++ goto exit; ++ *peer_version = service->peer_version; ++ status = VCHIQ_SUCCESS; ++ ++exit: ++ if (service) ++ unlock_service(service); ++ return status; ++} ++ ++VCHIQ_STATUS_T ++vchiq_get_config(VCHIQ_INSTANCE_T instance, ++ int config_size, VCHIQ_CONFIG_T *pconfig) ++{ ++ VCHIQ_CONFIG_T config; ++ ++ (void)instance; ++ ++ config.max_msg_size = VCHIQ_MAX_MSG_SIZE; ++ config.bulk_threshold = VCHIQ_MAX_MSG_SIZE; ++ config.max_outstanding_bulks = VCHIQ_NUM_SERVICE_BULKS; ++ config.max_services = VCHIQ_MAX_SERVICES; ++ config.version = VCHIQ_VERSION; ++ config.version_min = VCHIQ_VERSION_MIN; ++ ++ if (config_size > sizeof(VCHIQ_CONFIG_T)) ++ return VCHIQ_ERROR; ++ ++ memcpy(pconfig, &config, ++ min(config_size, (int)(sizeof(VCHIQ_CONFIG_T)))); ++ ++ return VCHIQ_SUCCESS; ++} ++ ++VCHIQ_STATUS_T ++vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T handle, ++ VCHIQ_SERVICE_OPTION_T option, int value) ++{ ++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle); ++ VCHIQ_STATUS_T status = VCHIQ_ERROR; ++ ++ if (service) { ++ switch (option) { ++ case VCHIQ_SERVICE_OPTION_AUTOCLOSE: ++ service->auto_close = value; ++ status = VCHIQ_SUCCESS; ++ break; ++ ++ case VCHIQ_SERVICE_OPTION_SLOT_QUOTA: { ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &service->state->service_quotas[ ++ service->localport]; ++ if (value == 0) ++ value = service->state->default_slot_quota; ++ if ((value >= service_quota->slot_use_count) && ++ (value < (unsigned short)~0)) { ++ service_quota->slot_quota = value; ++ if ((value >= service_quota->slot_use_count) && ++ (service_quota->message_quota >= ++ service_quota->message_use_count)) { ++ /* Signal the service that it may have ++ ** dropped below its quota */ ++ up(&service_quota->quota_event); ++ } ++ status = VCHIQ_SUCCESS; ++ } ++ } break; ++ ++ case VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA: { ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &service->state->service_quotas[ ++ service->localport]; ++ if (value == 0) ++ value = service->state->default_message_quota; ++ if ((value >= service_quota->message_use_count) && ++ (value < (unsigned short)~0)) { ++ service_quota->message_quota = value; ++ if ((value >= ++ service_quota->message_use_count) && ++ (service_quota->slot_quota >= ++ service_quota->slot_use_count)) ++ /* Signal the service that it may have ++ ** dropped below its quota */ ++ up(&service_quota->quota_event); ++ status = VCHIQ_SUCCESS; ++ } ++ } break; ++ ++ case VCHIQ_SERVICE_OPTION_SYNCHRONOUS: ++ if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) || ++ (service->srvstate == ++ VCHIQ_SRVSTATE_LISTENING)) { ++ service->sync = value; ++ status = VCHIQ_SUCCESS; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ unlock_service(service); ++ } ++ ++ return status; ++} ++ ++void ++vchiq_dump_shared_state(void *dump_context, VCHIQ_STATE_T *state, ++ VCHIQ_SHARED_STATE_T *shared, const char *label) ++{ ++ static const char *const debug_names[] = { ++ "", ++ "SLOT_HANDLER_COUNT", ++ "SLOT_HANDLER_LINE", ++ "PARSE_LINE", ++ "PARSE_HEADER", ++ "PARSE_MSGID", ++ "AWAIT_COMPLETION_LINE", ++ "DEQUEUE_MESSAGE_LINE", ++ "SERVICE_CALLBACK_LINE", ++ "MSG_QUEUE_FULL_COUNT", ++ "COMPLETION_QUEUE_FULL_COUNT" ++ }; ++ int i; ++ ++ char buf[80]; ++ int len; ++ len = snprintf(buf, sizeof(buf), ++ " %s: slots %d-%d tx_pos=%x recycle=%x", ++ label, shared->slot_first, shared->slot_last, ++ shared->tx_pos, shared->slot_queue_recycle); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ len = snprintf(buf, sizeof(buf), ++ " Slots claimed:"); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ for (i = shared->slot_first; i <= shared->slot_last; i++) { ++ VCHIQ_SLOT_INFO_T slot_info = *SLOT_INFO_FROM_INDEX(state, i); ++ if (slot_info.use_count != slot_info.release_count) { ++ len = snprintf(buf, sizeof(buf), ++ " %d: %d/%d", i, slot_info.use_count, ++ slot_info.release_count); ++ vchiq_dump(dump_context, buf, len + 1); ++ } ++ } ++ ++ for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++) { ++ len = snprintf(buf, sizeof(buf), " DEBUG: %s = %d(%x)", ++ debug_names[i], shared->debug[i], shared->debug[i]); ++ vchiq_dump(dump_context, buf, len + 1); ++ } ++} ++ ++void ++vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state) ++{ ++ char buf[80]; ++ int len; ++ int i; ++ ++ len = snprintf(buf, sizeof(buf), "State %d: %s", state->id, ++ conn_state_names[state->conn_state]); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ len = snprintf(buf, sizeof(buf), ++ " tx_pos=%x(@%x), rx_pos=%x(@%x)", ++ state->local->tx_pos, ++ (uint32_t)state->tx_data + ++ (state->local_tx_pos & VCHIQ_SLOT_MASK), ++ state->rx_pos, ++ (uint32_t)state->rx_data + ++ (state->rx_pos & VCHIQ_SLOT_MASK)); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ len = snprintf(buf, sizeof(buf), ++ " Version: %d (min %d)", ++ VCHIQ_VERSION, VCHIQ_VERSION_MIN); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ if (VCHIQ_ENABLE_STATS) { ++ len = snprintf(buf, sizeof(buf), ++ " Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, " ++ "error_count=%d", ++ state->stats.ctrl_tx_count, state->stats.ctrl_rx_count, ++ state->stats.error_count); ++ vchiq_dump(dump_context, buf, len + 1); ++ } ++ ++ len = snprintf(buf, sizeof(buf), ++ " Slots: %d available (%d data), %d recyclable, %d stalls " ++ "(%d data)", ++ ((state->slot_queue_available * VCHIQ_SLOT_SIZE) - ++ state->local_tx_pos) / VCHIQ_SLOT_SIZE, ++ state->data_quota - state->data_use_count, ++ state->local->slot_queue_recycle - state->slot_queue_available, ++ state->stats.slot_stalls, state->stats.data_stalls); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ vchiq_dump_platform_state(dump_context); ++ ++ vchiq_dump_shared_state(dump_context, state, state->local, "Local"); ++ vchiq_dump_shared_state(dump_context, state, state->remote, "Remote"); ++ ++ vchiq_dump_platform_instances(dump_context); ++ ++ for (i = 0; i < state->unused_service; i++) { ++ VCHIQ_SERVICE_T *service = find_service_by_port(state, i); ++ ++ if (service) { ++ vchiq_dump_service_state(dump_context, service); ++ unlock_service(service); ++ } ++ } ++} ++ ++void ++vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service) ++{ ++ char buf[80]; ++ int len; ++ ++ len = snprintf(buf, sizeof(buf), "Service %d: %s (ref %u)", ++ service->localport, srvstate_names[service->srvstate], ++ service->ref_count - 1); /*Don't include the lock just taken*/ ++ ++ if (service->srvstate != VCHIQ_SRVSTATE_FREE) { ++ char remoteport[30]; ++ VCHIQ_SERVICE_QUOTA_T *service_quota = ++ &service->state->service_quotas[service->localport]; ++ int fourcc = service->base.fourcc; ++ int tx_pending, rx_pending; ++ if (service->remoteport != VCHIQ_PORT_FREE) { ++ int len2 = snprintf(remoteport, sizeof(remoteport), ++ "%d", service->remoteport); ++ if (service->public_fourcc != VCHIQ_FOURCC_INVALID) ++ snprintf(remoteport + len2, ++ sizeof(remoteport) - len2, ++ " (client %x)", service->client_id); ++ } else ++ strcpy(remoteport, "n/a"); ++ ++ len += snprintf(buf + len, sizeof(buf) - len, ++ " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)", ++ VCHIQ_FOURCC_AS_4CHARS(fourcc), ++ remoteport, ++ service_quota->message_use_count, ++ service_quota->message_quota, ++ service_quota->slot_use_count, ++ service_quota->slot_quota); ++ ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ tx_pending = service->bulk_tx.local_insert - ++ service->bulk_tx.remote_insert; ++ ++ rx_pending = service->bulk_rx.local_insert - ++ service->bulk_rx.remote_insert; ++ ++ len = snprintf(buf, sizeof(buf), ++ " Bulk: tx_pending=%d (size %d)," ++ " rx_pending=%d (size %d)", ++ tx_pending, ++ tx_pending ? service->bulk_tx.bulks[ ++ BULK_INDEX(service->bulk_tx.remove)].size : 0, ++ rx_pending, ++ rx_pending ? service->bulk_rx.bulks[ ++ BULK_INDEX(service->bulk_rx.remove)].size : 0); ++ ++ if (VCHIQ_ENABLE_STATS) { ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ len = snprintf(buf, sizeof(buf), ++ " Ctrl: tx_count=%d, tx_bytes=%llu, " ++ "rx_count=%d, rx_bytes=%llu", ++ service->stats.ctrl_tx_count, ++ service->stats.ctrl_tx_bytes, ++ service->stats.ctrl_rx_count, ++ service->stats.ctrl_rx_bytes); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ len = snprintf(buf, sizeof(buf), ++ " Bulk: tx_count=%d, tx_bytes=%llu, " ++ "rx_count=%d, rx_bytes=%llu", ++ service->stats.bulk_tx_count, ++ service->stats.bulk_tx_bytes, ++ service->stats.bulk_rx_count, ++ service->stats.bulk_rx_bytes); ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ len = snprintf(buf, sizeof(buf), ++ " %d quota stalls, %d slot stalls, " ++ "%d bulk stalls, %d aborted, %d errors", ++ service->stats.quota_stalls, ++ service->stats.slot_stalls, ++ service->stats.bulk_stalls, ++ service->stats.bulk_aborted_count, ++ service->stats.error_count); ++ } ++ } ++ ++ vchiq_dump(dump_context, buf, len + 1); ++ ++ if (service->srvstate != VCHIQ_SRVSTATE_FREE) ++ vchiq_dump_platform_service_state(dump_context, service); ++} ++ ++ ++void ++vchiq_loud_error_header(void) ++{ ++ vchiq_log_error(vchiq_core_log_level, ++ "============================================================" ++ "================"); ++ vchiq_log_error(vchiq_core_log_level, ++ "============================================================" ++ "================"); ++ vchiq_log_error(vchiq_core_log_level, "====="); ++} ++ ++void ++vchiq_loud_error_footer(void) ++{ ++ vchiq_log_error(vchiq_core_log_level, "====="); ++ vchiq_log_error(vchiq_core_log_level, ++ "============================================================" ++ "================"); ++ vchiq_log_error(vchiq_core_log_level, ++ "============================================================" ++ "================"); ++} ++ ++ ++VCHIQ_STATUS_T vchiq_send_remote_use(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_RETRY; ++ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) ++ status = queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0), ++ NULL, 0, 0, 0); ++ return status; ++} ++ ++VCHIQ_STATUS_T vchiq_send_remote_release(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_RETRY; ++ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) ++ status = queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_RELEASE, 0, 0), ++ NULL, 0, 0, 0); ++ return status; ++} ++ ++VCHIQ_STATUS_T vchiq_send_remote_use_active(VCHIQ_STATE_T *state) ++{ ++ VCHIQ_STATUS_T status = VCHIQ_RETRY; ++ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED) ++ status = queue_message(state, NULL, ++ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0), ++ NULL, 0, 0, 0); ++ return status; ++} ++ ++void vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem, ++ size_t numBytes) ++{ ++ const uint8_t *mem = (const uint8_t *)voidMem; ++ size_t offset; ++ char lineBuf[100]; ++ char *s; ++ ++ while (numBytes > 0) { ++ s = lineBuf; ++ ++ for (offset = 0; offset < 16; offset++) { ++ if (offset < numBytes) ++ s += snprintf(s, 4, "%02x ", mem[offset]); ++ else ++ s += snprintf(s, 4, " "); ++ } ++ ++ for (offset = 0; offset < 16; offset++) { ++ if (offset < numBytes) { ++ uint8_t ch = mem[offset]; ++ ++ if ((ch < ' ') || (ch > '~')) ++ ch = '.'; ++ *s++ = (char)ch; ++ } ++ } ++ *s++ = '\0'; ++ ++ if ((label != NULL) && (*label != '\0')) ++ vchiq_log_trace(VCHIQ_LOG_TRACE, ++ "%s: %08x: %s", label, addr, lineBuf); ++ else ++ vchiq_log_trace(VCHIQ_LOG_TRACE, ++ "%08x: %s", addr, lineBuf); ++ ++ addr += 16; ++ mem += 16; ++ if (numBytes > 16) ++ numBytes -= 16; ++ else ++ numBytes = 0; ++ } ++} +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,706 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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. ++ */ ++ ++#ifndef VCHIQ_CORE_H ++#define VCHIQ_CORE_H ++ ++#include ++#include ++#include ++ ++#include "vchiq_cfg.h" ++ ++#include "vchiq.h" ++ ++/* Run time control of log level, based on KERN_XXX level. */ ++#define VCHIQ_LOG_DEFAULT 4 ++#define VCHIQ_LOG_ERROR 3 ++#define VCHIQ_LOG_WARNING 4 ++#define VCHIQ_LOG_INFO 6 ++#define VCHIQ_LOG_TRACE 7 ++ ++#define VCHIQ_LOG_PREFIX KERN_INFO "vchiq: " ++ ++#ifndef vchiq_log_error ++#define vchiq_log_error(cat, fmt, ...) \ ++ do { if (cat >= VCHIQ_LOG_ERROR) \ ++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) ++#endif ++#ifndef vchiq_log_warning ++#define vchiq_log_warning(cat, fmt, ...) \ ++ do { if (cat >= VCHIQ_LOG_WARNING) \ ++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) ++#endif ++#ifndef vchiq_log_info ++#define vchiq_log_info(cat, fmt, ...) \ ++ do { if (cat >= VCHIQ_LOG_INFO) \ ++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) ++#endif ++#ifndef vchiq_log_trace ++#define vchiq_log_trace(cat, fmt, ...) \ ++ do { if (cat >= VCHIQ_LOG_TRACE) \ ++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) ++#endif ++ ++#define vchiq_loud_error(...) \ ++ vchiq_log_error(vchiq_core_log_level, "===== " __VA_ARGS__) ++ ++#ifndef vchiq_static_assert ++#define vchiq_static_assert(cond) __attribute__((unused)) \ ++ extern int vchiq_static_assert[(cond) ? 1 : -1] ++#endif ++ ++#define IS_POW2(x) (x && ((x & (x - 1)) == 0)) ++ ++/* Ensure that the slot size and maximum number of slots are powers of 2 */ ++vchiq_static_assert(IS_POW2(VCHIQ_SLOT_SIZE)); ++vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS)); ++vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS_PER_SIDE)); ++ ++#define VCHIQ_SLOT_MASK (VCHIQ_SLOT_SIZE - 1) ++#define VCHIQ_SLOT_QUEUE_MASK (VCHIQ_MAX_SLOTS_PER_SIDE - 1) ++#define VCHIQ_SLOT_ZERO_SLOTS ((sizeof(VCHIQ_SLOT_ZERO_T) + \ ++ VCHIQ_SLOT_SIZE - 1) / VCHIQ_SLOT_SIZE) ++ ++#define VCHIQ_MSG_PADDING 0 /* - */ ++#define VCHIQ_MSG_CONNECT 1 /* - */ ++#define VCHIQ_MSG_OPEN 2 /* + (srcport, -), fourcc, client_id */ ++#define VCHIQ_MSG_OPENACK 3 /* + (srcport, dstport) */ ++#define VCHIQ_MSG_CLOSE 4 /* + (srcport, dstport) */ ++#define VCHIQ_MSG_DATA 5 /* + (srcport, dstport) */ ++#define VCHIQ_MSG_BULK_RX 6 /* + (srcport, dstport), data, size */ ++#define VCHIQ_MSG_BULK_TX 7 /* + (srcport, dstport), data, size */ ++#define VCHIQ_MSG_BULK_RX_DONE 8 /* + (srcport, dstport), actual */ ++#define VCHIQ_MSG_BULK_TX_DONE 9 /* + (srcport, dstport), actual */ ++#define VCHIQ_MSG_PAUSE 10 /* - */ ++#define VCHIQ_MSG_RESUME 11 /* - */ ++#define VCHIQ_MSG_REMOTE_USE 12 /* - */ ++#define VCHIQ_MSG_REMOTE_RELEASE 13 /* - */ ++#define VCHIQ_MSG_REMOTE_USE_ACTIVE 14 /* - */ ++ ++#define VCHIQ_PORT_MAX (VCHIQ_MAX_SERVICES - 1) ++#define VCHIQ_PORT_FREE 0x1000 ++#define VCHIQ_PORT_IS_VALID(port) (port < VCHIQ_PORT_FREE) ++#define VCHIQ_MAKE_MSG(type, srcport, dstport) \ ++ ((type<<24) | (srcport<<12) | (dstport<<0)) ++#define VCHIQ_MSG_TYPE(msgid) ((unsigned int)msgid >> 24) ++#define VCHIQ_MSG_SRCPORT(msgid) \ ++ (unsigned short)(((unsigned int)msgid >> 12) & 0xfff) ++#define VCHIQ_MSG_DSTPORT(msgid) \ ++ ((unsigned short)msgid & 0xfff) ++ ++#define VCHIQ_FOURCC_AS_4CHARS(fourcc) \ ++ ((fourcc) >> 24) & 0xff, \ ++ ((fourcc) >> 16) & 0xff, \ ++ ((fourcc) >> 8) & 0xff, \ ++ (fourcc) & 0xff ++ ++/* Ensure the fields are wide enough */ ++vchiq_static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0, 0, VCHIQ_PORT_MAX)) ++ == 0); ++vchiq_static_assert(VCHIQ_MSG_TYPE(VCHIQ_MAKE_MSG(0, VCHIQ_PORT_MAX, 0)) == 0); ++vchiq_static_assert((unsigned int)VCHIQ_PORT_MAX < ++ (unsigned int)VCHIQ_PORT_FREE); ++ ++#define VCHIQ_MSGID_PADDING VCHIQ_MAKE_MSG(VCHIQ_MSG_PADDING, 0, 0) ++#define VCHIQ_MSGID_CLAIMED 0x40000000 ++ ++#define VCHIQ_FOURCC_INVALID 0x00000000 ++#define VCHIQ_FOURCC_IS_LEGAL(fourcc) (fourcc != VCHIQ_FOURCC_INVALID) ++ ++#define VCHIQ_BULK_ACTUAL_ABORTED -1 ++ ++typedef uint32_t BITSET_T; ++ ++vchiq_static_assert((sizeof(BITSET_T) * 8) == 32); ++ ++#define BITSET_SIZE(b) ((b + 31) >> 5) ++#define BITSET_WORD(b) (b >> 5) ++#define BITSET_BIT(b) (1 << (b & 31)) ++#define BITSET_ZERO(bs) memset(bs, 0, sizeof(bs)) ++#define BITSET_IS_SET(bs, b) (bs[BITSET_WORD(b)] & BITSET_BIT(b)) ++#define BITSET_SET(bs, b) (bs[BITSET_WORD(b)] |= BITSET_BIT(b)) ++#define BITSET_CLR(bs, b) (bs[BITSET_WORD(b)] &= ~BITSET_BIT(b)) ++ ++#if VCHIQ_ENABLE_STATS ++#define VCHIQ_STATS_INC(state, stat) (state->stats. stat++) ++#define VCHIQ_SERVICE_STATS_INC(service, stat) (service->stats. stat++) ++#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) \ ++ (service->stats. stat += addend) ++#else ++#define VCHIQ_STATS_INC(state, stat) ((void)0) ++#define VCHIQ_SERVICE_STATS_INC(service, stat) ((void)0) ++#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) ((void)0) ++#endif ++ ++enum { ++ DEBUG_ENTRIES, ++#if VCHIQ_ENABLE_DEBUG ++ DEBUG_SLOT_HANDLER_COUNT, ++ DEBUG_SLOT_HANDLER_LINE, ++ DEBUG_PARSE_LINE, ++ DEBUG_PARSE_HEADER, ++ DEBUG_PARSE_MSGID, ++ DEBUG_AWAIT_COMPLETION_LINE, ++ DEBUG_DEQUEUE_MESSAGE_LINE, ++ DEBUG_SERVICE_CALLBACK_LINE, ++ DEBUG_MSG_QUEUE_FULL_COUNT, ++ DEBUG_COMPLETION_QUEUE_FULL_COUNT, ++#endif ++ DEBUG_MAX ++}; ++ ++#if VCHIQ_ENABLE_DEBUG ++ ++#define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug; ++#define DEBUG_TRACE(d) \ ++ do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(); } while (0) ++#define DEBUG_VALUE(d, v) \ ++ do { debug_ptr[DEBUG_ ## d] = (v); dsb(); } while (0) ++#define DEBUG_COUNT(d) \ ++ do { debug_ptr[DEBUG_ ## d]++; dsb(); } while (0) ++ ++#else /* VCHIQ_ENABLE_DEBUG */ ++ ++#define DEBUG_INITIALISE(local) ++#define DEBUG_TRACE(d) ++#define DEBUG_VALUE(d, v) ++#define DEBUG_COUNT(d) ++ ++#endif /* VCHIQ_ENABLE_DEBUG */ ++ ++typedef enum { ++ VCHIQ_CONNSTATE_DISCONNECTED, ++ VCHIQ_CONNSTATE_CONNECTING, ++ VCHIQ_CONNSTATE_CONNECTED, ++ VCHIQ_CONNSTATE_PAUSING, ++ VCHIQ_CONNSTATE_PAUSE_SENT, ++ VCHIQ_CONNSTATE_PAUSED, ++ VCHIQ_CONNSTATE_RESUMING, ++ VCHIQ_CONNSTATE_PAUSE_TIMEOUT, ++ VCHIQ_CONNSTATE_RESUME_TIMEOUT ++} VCHIQ_CONNSTATE_T; ++ ++enum { ++ VCHIQ_SRVSTATE_FREE, ++ VCHIQ_SRVSTATE_HIDDEN, ++ VCHIQ_SRVSTATE_LISTENING, ++ VCHIQ_SRVSTATE_OPENING, ++ VCHIQ_SRVSTATE_OPEN, ++ VCHIQ_SRVSTATE_OPENSYNC, ++ VCHIQ_SRVSTATE_CLOSESENT, ++ VCHIQ_SRVSTATE_CLOSERECVD, ++ VCHIQ_SRVSTATE_CLOSEWAIT, ++ VCHIQ_SRVSTATE_CLOSED ++}; ++ ++enum { ++ VCHIQ_POLL_TERMINATE, ++ VCHIQ_POLL_REMOVE, ++ VCHIQ_POLL_TXNOTIFY, ++ VCHIQ_POLL_RXNOTIFY, ++ VCHIQ_POLL_COUNT ++}; ++ ++typedef enum { ++ VCHIQ_BULK_TRANSMIT, ++ VCHIQ_BULK_RECEIVE ++} VCHIQ_BULK_DIR_T; ++ ++typedef void (*VCHIQ_USERDATA_TERM_T)(void *userdata); ++ ++typedef struct vchiq_bulk_struct { ++ short mode; ++ short dir; ++ void *userdata; ++ VCHI_MEM_HANDLE_T handle; ++ void *data; ++ int size; ++ void *remote_data; ++ int remote_size; ++ int actual; ++} VCHIQ_BULK_T; ++ ++typedef struct vchiq_bulk_queue_struct { ++ int local_insert; /* Where to insert the next local bulk */ ++ int remote_insert; /* Where to insert the next remote bulk (master) */ ++ int process; /* Bulk to transfer next */ ++ int remote_notify; /* Bulk to notify the remote client of next (mstr) */ ++ int remove; /* Bulk to notify the local client of, and remove, ++ ** next */ ++ VCHIQ_BULK_T bulks[VCHIQ_NUM_SERVICE_BULKS]; ++} VCHIQ_BULK_QUEUE_T; ++ ++typedef struct remote_event_struct { ++ int armed; ++ int fired; ++ struct semaphore *event; ++} REMOTE_EVENT_T; ++ ++typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T; ++ ++typedef struct vchiq_state_struct VCHIQ_STATE_T; ++ ++typedef struct vchiq_slot_struct { ++ char data[VCHIQ_SLOT_SIZE]; ++} VCHIQ_SLOT_T; ++ ++typedef struct vchiq_slot_info_struct { ++ /* Use two counters rather than one to avoid the need for a mutex. */ ++ short use_count; ++ short release_count; ++} VCHIQ_SLOT_INFO_T; ++ ++typedef struct vchiq_service_struct { ++ VCHIQ_SERVICE_BASE_T base; ++ VCHIQ_SERVICE_HANDLE_T handle; ++ unsigned int ref_count; ++ int srvstate; ++ VCHIQ_USERDATA_TERM_T userdata_term; ++ unsigned int localport; ++ unsigned int remoteport; ++ int public_fourcc; ++ int client_id; ++ char auto_close; ++ char sync; ++ char closing; ++ atomic_t poll_flags; ++ short version; ++ short version_min; ++ short peer_version; ++ ++ VCHIQ_STATE_T *state; ++ VCHIQ_INSTANCE_T instance; ++ ++ int service_use_count; ++ ++ VCHIQ_BULK_QUEUE_T bulk_tx; ++ VCHIQ_BULK_QUEUE_T bulk_rx; ++ ++ struct semaphore remove_event; ++ struct semaphore bulk_remove_event; ++ struct mutex bulk_mutex; ++ ++ struct service_stats_struct { ++ int quota_stalls; ++ int slot_stalls; ++ int bulk_stalls; ++ int error_count; ++ int ctrl_tx_count; ++ int ctrl_rx_count; ++ int bulk_tx_count; ++ int bulk_rx_count; ++ int bulk_aborted_count; ++ uint64_t ctrl_tx_bytes; ++ uint64_t ctrl_rx_bytes; ++ uint64_t bulk_tx_bytes; ++ uint64_t bulk_rx_bytes; ++ } stats; ++} VCHIQ_SERVICE_T; ++ ++/* The quota information is outside VCHIQ_SERVICE_T so that it can be ++ statically allocated, since for accounting reasons a service's slot ++ usage is carried over between users of the same port number. ++ */ ++typedef struct vchiq_service_quota_struct { ++ unsigned short slot_quota; ++ unsigned short slot_use_count; ++ unsigned short message_quota; ++ unsigned short message_use_count; ++ struct semaphore quota_event; ++ int previous_tx_index; ++} VCHIQ_SERVICE_QUOTA_T; ++ ++typedef struct vchiq_shared_state_struct { ++ ++ /* A non-zero value here indicates that the content is valid. */ ++ int initialised; ++ ++ /* The first and last (inclusive) slots allocated to the owner. */ ++ int slot_first; ++ int slot_last; ++ ++ /* The slot allocated to synchronous messages from the owner. */ ++ int slot_sync; ++ ++ /* Signalling this event indicates that owner's slot handler thread ++ ** should run. */ ++ REMOTE_EVENT_T trigger; ++ ++ /* Indicates the byte position within the stream where the next message ++ ** will be written. The least significant bits are an index into the ++ ** slot. The next bits are the index of the slot in slot_queue. */ ++ int tx_pos; ++ ++ /* This event should be signalled when a slot is recycled. */ ++ REMOTE_EVENT_T recycle; ++ ++ /* The slot_queue index where the next recycled slot will be written. */ ++ int slot_queue_recycle; ++ ++ /* This event should be signalled when a synchronous message is sent. */ ++ REMOTE_EVENT_T sync_trigger; ++ ++ /* This event should be signalled when a synchronous message has been ++ ** released. */ ++ REMOTE_EVENT_T sync_release; ++ ++ /* A circular buffer of slot indexes. */ ++ int slot_queue[VCHIQ_MAX_SLOTS_PER_SIDE]; ++ ++ /* Debugging state */ ++ int debug[DEBUG_MAX]; ++} VCHIQ_SHARED_STATE_T; ++ ++typedef struct vchiq_slot_zero_struct { ++ int magic; ++ short version; ++ short version_min; ++ int slot_zero_size; ++ int slot_size; ++ int max_slots; ++ int max_slots_per_side; ++ int platform_data[2]; ++ VCHIQ_SHARED_STATE_T master; ++ VCHIQ_SHARED_STATE_T slave; ++ VCHIQ_SLOT_INFO_T slots[VCHIQ_MAX_SLOTS]; ++} VCHIQ_SLOT_ZERO_T; ++ ++struct vchiq_state_struct { ++ int id; ++ int initialised; ++ VCHIQ_CONNSTATE_T conn_state; ++ int is_master; ++ ++ VCHIQ_SHARED_STATE_T *local; ++ VCHIQ_SHARED_STATE_T *remote; ++ VCHIQ_SLOT_T *slot_data; ++ ++ unsigned short default_slot_quota; ++ unsigned short default_message_quota; ++ ++ /* Event indicating connect message received */ ++ struct semaphore connect; ++ ++ /* Mutex protecting services */ ++ struct mutex mutex; ++ VCHIQ_INSTANCE_T *instance; ++ ++ /* Processes incoming messages */ ++ struct task_struct *slot_handler_thread; ++ ++ /* Processes recycled slots */ ++ struct task_struct *recycle_thread; ++ ++ /* Processes synchronous messages */ ++ struct task_struct *sync_thread; ++ ++ /* Local implementation of the trigger remote event */ ++ struct semaphore trigger_event; ++ ++ /* Local implementation of the recycle remote event */ ++ struct semaphore recycle_event; ++ ++ /* Local implementation of the sync trigger remote event */ ++ struct semaphore sync_trigger_event; ++ ++ /* Local implementation of the sync release remote event */ ++ struct semaphore sync_release_event; ++ ++ char *tx_data; ++ char *rx_data; ++ VCHIQ_SLOT_INFO_T *rx_info; ++ ++ struct mutex slot_mutex; ++ ++ struct mutex recycle_mutex; ++ ++ struct mutex sync_mutex; ++ ++ struct mutex bulk_transfer_mutex; ++ ++ /* Indicates the byte position within the stream from where the next ++ ** message will be read. The least significant bits are an index into ++ ** the slot.The next bits are the index of the slot in ++ ** remote->slot_queue. */ ++ int rx_pos; ++ ++ /* A cached copy of local->tx_pos. Only write to local->tx_pos, and read ++ from remote->tx_pos. */ ++ int local_tx_pos; ++ ++ /* The slot_queue index of the slot to become available next. */ ++ int slot_queue_available; ++ ++ /* A flag to indicate if any poll has been requested */ ++ int poll_needed; ++ ++ /* Ths index of the previous slot used for data messages. */ ++ int previous_data_index; ++ ++ /* The number of slots occupied by data messages. */ ++ unsigned short data_use_count; ++ ++ /* The maximum number of slots to be occupied by data messages. */ ++ unsigned short data_quota; ++ ++ /* An array of bit sets indicating which services must be polled. */ ++ atomic_t poll_services[BITSET_SIZE(VCHIQ_MAX_SERVICES)]; ++ ++ /* The number of the first unused service */ ++ int unused_service; ++ ++ /* Signalled when a free slot becomes available. */ ++ struct semaphore slot_available_event; ++ ++ struct semaphore slot_remove_event; ++ ++ /* Signalled when a free data slot becomes available. */ ++ struct semaphore data_quota_event; ++ ++ /* Incremented when there are bulk transfers which cannot be processed ++ * whilst paused and must be processed on resume */ ++ int deferred_bulks; ++ ++ struct state_stats_struct { ++ int slot_stalls; ++ int data_stalls; ++ int ctrl_tx_count; ++ int ctrl_rx_count; ++ int error_count; ++ } stats; ++ ++ VCHIQ_SERVICE_T * services[VCHIQ_MAX_SERVICES]; ++ VCHIQ_SERVICE_QUOTA_T service_quotas[VCHIQ_MAX_SERVICES]; ++ VCHIQ_SLOT_INFO_T slot_info[VCHIQ_MAX_SLOTS]; ++ ++ VCHIQ_PLATFORM_STATE_T platform_state; ++}; ++ ++struct bulk_waiter { ++ VCHIQ_BULK_T *bulk; ++ struct semaphore event; ++ int actual; ++}; ++ ++extern spinlock_t bulk_waiter_spinlock; ++ ++extern int vchiq_core_log_level; ++extern int vchiq_core_msg_log_level; ++extern int vchiq_sync_log_level; ++ ++extern VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES]; ++ ++extern const char * ++get_conn_state_name(VCHIQ_CONNSTATE_T conn_state); ++ ++extern VCHIQ_SLOT_ZERO_T * ++vchiq_init_slots(void *mem_base, int mem_size); ++ ++extern VCHIQ_STATUS_T ++vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, ++ int is_master); ++ ++extern VCHIQ_STATUS_T ++vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance); ++ ++extern VCHIQ_SERVICE_T * ++vchiq_add_service_internal(VCHIQ_STATE_T *state, ++ const VCHIQ_SERVICE_PARAMS_T *params, int srvstate, ++ VCHIQ_INSTANCE_T instance, VCHIQ_USERDATA_TERM_T userdata_term); ++ ++extern VCHIQ_STATUS_T ++vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id); ++ ++extern VCHIQ_STATUS_T ++vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd); ++ ++extern void ++vchiq_terminate_service_internal(VCHIQ_SERVICE_T *service); ++ ++extern void ++vchiq_free_service_internal(VCHIQ_SERVICE_T *service); ++ ++extern VCHIQ_STATUS_T ++vchiq_shutdown_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance); ++ ++extern VCHIQ_STATUS_T ++vchiq_pause_internal(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_resume_internal(VCHIQ_STATE_T *state); ++ ++extern void ++remote_event_pollall(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, ++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata, ++ VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir); ++ ++extern void ++vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service); ++ ++extern void ++vchiq_loud_error_header(void); ++ ++extern void ++vchiq_loud_error_footer(void); ++ ++extern void ++request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type); ++ ++static inline VCHIQ_SERVICE_T * ++handle_to_service(VCHIQ_SERVICE_HANDLE_T handle) ++{ ++ VCHIQ_STATE_T *state = vchiq_states[(handle / VCHIQ_MAX_SERVICES) & ++ (VCHIQ_MAX_STATES - 1)]; ++ if (!state) ++ return NULL; ++ ++ return state->services[handle & (VCHIQ_MAX_SERVICES - 1)]; ++} ++ ++extern VCHIQ_SERVICE_T * ++find_service_by_handle(VCHIQ_SERVICE_HANDLE_T handle); ++ ++extern VCHIQ_SERVICE_T * ++find_service_by_port(VCHIQ_STATE_T *state, int localport); ++ ++extern VCHIQ_SERVICE_T * ++find_service_for_instance(VCHIQ_INSTANCE_T instance, ++ VCHIQ_SERVICE_HANDLE_T handle); ++ ++extern VCHIQ_SERVICE_T * ++next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance, ++ int *pidx); ++ ++extern void ++lock_service(VCHIQ_SERVICE_T *service); ++ ++extern void ++unlock_service(VCHIQ_SERVICE_T *service); ++ ++/* The following functions are called from vchiq_core, and external ++** implementations must be provided. */ ++ ++extern VCHIQ_STATUS_T ++vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, ++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, int dir); ++ ++extern void ++vchiq_transfer_bulk(VCHIQ_BULK_T *bulk); ++ ++extern void ++vchiq_complete_bulk(VCHIQ_BULK_T *bulk); ++ ++extern VCHIQ_STATUS_T ++vchiq_copy_from_user(void *dst, const void *src, int size); ++ ++extern void ++remote_event_signal(REMOTE_EVENT_T *event); ++ ++void ++vchiq_platform_check_suspend(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_platform_paused(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_platform_resume(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_platform_resumed(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_dump(void *dump_context, const char *str, int len); ++ ++extern void ++vchiq_dump_platform_state(void *dump_context); ++ ++extern void ++vchiq_dump_platform_instances(void *dump_context); ++ ++extern void ++vchiq_dump_platform_service_state(void *dump_context, ++ VCHIQ_SERVICE_T *service); ++ ++extern VCHIQ_STATUS_T ++vchiq_use_service_internal(VCHIQ_SERVICE_T *service); ++ ++extern VCHIQ_STATUS_T ++vchiq_release_service_internal(VCHIQ_SERVICE_T *service); ++ ++extern void ++vchiq_on_remote_use(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_on_remote_release(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_platform_init_state(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_check_service(VCHIQ_SERVICE_T *service); ++ ++extern void ++vchiq_on_remote_use_active(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_send_remote_use(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_send_remote_release(VCHIQ_STATE_T *state); ++ ++extern VCHIQ_STATUS_T ++vchiq_send_remote_use_active(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, ++ VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate); ++ ++extern void ++vchiq_platform_handle_timeout(VCHIQ_STATE_T *state); ++ ++extern void ++vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate); ++ ++ ++extern void ++vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem, ++ size_t numBytes); ++ ++#endif +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,89 @@ ++#!/usr/bin/perl -w ++ ++use strict; ++ ++# ++# Generate a version from available information ++# ++ ++my $prefix = shift @ARGV; ++my $root = shift @ARGV; ++ ++ ++if ( not defined $root ) { ++ die "usage: $0 prefix root-dir\n"; ++} ++ ++if ( ! -d $root ) { ++ die "root directory $root not found\n"; ++} ++ ++my $version = "unknown"; ++my $tainted = ""; ++ ++if ( -d "$root/.git" ) { ++ # attempt to work out git version. only do so ++ # on a linux build host, as cygwin builds are ++ # already slow enough ++ ++ if ( -f "/usr/bin/git" || -f "/usr/local/bin/git" ) { ++ if (not open(F, "git --git-dir $root/.git rev-parse --verify HEAD|")) { ++ $version = "no git version"; ++ } ++ else { ++ $version = ; ++ $version =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin). ++ $version =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin). ++ } ++ ++ if (open(G, "git --git-dir $root/.git status --porcelain|")) { ++ $tainted = ; ++ $tainted =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin). ++ $tainted =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin). ++ if (length $tainted) { ++ $version = join ' ', $version, "(tainted)"; ++ } ++ else { ++ $version = join ' ', $version, "(clean)"; ++ } ++ } ++ } ++} ++ ++my $hostname = `hostname`; ++$hostname =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin). ++$hostname =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin). ++ ++ ++print STDERR "Version $version\n"; ++print < ++ ++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_hostname, "$hostname" ); ++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_version, "$version" ); ++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_time, __TIME__ ); ++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_date, __DATE__ ); ++ ++const char *vchiq_get_build_hostname( void ) ++{ ++ return vchiq_build_hostname; ++} ++ ++const char *vchiq_get_build_version( void ) ++{ ++ return vchiq_build_version; ++} ++ ++const char *vchiq_get_build_date( void ) ++{ ++ return vchiq_build_date; ++} ++ ++const char *vchiq_get_build_time( void ) ++{ ++ return vchiq_build_time; ++} ++EOF ++ ++ +Index: linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.10-3.10.11/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h 2014-05-05 12:51:22.000000000 +0000 +@@ -0,0 +1,188 @@ ++/** ++ * Copyright (c) 2010-2012 Broadcom. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * 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 ++ *