[-]
[+]
|
Changed |
kernel-debug.changes
|
|
[-]
[+]
|
Changed |
kernel-default.changes
^
|
|
[-]
[+]
|
Changed |
kernel-dummy.changes
^
|
|
[-]
[+]
|
Changed |
kernel-kdump.changes
^
|
|
[-]
[+]
|
Changed |
kernel-pae.changes
^
|
|
[-]
[+]
|
Changed |
kernel-ppc64.changes
^
|
|
[-]
[+]
|
Changed |
kernel-ps3.changes
^
|
|
[-]
[+]
|
Deleted |
kernel-rt.changes
^
|
@@ -1,44467 +0,0 @@
--------------------------------------------------------------------
-Sun Nov 2 01:05:36 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
- Use raw_smp_processor_id in __mem_cgroup_stat_add_safe.
-
--------------------------------------------------------------------
-Sun Nov 2 01:03:00 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
-
--------------------------------------------------------------------
-Sun Nov 2 00:12:04 CET 2008 - sdietrich@suse.de
-
-- patches.rt/workqueue-introduce-create_rt_workqueue.patch:
- workqueue: introduce create_rt_workqueue. (from 2.6.28)
-Refresh to eliminate fuzz:
- - patches.rt/preempt-realtime-core.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 23:41:00 CET 2008 - sdietrich@suse.de
-
-- Update RT config files:
- - Sync with SLES 11 default/debug configs
- - Limit CPUS to 32
- - Disable CONFIG_RADIX_TREE_CONCURRENT
- - Disable CONFIG_RADIX_TREE_OPTIMISTIC
- - Disable CONFIG_PREEMPT_RCU_BOOST
- - Enable CONFIG_RTMUTEX_CHECK
-
-- Adapt RT patches to changes made by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/mitigate-resched-flood-update.patch: Update
- smp_send_reschedule_allbutself_cpumask mask parameter.
- - patches.rt/x86-nmi-send_IPI_mask-pointer-fix.patch: Update
- smp_send_nmi_allbutself mask parameter.
-
-Resolve conflicts introduced by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/nmi-profiling-base.patch
- - patches.rt/send-nmi-all-preempt-disable.patch
-
-Refresh to eliminate fuzz
-- patches.rt/apic-dumpstack.patch: Linux-RT 2.6.27-RT.
-- patches.rt/mitigate-resched-flood.patch: Linux-RT 2.6.27-RT.
-- patches.rt/preempt-realtime-x86_64.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 08:32:52 CET 2008 - bwalle@suse.de
-
-- patches.fixes/kdb-fix-stack-overflow.patch:
- kdb: fix stack overflow for large NR_CPUS count (bnc#440361).
-
--------------------------------------------------------------------
-Fri Oct 31 18:41:23 CET 2008 - trenn@suse.de
-
-Fate 304268 and 304266. SGI scir driver (replaces the more intrusive
-leds one) and the rather intrusive x86_64 4096 CPU support patches:
-
-- Update config files.
-- patches.arch/x86_uv_early_detect.patch: Delete hacks that were
- necessary while waiting for x2apic code. (bnc#429984).
-- patches.arch/x86_sgi-uv-scir.patch: SGI X86 UV: Provide a
- System Activity Indicator driver (FATE304268 bnc#426066).
-- patches.arch/x86_sgi_cpus4096-01-fix-smp_call_function.patch:
- smp: reduce stack requirements for smp_call_function_mask
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-02-fix-send_call_func_ip.patch:
- x86: reduce stack requirements for send_call_func_ipi
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-05-update-send_IPI_mask.patch:
- x86 cpumask: Updates to support NR_CPUS=4096 (bnc#425240
- FATE304266).
-- patches.arch/x86_sgi_cpus4096-06-optimize-cpumask-in-sched_c.patch:
- Additional cpumask fixups (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-04-add-for_each_cpu_mask_and.patch:
- Add for_each_cpu_mask_and (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-07_pae_compile_fixups.patch:
- more cpumask cleanups for previous (x86_sgi_cpu4096..) patches
- (Additional cpumask fixups).
-- patches.suse/kdb-x86: kdb-v4.4-2.6.27-rc8-x86-1 (FATE#303971).
-- patches.xen/xen3-patch-2.6.27: Linux: Update to 2.6.27.
-- patches.xen/x86_sgi_xen-x86-cpus4096.patch: x86 cpumask xen:
- Updates to support NR_CPUS=4096 (Additional cpumask fixups).
-
--------------------------------------------------------------------
-Fri Oct 31 17:57:22 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-realtek-alc269-dmic: ALSA: hda -
- Add digital-mic for ALC269 auto-probe mode (bnc#440626).
-- patches.drivers/alsa-hda-realtek-mic-automute-fix: ALSA: hda -
- Disable broken mic auto-muting in Realtek codes (bnc#440626).
-
--------------------------------------------------------------------
-Fri Oct 31 12:34:44 CET 2008 - hare@suse.de
-
-- Update config files.
-- patches.drivers/cxgb3i: add cxgb3i iscsi driver
- (FATE#304154,bnc#433500).
-- patches.drivers/cxgb3-private-iscsi-ip-addresses: cxgb3 -
- manage private iSCSI IP addresses (FATE#304154,bnc#433500).
-- patches.drivers/open-iscsi-offloading-support: support for iscsi
- pdu digest offload and payload DDP. (FATE#304154,bnc#433500).
-- patches.fixes/cxgb3-remove-duplicate-tests-in-lro: cxgb3 -
- remove duplicate tests in lro (FATE#304154, bnc#430538).
-- supported.conf: Mark cxgb3i as supported.
-
--------------------------------------------------------------------
-Fri Oct 31 10:08:17 CET 2008 - bwalle@suse.de
-
-- patches.suse/kdb-resolve-uv-conflict.diff:
- Resolve KDB conflicts with UV (bnc#440376).
-
--------------------------------------------------------------------
-Fri Oct 31 09:04:16 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-sigmatel-spdif-fix: ALSA: hda -
- Fix SPDIF mute on IDT/STAC codecs.
-- patches.drivers/alsa-hda-reboot-notifier: ALSA: hda - Add
- reboot notifier.
-
--------------------------------------------------------------------
-Fri Oct 31 08:33:45 CET 2008 - jack@suse.cz
-
-- patches.suse/ocfs2-Fix-mount-cleanup-after-quota-failure.patch:
- ocfs2: Fix mount cleanup after quota failure (fate#302681).
-- patches.suse/ocfs2-Fix-oop-in-recovery-without-quotas:
- ocfs2: Fix recovery of nodes when quota feature is disabled
- (fate#302681).
-- patches.suse/ocfs2-Fix-grace-time-syncing.patch: ocfs2: Fix
- grace time syncing (fate#302681).
-
--------------------------------------------------------------------
-Fri Oct 31 01:28:20 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-del-timer-after-dequeue: blk: move
- blk_delete_timer call in end_that_request_last (bnc#440076
- bnc#440173).
-
--------------------------------------------------------------------
-Thu Oct 30 23:19:43 CET 2008 - trenn@suse.de
-
-- patches.arch/x86_agpgart-g33-stoeln-fix-2.patch: Avoid oops
- on G33 in 1MB stolen Mem case (bnc#391261).
-
--------------------------------------------------------------------
-Thu Oct 30 16:53:09 CET 2008 - gregkh@suse.de
-
-- patches.fixes/agp-fix-stolen-memory-counting-on-g4x.patch:
- agp: Fix stolen memory counting on G4X. (bnc#437618).
-
--------------------------------------------------------------------
-Thu Oct 30 13:44:43 CET 2008 - oneukum@suse.de
-
-- patches.fixes/sd_liberal_28_sense_invalid.diff: fix medium
- presence misdetection in usb storage device (bnc#362850).
-
--------------------------------------------------------------------
-Thu Oct 30 10:17:19 CET 2008 - olh@suse.de
-
-- add patches.fixes/scsi-ibmvscsi-show-config.patch
- use 4k buffer to transfer config data (439970 - LTC49349)
-
--------------------------------------------------------------------
-Thu Oct 30 06:02:17 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-add-timeout-on-dequeue: block: add timer
- on blkdev_dequeue_request() not elv_next_request() (bnc#440076).
-
--------------------------------------------------------------------
-Wed Oct 29 18:41:36 CET 2008 - sdietrich@suse.de
-
-Refresh RT patches:
-- patches.rt/adaptive-spinlock-lite-v2.patch: Linux-RT 2.6.27-RT
- adaptive spinlocks lite.
-- patches.rt/adaptive-task-oncpu.patch: Linux-RT 2.6.27-RT.
-- patches.rt/apic-level-smp-affinity.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-state-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-uptodate-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bz235099-idle-load-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/check-for-migration-during-push.patch: RT: fix
- push_rt_task() to handle dequeue_pushable properly.
-- patches.rt/cond_resched_softirq-WARN-fix.patch: Linux-RT
- 2.6.27-RT
- WARNING: at kernel/sched.c:5071 2.6.23-rc1-rt7.
-- patches.rt/cputimer-thread-rt_A0.patch: Linux-RT 2.6.27-RT.
-- patches.rt/dev-queue-xmit-preempt-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-ist-x86_64.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-run-softirq-from-hardirq-completely.patch:
- Linux-RT 2.6.27-RT
- Disable running softirqs from hardirqs completely!.
-- patches.rt/dont-disable-preemption-without-IST.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/dont-unmask-io_apic.patch: Linux-RT 2.6.27-RT.
-- patches.rt/drain-all-local-pages-via-sched.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/event-trace-hrtimer-trace.patch: Linux-RT 2.6.27-RT
- event-tracer: add clockevent trace.
-- patches.rt/event-tracer-syscall-x86_64.patch: Linux-RT
|
[-]
[+]
|
Deleted |
kernel-rt_debug.changes
^
|
@@ -1,44467 +0,0 @@
--------------------------------------------------------------------
-Sun Nov 2 01:05:36 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
- Use raw_smp_processor_id in __mem_cgroup_stat_add_safe.
-
--------------------------------------------------------------------
-Sun Nov 2 01:03:00 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
-
--------------------------------------------------------------------
-Sun Nov 2 00:12:04 CET 2008 - sdietrich@suse.de
-
-- patches.rt/workqueue-introduce-create_rt_workqueue.patch:
- workqueue: introduce create_rt_workqueue. (from 2.6.28)
-Refresh to eliminate fuzz:
- - patches.rt/preempt-realtime-core.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 23:41:00 CET 2008 - sdietrich@suse.de
-
-- Update RT config files:
- - Sync with SLES 11 default/debug configs
- - Limit CPUS to 32
- - Disable CONFIG_RADIX_TREE_CONCURRENT
- - Disable CONFIG_RADIX_TREE_OPTIMISTIC
- - Disable CONFIG_PREEMPT_RCU_BOOST
- - Enable CONFIG_RTMUTEX_CHECK
-
-- Adapt RT patches to changes made by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/mitigate-resched-flood-update.patch: Update
- smp_send_reschedule_allbutself_cpumask mask parameter.
- - patches.rt/x86-nmi-send_IPI_mask-pointer-fix.patch: Update
- smp_send_nmi_allbutself mask parameter.
-
-Resolve conflicts introduced by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/nmi-profiling-base.patch
- - patches.rt/send-nmi-all-preempt-disable.patch
-
-Refresh to eliminate fuzz
-- patches.rt/apic-dumpstack.patch: Linux-RT 2.6.27-RT.
-- patches.rt/mitigate-resched-flood.patch: Linux-RT 2.6.27-RT.
-- patches.rt/preempt-realtime-x86_64.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 08:32:52 CET 2008 - bwalle@suse.de
-
-- patches.fixes/kdb-fix-stack-overflow.patch:
- kdb: fix stack overflow for large NR_CPUS count (bnc#440361).
-
--------------------------------------------------------------------
-Fri Oct 31 18:41:23 CET 2008 - trenn@suse.de
-
-Fate 304268 and 304266. SGI scir driver (replaces the more intrusive
-leds one) and the rather intrusive x86_64 4096 CPU support patches:
-
-- Update config files.
-- patches.arch/x86_uv_early_detect.patch: Delete hacks that were
- necessary while waiting for x2apic code. (bnc#429984).
-- patches.arch/x86_sgi-uv-scir.patch: SGI X86 UV: Provide a
- System Activity Indicator driver (FATE304268 bnc#426066).
-- patches.arch/x86_sgi_cpus4096-01-fix-smp_call_function.patch:
- smp: reduce stack requirements for smp_call_function_mask
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-02-fix-send_call_func_ip.patch:
- x86: reduce stack requirements for send_call_func_ipi
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-05-update-send_IPI_mask.patch:
- x86 cpumask: Updates to support NR_CPUS=4096 (bnc#425240
- FATE304266).
-- patches.arch/x86_sgi_cpus4096-06-optimize-cpumask-in-sched_c.patch:
- Additional cpumask fixups (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-04-add-for_each_cpu_mask_and.patch:
- Add for_each_cpu_mask_and (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-07_pae_compile_fixups.patch:
- more cpumask cleanups for previous (x86_sgi_cpu4096..) patches
- (Additional cpumask fixups).
-- patches.suse/kdb-x86: kdb-v4.4-2.6.27-rc8-x86-1 (FATE#303971).
-- patches.xen/xen3-patch-2.6.27: Linux: Update to 2.6.27.
-- patches.xen/x86_sgi_xen-x86-cpus4096.patch: x86 cpumask xen:
- Updates to support NR_CPUS=4096 (Additional cpumask fixups).
-
--------------------------------------------------------------------
-Fri Oct 31 17:57:22 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-realtek-alc269-dmic: ALSA: hda -
- Add digital-mic for ALC269 auto-probe mode (bnc#440626).
-- patches.drivers/alsa-hda-realtek-mic-automute-fix: ALSA: hda -
- Disable broken mic auto-muting in Realtek codes (bnc#440626).
-
--------------------------------------------------------------------
-Fri Oct 31 12:34:44 CET 2008 - hare@suse.de
-
-- Update config files.
-- patches.drivers/cxgb3i: add cxgb3i iscsi driver
- (FATE#304154,bnc#433500).
-- patches.drivers/cxgb3-private-iscsi-ip-addresses: cxgb3 -
- manage private iSCSI IP addresses (FATE#304154,bnc#433500).
-- patches.drivers/open-iscsi-offloading-support: support for iscsi
- pdu digest offload and payload DDP. (FATE#304154,bnc#433500).
-- patches.fixes/cxgb3-remove-duplicate-tests-in-lro: cxgb3 -
- remove duplicate tests in lro (FATE#304154, bnc#430538).
-- supported.conf: Mark cxgb3i as supported.
-
--------------------------------------------------------------------
-Fri Oct 31 10:08:17 CET 2008 - bwalle@suse.de
-
-- patches.suse/kdb-resolve-uv-conflict.diff:
- Resolve KDB conflicts with UV (bnc#440376).
-
--------------------------------------------------------------------
-Fri Oct 31 09:04:16 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-sigmatel-spdif-fix: ALSA: hda -
- Fix SPDIF mute on IDT/STAC codecs.
-- patches.drivers/alsa-hda-reboot-notifier: ALSA: hda - Add
- reboot notifier.
-
--------------------------------------------------------------------
-Fri Oct 31 08:33:45 CET 2008 - jack@suse.cz
-
-- patches.suse/ocfs2-Fix-mount-cleanup-after-quota-failure.patch:
- ocfs2: Fix mount cleanup after quota failure (fate#302681).
-- patches.suse/ocfs2-Fix-oop-in-recovery-without-quotas:
- ocfs2: Fix recovery of nodes when quota feature is disabled
- (fate#302681).
-- patches.suse/ocfs2-Fix-grace-time-syncing.patch: ocfs2: Fix
- grace time syncing (fate#302681).
-
--------------------------------------------------------------------
-Fri Oct 31 01:28:20 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-del-timer-after-dequeue: blk: move
- blk_delete_timer call in end_that_request_last (bnc#440076
- bnc#440173).
-
--------------------------------------------------------------------
-Thu Oct 30 23:19:43 CET 2008 - trenn@suse.de
-
-- patches.arch/x86_agpgart-g33-stoeln-fix-2.patch: Avoid oops
- on G33 in 1MB stolen Mem case (bnc#391261).
-
--------------------------------------------------------------------
-Thu Oct 30 16:53:09 CET 2008 - gregkh@suse.de
-
-- patches.fixes/agp-fix-stolen-memory-counting-on-g4x.patch:
- agp: Fix stolen memory counting on G4X. (bnc#437618).
-
--------------------------------------------------------------------
-Thu Oct 30 13:44:43 CET 2008 - oneukum@suse.de
-
-- patches.fixes/sd_liberal_28_sense_invalid.diff: fix medium
- presence misdetection in usb storage device (bnc#362850).
-
--------------------------------------------------------------------
-Thu Oct 30 10:17:19 CET 2008 - olh@suse.de
-
-- add patches.fixes/scsi-ibmvscsi-show-config.patch
- use 4k buffer to transfer config data (439970 - LTC49349)
-
--------------------------------------------------------------------
-Thu Oct 30 06:02:17 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-add-timeout-on-dequeue: block: add timer
- on blkdev_dequeue_request() not elv_next_request() (bnc#440076).
-
--------------------------------------------------------------------
-Wed Oct 29 18:41:36 CET 2008 - sdietrich@suse.de
-
-Refresh RT patches:
-- patches.rt/adaptive-spinlock-lite-v2.patch: Linux-RT 2.6.27-RT
- adaptive spinlocks lite.
-- patches.rt/adaptive-task-oncpu.patch: Linux-RT 2.6.27-RT.
-- patches.rt/apic-level-smp-affinity.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-state-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-uptodate-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bz235099-idle-load-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/check-for-migration-during-push.patch: RT: fix
- push_rt_task() to handle dequeue_pushable properly.
-- patches.rt/cond_resched_softirq-WARN-fix.patch: Linux-RT
- 2.6.27-RT
- WARNING: at kernel/sched.c:5071 2.6.23-rc1-rt7.
-- patches.rt/cputimer-thread-rt_A0.patch: Linux-RT 2.6.27-RT.
-- patches.rt/dev-queue-xmit-preempt-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-ist-x86_64.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-run-softirq-from-hardirq-completely.patch:
- Linux-RT 2.6.27-RT
- Disable running softirqs from hardirqs completely!.
-- patches.rt/dont-disable-preemption-without-IST.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/dont-unmask-io_apic.patch: Linux-RT 2.6.27-RT.
-- patches.rt/drain-all-local-pages-via-sched.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/event-trace-hrtimer-trace.patch: Linux-RT 2.6.27-RT
- event-tracer: add clockevent trace.
-- patches.rt/event-tracer-syscall-x86_64.patch: Linux-RT
|
[-]
[+]
|
Changed |
kernel-s390.changes
^
|
|
[-]
[+]
|
Deleted |
kernel-source-rt.changes
^
|
@@ -1,44467 +0,0 @@
--------------------------------------------------------------------
-Sun Nov 2 01:05:36 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
- Use raw_smp_processor_id in __mem_cgroup_stat_add_safe.
-
--------------------------------------------------------------------
-Sun Nov 2 01:03:00 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
-
--------------------------------------------------------------------
-Sun Nov 2 00:12:04 CET 2008 - sdietrich@suse.de
-
-- patches.rt/workqueue-introduce-create_rt_workqueue.patch:
- workqueue: introduce create_rt_workqueue. (from 2.6.28)
-Refresh to eliminate fuzz:
- - patches.rt/preempt-realtime-core.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 23:41:00 CET 2008 - sdietrich@suse.de
-
-- Update RT config files:
- - Sync with SLES 11 default/debug configs
- - Limit CPUS to 32
- - Disable CONFIG_RADIX_TREE_CONCURRENT
- - Disable CONFIG_RADIX_TREE_OPTIMISTIC
- - Disable CONFIG_PREEMPT_RCU_BOOST
- - Enable CONFIG_RTMUTEX_CHECK
-
-- Adapt RT patches to changes made by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/mitigate-resched-flood-update.patch: Update
- smp_send_reschedule_allbutself_cpumask mask parameter.
- - patches.rt/x86-nmi-send_IPI_mask-pointer-fix.patch: Update
- smp_send_nmi_allbutself mask parameter.
-
-Resolve conflicts introduced by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/nmi-profiling-base.patch
- - patches.rt/send-nmi-all-preempt-disable.patch
-
-Refresh to eliminate fuzz
-- patches.rt/apic-dumpstack.patch: Linux-RT 2.6.27-RT.
-- patches.rt/mitigate-resched-flood.patch: Linux-RT 2.6.27-RT.
-- patches.rt/preempt-realtime-x86_64.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 08:32:52 CET 2008 - bwalle@suse.de
-
-- patches.fixes/kdb-fix-stack-overflow.patch:
- kdb: fix stack overflow for large NR_CPUS count (bnc#440361).
-
--------------------------------------------------------------------
-Fri Oct 31 18:41:23 CET 2008 - trenn@suse.de
-
-Fate 304268 and 304266. SGI scir driver (replaces the more intrusive
-leds one) and the rather intrusive x86_64 4096 CPU support patches:
-
-- Update config files.
-- patches.arch/x86_uv_early_detect.patch: Delete hacks that were
- necessary while waiting for x2apic code. (bnc#429984).
-- patches.arch/x86_sgi-uv-scir.patch: SGI X86 UV: Provide a
- System Activity Indicator driver (FATE304268 bnc#426066).
-- patches.arch/x86_sgi_cpus4096-01-fix-smp_call_function.patch:
- smp: reduce stack requirements for smp_call_function_mask
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-02-fix-send_call_func_ip.patch:
- x86: reduce stack requirements for send_call_func_ipi
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-05-update-send_IPI_mask.patch:
- x86 cpumask: Updates to support NR_CPUS=4096 (bnc#425240
- FATE304266).
-- patches.arch/x86_sgi_cpus4096-06-optimize-cpumask-in-sched_c.patch:
- Additional cpumask fixups (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-04-add-for_each_cpu_mask_and.patch:
- Add for_each_cpu_mask_and (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-07_pae_compile_fixups.patch:
- more cpumask cleanups for previous (x86_sgi_cpu4096..) patches
- (Additional cpumask fixups).
-- patches.suse/kdb-x86: kdb-v4.4-2.6.27-rc8-x86-1 (FATE#303971).
-- patches.xen/xen3-patch-2.6.27: Linux: Update to 2.6.27.
-- patches.xen/x86_sgi_xen-x86-cpus4096.patch: x86 cpumask xen:
- Updates to support NR_CPUS=4096 (Additional cpumask fixups).
-
--------------------------------------------------------------------
-Fri Oct 31 17:57:22 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-realtek-alc269-dmic: ALSA: hda -
- Add digital-mic for ALC269 auto-probe mode (bnc#440626).
-- patches.drivers/alsa-hda-realtek-mic-automute-fix: ALSA: hda -
- Disable broken mic auto-muting in Realtek codes (bnc#440626).
-
--------------------------------------------------------------------
-Fri Oct 31 12:34:44 CET 2008 - hare@suse.de
-
-- Update config files.
-- patches.drivers/cxgb3i: add cxgb3i iscsi driver
- (FATE#304154,bnc#433500).
-- patches.drivers/cxgb3-private-iscsi-ip-addresses: cxgb3 -
- manage private iSCSI IP addresses (FATE#304154,bnc#433500).
-- patches.drivers/open-iscsi-offloading-support: support for iscsi
- pdu digest offload and payload DDP. (FATE#304154,bnc#433500).
-- patches.fixes/cxgb3-remove-duplicate-tests-in-lro: cxgb3 -
- remove duplicate tests in lro (FATE#304154, bnc#430538).
-- supported.conf: Mark cxgb3i as supported.
-
--------------------------------------------------------------------
-Fri Oct 31 10:08:17 CET 2008 - bwalle@suse.de
-
-- patches.suse/kdb-resolve-uv-conflict.diff:
- Resolve KDB conflicts with UV (bnc#440376).
-
--------------------------------------------------------------------
-Fri Oct 31 09:04:16 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-sigmatel-spdif-fix: ALSA: hda -
- Fix SPDIF mute on IDT/STAC codecs.
-- patches.drivers/alsa-hda-reboot-notifier: ALSA: hda - Add
- reboot notifier.
-
--------------------------------------------------------------------
-Fri Oct 31 08:33:45 CET 2008 - jack@suse.cz
-
-- patches.suse/ocfs2-Fix-mount-cleanup-after-quota-failure.patch:
- ocfs2: Fix mount cleanup after quota failure (fate#302681).
-- patches.suse/ocfs2-Fix-oop-in-recovery-without-quotas:
- ocfs2: Fix recovery of nodes when quota feature is disabled
- (fate#302681).
-- patches.suse/ocfs2-Fix-grace-time-syncing.patch: ocfs2: Fix
- grace time syncing (fate#302681).
-
--------------------------------------------------------------------
-Fri Oct 31 01:28:20 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-del-timer-after-dequeue: blk: move
- blk_delete_timer call in end_that_request_last (bnc#440076
- bnc#440173).
-
--------------------------------------------------------------------
-Thu Oct 30 23:19:43 CET 2008 - trenn@suse.de
-
-- patches.arch/x86_agpgart-g33-stoeln-fix-2.patch: Avoid oops
- on G33 in 1MB stolen Mem case (bnc#391261).
-
--------------------------------------------------------------------
-Thu Oct 30 16:53:09 CET 2008 - gregkh@suse.de
-
-- patches.fixes/agp-fix-stolen-memory-counting-on-g4x.patch:
- agp: Fix stolen memory counting on G4X. (bnc#437618).
-
--------------------------------------------------------------------
-Thu Oct 30 13:44:43 CET 2008 - oneukum@suse.de
-
-- patches.fixes/sd_liberal_28_sense_invalid.diff: fix medium
- presence misdetection in usb storage device (bnc#362850).
-
--------------------------------------------------------------------
-Thu Oct 30 10:17:19 CET 2008 - olh@suse.de
-
-- add patches.fixes/scsi-ibmvscsi-show-config.patch
- use 4k buffer to transfer config data (439970 - LTC49349)
-
--------------------------------------------------------------------
-Thu Oct 30 06:02:17 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-add-timeout-on-dequeue: block: add timer
- on blkdev_dequeue_request() not elv_next_request() (bnc#440076).
-
--------------------------------------------------------------------
-Wed Oct 29 18:41:36 CET 2008 - sdietrich@suse.de
-
-Refresh RT patches:
-- patches.rt/adaptive-spinlock-lite-v2.patch: Linux-RT 2.6.27-RT
- adaptive spinlocks lite.
-- patches.rt/adaptive-task-oncpu.patch: Linux-RT 2.6.27-RT.
-- patches.rt/apic-level-smp-affinity.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-state-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-uptodate-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bz235099-idle-load-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/check-for-migration-during-push.patch: RT: fix
- push_rt_task() to handle dequeue_pushable properly.
-- patches.rt/cond_resched_softirq-WARN-fix.patch: Linux-RT
- 2.6.27-RT
- WARNING: at kernel/sched.c:5071 2.6.23-rc1-rt7.
-- patches.rt/cputimer-thread-rt_A0.patch: Linux-RT 2.6.27-RT.
-- patches.rt/dev-queue-xmit-preempt-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-ist-x86_64.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-run-softirq-from-hardirq-completely.patch:
- Linux-RT 2.6.27-RT
- Disable running softirqs from hardirqs completely!.
-- patches.rt/dont-disable-preemption-without-IST.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/dont-unmask-io_apic.patch: Linux-RT 2.6.27-RT.
-- patches.rt/drain-all-local-pages-via-sched.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/event-trace-hrtimer-trace.patch: Linux-RT 2.6.27-RT
- event-tracer: add clockevent trace.
-- patches.rt/event-tracer-syscall-x86_64.patch: Linux-RT
|
[-]
[+]
|
Changed |
kernel-source.changes
^
|
|
[-]
[+]
|
Deleted |
kernel-syms-rt.changes
^
|
@@ -1,44467 +0,0 @@
--------------------------------------------------------------------
-Sun Nov 2 01:05:36 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
- Use raw_smp_processor_id in __mem_cgroup_stat_add_safe.
-
--------------------------------------------------------------------
-Sun Nov 2 01:03:00 CET 2008 - sdietrich@suse.de
-
-- patches.rt/mem_cgroup_charge_statistics-smp_processor_id.patch:
-
--------------------------------------------------------------------
-Sun Nov 2 00:12:04 CET 2008 - sdietrich@suse.de
-
-- patches.rt/workqueue-introduce-create_rt_workqueue.patch:
- workqueue: introduce create_rt_workqueue. (from 2.6.28)
-Refresh to eliminate fuzz:
- - patches.rt/preempt-realtime-core.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 23:41:00 CET 2008 - sdietrich@suse.de
-
-- Update RT config files:
- - Sync with SLES 11 default/debug configs
- - Limit CPUS to 32
- - Disable CONFIG_RADIX_TREE_CONCURRENT
- - Disable CONFIG_RADIX_TREE_OPTIMISTIC
- - Disable CONFIG_PREEMPT_RCU_BOOST
- - Enable CONFIG_RTMUTEX_CHECK
-
-- Adapt RT patches to changes made by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/mitigate-resched-flood-update.patch: Update
- smp_send_reschedule_allbutself_cpumask mask parameter.
- - patches.rt/x86-nmi-send_IPI_mask-pointer-fix.patch: Update
- smp_send_nmi_allbutself mask parameter.
-
-Resolve conflicts introduced by:
- x86_sgi_cpus4096-05-update-send_IPI_mask.patch
- - patches.rt/nmi-profiling-base.patch
- - patches.rt/send-nmi-all-preempt-disable.patch
-
-Refresh to eliminate fuzz
-- patches.rt/apic-dumpstack.patch: Linux-RT 2.6.27-RT.
-- patches.rt/mitigate-resched-flood.patch: Linux-RT 2.6.27-RT.
-- patches.rt/preempt-realtime-x86_64.patch: Linux-RT 2.6.27-RT.
-
--------------------------------------------------------------------
-Sat Nov 1 08:32:52 CET 2008 - bwalle@suse.de
-
-- patches.fixes/kdb-fix-stack-overflow.patch:
- kdb: fix stack overflow for large NR_CPUS count (bnc#440361).
-
--------------------------------------------------------------------
-Fri Oct 31 18:41:23 CET 2008 - trenn@suse.de
-
-Fate 304268 and 304266. SGI scir driver (replaces the more intrusive
-leds one) and the rather intrusive x86_64 4096 CPU support patches:
-
-- Update config files.
-- patches.arch/x86_uv_early_detect.patch: Delete hacks that were
- necessary while waiting for x2apic code. (bnc#429984).
-- patches.arch/x86_sgi-uv-scir.patch: SGI X86 UV: Provide a
- System Activity Indicator driver (FATE304268 bnc#426066).
-- patches.arch/x86_sgi_cpus4096-01-fix-smp_call_function.patch:
- smp: reduce stack requirements for smp_call_function_mask
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-02-fix-send_call_func_ip.patch:
- x86: reduce stack requirements for send_call_func_ipi
- (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-05-update-send_IPI_mask.patch:
- x86 cpumask: Updates to support NR_CPUS=4096 (bnc#425240
- FATE304266).
-- patches.arch/x86_sgi_cpus4096-06-optimize-cpumask-in-sched_c.patch:
- Additional cpumask fixups (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-04-add-for_each_cpu_mask_and.patch:
- Add for_each_cpu_mask_and (bnc#425240 FATE304266).
-- patches.arch/x86_sgi_cpus4096-07_pae_compile_fixups.patch:
- more cpumask cleanups for previous (x86_sgi_cpu4096..) patches
- (Additional cpumask fixups).
-- patches.suse/kdb-x86: kdb-v4.4-2.6.27-rc8-x86-1 (FATE#303971).
-- patches.xen/xen3-patch-2.6.27: Linux: Update to 2.6.27.
-- patches.xen/x86_sgi_xen-x86-cpus4096.patch: x86 cpumask xen:
- Updates to support NR_CPUS=4096 (Additional cpumask fixups).
-
--------------------------------------------------------------------
-Fri Oct 31 17:57:22 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-realtek-alc269-dmic: ALSA: hda -
- Add digital-mic for ALC269 auto-probe mode (bnc#440626).
-- patches.drivers/alsa-hda-realtek-mic-automute-fix: ALSA: hda -
- Disable broken mic auto-muting in Realtek codes (bnc#440626).
-
--------------------------------------------------------------------
-Fri Oct 31 12:34:44 CET 2008 - hare@suse.de
-
-- Update config files.
-- patches.drivers/cxgb3i: add cxgb3i iscsi driver
- (FATE#304154,bnc#433500).
-- patches.drivers/cxgb3-private-iscsi-ip-addresses: cxgb3 -
- manage private iSCSI IP addresses (FATE#304154,bnc#433500).
-- patches.drivers/open-iscsi-offloading-support: support for iscsi
- pdu digest offload and payload DDP. (FATE#304154,bnc#433500).
-- patches.fixes/cxgb3-remove-duplicate-tests-in-lro: cxgb3 -
- remove duplicate tests in lro (FATE#304154, bnc#430538).
-- supported.conf: Mark cxgb3i as supported.
-
--------------------------------------------------------------------
-Fri Oct 31 10:08:17 CET 2008 - bwalle@suse.de
-
-- patches.suse/kdb-resolve-uv-conflict.diff:
- Resolve KDB conflicts with UV (bnc#440376).
-
--------------------------------------------------------------------
-Fri Oct 31 09:04:16 CET 2008 - tiwai@suse.de
-
-- patches.drivers/alsa-hda-sigmatel-spdif-fix: ALSA: hda -
- Fix SPDIF mute on IDT/STAC codecs.
-- patches.drivers/alsa-hda-reboot-notifier: ALSA: hda - Add
- reboot notifier.
-
--------------------------------------------------------------------
-Fri Oct 31 08:33:45 CET 2008 - jack@suse.cz
-
-- patches.suse/ocfs2-Fix-mount-cleanup-after-quota-failure.patch:
- ocfs2: Fix mount cleanup after quota failure (fate#302681).
-- patches.suse/ocfs2-Fix-oop-in-recovery-without-quotas:
- ocfs2: Fix recovery of nodes when quota feature is disabled
- (fate#302681).
-- patches.suse/ocfs2-Fix-grace-time-syncing.patch: ocfs2: Fix
- grace time syncing (fate#302681).
-
--------------------------------------------------------------------
-Fri Oct 31 01:28:20 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-del-timer-after-dequeue: blk: move
- blk_delete_timer call in end_that_request_last (bnc#440076
- bnc#440173).
-
--------------------------------------------------------------------
-Thu Oct 30 23:19:43 CET 2008 - trenn@suse.de
-
-- patches.arch/x86_agpgart-g33-stoeln-fix-2.patch: Avoid oops
- on G33 in 1MB stolen Mem case (bnc#391261).
-
--------------------------------------------------------------------
-Thu Oct 30 16:53:09 CET 2008 - gregkh@suse.de
-
-- patches.fixes/agp-fix-stolen-memory-counting-on-g4x.patch:
- agp: Fix stolen memory counting on G4X. (bnc#437618).
-
--------------------------------------------------------------------
-Thu Oct 30 13:44:43 CET 2008 - oneukum@suse.de
-
-- patches.fixes/sd_liberal_28_sense_invalid.diff: fix medium
- presence misdetection in usb storage device (bnc#362850).
-
--------------------------------------------------------------------
-Thu Oct 30 10:17:19 CET 2008 - olh@suse.de
-
-- add patches.fixes/scsi-ibmvscsi-show-config.patch
- use 4k buffer to transfer config data (439970 - LTC49349)
-
--------------------------------------------------------------------
-Thu Oct 30 06:02:17 CET 2008 - teheo@suse.de
-
-- patches.drivers/block-add-timeout-on-dequeue: block: add timer
- on blkdev_dequeue_request() not elv_next_request() (bnc#440076).
-
--------------------------------------------------------------------
-Wed Oct 29 18:41:36 CET 2008 - sdietrich@suse.de
-
-Refresh RT patches:
-- patches.rt/adaptive-spinlock-lite-v2.patch: Linux-RT 2.6.27-RT
- adaptive spinlocks lite.
-- patches.rt/adaptive-task-oncpu.patch: Linux-RT 2.6.27-RT.
-- patches.rt/apic-level-smp-affinity.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-state-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bh-uptodate-lock.patch: Linux-RT 2.6.27-RT.
-- patches.rt/bz235099-idle-load-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/check-for-migration-during-push.patch: RT: fix
- push_rt_task() to handle dequeue_pushable properly.
-- patches.rt/cond_resched_softirq-WARN-fix.patch: Linux-RT
- 2.6.27-RT
- WARNING: at kernel/sched.c:5071 2.6.23-rc1-rt7.
-- patches.rt/cputimer-thread-rt_A0.patch: Linux-RT 2.6.27-RT.
-- patches.rt/dev-queue-xmit-preempt-fix.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-ist-x86_64.patch: Linux-RT 2.6.27-RT.
-- patches.rt/disable-run-softirq-from-hardirq-completely.patch:
- Linux-RT 2.6.27-RT
- Disable running softirqs from hardirqs completely!.
-- patches.rt/dont-disable-preemption-without-IST.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/dont-unmask-io_apic.patch: Linux-RT 2.6.27-RT.
-- patches.rt/drain-all-local-pages-via-sched.patch: Linux-RT
- 2.6.27-RT.
-- patches.rt/event-trace-hrtimer-trace.patch: Linux-RT 2.6.27-RT
- event-tracer: add clockevent trace.
-- patches.rt/event-tracer-syscall-x86_64.patch: Linux-RT
|
[-]
[+]
|
Changed |
kernel-syms.changes
^
|
|
[-]
[+]
|
Changed |
kernel-trace.changes
^
|
|
[-]
[+]
|
Changed |
kernel-vanilla.changes
^
|
|
[-]
[+]
|
Changed |
kernel-xen.changes
^
|
|
[-]
[+]
|
Changed |
kernel-debug.spec
^
|
|
[-]
[+]
|
Changed |
kernel-default.spec
^
|
|
[-]
[+]
|
Changed |
kernel-dummy.spec
^
|
|
[-]
[+]
|
Changed |
kernel-kdump.spec
^
|
|
[-]
[+]
|
Changed |
kernel-pae.spec
^
|
|
[-]
[+]
|
Changed |
kernel-ppc64.spec
^
|
|
[-]
[+]
|
Changed |
kernel-ps3.spec
^
|
|
[-]
[+]
|
Deleted |
kernel-rt.spec
^
|
@@ -1,828 +0,0 @@
-#
-# spec file for package kernel-rt (Version 2.6.27.4)
-#
-# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
-# This file and all modifications and additions to the pristine
-# package are under the same license as the package itself.
-#
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
-#
-
-# norootforbuild
-
-%if 0%{?opensuse_bs}
-# Strip off the build number ("y") from the "x.y" release number
-%define source_rel %(release=%release; echo ${release%.*})
-%else
-# We don't have build numbers internally
-%define source_rel %release
-%endif
-
-# Don't use shell commands in build macros, this won't work outside of rpm
-%define build_flavor "rt"
-%define build_kdump 0
-%define build_xen 0
-%define build_um 0
-%define build_vanilla 0
-
-%if %{build_flavor} == "kdump"
-%define build_kdump 1
-%endif
-%if %{build_flavor} == "xen"
-%define build_xen 1
-%endif
-%if %{build_flavor} == "um"
-%define build_um 1
-%endif
-%if %{build_flavor} == "vanilla"
-%define build_vanilla 1
-%endif
-
-%(chmod +x %_sourcedir/{arch-symbols,guards,config-subst,check-for-config-changes,check-supported-list,built-in-where,find-provides,list-exported-symbols,split-into-symsets,modversions,kabi-checks})
-
-%define symbols %(set -- kernel-rt rt $(case rt in (rt|rt_*) echo RT ;; esac) $(%_sourcedir/arch-symbols %_target_cpu) $([ -e %_sourcedir/extra-symbols ] && cat %_sourcedir/extra-symbols) ; echo $*)
-%define subarch_flavor %(%_sourcedir/guards %symbols < %_sourcedir/config.conf | grep '/rt$')
-
-# Define some CONFIG variables as rpm macros as well. (rpm cannot handle
-# defining them all at once.)
-%define config_vars CONFIG_MODULES
-%{expand:%(eval "$(test -n "%subarch_flavor" && tar xfj %_sourcedir/config.tar.bz2 --to-stdout config/%subarch_flavor)"; for config in %config_vars; do echo "%%global $config ${!config:-n}"; done)}
-
-%if %build_vanilla || %build_kdump || %CONFIG_MODULES != "y"
-%define split_packages 0
-%else
-%define split_packages 1
-%endif
-
-Name: kernel-rt
-Summary: Dummy summary
-Version: 2.6.27.4
-Release: <RELEASE>
-License: GPL
-Group: System/Kernel
-Url: http://www.kernel.org/
-AutoReqProv: on
-BuildRequires: coreutils module-init-tools sparse
-BuildRequires: fdupes
-%if %split_packages
-Requires: kernel-rt-base = %version-%release
-%endif
-Requires(pre): coreutils awk
-Requires(post): module-init-tools
-# This Requires is wrong, because the post/postun scripts have a
-# test -x update-bootloader, having perl-Bootloader is not a hard requirement.
-# But, there is no way to tell rpm or yast to schedule the installation
-# of perl-Bootloader before kernel-binary.rpm if both are in the list of
-# packages to install/update. Likewise, this is true for mkinitrd.
-# A specific version of perl-Bootloader is not required, because the post/postun
-# scripts handle the two API versions of 10.1/SLES10 GA and 10.2/SLES10 SP1
-Requires(post): perl-Bootloader
-Requires(post): mkinitrd
-Recommends: kerneloops
-#!BuildIgnore: perl-Bootloader mkinitrd
-
-%if ! 0%{?opensuse_bs}
-BuildRequires: kernel-dummy
-%endif
-%if %build_um
-BuildRequires: libpcap xorg-x11-devel
-%endif
-%ifarch ia64
-# arch/ia64/scripts/unwcheck.py
-BuildRequires: python
-%endif
-%ifarch ppc ppc64
-# for PS3 zImage
-BuildRequires: dtc
-%endif
-%if %build_xen
-%ifarch %ix86
-Provides: kernel-xenpae = 2.6.27.4
-Obsoletes: kernel-xenpae <= 2.6.27.4
-%endif
-#!BuildIgnore: xen
-%endif
-
-Provides: kernel-rt-nongpl
-Obsoletes: kernel-rt-nongpl
-%if %build_vanilla
-# force bzip2 instead of lzma compression to allow install on older dist versions
-%define _binary_payload w9.bzdio
-%endif
-# dead network if installed on SLES10, otherwise it will work (mostly)
-Conflicts: sysfsutils < 2.0
-%if ! %build_vanilla
-Conflicts: apparmor-profiles <= 2.1
-Conflicts: apparmor-parser < 2.3
-# root-lvm only works with newer udevs
-Conflicts: udev < 118
-Conflicts: lvm2 < 2.02.33
-%endif
-%ifarch %ix86
-Conflicts: libc.so.6()(64bit)
-%endif
-%if %build_um
-#Conflicts: kernel
-%else
-Provides: kernel = 2.6.27.4-%source_rel
-%endif
-%ifarch %ix86
-%else
-%ifarch x86_64
-%endif
-%endif
-
-Source0: http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.tar.bz2
-Source10: preun.sh
-Source11: postun.sh
-Source12: pre.sh
-Source13: post.sh
-Source20: series.conf
-Source21: config.conf
-Source22: supported.conf
-Source30: arch-symbols
-Source31: guards
-Source32: config-subst
-Source33: check-for-config-changes
-Source34: check-supported-list
-Source38: kabi-checks
-Source40: build-source-timestamp
-Source41: built-in-where
-Source42: list-exported-symbols
-Source43: split-into-symsets
-Source44: find-provides
-Source45: module-renames
-Source46: modversions
-Source100: config.tar.bz2
-Source101: patches.arch.tar.bz2
-Source102: patches.drivers.tar.bz2
-Source103: patches.fixes.tar.bz2
-Source104: patches.rpmify.tar.bz2
-Source105: patches.suse.tar.bz2
-Source107: patches.xen.tar.bz2
-Source108: patches.addon.tar.bz2
-Source109: patches.kernel.org.tar.bz2
-Source110: patches.apparmor.tar.bz2
-Source111: patches.rt.tar.bz2
-Source112: patches.trace.tar.bz2
-Source120: kabi.tar.bz2
-%define my_builddir %_builddir/%{name}-%{version}
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-ExclusiveArch: %ix86 x86_64
-
-# These files are found in the kernel-source package:
-NoSource: 0
-NoSource: 100
-NoSource: 101
-NoSource: 102
-NoSource: 103
-NoSource: 104
-NoSource: 105
-NoSource: 107
-NoSource: 108
-NoSource: 109
-NoSource: 110
-NoSource: 111
-NoSource: 120
-
-# The following KMPs have been integrated into the kernel package.
-Obsoletes: iwlwifi-kmp
-Obsoletes: ipw3945-kmp
-Obsoletes: adm8211-kmp
-Obsoletes: rt2x00-kmp
-Obsoletes: rfswitch-kmp
-Obsoletes: uvcvideo-kmp
-Obsoletes: atl2-kmp
-Obsoletes: wlan-ng-kmp
-Obsoletes: et131x-kmp
-Obsoletes: ivtv-kmp
-Obsoletes: at76_usb-kmp
|
[-]
[+]
|
Deleted |
kernel-rt_debug.spec
^
|
@@ -1,828 +0,0 @@
-#
-# spec file for package kernel-rt_debug (Version 2.6.27.4)
-#
-# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
-# This file and all modifications and additions to the pristine
-# package are under the same license as the package itself.
-#
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
-#
-
-# norootforbuild
-
-%if 0%{?opensuse_bs}
-# Strip off the build number ("y") from the "x.y" release number
-%define source_rel %(release=%release; echo ${release%.*})
-%else
-# We don't have build numbers internally
-%define source_rel %release
-%endif
-
-# Don't use shell commands in build macros, this won't work outside of rpm
-%define build_flavor "rt_debug"
-%define build_kdump 0
-%define build_xen 0
-%define build_um 0
-%define build_vanilla 0
-
-%if %{build_flavor} == "kdump"
-%define build_kdump 1
-%endif
-%if %{build_flavor} == "xen"
-%define build_xen 1
-%endif
-%if %{build_flavor} == "um"
-%define build_um 1
-%endif
-%if %{build_flavor} == "vanilla"
-%define build_vanilla 1
-%endif
-
-%(chmod +x %_sourcedir/{arch-symbols,guards,config-subst,check-for-config-changes,check-supported-list,built-in-where,find-provides,list-exported-symbols,split-into-symsets,modversions,kabi-checks})
-
-%define symbols %(set -- kernel-rt_debug rt_debug $(case rt_debug in (rt|rt_*) echo RT ;; esac) $(%_sourcedir/arch-symbols %_target_cpu) $([ -e %_sourcedir/extra-symbols ] && cat %_sourcedir/extra-symbols) ; echo $*)
-%define subarch_flavor %(%_sourcedir/guards %symbols < %_sourcedir/config.conf | grep '/rt_debug$')
-
-# Define some CONFIG variables as rpm macros as well. (rpm cannot handle
-# defining them all at once.)
-%define config_vars CONFIG_MODULES
-%{expand:%(eval "$(test -n "%subarch_flavor" && tar xfj %_sourcedir/config.tar.bz2 --to-stdout config/%subarch_flavor)"; for config in %config_vars; do echo "%%global $config ${!config:-n}"; done)}
-
-%if %build_vanilla || %build_kdump || %CONFIG_MODULES != "y"
-%define split_packages 0
-%else
-%define split_packages 1
-%endif
-
-Name: kernel-rt_debug
-Summary: Dummy summary
-Version: 2.6.27.4
-Release: <RELEASE>
-License: GPL
-Group: System/Kernel
-Url: http://www.kernel.org/
-AutoReqProv: on
-BuildRequires: coreutils module-init-tools sparse
-BuildRequires: fdupes
-%if %split_packages
-Requires: kernel-rt_debug-base = %version-%release
-%endif
-Requires(pre): coreutils awk
-Requires(post): module-init-tools
-# This Requires is wrong, because the post/postun scripts have a
-# test -x update-bootloader, having perl-Bootloader is not a hard requirement.
-# But, there is no way to tell rpm or yast to schedule the installation
-# of perl-Bootloader before kernel-binary.rpm if both are in the list of
-# packages to install/update. Likewise, this is true for mkinitrd.
-# A specific version of perl-Bootloader is not required, because the post/postun
-# scripts handle the two API versions of 10.1/SLES10 GA and 10.2/SLES10 SP1
-Requires(post): perl-Bootloader
-Requires(post): mkinitrd
-Recommends: kerneloops
-#!BuildIgnore: perl-Bootloader mkinitrd
-
-%if ! 0%{?opensuse_bs}
-BuildRequires: kernel-dummy
-%endif
-%if %build_um
-BuildRequires: libpcap xorg-x11-devel
-%endif
-%ifarch ia64
-# arch/ia64/scripts/unwcheck.py
-BuildRequires: python
-%endif
-%ifarch ppc ppc64
-# for PS3 zImage
-BuildRequires: dtc
-%endif
-%if %build_xen
-%ifarch %ix86
-Provides: kernel-xenpae = 2.6.27.4
-Obsoletes: kernel-xenpae <= 2.6.27.4
-%endif
-#!BuildIgnore: xen
-%endif
-
-Provides: kernel-rt_debug-nongpl
-Obsoletes: kernel-rt_debug-nongpl
-%if %build_vanilla
-# force bzip2 instead of lzma compression to allow install on older dist versions
-%define _binary_payload w9.bzdio
-%endif
-# dead network if installed on SLES10, otherwise it will work (mostly)
-Conflicts: sysfsutils < 2.0
-%if ! %build_vanilla
-Conflicts: apparmor-profiles <= 2.1
-Conflicts: apparmor-parser < 2.3
-# root-lvm only works with newer udevs
-Conflicts: udev < 118
-Conflicts: lvm2 < 2.02.33
-%endif
-%ifarch %ix86
-Conflicts: libc.so.6()(64bit)
-%endif
-%if %build_um
-#Conflicts: kernel
-%else
-Provides: kernel = 2.6.27.4-%source_rel
-%endif
-%ifarch %ix86
-%else
-%ifarch x86_64
-%endif
-%endif
-
-Source0: http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.tar.bz2
-Source10: preun.sh
-Source11: postun.sh
-Source12: pre.sh
-Source13: post.sh
-Source20: series.conf
-Source21: config.conf
-Source22: supported.conf
-Source30: arch-symbols
-Source31: guards
-Source32: config-subst
-Source33: check-for-config-changes
-Source34: check-supported-list
-Source38: kabi-checks
-Source40: build-source-timestamp
-Source41: built-in-where
-Source42: list-exported-symbols
-Source43: split-into-symsets
-Source44: find-provides
-Source45: module-renames
-Source46: modversions
-Source100: config.tar.bz2
-Source101: patches.arch.tar.bz2
-Source102: patches.drivers.tar.bz2
-Source103: patches.fixes.tar.bz2
-Source104: patches.rpmify.tar.bz2
-Source105: patches.suse.tar.bz2
-Source107: patches.xen.tar.bz2
-Source108: patches.addon.tar.bz2
-Source109: patches.kernel.org.tar.bz2
-Source110: patches.apparmor.tar.bz2
-Source111: patches.rt.tar.bz2
-Source112: patches.trace.tar.bz2
-Source120: kabi.tar.bz2
-%define my_builddir %_builddir/%{name}-%{version}
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-ExclusiveArch: %ix86 x86_64
-
-# These files are found in the kernel-source package:
-NoSource: 0
-NoSource: 100
-NoSource: 101
-NoSource: 102
-NoSource: 103
-NoSource: 104
-NoSource: 105
-NoSource: 107
-NoSource: 108
-NoSource: 109
-NoSource: 110
-NoSource: 111
-NoSource: 120
-
-# The following KMPs have been integrated into the kernel package.
-Obsoletes: iwlwifi-kmp
-Obsoletes: ipw3945-kmp
-Obsoletes: adm8211-kmp
-Obsoletes: rt2x00-kmp
-Obsoletes: rfswitch-kmp
-Obsoletes: uvcvideo-kmp
-Obsoletes: atl2-kmp
-Obsoletes: wlan-ng-kmp
-Obsoletes: et131x-kmp
-Obsoletes: ivtv-kmp
-Obsoletes: at76_usb-kmp
|
[-]
[+]
|
Changed |
kernel-s390.spec
^
|
|
[-]
[+]
|
Deleted |
kernel-source-rt.spec
^
|
@@ -1,307 +0,0 @@
-#
-# spec file for package kernel-source-rt (Version 2.6.27.4)
-#
-# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
-# This file and all modifications and additions to the pristine
-# package are under the same license as the package itself.
-#
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
-#
-
-# norootforbuild
-# icecream 0
-
-# FIXME: this check will go before the next release ...
-
-%if 0%{?opensuse_bs}
-# Strip off the build number ("y") from the "x.y" release number
-%define source_rel %(release=%release; echo ${release%.*})
-%else
-# We don't have build numbers internally
-%define source_rel %release
-%endif
-
-Name: kernel-source-rt
-Summary: Dummy summary
-Version: 2.6.27.4
-Release: <RELEASE>
-License: GPL
-Group: Development/Sources
-AutoReqProv: off
-BuildRequires: coreutils sed
-BuildRequires: fdupes
-Requires(post): coreutils sed
-%if ! 0%{?opensuse_bs}
-BuildRequires: kernel-dummy
-%endif
-ExclusiveArch: %ix86 x86_64
-Provides: linux
-Provides: kernel-source-rt = 2.6.27.4-%source_rel
-%if "kernel-source-rt" == "kernel-source"
-Provides: linux lx_suse lx_sus22 lx_sus24
-Obsoletes: linux lx-gdt lx-hack lx-suse lx1162_1 lx1162_2 lx1212_1 lx1212_2 lx1213_1 lx1213_2 lx121_1 lx121_2 lx126_1 lx126_2 lx129_1 lx129_2 lx_large kernel_headers lx_suse lx_sus22 lx_sus24
-%endif
-Source0: http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.tar.bz2
-Source1: source-post.sh
-Source2: kernel-source-rt.rpmlintrc
-Source10: preun.sh
-Source11: postun.sh
-Source12: pre.sh
-Source13: post.sh
-Source14: series.conf
-Source15: arch-symbols
-Source16: guards
-Source21: config.conf
-Source23: supported.conf
-Source30: config-subst
-Source33: check-for-config-changes
-Source34: check-supported-list
-Source37: README.SUSE
-Source38: kabi-checks
-Source40: build-source-timestamp
-Source41: built-in-where
-Source42: list-exported-symbols
-Source43: split-into-symsets
-Source44: find-provides
-Source45: module-renames
-Source46: modversions
-Source47: extract-modaliases
-Source48: macros.kernel-source
-Source49: kernel-module-subpackage
-Source50: kernel-syms.spec
-Source51: kernel-debug.spec
-Source52: kernel-default.spec
-Source53: kernel-kdump.spec
-Source54: kernel-pae.spec
-Source55: kernel-ppc64.spec
-Source56: kernel-ps3.spec
-Source57: kernel-rt.spec
-Source58: kernel-rt_debug.spec
-Source59: kernel-s390.spec
-Source60: kernel-trace.spec
-Source61: kernel-vanilla.spec
-Source62: kernel-xen.spec
-Source100: config.tar.bz2
-Source101: patches.arch.tar.bz2
-Source102: patches.drivers.tar.bz2
-Source103: patches.fixes.tar.bz2
-Source104: patches.rpmify.tar.bz2
-Source105: patches.suse.tar.bz2
-Source107: patches.xen.tar.bz2
-Source108: patches.addon.tar.bz2
-Source109: patches.kernel.org.tar.bz2
-Source110: patches.apparmor.tar.bz2
-Source111: patches.rt.tar.bz2
-Source112: patches.trace.tar.bz2
-Source120: kabi.tar.bz2
-BuildRoot: %_tmppath/%name-%version-build
-Prefix: /usr/src
-
-# Build with bash instead of sh as the shell: this turns on bash
-# extensions like <(...).
-%define _buildshell /bin/bash
-
-%define my_builddir %_builddir/%{name}-%{version}
-
-%(chmod +x %_sourcedir/{arch-symbols,guards,config-subst,check-for-config-changes,kabi-checks})
-
-%define symbols %(set -- $(%_sourcedir/arch-symbols %_target_cpu) $([ -e %_sourcedir/extra-symbols ] && cat %_sourcedir/extra-symbols) ; echo $*)
-
-%define tolerate_unknown_new_config_options 1
-
-%description
-Dummy description.
-
-%prep
-if ! [ -e %_sourcedir/linux-2.6.27.tar.bz2 ]; then
- echo "Please get a copy of linux-2.6.27.tar.bz2 from" \
- "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/."
-fi
-
-echo "Architecture symbol(s): %symbols"
-
-# Unpack all sources and patches
-%setup -q -c -T -a 100 -a 101 -a 102 -a 103 -a 104 -a 105 -a 107 -a 108 -a 109 -a 110 -a 111 -a 112
-
-%build
-# Release number without the EXTRAVERSION
-RELEASE=%source_rel
-while [ "$RELEASE" != "${RELEASE#[^0-9]*.}" ]; do
- RELEASE=${RELEASE#[^0-9]*.}
-done
-
-KERNELRELEASE=2.6.27.4-$RELEASE
-
-case kernel-source-rt in
-(*-rt)
- variant=-rt
- variant_symbols=RT
- ;;
-(*)
- variant=
- variant_symbols=
- ;;
-esac
-
-cat > %_builddir/%{name}-%{version}/.rpm-defs <<EOF
-KERNELRELEASE=$KERNELRELEASE
-variant=$variant
-EOF
-
-mkdir -p $RPM_BUILD_ROOT/usr/src
-cd $RPM_BUILD_ROOT/usr/src
-
-# Unpack the vanilla kernel sources
-bzip2 -cd %_sourcedir/linux-2.6.27.tar.bz2 \
-| tar xf -
-
-mv linux-2.6.27 linux-$KERNELRELEASE$variant
-cd linux-$KERNELRELEASE$variant
-
-chmod -x arch/arm/mach-at91/board-yl-9200.c # executable by accident (fixed in 2.6.27)
-
-%_sourcedir/guards $variant_symbols %symbols < %_sourcedir/series.conf \
- > .patches
-for patch in $(< .patches); do
- if ! patch -s -F0 -E -p1 --no-backup-if-mismatch \
- -i %_builddir/kernel-source-rt-2.6.27.4/$patch; then
- echo "*** Patch $patch failed ***"
- exit 1
- fi
-done
-
-if [ -f %_sourcedir/localversion ] ; then
- cat %_sourcedir/localversion > localversion
-fi
-
-cat > %my_builddir/kernel-source-rt.files <<EOF
-%%%%defattr(-, root, root)
-%%%%ghost /usr/src/linux$variant
-%%%%ghost /usr/src/linux$variant-obj
-/usr/src/linux-$KERNELRELEASE$variant
-/usr/src/linux-$KERNELRELEASE$variant-obj
-/usr/share/doc/packages/%name
-/etc/rpm/macros.kernel-source
-/usr/lib/rpm/kernel-module-subpackage
-/lib/modules/*
-EOF
-
-for config in $(%_sourcedir/guards %symbols < %_sourcedir/config.conf | grep -v vanilla); do
- arch=${config%/*}
- flavor=${config#*/}
- config=%_builddir/%buildsubdir/config/$config
-
- case "$flavor" in
- *-*)
- echo "Flavor '$flavor' must not contain dashes." >&2
- exit 1
- ;;
- esac
|
[-]
[+]
|
Changed |
kernel-source.spec
^
|
|
[-]
[+]
|
Deleted |
kernel-syms-rt.spec
^
|
@@ -1,118 +0,0 @@
-#
-# spec file for package kernel-syms-rt (Version 2.6.27.4)
-#
-# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
-# This file and all modifications and additions to the pristine
-# package are under the same license as the package itself.
-#
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
-#
-
-# norootforbuild
-# ( kernel-binary-packages is expanded into the list of all binary kernel
-# packages for each architecture by Autobuild. )
-
-%if 0%{?opensuse_bs}
-# Strip off the build number ("y") from the "x.y" release number
-%define source_rel %(release=%release; echo ${release%.*})
-%else
-# We don't have build numbers internally
-%define source_rel %release
-%endif
-
-Name: kernel-syms-rt
-Summary: Dummy summary
-Version: 2.6.27.4
-Release: <RELEASE>
-License: GPL
-Group: Development/Sources
-AutoReqProv: off
-BuildRequires: coreutils
-%if ! 0%{?opensuse_bs}
-BuildRequires: kernel-dummy
-%endif
-ExclusiveArch: %ix86 x86_64
-%ifarch %ix86
-BuildRequires: kernel-rt kernel-rt_debug
-%else
-%ifarch x86_64
-BuildRequires: kernel-rt kernel-rt_debug
-%endif
-%endif
-# the packages above do require other things, but none of those are needed during package build
-#!BuildIgnore: irqbalance xen
-#!BuildIgnore: perl-Bootloader mkinitrd
-Requires: linux
-Requires: kernel-source = 2.6.27.4-%source_rel
-Source11: arch-symbols
-Source12: guards
-Source21: config.conf
-BuildRoot: %_tmppath/%name-%version-build
-Prefix: /usr/src
-
-%(chmod +x %_sourcedir/{arch-symbols,guards})
-
-%define symbols %(set -- $(%_sourcedir/arch-symbols %_target_cpu) $([ -e %_sourcedir/extra-symbols ] && cat %_sourcedir/extra-symbols) ; echo $*)
-
-%description
-Dummy description.
-
-%prep
-
-echo "Architecture symbol(s):" %symbols
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir $RPM_BUILD_ROOT
-
-set -- %symbols
-case kernel-syms-rt in
-(*-rt)
- set -- RT "$@"
- ;;
-esac
-%_sourcedir/guards "$@" < %_sourcedir/series.conf > %_builddir/kernel-syms-rt.patches
-for config in $(%_sourcedir/guards %symbols < %_sourcedir/config.conf) ; do
- arch="${config%%/*}"
- flavor="${config#*/}"
-
- rpm -q --quiet kernel-$flavor || continue
-
- # Don't add the build infrastructure for kernels that are based
- # on a different set of patches.
- set -- kernel-$flavor $flavor $(case $flavor in (rt|rt_*) echo RT ;; esac)
- %_sourcedir/guards $* %symbols < %_sourcedir/series.conf \
- > %_builddir/kernel-$flavor.patches
- diff -q %_builddir/{kernel-syms-rt,kernel-$flavor}.patches || continue
-
- # Make sure that all the kernel-$flavor release numbers match the
- # kernel-syms release number.
- set -- %release $(rpm -q --qf '%{RELEASE}' kernel-$flavor)
-%if 0%{?opensuse_bs}
- set -- ${1%.*} ${2%.*}
-%endif
- if [ "$1" != "$2" ]; then
- echo "Release numbers $1 and $2 do not match" >&2
- exit 1
- fi
-
- shopt -s nullglob
- for symvers in /usr/src/linux-*-obj/$arch/$flavor/Module.symvers; do
- cp -p --parents $symvers $RPM_BUILD_ROOT/
- for file in /lib/modules/*-$flavor/modules.alias; do
- cp -p $file $(dirname $RPM_BUILD_ROOT$symvers)
- done
- done
- for symsets in /boot/symsets-*-$flavor.tar.gz; do
- cp -p --parents $symsets $RPM_BUILD_ROOT/
- done
- for file in /lib/modules/*-$flavor/build; do
- cp -pd --parents $file $RPM_BUILD_ROOT/
- done
-done
-
-%files
-%defattr(-, root, root)
-/usr/src/linux-*-obj
-/boot/symsets-*-*.tar.gz
-/lib/modules/*/build
|
[-]
[+]
|
Changed |
kernel-syms.spec
^
|
|
[-]
[+]
|
Changed |
kernel-trace.spec
^
|
|
[-]
[+]
|
Changed |
kernel-vanilla.spec
^
|
|
[-]
[+]
|
Changed |
kernel-xen.spec
^
|
|
[-]
[+]
|
Changed |
README.SUSE
^
|
@@ -120,7 +120,13 @@
followed by ``make install''). This will automatically create
an initrd for the new kernel as well (see ``mkinitrd -h'').
- (6) Add the kernel to the boot manager. When using lilo, run ``lilo''
+ (6) Make sure that /etc/modprobe.d/unsupported-modules contains
+
+ allow_unsupported_modules 1
+
+ otherwise modprobe will refuse to load any modules.
+
+ (7) Add the kernel to the boot manager. When using lilo, run ``lilo''
to update the boot map.
Instead of building binary kernels by hand, you can also build
|
[-]
[+]
|
Changed |
build-source-timestamp
^
|
@@ -1 +1,3 @@
-2008-11-02 01:05:51 +0100
+2008-12-04 18:10:04 +0100
+GIT Revision: 8dd362c79c58c10d180b3dd8861e441737a102dd
+GIT Branch: SL111_BRANCH
|
[-]
[+]
|
Changed |
built-in-where
^
|
@@ -21,14 +21,14 @@
for obj in $(find -name built-in.o -printf '%d %P\n' \
| sort -r \
| awk '{ print $2 }'); do
- $sourcedir/list-exported-symbols -n ${obj%.o} $obj
+ $sourcedir/symsets.pl --list-exported-symbols $obj
done
# We could go through the libraries as well, but those functions
# are so unlikely to change that this wouldn't help.
# (All remaining symbols will end up in the vmlinux set.)
#for archive in $(find -name '*.a'); do
- # $sourcedir/list-exported-symbols -n ${archive%.a} $archive
+ # $sourcedir/symsets.pl --list-exported-symbols $archive
#done
}
|
[-]
[+]
|
Changed |
config.conf
^
|
@@ -1,13 +1,18 @@
# Kernel configuration file selection.
# (See series.conf for a list of symbols defined.)
+#
+# IMPORTANT: the subdirectory names map to cpuarch
+# kernel-binary and kernel-source rely on this
+#
+
+IA32 i386/default
+IA32 i386/pae
+IA32 i386/debug
+IA32 i386/xen
+IA32 i386/vanilla
-+IA32 i386/rt
-+IA32 i386/rt_debug
++IA32 - i386/rt
++IA32 - i386/rt_debug
+IA32 i386/trace
+ia64 ia64/default
@@ -19,17 +24,37 @@
+x86_64 x86_64/xen
+x86_64 x86_64/debug
+x86_64 x86_64/vanilla
-+x86_64 x86_64/rt
-+x86_64 x86_64/rt_debug
++x86_64 - x86_64/rt
++x86_64 - x86_64/rt_debug
+x86_64 - x86_64/rt_timing
+x86_64 x86_64/trace
-+PPC powerpc/default
-+PPC powerpc/ppc64
-+PPC powerpc/kdump
-+PPC powerpc/vanilla
-+PPC - powerpc/rt
-+PPC powerpc/ps3
+# openSuSE:
+# G3 G4 bPlan
++ppc ppc/default
+# pSeries
++ppc ppc/kdump
+# G5 PS3 pSeries
++ppc ppc/ppc64
+# PS3 bootloader
++ppc ppc/ps3
+# maybe the kernels above were patched to death?
++ppc ppc/vanilla
+
+# SLES
+# identical to ppc64 flavor, all KMP packages need a kernel-default
+# Up to now, the openSuSE 11.1 ppc media can not have a
+# kernel-default.ppc.rpm and a kernel-default.ppc64.rpm to continue
+# supporting 32bit and 64bit systems.
++ppc64 ppc64/default
+# pSeries
++ppc64 ppc64/kdump
+# G5 pSeries
++ppc64 ppc64/ppc64
+# maybe the kernels above were patched to death?
++ppc64 ppc64/vanilla
+# ?
++ppc - ppc/rt
+s390 s390/s390
+s390x s390/default
|
|
Changed |
config.tar.bz2
^
|
[-]
[+]
|
Changed |
find-provides
^
|
@@ -5,27 +5,30 @@
printf "%s\n" "${filelist[@]}" | /usr/lib/rpm/find-provides "$@"
+# these two are updated by the spec file
sourcedir=${0%/*}
+builddir="$sourcedir/../BUILD"
+
flavor=${1##*-}
-tmpdir=$(mktemp -dt ${0##*/}.XXXXXXXXXX)
-trap "rm -rf $tmpdir" EXIT
+modlist=$(mktemp -t ${0##*/}.XXXXXXXXXX)
+trap "rm -rf $modlist" EXIT
+symvers=
for file in "${filelist[@]}"; do
case "$file" in
- */boot/symvers-*.gz)
- zcat "$file" \
- | awk '$3 == "vmlinux" || $3 ~ /\/built-in$/ { print }'
+ */Module.symvers)
+ symvers="--symvers-file=$file"
;;
*.ko)
- $sourcedir/list-exported-symbols $file
+ echo "$file" >>"$modlist"
;;
esac
-done \
-| $sourcedir/split-into-symsets $tmpdir
-
-shopt -s nullglob
-for symset in $tmpdir/*; do
- class=${symset##*/} ; class=${class%.*}
- echo "kernel($flavor:$class) = ${symset##*.}"
done
+
+reference=
+# TODO
+# reference="--reference=$builddir/kabi/..."
+$sourcedir/symsets.pl --list-symsets --modules=$modlist $symvers $reference |\
+ sed -rn 's/^(.+)\.([a-z0-9]{16})/kernel('$flavor':\1) = \2/p'
+
|
[-]
[+]
|
Changed |
get_release_number.sh
^
|
@@ -1,12 +1,13 @@
#! /bin/sh
prefix=
suffix=
+commit=8dd362c7
if [ "$3" = kernel-dummy -o -n "$suffix" ]; then
[ -n "$suffix" ] || suffix=$2
while [ "$suffix" != "${suffix#[^0-9]*.}" ]; do
suffix=${suffix#[^0-9]*.}
done
- echo $prefix$suffix
+ echo $prefix$suffix${commit:+_}$commit
else
echo "pkg:kernel-dummy"
fi
|
[-]
[+]
|
Deleted |
kabi-checks
^
|
@@ -1,235 +0,0 @@
-#!/bin/bash
-# Tool to do kABI checks.
-# (c) Kurt Garloff <garloff@suse.de>, GNU GPL, 11/2005
-# $Id$
-#
-# This tool looks at the generated symvers and compares it to the
-# reference file (if existent). It prints warnings for changed symbol
-# versions.
-#
-# Return value:
-# 0 -- no changes
-# 1 -- usage/input error
-# 2 -- internal error
-# 4 -- only additions
-# >= 8 -- removed or changed symbols (see below)
-#
-# Severity classification:
-# - 8 -- 15: if it's not found in a list (commonsyms or usedsyms)
-# The score depends on the source; symbols in vmlinux are more
-# likely to be used by anyone.
-# - 16 -- 23: symbol is found in the list usedsyms
-# - 24 -- 31: symbol is found in the list commonsyms
-
-severities="
-# unimportant ---. .--- important
-# v v
-
-drivers/base/* 13
-drivers/char/ipmi/* 10
-drivers/char/tpm/tpm 9
-drivers/hwmon/* 10
-drivers/i2c/i2c-core 9
-drivers/md/* 13
-drivers/message/fusion/* 6
-drivers/pci/* 12
-drivers/pci/hotplug/pci_hotplug 10
-drivers/scsi/libata 12
-drivers/scsi/scsi* 12
-drivers/scsi/*/scsi_transport_* 12
-drivers/scsi/libiscsi* 12
-drivers/ide/ide-core 11
-drivers/usb/core/usbcore 10
-drivers/usb/serial/usbserial 9
-fs/dmapi/dmapi 11
-fs/fat/fat 11
-fs/jbd/jbd 11
-net/ipv4/netfilter/ip_tables 9
-vmlinux 15
-"
-
-# Turning off UTF-8 processing provides a major speedup.
-export LC_ALL=C
-
-echo "${0##*/} $@"
-
-unset quiet verbose
-if [ "$1" = "-q" ]; then
- shift
- quiet=1
-fi
-if [ "$1" = "-v" ]; then
- shift
- verbose=1
-fi
-
-if [ $# -lt 2 -o $# -gt 4 ]; then
- echo "Usage: ${0##*/} [-q] [-v] reference symvers [commonsyms [usedsyms]]" >&2
- exit 1
-fi
-for file in "$@"; do
- [ -r "$file" ] && continue
- echo "Cannot read from '$file'" >&2
- exit 1
-done
-
-declare_symbol_severity() {
- declare severity=$1
-
- while [ $# -ge 2 ]; do
- if ! eval "severity_of_${2//[^a-zA-Z0-9_]/_}=$severity"; then
- echo "Internal error" >&2
- exit 2
- fi
- shift
- done
-}
-
-consistency_check() {
- declare_symbol_severity 16 consistency_check_foo
- check_modified_symbols >/dev/null <<-EOF
- consistency_check_foo -0x12345678 consistency/check/foo +0x98765432 consistency/check/foo
- EOF
- if [ $? -ne 31 ]; then
- echo "Internal error" >&2
- exit 2
- fi
-}
-
-#set -x
-eval '
-severity() {
- case $2 in
-'"$(
-
- ( echo "$severities"
- echo "consistency/check/* 15" # For the consistency test
- ) \
- | sed -e '/^#/d' -e '/^$/d' \
- | while read glob severity; do
- echo " ($glob) _rc=$severity ;;"
- done
-
-)"'
- (*) _rc=8 ;;
- esac
-
- # Is a particular severity defined for this symbol?
- declare severity=severity_of_$1
- if [ -n "${!severity}" ]; then
- ((_rc += ${!severity}))
- fi
-
- return $_rc
-}'
-#set +x
-
-grab_symvers_from_rpm() {(
- # (Run in subshell to make trap work.)
-
- tmpdir=$(mktemp -t -d ${0##*/}.XXXXXX)
- trap "cd /; rm -rf $tmpdir" EXIT
- cd $tmpdir
- rpm2cpio "$file" \
- | cpio -dim --quiet './boot/symvers-*.gz'
- set -- boot/symvers-*.gz
- if ! [ -e "$1" ]; then
- echo "Failed to extract symvers-*.gz from $file" >&2
- exit 1
- fi
- zcat "$1"
-)}
-
-grab_symvers() {
- declare tag=$1 file=$2 pwd tmpdir
-
- case "$(file -b - <"$file")" in
- gzip*)
- zcat "$file"
- ;;
- RPM*)
- grab_symvers_from_rpm "$file"
- ;;
- *)
- cat "$file"
- ;;
- esac \
- | sed -e "/^#/d" -e "s/^/$tag/" \
- | sort -k 2
-}
-
-filter_out_identical_symbols() {
- # This expression works no matter how many columns the files have.
- grep -v -P '^\S+ -(\S+)( \S+)+ \+\1( \S+)+$'
-}
-
-check_modified_symbols() {
- declare -i RC=0 _rc
- declare ignored
-
- while read symbol tail; do
- # Split in half no matter how many columns the files have.
- set -- $tail ; half=$(($#/2+1))
- version1=$1 ; version2=${!half} ; shift
- source1=$1 ; source2=${!half} ; shift
-
- case "$version1$version2" in
- -\#*)
- continue
- ;;
- -*+* | -*)
- ignored=
- case "$version1" in
- *=\>*)
- if [ "${version1#*=>}" = "${version2#+}" ]; then
- version1="${version1%=>*}"
- ignored="; ignored"
- fi
- ;;
- esac
- severity $symbol $source1 && continue
- _rc=$?
- if [ -z "$quiet" ]; then
- echo -n "Warning: $source1: $symbol(${version1#-}) "
- if [ -n "$version2" ]; then
- echo -n "changed to $symbol(${version2#+})"
- [ "$source1" != "$source2" ] &&
- echo -n " and moved to $source2"
- else
- echo -n "removed"
|
[-]
[+]
|
Added |
kabi.tar.bz2/severities
^
|
@@ -0,0 +1,31 @@
+# Severity classification:
+# - 8 -- 15: if it's not found in a list (commonsyms or usedsyms)
+# The score depends on the source; symbols in vmlinux are more
+# likely to be used by anyone.
+# - 16 -- 23: symbol is found in the list usedsyms
+# - 24 -- 31: symbol is found in the list commonsyms
+#
+# unimportant ---. .--- important
+# v v
+
+drivers/base/* 13
+drivers/char/ipmi/* 10
+drivers/char/tpm/tpm 9
+drivers/hwmon/* 10
+drivers/i2c/i2c-core 9
+drivers/md/* 13
+drivers/message/fusion/* 6
+drivers/pci/* 12
+drivers/pci/hotplug/pci_hotplug 10
+drivers/scsi/libata 12
+drivers/scsi/scsi* 12
+drivers/scsi/*/scsi_transport_* 12
+drivers/scsi/libiscsi* 12
+drivers/ide/ide-core 11
+drivers/usb/core/usbcore 10
+drivers/usb/serial/usbserial 9
+fs/dmapi/dmapi 11
+fs/fat/fat 11
+fs/jbd/jbd 11
+net/ipv4/netfilter/ip_tables 9
+vmlinux 15
|
[-]
[+]
|
Changed |
kernel-module-subpackage
^
|
@@ -20,7 +20,7 @@
' $spec
)
Provides: %{-n*} = %(echo %{-v*}-%3 | tr - _)
-Requires: kernel-%1 coreutils grep
+Requires: coreutils grep
AutoReqProv: on
%{-p:%{expand:%(cd %_sourcedir; cat %{-p*})}}
%description -n %{-n*}-%1
|
[-]
[+]
|
Deleted |
kernel-source-rt.rpmlintrc
^
|
@@ -1,2 +0,0 @@
-# These zero-length files are correct:
-addFilter("zero-length /usr/src/linux-2\.6\..*obj/.*include/config.*h")
|
[-]
[+]
|
Deleted |
list-exported-symbols
^
|
@@ -1,57 +0,0 @@
-#! /bin/sh
-
-# Generate a Module.symvers-like list of symbols a module exports.
-
-usage() {
- echo "USAGE: ${0##*/} [-n name] objfile" >&2
- exit 1
-}
-
-options=`getopt -o n: -- "$@"`
-[ $? -eq 0 ] || usage
-
-eval set -- "$options"
-while :; do
- case "$1" in
- -n)
- opt_n=$2
- shift
- ;;
- --)
- shift
- break
- ;;
- esac
- shift
-done
-
-[ $# -eq 1 ] || usage
-
-if [ -z "$opt_n" ]; then
- opt_n=${1%.ko}
- opt_n=${opt_n#*/kernel/}
-fi
-
-objdump -t "$1" | awk '
-BEGIN { known_types["__ksymtab"] = "EXPORT_SYMBOL"
- known_types["__ksymtab_unused"] = "EXPORT_UNUSED_SYMBOL"
- known_types["__ksymtab_gpl"] = "EXPORT_SYMBOL_GPL"
- known_types["__ksymtab_unused_gpl"] = "EXPORT_UNUSED_SYMBOL_GPL"
- known_types["__ksymtab_gpl_future"] = "EXPORT_SYMBOL_GPL_FUTURE"
- }
- { if (NF < 3)
- next
- if (substr($0, index($0, " ") + 6, 1) == "d")
- next # debug symbol
- if (gsub(/^__crc_/, "", $NF))
- crcs[$NF] = gensub(/^00000000(.+)/, "\\1", "", $1)
- else if (gsub(/^__ksymtab_/, "", $NF) &&
- ($(NF-2) in known_types))
- types[$NF] = known_types[$(NF-2)]
- }
-END { for (sym in types) {
- crc = (sym in crcs ? crcs[sym] : "00000000")
- print "0x" crc "\t" sym "\t" module "\t" types[sym]
- }
- }
-' module="$opt_n"
|
[-]
[+]
|
Changed |
macros.kernel-source
^
|
@@ -1,19 +1,22 @@
+# A few cross-distro definitions:
+%kernel_module_package_release 1
+%kernel_module_package_buildreqs module-init-tools kernel-syms
+
# Defines %flavors_to_build and %kernel_source() as a side effect.
-%_kernel_module_package(n:v:r:s:f:Xp:) \
-BuildRequires: module-init-tools kernel-syms\
+%_kernel_module_package(n:v:r:t:f:Xp:) \
%{expand:%( \
- subpkg=%{-s*}%{!-s:/usr/lib/rpm/kernel-module-subpackage} \
+ subpkg=%{-t*}%{!-t:/usr/lib/rpm/kernel-module-subpackage} \
echo "%%define _suse_kernel_module_subpackage(n:v:r:f:p:) %%{expand:%%(cd %_sourcedir; cat $subpkg; echo %%%%nil)}" \
- flavors="%{!-X:%*}%{-X:$(ls /usr/src/linux-obj/%_target_cpu 2>/dev/null)}" \
flavors_to_build= \
kver=$(rpm -q --qf '%{VERSION}-%{RELEASE}' kernel-source) \
- for flavor in $flavors; do \
- if [ -n "%{-X}" ]; then \
- case " %* " in \
- (*" $flavor "*) \
- continue ;; \
- esac \
- fi \
+ flavors="%*" \
+ for flavor in $(ls /usr/src/linux-obj/%_target_cpu 2>/dev/null); do \
+ case " $flavors " in \
+ (*" $flavor "*) \
+ [ -n "%{-X}" ] && continue ;; \
+ (*) \
+ [ -z "%{-X}" -a -n "$flavors" ] && continue ;; \
+ esac \
krel=$(make -s -C /usr/src/linux-obj/%_target_cpu/$flavor kernelrelease) \
[ -e /boot/symsets-$krel.tar.gz ] || continue \
flavors_to_build="$flavors_to_build $flavor" \
@@ -31,10 +34,10 @@
)}
# kernel_module_package: simply pass on all options and arguments.
-%kernel_module_package(n:v:r:s:f:xp:) \
- %{expand:%%_kernel_module_package %{-x:-X} %{-n} %{-v} %{-r} %{-s} %{-f} %{-p} %*}
+%kernel_module_package(n:v:r:t:f:xp:) \
+ %{expand:%%_kernel_module_package %{-x:-X} %{-n} %{-v} %{-r} %{-t} %{-f} %{-p} %*}
# suse_kernel_module_package: invert the meaning of the -x flag. (You are not
# supposed to understand why a simple %{-x:}%{!-x:-x} won't work.)
%suse_kernel_module_package(n:v:r:s:f:xp:) \
- %{expand:%%_kernel_module_package %{-x: }%{!-x:-X} %{-n} %{-v} %{-r} %{-s} %{-f} %{-p} %*}
+ %{expand:%%_kernel_module_package %{-x: }%{!-x:-X} %{-n} %{-v} %{-r} %{-s:-t %{-s*}} %{-f} %{-p} %*}
|
[-]
[+]
|
Deleted |
minmem
^
|
@@ -1 +0,0 @@
-1048576
|
[-]
[+]
|
Deleted |
needed_space_in_mb
^
|
@@ -1 +0,0 @@
-6144
|
[-]
[+]
|
Changed |
patches.apparmor.tar.bz2/apparmor-intree.diff
^
|
@@ -11,7 +11,7 @@
--- a/security/Kconfig
+++ b/security/Kconfig
-@@ -120,6 +120,7 @@ config SECURITY_DEFAULT_MMAP_MIN_ADDR
+@@ -117,6 +117,7 @@ config SECURITY_DEFAULT_MMAP_MIN_ADDR
source security/selinux/Kconfig
source security/smack/Kconfig
|
[-]
[+]
|
Added |
patches.apparmor.tar.bz2/d_namespace_path_oops_fix.diff
^
|
@@ -0,0 +1,27 @@
+From: Miklos Szeredi <mszeredi@suse.cz>
+Subject: fix oops in d_namespace_path
+Patch-mainline: no
+References: bnc#433504
+
+d_namespace_path uses the current->fs->root to get the current
+namespace. If root is detached root.mnt->mnt_ns will be NULL, causing
+an Oops. Fix by checking this before dereferencing the mnt_ns.
+
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+---
+ fs/namespace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux-2.6.27/fs/namespace.c
+===================================================================
+--- linux-2.6.27.orig/fs/namespace.c 2008-10-31 11:58:02.000000000 +0100
++++ linux-2.6.27/fs/namespace.c 2008-10-31 14:53:44.000000000 +0100
+@@ -2370,7 +2370,7 @@ char *d_namespace_path(struct dentry *de
+ path_get(¤t->fs->root);
+ read_unlock(¤t->fs->lock);
+ spin_lock(&vfsmount_lock);
+- if (root.mnt)
++ if (root.mnt && root.mnt->mnt_ns)
+ ns_root.mnt = mntget(root.mnt->mnt_ns->root);
+ if (ns_root.mnt)
+ ns_root.dentry = dget(ns_root.mnt->mnt_root);
|
[-]
[+]
|
Changed |
patches.apparmor.tar.bz2/security-removexattr.diff
^
|
@@ -74,7 +74,7 @@
static inline int security_inode_need_killpriv(struct dentry *dentry)
--- a/security/commoncap.c
+++ b/security/commoncap.c
-@@ -435,7 +435,8 @@ int cap_inode_setxattr(struct dentry *de
+@@ -429,7 +429,8 @@ int cap_inode_setxattr(struct dentry *de
return 0;
}
|
[-]
[+]
|
Changed |
patches.apparmor.tar.bz2/security-setxattr.diff
^
|
@@ -136,7 +136,7 @@
}
--- a/security/commoncap.c
+++ b/security/commoncap.c
-@@ -420,8 +420,9 @@ int cap_bprm_secureexec (struct linux_bi
+@@ -414,8 +414,9 @@ int cap_bprm_secureexec (struct linux_bi
current->egid != current->gid);
}
|
[-]
[+]
|
Changed |
patches.apparmor.tar.bz2/security-xattr-file.diff
^
|
@@ -418,7 +418,7 @@
}
--- a/security/commoncap.c
+++ b/security/commoncap.c
-@@ -422,7 +422,7 @@ int cap_bprm_secureexec (struct linux_bi
+@@ -416,7 +416,7 @@ int cap_bprm_secureexec (struct linux_bi
int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
const char *name, const void *value, size_t size,
@@ -427,7 +427,7 @@
{
if (!strcmp(name, XATTR_NAME_CAPS)) {
if (!capable(CAP_SETFCAP))
-@@ -436,7 +436,7 @@ int cap_inode_setxattr(struct dentry *de
+@@ -430,7 +430,7 @@ int cap_inode_setxattr(struct dentry *de
}
int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
|
[-]
[+]
|
Changed |
patches.apparmor.tar.bz2/sysctl-pathname.diff
^
|
@@ -27,7 +27,7 @@
void __user *newval, size_t newlen);
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
-@@ -1544,6 +1544,33 @@ void register_sysctl_root(struct ctl_tab
+@@ -1536,6 +1536,33 @@ void register_sysctl_root(struct ctl_tab
spin_unlock(&sysctl_lock);
}
|
[-]
[+]
|
Changed |
patches.apparmor.tar.bz2/vfs-mkdir.diff
^
|
@@ -126,7 +126,7 @@
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
-@@ -2905,7 +2905,7 @@ int cgroup_clone(struct task_struct *tsk
+@@ -2904,7 +2904,7 @@ int cgroup_clone(struct task_struct *tsk
}
/* Create the cgroup directory, which also creates the cgroup */
|
|
Changed |
patches.arch.tar.bz2
^
|
|
Changed |
patches.drivers.tar.bz2
^
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/SUNRPC-Fix-autobind-on-cloned-rpc-clients.patch
^
|
@@ -0,0 +1,98 @@
+Patch-mainline: 2.6.28
+References: 450083
+Git: 9a4bd29fe8f6d3f015fe1c8e5450eb62cfebfcc9 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 3 Oct 2008 16:48:34 -0400
+Subject: [PATCH] SUNRPC: Fix autobind on cloned rpc clients
+
+Despite the fact that cloned rpc clients won't have the cl_autobind flag
+set, they may still find themselves calling rpcb_getport_async(). For this
+to happen, it suffices for a _parent_ rpc_clnt to use autobinding, in which
+case any clone may find itself triggering the !xprt_bound() case in
+call_bind().
+
+The correct fix for this is to walk back up the tree of cloned rpc clients,
+in order to find the parent that 'owns' the transport, either because it
+has clnt->cl_autobind set, or because it originally created the
+transport...
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Acked-by: NeilBrown <neilb@suse.de>
+
+---
+ net/sunrpc/rpcb_clnt.c | 36 +++++++++++++++++++++++++++++-------
+ 1 file changed, 29 insertions(+), 7 deletions(-)
+
+--- linux-2.6.27.orig/net/sunrpc/rpcb_clnt.c
++++ linux-2.6.27/net/sunrpc/rpcb_clnt.c
+@@ -469,6 +469,28 @@ static struct rpc_task *rpcb_call_async(
+ return rpc_run_task(&task_setup_data);
+ }
+
++/*
++ * In the case where rpc clients have been cloned, we want to make
++ * sure that we use the program number/version etc of the actual
++ * owner of the xprt. To do so, we walk back up the tree of parents
++ * to find whoever created the transport and/or whoever has the
++ * autobind flag set.
++ */
++static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
++{
++ struct rpc_clnt *parent = clnt->cl_parent;
++
++ while (parent != clnt) {
++ if (parent->cl_xprt != clnt->cl_xprt)
++ break;
++ if (clnt->cl_autobind)
++ break;
++ clnt = parent;
++ parent = parent->cl_parent;
++ }
++ return clnt;
++}
++
+ /**
+ * rpcb_getport_async - obtain the port for a given RPC service on a given host
+ * @task: task that is waiting for portmapper request
+@@ -478,10 +500,10 @@ static struct rpc_task *rpcb_call_async(
+ */
+ void rpcb_getport_async(struct rpc_task *task)
+ {
+- struct rpc_clnt *clnt = task->tk_client;
++ struct rpc_clnt *clnt;
+ struct rpc_procinfo *proc;
+ u32 bind_version;
+- struct rpc_xprt *xprt = task->tk_xprt;
++ struct rpc_xprt *xprt;
+ struct rpc_clnt *rpcb_clnt;
+ static struct rpcbind_args *map;
+ struct rpc_task *child;
+@@ -490,13 +512,13 @@ void rpcb_getport_async(struct rpc_task
+ size_t salen;
+ int status;
+
++ clnt = rpcb_find_transport_owner(task->tk_client);
++ xprt = clnt->cl_xprt;
++
+ dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
+ task->tk_pid, __func__,
+ clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
+
+- /* Autobind on cloned rpc clients is discouraged */
+- BUG_ON(clnt->cl_parent != clnt);
+-
+ /* Put self on the wait queue to ensure we get notified if
+ * some other task is already attempting to bind the port */
+ rpc_sleep_on(&xprt->binding, task, NULL);
+@@ -578,9 +600,9 @@ void rpcb_getport_async(struct rpc_task
+ task->tk_pid, __func__);
+ return;
+ }
+- rpc_put_task(child);
+
+- task->tk_xprt->stat.bind_count++;
++ xprt->stat.bind_count++;
++ rpc_put_task(child);
+ return;
+
+ bailout_nofree:
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/acpi-clear-wake-status.patch
^
|
@@ -1,27 +0,0 @@
-From: Matthew Garrett <mjg59@srcf.ucam.org>
-Subject: Clear wak_sts register on resume
-Patch-Mainline: Queued for .28
-
-
-Signed-off-by: Thomas Renninger <trenn@suse.de>
-
----
- drivers/acpi/hardware/hwsleep.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/drivers/acpi/hardware/hwsleep.c
-+++ b/drivers/acpi/hardware/hwsleep.c
-@@ -612,6 +612,13 @@ acpi_status acpi_leave_sleep_state(u8 sl
- }
- /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
-
-+ /*
-+ * Some BIOSes assume that WAK_STS will be cleared on resume and use
-+ * it to determine whether the system is rebooting or resuming. Clear
-+ * it for compatibility.
-+ */
-+ acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
-+
- acpi_gbl_system_awake_and_running = TRUE;
-
- /* Enable power button */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/acpi-set-SCI_EN-on-MacBook.patch
^
|
@@ -0,0 +1,96 @@
+From: Rafael J. Wysocki <rjw@suse.de>
+Subject: ACPI suspend: Blacklist boxes that require us to set SCI_EN directly on resume
+References: bnc#444786
+
+Some Apple boxes evidently require us to set SCI_EN on resume
+directly, because if we don't do that, they hang somewhere in the
+resume code path. Moreover, on these boxes it is not sufficient to
+use acpi_enable() to turn ACPI on during resume. All of this is
+against the ACPI specification which states that (1) the BIOS is
+supposed to return from the S3 sleep state with ACPI enabled
+(SCI_EN set) and (2) the SCI_EN bit is owned by the hardware and we
+are not supposed to change it.
+
+For this reason, blacklist the affected systems so that the SCI_EN
+bit is set during resume on them.
+
+[NOTE: Unconditional setting of SCI_EN for all system on resume
+ doesn't work, because it makes some other systems crash (that's to
+ be expected). Also, it is not entirely clear right now if all of the
+ Apple boxes require this workaround.]
+
+Signed-off-by: Rafael J. Wysocki <rjw@suse.de>
+---
+ drivers/acpi/sleep/main.c | 40 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 39 insertions(+), 1 deletion(-)
+
+--- a/drivers/acpi/sleep/main.c
++++ b/drivers/acpi/sleep/main.c
+@@ -60,6 +60,18 @@ void __init acpi_old_suspend_ordering(vo
+ old_suspend_ordering = true;
+ }
+
++/*
++ * According to the ACPI specification the BIOS should make sure that ACPI is
++ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
++ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
++ * on such systems during resume. Unfortunately that doesn't help in
++ * particularly pathological cases in which SCI_EN has to be set directly on
++ * resume, although the specification states very clearly that this flag is
++ * owned by the hardware. The set_sci_en_on_resume variable will be set in such
++ * cases.
++ */
++static bool set_sci_en_on_resume;
++
+ /**
+ * acpi_pm_disable_gpes - Disable the GPEs.
+ */
+@@ -201,7 +213,11 @@ static int acpi_suspend_enter(suspend_st
+ }
+
+ /* If ACPI is not enabled by the BIOS, we need to enable it here. */
+- acpi_enable();
++ if (set_sci_en_on_resume)
++ acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
++ else
++ acpi_enable();
++
+ /* Reprogram control registers and execute _BFS */
+ acpi_leave_sleep_state_prep(acpi_state);
+
+@@ -289,6 +305,12 @@ static int __init init_old_suspend_order
+ return 0;
+ }
+
++static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d)
++{
++ set_sci_en_on_resume = true;
++ return 0;
++}
++
+ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
+ {
+ .callback = init_old_suspend_ordering,
+@@ -306,6 +328,22 @@ static struct dmi_system_id __initdata a
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
+ },
+ },
++ {
++ .callback = init_set_sci_en_on_resume,
++ .ident = "Apple MacBook 1,1",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
++ },
++ },
++ {
++ .callback = init_set_sci_en_on_resume,
++ .ident = "Apple MacMini 1,1",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
++ },
++ },
+ {},
+ };
+ #endif /* CONFIG_SUSPEND */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/acpi_check_for_invalid_handle.patch
^
|
@@ -0,0 +1,30 @@
+From: Fiodor Suietov <fiodor.f.suietov@intel.com>
+Subject: ACPICA: Add check for invalid handle in acpi_get_object_info
+References: http://www.acpica.org/bugzilla/show_bug.cgi?id=474
+Patch-Mainline: in 2.6.28
+Commit-ID: 237a927682a63f02adb542dbdaafe8a81566451d
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+
+Return AE_BAD_PARAMETER if input handle is invalid.
+
+http://www.acpica.org/bugzilla/show_bug.cgi?id=474
+
+Signed-off-by: Fiodor Suietov <fiodor.f.suietov@intel.com>
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Lin Ming <ming.m.lin@intel.com>
+Signed-off-by: Andi Kleen <ak@linux.intel.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+
+diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
+index a287ed5..3cb910d 100644
+--- a/drivers/acpi/namespace/nsxfname.c
++++ b/drivers/acpi/namespace/nsxfname.c
+@@ -253,6 +253,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
+ node = acpi_ns_map_handle_to_node(handle);
+ if (!node) {
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
++ status = AE_BAD_PARAMETER;
+ goto cleanup;
+ }
+
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/acpi_copy_tables_fix_suspend.patch
^
|
@@ -0,0 +1,202 @@
+From: Dennis Noordsij <dennis.noordsij@helsinki.fi>
+Subject: ACPICA: Copy dynamically loaded tables to local buffer
+References: bnc#410726
+Patch-Mainline: in 2.6.28
+Commit-ID: f0e0da8a6cca44396c7a711e308d58084e881617
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+
+Previously, dynamically loaded tables were simply mapped, but on some machines
+this memory is corrupted after suspend. Now copy the table to a local buffer.
+For OpRegion case, added checksum verify. Use the table length from the table header,
+not the region length. For Buffer case, use the table length also.
+
+http://bugzilla.kernel.org/show_bug.cgi?id=10734
+
+Signed-off-by: Dennis Noordsij <dennis.noordsij@helsinki.fi>
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Lin Ming <ming.m.lin@intel.com>
+Signed-off-by: Andi Kleen <ak@linux.intel.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+
+diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
+index 8892b98..331a114 100644
+--- a/drivers/acpi/executer/exconfig.c
++++ b/drivers/acpi/executer/exconfig.c
+@@ -280,6 +280,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
+ struct acpi_walk_state *walk_state)
+ {
+ union acpi_operand_object *ddb_handle;
++ struct acpi_table_header *table;
+ struct acpi_table_desc table_desc;
+ u32 table_index;
+ acpi_status status;
+@@ -294,9 +295,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
+ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ case ACPI_TYPE_REGION:
+
+- ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
+- obj_desc,
+- acpi_ut_get_object_type_name(obj_desc)));
++ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
++ "Load table from Region %p\n", obj_desc));
+
+ /* Region must be system_memory (from ACPI spec) */
+
+@@ -316,61 +316,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
+ }
+
+ /*
+- * We will simply map the memory region for the table. However, the
+- * memory region is technically not guaranteed to remain stable and
+- * we may eventually have to copy the table to a local buffer.
++ * Map the table header and get the actual table length. The region
++ * length is not guaranteed to be the same as the table length.
++ */
++ table = acpi_os_map_memory(obj_desc->region.address,
++ sizeof(struct acpi_table_header));
++ if (!table) {
++ return_ACPI_STATUS(AE_NO_MEMORY);
++ }
++
++ length = table->length;
++ acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
++
++ /* Must have at least an ACPI table header */
++
++ if (length < sizeof(struct acpi_table_header)) {
++ return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
++ }
++
++ /*
++ * The memory region is not guaranteed to remain stable and we must
++ * copy the table to a local buffer. For example, the memory region
++ * is corrupted after suspend on some machines. Dynamically loaded
++ * tables are usually small, so this overhead is minimal.
+ */
++
++ /* Allocate a buffer for the table */
++
++ table_desc.pointer = ACPI_ALLOCATE(length);
++ if (!table_desc.pointer) {
++ return_ACPI_STATUS(AE_NO_MEMORY);
++ }
++
++ /* Map the entire table and copy it */
++
++ table = acpi_os_map_memory(obj_desc->region.address, length);
++ if (!table) {
++ ACPI_FREE(table_desc.pointer);
++ return_ACPI_STATUS(AE_NO_MEMORY);
++ }
++
++ ACPI_MEMCPY(table_desc.pointer, table, length);
++ acpi_os_unmap_memory(table, length);
++
+ table_desc.address = obj_desc->region.address;
+- table_desc.length = obj_desc->region.length;
+- table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
+ break;
+
+ case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
+
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+- "Load from Buffer or Field %p %s\n", obj_desc,
+- acpi_ut_get_object_type_name(obj_desc)));
+-
+- length = obj_desc->buffer.length;
++ "Load table from Buffer or Field %p\n",
++ obj_desc));
+
+ /* Must have at least an ACPI table header */
+
+- if (length < sizeof(struct acpi_table_header)) {
++ if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
+ return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+ }
+
+- /* Validate checksum here. It won't get validated in tb_add_table */
++ /* Get the actual table length from the table header */
+
+- status =
+- acpi_tb_verify_checksum(ACPI_CAST_PTR
+- (struct acpi_table_header,
+- obj_desc->buffer.pointer), length);
+- if (ACPI_FAILURE(status)) {
+- return_ACPI_STATUS(status);
++ table =
++ ACPI_CAST_PTR(struct acpi_table_header,
++ obj_desc->buffer.pointer);
++ length = table->length;
++
++ /* Table cannot extend beyond the buffer */
++
++ if (length > obj_desc->buffer.length) {
++ return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
++ }
++ if (length < sizeof(struct acpi_table_header)) {
++ return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+ }
+
+ /*
+- * We need to copy the buffer since the original buffer could be
+- * changed or deleted in the future
++ * Copy the table from the buffer because the buffer could be modified
++ * or even deleted in the future
+ */
+ table_desc.pointer = ACPI_ALLOCATE(length);
+ if (!table_desc.pointer) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+- ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
+- length);
+- table_desc.length = length;
+- table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
++ ACPI_MEMCPY(table_desc.pointer, table, length);
++ table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
+ break;
+
+ default:
+ return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
+ }
+
+- /*
+- * Install the new table into the local data structures
+- */
++ /* Validate table checksum (will not get validated in tb_add_table) */
++
++ status = acpi_tb_verify_checksum(table_desc.pointer, length);
++ if (ACPI_FAILURE(status)) {
++ ACPI_FREE(table_desc.pointer);
++ return_ACPI_STATUS(status);
++ }
++
++ /* Complete the table descriptor */
++
++ table_desc.length = length;
++ table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
++
++ /* Install the new table into the local data structures */
++
+ status = acpi_tb_add_table(&table_desc, &table_index);
+ if (ACPI_FAILURE(status)) {
+ goto cleanup;
+@@ -379,7 +430,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
+ /*
+ * Add the table to the namespace.
+ *
+- * Note: We load the table objects relative to the root of the namespace.
++ * Note: Load the table objects relative to the root of the namespace.
+ * This appears to go against the ACPI specification, but we do it for
+ * compatibility with other ACPI implementations.
+ */
+@@ -415,7 +466,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
+ cleanup:
+ if (ACPI_FAILURE(status)) {
+
+- /* Delete allocated buffer or mapping */
++ /* Delete allocated table buffer */
+
+ acpi_tb_delete_table(&table_desc);
+ }
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/acpi_dereference_object_if_possible.patch
^
|
@@ -0,0 +1,142 @@
+From: Lin Ming <ming.m.lin@intel.com>
+Subject: ACPICA: Add function to dereference returned reference objects
+References: http://bugzilla.kernel.org/show_bug.cgi?id=11105
+Patch-Mainline: in 2.6.28
+Commit-ID: bbc241340681557a16982f4d1840f00963bc05b4
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+
+Examines the return object from a call to acpi_evaluate_object.
+Any Index or RefOf references are automatically dereferenced in
+an attempt to return something useful (these reference types
+cannot be converted into an external ACPI_OBJECT.)
+Lin Ming, Bob Moore.
+
+http://bugzilla.kernel.org/show_bug.cgi?id=11105
+
+Signed-off-by: Lin Ming <ming.m.lin@intel.com>
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Andi Kleen <ak@linux.intel.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+
+diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
+index 38be586..f3cc376 100644
+--- a/drivers/acpi/namespace/nsxfeval.c
++++ b/drivers/acpi/namespace/nsxfeval.c
+@@ -45,9 +45,14 @@
+ #include <acpi/acpi.h>
+ #include <acpi/acnamesp.h>
+ #include <acpi/acinterp.h>
++#include <acpi/amlcode.h>
+
+ #define _COMPONENT ACPI_NAMESPACE
+ ACPI_MODULE_NAME("nsxfeval")
++
++/* Local prototypes */
++static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
++
+ #ifdef ACPI_FUTURE_USAGE
+ /*******************************************************************************
+ *
+@@ -69,6 +74,7 @@ ACPI_MODULE_NAME("nsxfeval")
+ * be valid (non-null)
+ *
+ ******************************************************************************/
++
+ acpi_status
+ acpi_evaluate_object_typed(acpi_handle handle,
+ acpi_string pathname,
+@@ -283,6 +289,10 @@ acpi_evaluate_object(acpi_handle handle,
+
+ if (ACPI_SUCCESS(status)) {
+
++ /* Dereference Index and ref_of references */
++
++ acpi_ns_resolve_references(info);
++
+ /* Get the size of the returned object */
+
+ status =
+@@ -352,6 +362,74 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
+
+ /*******************************************************************************
+ *
++ * FUNCTION: acpi_ns_resolve_references
++ *
++ * PARAMETERS: Info - Evaluation info block
++ *
++ * RETURN: Info->return_object is replaced with the dereferenced object
++ *
++ * DESCRIPTION: Dereference certain reference objects. Called before an
++ * internal return object is converted to an external union acpi_object.
++ *
++ * Performs an automatic dereference of Index and ref_of reference objects.
++ * These reference objects are not supported by the union acpi_object, so this is a
++ * last resort effort to return something useful. Also, provides compatibility
++ * with other ACPI implementations.
++ *
++ * NOTE: does not handle references within returned package objects or nested
++ * references, but this support could be added later if found to be necessary.
++ *
++ ******************************************************************************/
++static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
++{
++ union acpi_operand_object *obj_desc = NULL;
++ struct acpi_namespace_node *node;
++
++ /* We are interested in reference objects only */
++
++ if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
++ ACPI_TYPE_LOCAL_REFERENCE) {
++ return;
++ }
++
++ /*
++ * Two types of references are supported - those created by Index and
++ * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
++ * to an union acpi_object, so it is not dereferenced here. A ddb_handle
++ * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
++ * an union acpi_object.
++ */
++ switch (info->return_object->reference.opcode) {
++ case AML_INDEX_OP:
++
++ obj_desc = *(info->return_object->reference.where);
++ break;
++
++ case AML_REF_OF_OP:
++
++ node = info->return_object->reference.object;
++ if (node) {
++ obj_desc = node->object;
++ }
++ break;
++
++ default:
++ return;
++ }
++
++ /* Replace the existing reference object */
++
++ if (obj_desc) {
++ acpi_ut_add_reference(obj_desc);
++ acpi_ut_remove_reference(info->return_object);
++ info->return_object = obj_desc;
++ }
++
++ return;
++}
++
++/*******************************************************************************
++ *
+ * FUNCTION: acpi_walk_namespace
+ *
+ * PARAMETERS: Type - acpi_object_type to search for
+@@ -379,6 +457,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
+ * function, etc.
+ *
+ ******************************************************************************/
++
+ acpi_status
+ acpi_walk_namespace(acpi_object_type type,
+ acpi_handle start_object,
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/acpi_do_not_load_acpi_cpufreq_acpioff.patch
^
|
@@ -0,0 +1,25 @@
+From: Yinghai Lu <yhlu.kernel@gmail.com>
+Subject: ACPI: don't load acpi_cpufreq if acpi=off
+References: no reference
+Patch-Mainline: in 2.6.28
+Commit-ID: ee297533279a802eac8b1cbea8e65b24b36a1aac
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+
+Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+
+diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+index dd097b8..9943b4c 100644
+--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
++++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+@@ -779,6 +779,9 @@ static int __init acpi_cpufreq_init(void)
+ {
+ int ret;
+
++ if (acpi_disabled)
++ return 0;
++
+ dprintk("acpi_cpufreq_init\n");
+
+ ret = acpi_cpufreq_early_init();
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/agp-fix-stolen-memory-counting-on-g4x.patch
^
|
@@ -1,63 +0,0 @@
-From 82e14a6215cbc9804ecc35281e973c6c8ce22fe7 Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Tue, 14 Oct 2008 11:28:58 -0700
-Subject: agp: Fix stolen memory counting on G4X.
-Patch-mainline: 2.6.28
-References: bnc#437618
-
-From: Eric Anholt <eric@anholt.net>
-
-commit 82e14a6215cbc9804ecc35281e973c6c8ce22fe7 upstream
-
-On the GM45, the amount of stolen memory mapped to the GTT was underestimated,
-even though we had 508KB more available since the GTT doesn't take from
-stolen memory. On the non-GM45 G4X, we overestimated how much stolen was
-mapped to the GTT by 4KB, resulting in GPU page faults when that page was
-accessed.
-
-This update requires a corresponding update to xf86-video-intel to work
-correctly.
-
-Signed-off-by: Eric Anholt <eric@anholt.net>
-Signed-off-by: Dave Airlie <airlied@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/char/agp/intel-agp.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
---- a/drivers/char/agp/intel-agp.c
-+++ b/drivers/char/agp/intel-agp.c
-@@ -54,8 +54,7 @@
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
-- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \
-- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
-+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
-
- #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
-@@ -63,7 +62,8 @@
-
- #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
-- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB)
-+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
-+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
-
- extern int agp_memory_reserved;
-
-@@ -525,8 +525,10 @@ static void intel_i830_init_gtt_entries(
- size += 4;
- } else if (IS_G4X) {
- /* On 4 series hardware, GTT stolen is separate from graphics
-- * stolen, ignore it in stolen gtt entries counting */
-- size = 0;
-+ * stolen, ignore it in stolen gtt entries counting. However,
-+ * 4KB of the stolen memory doesn't get mapped to the GTT.
-+ */
-+ size = 4;
- } else {
- /* On previous hardware, the GTT size was just what was
- * required to map the aperture.
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/blk-leave-sync-timer-running
^
|
@@ -0,0 +1,48 @@
+From: Jens Axboe <jens.axboe@oracle.com>
+Date: Wed, 19 Nov 2008 13:38:39 +0000 (+0100)
+Subject: block: leave request timeout timer running on an empty list
+References: bnc#447249
+X-Git-Tag: next-20081124~22^2~5
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fsfr%2Flinux-next.git;a=commitdiff_plain;h=4fc4d9c3fc9091db5a9fc534bd1c86bb338aff9f
+
+block: leave the request timeout timer running even on an empty list
+
+For sync IO, we'll often do them serialized. This means we'll be touching
+the queue timer for every IO, as opposed to only occasionally like we
+do for queued IO. Instead of deleting the timer when the last request
+is removed, just let continue running. If a new request comes up soon
+we then don't have to readd the timer again. If no new requests arrive,
+the timer will expire without side effect later.
+
+This improves high iops sync IO by ~1%.
+
+Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 04267d6..44f547c 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -391,6 +391,7 @@ EXPORT_SYMBOL(blk_stop_queue);
+ void blk_sync_queue(struct request_queue *q)
+ {
+ del_timer_sync(&q->unplug_timer);
++ del_timer_sync(&q->timeout);
+ kblockd_flush_work(&q->unplug_work);
+ }
+ EXPORT_SYMBOL(blk_sync_queue);
+diff --git a/block/blk-timeout.c b/block/blk-timeout.c
+index 99c3efc..a095353 100644
+--- a/block/blk-timeout.c
++++ b/block/blk-timeout.c
+@@ -23,9 +23,6 @@ void blk_delete_timer(struct request *re
+ return;
+
+ list_del_init(&req->timeout_list);
+-
+- if (list_empty(&q->timeout_list))
+- del_timer(&q->timeout);
+ }
+
+ static void blk_rq_timed_out(struct request *req)
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/block-discard-requests
^
|
@@ -24,8 +24,10 @@
include/linux/mtd/blktrans.h | 2 +
16 files changed, 314 insertions(+), 50 deletions(-)
---- a/block/blk-barrier.c
-+++ b/block/blk-barrier.c
+Index: linux-2.6.27/block/blk-barrier.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-barrier.c
++++ linux-2.6.27/block/blk-barrier.c
@@ -315,3 +315,72 @@ int blkdev_issue_flush(struct block_devi
return ret;
}
@@ -99,8 +101,10 @@
+ return ret;
+}
+EXPORT_SYMBOL(blkdev_issue_discard);
---- a/block/blk-core.c
-+++ b/block/blk-core.c
+Index: linux-2.6.27/block/blk-core.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-core.c
++++ linux-2.6.27/block/blk-core.c
@@ -1077,7 +1077,12 @@ void init_request_from_bio(struct reques
/*
* REQ_BARRIER implies no merging, but lets make it explicit
@@ -194,8 +198,10 @@
rq->data_len = bio->bi_size;
rq->bio = rq->biotail = bio;
---- a/block/blk-merge.c
-+++ b/block/blk-merge.c
+Index: linux-2.6.27/block/blk-merge.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-merge.c
++++ linux-2.6.27/block/blk-merge.c
@@ -11,7 +11,7 @@
void blk_recalc_rq_sectors(struct request *rq, int nsect)
@@ -205,13 +211,14 @@
rq->hard_sector += nsect;
rq->hard_nr_sectors -= nsect;
-@@ -131,13 +131,17 @@ static int blk_phys_contig_segment(struc
+@@ -138,14 +138,18 @@ static int blk_phys_contig_segment(struc
if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
return 0;
- if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
- return 0;
- if (bio->bi_size + nxt->bi_size > q->max_segment_size)
+ if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
+ q->max_segment_size)
return 0;
+ if (!bio_has_data(bio))
@@ -222,11 +229,11 @@
+
/*
- * bio and nxt are contigous in memory, check if the queue allows
-+ * bio and nxt are contiguous in memory; check if the queue allows
++ * bio and nxt are contiguous in memory, check if the queue allows
* these two to be merged into one
*/
if (BIO_SEG_BOUNDARY(q, bio, nxt))
-@@ -153,8 +157,9 @@ static int blk_hw_contig_segment(struct
+@@ -161,8 +165,9 @@ static int blk_hw_contig_segment(struct
blk_recount_segments(q, bio);
if (!bio_flagged(nxt, BIO_SEG_VALID))
blk_recount_segments(q, nxt);
@@ -238,7 +245,7 @@
return 0;
if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size)
return 0;
-@@ -317,8 +322,9 @@ int ll_back_merge_fn(struct request_queu
+@@ -325,8 +330,9 @@ int ll_back_merge_fn(struct request_queu
if (!bio_flagged(bio, BIO_SEG_VALID))
blk_recount_segments(q, bio);
len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size;
@@ -250,7 +257,7 @@
int mergeable = ll_new_mergeable(q, req, bio);
if (mergeable) {
-@@ -356,8 +362,9 @@ int ll_front_merge_fn(struct request_que
+@@ -364,8 +370,9 @@ int ll_front_merge_fn(struct request_que
blk_recount_segments(q, bio);
if (!bio_flagged(req->bio, BIO_SEG_VALID))
blk_recount_segments(q, req->bio);
@@ -262,8 +269,10 @@
int mergeable = ll_new_mergeable(q, req, bio);
if (mergeable) {
---- a/block/blk-settings.c
-+++ b/block/blk-settings.c
+Index: linux-2.6.27/block/blk-settings.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-settings.c
++++ linux-2.6.27/block/blk-settings.c
@@ -33,6 +33,23 @@ void blk_queue_prep_rq(struct request_qu
EXPORT_SYMBOL(blk_queue_prep_rq);
@@ -288,8 +297,10 @@
* blk_queue_merge_bvec - set a merge_bvec function for queue
* @q: queue
* @mbfn: merge_bvec_fn
---- a/block/blktrace.c
-+++ b/block/blktrace.c
+Index: linux-2.6.27/block/blktrace.c
+===================================================================
+--- linux-2.6.27.orig/block/blktrace.c
++++ linux-2.6.27/block/blktrace.c
@@ -111,23 +111,9 @@ static int act_log_check(struct blk_trac
*/
static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) };
@@ -333,8 +344,10 @@
pid = tsk->pid;
if (unlikely(act_log_check(bt, what, sector, pid)))
---- a/block/compat_ioctl.c
-+++ b/block/compat_ioctl.c
+Index: linux-2.6.27/block/compat_ioctl.c
+===================================================================
+--- linux-2.6.27.orig/block/compat_ioctl.c
++++ linux-2.6.27/block/compat_ioctl.c
@@ -788,6 +788,7 @@ long compat_blkdev_ioctl(struct file *fi
return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
case BLKFLSBUF:
@@ -343,9 +356,11 @@
/*
* the ones below are implemented in blkdev_locked_ioctl,
* but we call blkdev_ioctl, which gets the lock for us
---- a/block/elevator.c
-+++ b/block/elevator.c
-@@ -75,6 +75,12 @@ int elv_rq_merge_ok(struct request *rq,
+Index: linux-2.6.27/block/elevator.c
+===================================================================
+--- linux-2.6.27.orig/block/elevator.c
++++ linux-2.6.27/block/elevator.c
+@@ -75,6 +75,12 @@ int elv_rq_merge_ok(struct request *rq,
return 0;
/*
@@ -385,8 +400,10 @@
q->end_sector = rq_end_sector(rq);
q->boundary_rq = rq;
}
---- a/block/ioctl.c
-+++ b/block/ioctl.c
+Index: linux-2.6.27/block/ioctl.c
+===================================================================
+--- linux-2.6.27.orig/block/ioctl.c
++++ linux-2.6.27/block/ioctl.c
@@ -111,6 +111,69 @@ static int blkdev_reread_part(struct blo
return res;
}
@@ -477,8 +494,10 @@
case HDIO_GETGEO: {
struct hd_geometry geo;
---- a/drivers/mtd/ftl.c
-+++ b/drivers/mtd/ftl.c
+Index: linux-2.6.27/drivers/mtd/ftl.c
+===================================================================
+--- linux-2.6.27.orig/drivers/mtd/ftl.c
++++ linux-2.6.27/drivers/mtd/ftl.c
@@ -1005,6 +1005,29 @@ static int ftl_writesect(struct mtd_blkt
return ftl_write((void *)dev, buf, block, 1);
}
@@ -509,7 +528,7 @@
/*====================================================================*/
static void ftl_freepart(partition_t *part)
-@@ -1069,6 +1092,7 @@ static struct mtd_blktrans_ops ftl_tr =
+@@ -1069,6 +1092,7 @@ static struct mtd_blktrans_ops ftl_tr =
.blksize = SECTOR_SIZE,
.readsect = ftl_readsect,
.writesect = ftl_writesect,
@@ -517,8 +536,10 @@
.getgeo = ftl_getgeo,
.add_mtd = ftl_add_mtd,
.remove_dev = ftl_remove_dev,
---- a/drivers/mtd/mtd_blkdevs.c
-+++ b/drivers/mtd/mtd_blkdevs.c
+Index: linux-2.6.27/drivers/mtd/mtd_blkdevs.c
+===================================================================
+--- linux-2.6.27.orig/drivers/mtd/mtd_blkdevs.c
++++ linux-2.6.27/drivers/mtd/mtd_blkdevs.c
@@ -32,6 +32,14 @@ struct mtd_blkcore_priv {
spinlock_t queue_lock;
};
@@ -556,8 +577,10 @@
tr->blkshift = ffs(tr->blksize) - 1;
tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
---- a/fs/fat/fatent.c
-+++ b/fs/fat/fatent.c
+Index: linux-2.6.27/fs/fat/fatent.c
+===================================================================
+--- linux-2.6.27.orig/fs/fat/fatent.c
++++ linux-2.6.27/fs/fat/fatent.c
@@ -6,6 +6,7 @@
#include <linux/module.h>
#include <linux/fs.h>
@@ -593,9 +616,11 @@
ops->ent_put(&fatent, FAT_ENT_FREE);
if (sbi->free_clusters != -1) {
sbi->free_clusters++;
---- a/include/linux/bio.h
-+++ b/include/linux/bio.h
-@@ -149,6 +149,8 @@ struct bio {
+Index: linux-2.6.27/include/linux/bio.h
+===================================================================
+--- linux-2.6.27.orig/include/linux/bio.h
++++ linux-2.6.27/include/linux/bio.h
+@@ -156,6 +156,8 @@ struct bio {
* bit 2 -- barrier
* bit 3 -- fail fast, don't want low level driver retries
* bit 4 -- synchronous I/O hint: the block layer will unplug immediately
@@ -604,7 +629,7 @@
*/
#define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */
#define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */
-@@ -156,6 +158,7 @@ struct bio {
+@@ -163,6 +165,7 @@ struct bio {
#define BIO_RW_FAILFAST 3
#define BIO_RW_SYNC 4
#define BIO_RW_META 5
@@ -612,7 +637,7 @@
/*
* upper 16 bits of bi_rw define the io priority of this bio
-@@ -185,14 +188,15 @@ struct bio {
+@@ -192,14 +195,15 @@ struct bio {
#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META))
@@ -631,8 +656,10 @@
}
static inline void *bio_data(struct bio *bio)
---- a/include/linux/blkdev.h
-+++ b/include/linux/blkdev.h
+Index: linux-2.6.27/include/linux/blkdev.h
+===================================================================
+--- linux-2.6.27.orig/include/linux/blkdev.h
++++ linux-2.6.27/include/linux/blkdev.h
@@ -81,6 +81,7 @@ enum {
*/
REQ_LB_OP_EJECT = 0x40, /* eject request */
@@ -700,7 +727,7 @@
/*
* q->prep_rq_fn return values
-@@ -796,6 +803,7 @@ extern void blk_queue_merge_bvec(struct
+@@ -796,6 +803,7 @@ extern void blk_queue_merge_bvec(struct
extern void blk_queue_dma_alignment(struct request_queue *, int);
extern void blk_queue_update_dma_alignment(struct request_queue *, int);
extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
@@ -725,8 +752,10 @@
/*
* command filter functions
---- a/include/linux/blktrace_api.h
-+++ b/include/linux/blktrace_api.h
+Index: linux-2.6.27/include/linux/blktrace_api.h
+===================================================================
+--- linux-2.6.27.orig/include/linux/blktrace_api.h
++++ linux-2.6.27/include/linux/blktrace_api.h
@@ -23,7 +23,8 @@ enum blktrace_cat {
BLK_TC_NOTIFY = 1 << 10, /* special message */
BLK_TC_AHEAD = 1 << 11, /* readahead */
@@ -747,8 +776,10 @@
if (blk_pc_request(rq)) {
what |= BLK_TC_ACT(BLK_TC_PC);
__blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors, sizeof(rq->cmd), rq->cmd);
---- a/include/linux/fs.h
-+++ b/include/linux/fs.h
+Index: linux-2.6.27/include/linux/fs.h
+===================================================================
+--- linux-2.6.27.orig/include/linux/fs.h
++++ linux-2.6.27/include/linux/fs.h
@@ -86,7 +86,9 @@ extern int dir_notify_enable;
#define READ_META (READ | (1 << BIO_RW_META))
#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC))
@@ -768,8 +799,10 @@
#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
#define FIBMAP _IO(0x00,1) /* bmap access */
---- a/include/linux/mtd/blktrans.h
-+++ b/include/linux/mtd/blktrans.h
+Index: linux-2.6.27/include/linux/mtd/blktrans.h
+===================================================================
+--- linux-2.6.27.orig/include/linux/mtd/blktrans.h
++++ linux-2.6.27/include/linux/mtd/blktrans.h
@@ -41,6 +41,8 @@ struct mtd_blktrans_ops {
unsigned long block, char *buffer);
int (*writesect)(struct mtd_blktrans_dev *dev,
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/block-git-fixes
^
|
@@ -47,8 +47,10 @@
include/linux/blkdev.h | 18 +--
23 files changed, 310 insertions(+), 374 deletions(-)
---- a/block/blk-core.c
-+++ b/block/blk-core.c
+Index: linux-2.6.27/block/blk-core.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-core.c
++++ linux-2.6.27/block/blk-core.c
@@ -26,8 +26,6 @@
#include <linux/swap.h>
#include <linux/writeback.h>
@@ -433,8 +435,10 @@
return 0;
}
---- a/block/blk-exec.c
-+++ b/block/blk-exec.c
+Index: linux-2.6.27/block/blk-exec.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-exec.c
++++ linux-2.6.27/block/blk-exec.c
@@ -16,7 +16,7 @@
/**
* blk_end_sync_rq - executes a completion event on a request
@@ -462,8 +466,10 @@
* for execution and wait for completion.
*/
int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
---- a/block/blk-integrity.c
-+++ b/block/blk-integrity.c
+Index: linux-2.6.27/block/blk-integrity.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-integrity.c
++++ linux-2.6.27/block/blk-integrity.c
@@ -109,8 +109,8 @@ EXPORT_SYMBOL(blk_rq_map_integrity_sg);
/**
@@ -475,8 +481,10 @@
*
* Description: Meta-devices like DM and MD need to verify that all
* sub-devices use the same integrity format before advertising to
---- a/block/blk-map.c
-+++ b/block/blk-map.c
+Index: linux-2.6.27/block/blk-map.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-map.c
++++ linux-2.6.27/block/blk-map.c
@@ -85,17 +85,17 @@ static int __blk_rq_map_user(struct requ
}
@@ -538,8 +546,10 @@
* @q: request queue where request should be inserted
* @rq: request to fill
* @kbuf: the kernel buffer
---- a/block/blk-merge.c
-+++ b/block/blk-merge.c
+Index: linux-2.6.27/block/blk-merge.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-merge.c
++++ linux-2.6.27/block/blk-merge.c
@@ -41,12 +41,9 @@ void blk_recalc_rq_sectors(struct reques
void blk_recalc_rq_segments(struct request *rq)
{
@@ -573,7 +583,7 @@
if (cluster) {
if (seg_size + bv->bv_len > q->max_segment_size)
goto new_segment;
-@@ -74,40 +71,19 @@ void blk_recalc_rq_segments(struct reque
+@@ -74,27 +71,12 @@ void blk_recalc_rq_segments(struct reque
goto new_segment;
if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
goto new_segment;
@@ -598,9 +608,10 @@
- nr_hw_segs++;
- }
-
- nr_phys_segs++;
- bvprv = bv;
- seg_size = bv->bv_len;
+ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
+ rq->bio->bi_seg_front_size = seg_size;
+
+@@ -104,17 +86,11 @@ new_hw_segment:
highprv = high;
}
@@ -609,12 +620,16 @@
- rq->bio->bi_hw_front_size = hw_seg_size;
- if (hw_seg_size > rq->biotail->bi_hw_back_size)
- rq->biotail->bi_hw_back_size = hw_seg_size;
+ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
+ rq->bio->bi_seg_front_size = seg_size;
+ if (seg_size > rq->biotail->bi_seg_back_size)
+ rq->biotail->bi_seg_back_size = seg_size;
rq->nr_phys_segments = nr_phys_segs;
- rq->nr_hw_segments = nr_hw_segs;
}
void blk_recount_segments(struct request_queue *q, struct bio *bio)
-@@ -120,7 +96,6 @@ void blk_recount_segments(struct request
+@@ -127,7 +103,6 @@ void blk_recount_segments(struct request
blk_recalc_rq_segments(&rq);
bio->bi_next = nxt;
bio->bi_phys_segments = rq.nr_phys_segments;
@@ -622,7 +637,7 @@
bio->bi_flags |= (1 << BIO_SEG_VALID);
}
EXPORT_SYMBOL(blk_recount_segments);
-@@ -150,23 +125,6 @@ static int blk_phys_contig_segment(struc
+@@ -158,23 +133,6 @@ static int blk_phys_contig_segment(struc
return 0;
}
@@ -646,7 +661,7 @@
/*
* map a request to scatterlist, return number of sg entries setup. Caller
* must make sure sg can hold rq->nr_phys_segments entries
-@@ -280,10 +238,9 @@ static inline int ll_new_hw_segment(stru
+@@ -288,10 +246,9 @@ static inline int ll_new_hw_segment(stru
struct request *req,
struct bio *bio)
{
@@ -658,7 +673,7 @@
|| req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) {
req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
-@@ -295,7 +252,6 @@ static inline int ll_new_hw_segment(stru
+@@ -303,7 +260,6 @@ static inline int ll_new_hw_segment(stru
* This will form the start of a new hw segment. Bump both
* counters.
*/
@@ -666,7 +681,7 @@
req->nr_phys_segments += nr_phys_segs;
return 1;
}
-@@ -304,7 +260,6 @@ int ll_back_merge_fn(struct request_queu
+@@ -312,7 +268,6 @@ int ll_back_merge_fn(struct request_queu
struct bio *bio)
{
unsigned short max_sectors;
@@ -674,7 +689,7 @@
if (unlikely(blk_pc_request(req)))
max_sectors = q->max_hw_sectors;
-@@ -321,20 +276,6 @@ int ll_back_merge_fn(struct request_queu
+@@ -329,20 +284,6 @@ int ll_back_merge_fn(struct request_queu
blk_recount_segments(q, req->biotail);
if (!bio_flagged(bio, BIO_SEG_VALID))
blk_recount_segments(q, bio);
@@ -695,7 +710,7 @@
return ll_new_hw_segment(q, req, bio);
}
-@@ -343,7 +284,6 @@ int ll_front_merge_fn(struct request_que
+@@ -351,7 +292,6 @@ int ll_front_merge_fn(struct request_que
struct bio *bio)
{
unsigned short max_sectors;
@@ -703,7 +718,7 @@
if (unlikely(blk_pc_request(req)))
max_sectors = q->max_hw_sectors;
-@@ -357,24 +297,10 @@ int ll_front_merge_fn(struct request_que
+@@ -365,24 +305,10 @@ int ll_front_merge_fn(struct request_que
q->last_merge = NULL;
return 0;
}
@@ -728,15 +743,15 @@
return ll_new_hw_segment(q, req, bio);
}
-@@ -383,7 +309,6 @@ static int ll_merge_requests_fn(struct r
+@@ -391,7 +317,6 @@ static int ll_merge_requests_fn(struct r
struct request *next)
{
int total_phys_segments;
- int total_hw_segments;
+ unsigned int seg_size =
+ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
- /*
- * First check if the either of the requests are re-queued
-@@ -405,26 +330,11 @@ static int ll_merge_requests_fn(struct r
+@@ -420,26 +345,11 @@ static int ll_merge_requests_fn(struct r
if (total_phys_segments > q->max_phys_segments)
return 0;
@@ -764,8 +779,10 @@
return 1;
}
---- a/block/blk-settings.c
-+++ b/block/blk-settings.c
+Index: linux-2.6.27/block/blk-settings.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-settings.c
++++ linux-2.6.27/block/blk-settings.c
@@ -144,7 +144,7 @@ EXPORT_SYMBOL(blk_queue_make_request);
* Different hardware can have different requirements as to what pages
* it can do I/O directly to. A low level driver can call
@@ -802,8 +819,10 @@
* If the requested alignment is larger than the current alignment, then
* the current queue alignment is updated to the new value, otherwise it
* is left alone. The design of this is to allow multiple objects
+Index: linux-2.6.27/block/blk-softirq.c
+===================================================================
--- /dev/null
-+++ b/block/blk-softirq.c
++++ linux-2.6.27/block/blk-softirq.c
@@ -0,0 +1,103 @@
+/*
+ * Functions related to softirq rq completions
@@ -908,8 +927,10 @@
+ return 0;
+}
+subsys_initcall(blk_softirq_init);
---- a/block/blk-tag.c
-+++ b/block/blk-tag.c
+Index: linux-2.6.27/block/blk-tag.c
+===================================================================
+--- linux-2.6.27.orig/block/blk-tag.c
++++ linux-2.6.27/block/blk-tag.c
@@ -29,7 +29,7 @@ EXPORT_SYMBOL(blk_queue_find_tag);
* __blk_free_tags - release a given set of tag maintenance info
* @bqt: the tag map to free
@@ -946,8 +967,10 @@
* all transfers have been done for a request. It's important to call
* this function before end_that_request_last(), as that will put the
* request back on the free list thus corrupting the internal tag list.
---- a/block/cfq-iosched.c
-+++ b/block/cfq-iosched.c
+Index: linux-2.6.27/block/cfq-iosched.c
+===================================================================
+--- linux-2.6.27.orig/block/cfq-iosched.c
++++ linux-2.6.27/block/cfq-iosched.c
@@ -39,6 +39,7 @@ static int cfq_slice_idle = HZ / 125;
#define CFQ_MIN_TT (2)
@@ -971,7 +994,7 @@
/*
* idle window management
-@@ -654,15 +662,6 @@ static void cfq_activate_request(struct
+@@ -654,15 +662,6 @@ static void cfq_activate_request(struct
cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d",
cfqd->rq_in_driver);
@@ -1052,8 +1075,10 @@
return cfqd;
}
---- a/block/deadline-iosched.c
-+++ b/block/deadline-iosched.c
+Index: linux-2.6.27/block/deadline-iosched.c
+===================================================================
+--- linux-2.6.27.orig/block/deadline-iosched.c
++++ linux-2.6.27/block/deadline-iosched.c
@@ -33,7 +33,7 @@ struct deadline_data {
*/
struct rb_root sort_list[2];
@@ -1094,7 +1119,7 @@
}
static inline void
-@@ -91,7 +91,7 @@ deadline_del_rq_rb(struct deadline_data
+@@ -91,7 +91,7 @@ deadline_del_rq_rb(struct deadline_data
if (dd->next_rq[data_dir] == rq)
dd->next_rq[data_dir] = deadline_latter_request(rq);
@@ -1160,8 +1185,10 @@
/*
* at this point we are not running a batch. select the appropriate
---- a/block/elevator.c
-+++ b/block/elevator.c
+Index: linux-2.6.27/block/elevator.c
+===================================================================
+--- linux-2.6.27.orig/block/elevator.c
++++ linux-2.6.27/block/elevator.c
@@ -34,8 +34,7 @@
#include <linux/delay.h>
#include <linux/blktrace_api.h>
@@ -1172,7 +1199,7 @@
static DEFINE_SPINLOCK(elv_list_lock);
static LIST_HEAD(elv_list);
-@@ -790,7 +789,6 @@ struct request *elv_next_request(struct
+@@ -790,7 +789,6 @@ struct request *elv_next_request(struct
* device can handle
*/
rq->nr_phys_segments++;
@@ -1180,7 +1207,7 @@
}
if (!q->prep_rq_fn)
-@@ -813,7 +811,6 @@ struct request *elv_next_request(struct
+@@ -813,7 +811,6 @@ struct request *elv_next_request(struct
* so that we don't add it again
*/
--rq->nr_phys_segments;
@@ -1188,8 +1215,10 @@
}
rq = NULL;
---- a/block/genhd.c
-+++ b/block/genhd.c
+Index: linux-2.6.27/block/genhd.c
+===================================================================
+--- linux-2.6.27.orig/block/genhd.c
++++ linux-2.6.27/block/genhd.c
@@ -211,10 +211,11 @@ void unlink_gendisk(struct gendisk *disk
/**
@@ -1204,8 +1233,10 @@
*/
struct gendisk *get_gendisk(dev_t devt, int *part)
{
---- a/block/Makefile
-+++ b/block/Makefile
+Index: linux-2.6.27/block/Makefile
+===================================================================
+--- linux-2.6.27.orig/block/Makefile
++++ linux-2.6.27/block/Makefile
@@ -4,8 +4,8 @@
obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
@@ -1217,8 +1248,10 @@
obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
---- a/Documentation/block/deadline-iosched.txt
-+++ b/Documentation/block/deadline-iosched.txt
+Index: linux-2.6.27/Documentation/block/deadline-iosched.txt
+===================================================================
+--- linux-2.6.27.orig/Documentation/block/deadline-iosched.txt
++++ linux-2.6.27/Documentation/block/deadline-iosched.txt
@@ -30,12 +30,18 @@ write_expire (in ms)
Similar to read_expire mentioned above, but for writes.
@@ -1242,8 +1275,10 @@
writes_starved (number of dispatches)
---- a/Documentation/DocBook/kernel-api.tmpl
-+++ b/Documentation/DocBook/kernel-api.tmpl
+Index: linux-2.6.27/Documentation/DocBook/kernel-api.tmpl
+===================================================================
+--- linux-2.6.27.orig/Documentation/DocBook/kernel-api.tmpl
++++ linux-2.6.27/Documentation/DocBook/kernel-api.tmpl
@@ -364,6 +364,10 @@ X!Edrivers/pnp/system.c
!Eblock/blk-barrier.c
!Eblock/blk-tag.c
@@ -1255,8 +1290,10 @@
</chapter>
<chapter id="chrdev">
---- a/drivers/block/ps3disk.c
-+++ b/drivers/block/ps3disk.c
+Index: linux-2.6.27/drivers/block/ps3disk.c
+===================================================================
+--- linux-2.6.27.orig/drivers/block/ps3disk.c
++++ linux-2.6.27/drivers/block/ps3disk.c
@@ -199,7 +199,8 @@ static void ps3disk_do_request(struct ps
if (blk_fs_request(req)) {
if (ps3disk_submit_request_sg(dev, req))
@@ -1287,9 +1324,11 @@
}
static unsigned long ps3disk_mask;
---- a/drivers/block/virtio_blk.c
-+++ b/drivers/block/virtio_blk.c
-@@ -84,11 +84,11 @@ static bool do_req(struct request_queue
+Index: linux-2.6.27/drivers/block/virtio_blk.c
+===================================================================
+--- linux-2.6.27.orig/drivers/block/virtio_blk.c
++++ linux-2.6.27/drivers/block/virtio_blk.c
+@@ -84,11 +84,11 @@ static bool do_req(struct request_queue
if (blk_fs_request(vbr->req)) {
vbr->out_hdr.type = 0;
vbr->out_hdr.sector = vbr->req->sector;
@@ -1303,8 +1342,10 @@
} else {
/* We don't put anything else in the queue. */
BUG();
---- a/drivers/md/raid10.c
-+++ b/drivers/md/raid10.c
+Index: linux-2.6.27/drivers/md/raid10.c
+===================================================================
+--- linux-2.6.27.orig/drivers/md/raid10.c
++++ linux-2.6.27/drivers/md/raid10.c
@@ -1345,9 +1345,6 @@ static void sync_request_write(mddev_t *
tbio->bi_size = r10_bio->sectors << 9;
tbio->bi_idx = 0;
@@ -1323,8 +1364,10 @@
bio->bi_size = 0;
}
---- a/drivers/md/raid1.c
-+++ b/drivers/md/raid1.c
+Index: linux-2.6.27/drivers/md/raid1.c
+===================================================================
+--- linux-2.6.27.orig/drivers/md/raid1.c
++++ linux-2.6.27/drivers/md/raid1.c
@@ -1302,9 +1302,6 @@ static void sync_request_write(mddev_t *
sbio->bi_size = r1_bio->sectors << 9;
sbio->bi_idx = 0;
@@ -1343,8 +1386,10 @@
bio->bi_size = 0;
bio->bi_end_io = NULL;
bio->bi_private = NULL;
---- a/drivers/md/raid5.c
-+++ b/drivers/md/raid5.c
+Index: linux-2.6.27/drivers/md/raid5.c
+===================================================================
+--- linux-2.6.27.orig/drivers/md/raid5.c
++++ linux-2.6.27/drivers/md/raid5.c
@@ -101,6 +101,40 @@
const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
#endif
@@ -1517,8 +1562,10 @@
spin_unlock_irq(&conf->device_lock);
if (remaining == 0)
bio_endio(raid_bio, 0);
---- a/fs/bio.c
-+++ b/fs/bio.c
+Index: linux-2.6.27/fs/bio.c
+===================================================================
+--- linux-2.6.27.orig/fs/bio.c
++++ linux-2.6.27/fs/bio.c
@@ -208,14 +208,6 @@ inline int bio_phys_segments(struct requ
return bio->bi_phys_segments;
}
@@ -1567,8 +1614,10 @@
EXPORT_SYMBOL(bio_add_page);
EXPORT_SYMBOL(bio_add_pc_page);
EXPORT_SYMBOL(bio_get_nr_vecs);
---- a/include/linux/bio.h
-+++ b/include/linux/bio.h
+Index: linux-2.6.27/include/linux/bio.h
+===================================================================
+--- linux-2.6.27.orig/include/linux/bio.h
++++ linux-2.6.27/include/linux/bio.h
@@ -26,21 +26,8 @@
#ifdef CONFIG_BLOCK
@@ -1591,7 +1640,7 @@
#define BIO_DEBUG
#ifdef BIO_DEBUG
-@@ -88,23 +75,10 @@ struct bio {
+@@ -88,12 +75,7 @@ struct bio {
/* Number of segments in this BIO after
* physical address coalescing is performed.
*/
@@ -1605,6 +1654,10 @@
unsigned int bi_size; /* residual I/O count */
+@@ -104,14 +86,6 @@ struct bio {
+ unsigned int bi_seg_front_size;
+ unsigned int bi_seg_back_size;
+
- /*
- * To keep track of the max hw size, we account for the
- * sizes of the first and last virtually mergeable segments
@@ -1616,7 +1669,7 @@
unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
struct bio_vec *bi_io_vec; /* the actual vec list */
-@@ -126,7 +100,7 @@ struct bio {
+@@ -133,7 +107,7 @@ struct bio {
#define BIO_UPTODATE 0 /* ok after I/O completion */
#define BIO_RW_BLOCK 1 /* RW_AHEAD set, and read/write would block */
#define BIO_EOF 2 /* out-out-bounds error */
@@ -1625,7 +1678,7 @@
#define BIO_CLONED 4 /* doesn't own data */
#define BIO_BOUNCED 5 /* bio is a bounce bio */
#define BIO_USER_MAPPED 6 /* contains user pages */
-@@ -240,8 +214,6 @@ static inline void *bio_data(struct bio
+@@ -247,8 +221,6 @@ static inline void *bio_data(struct bio
((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
#endif
@@ -1634,7 +1687,7 @@
#define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \
(((addr1) | (mask)) == (((addr2) - 1) | (mask)))
#define BIOVEC_SEG_BOUNDARY(q, b1, b2) \
-@@ -339,7 +311,6 @@ extern void bio_free(struct bio *, struc
+@@ -346,7 +318,6 @@ extern void bio_free(struct bio *, struc
extern void bio_endio(struct bio *, int);
struct request_queue;
extern int bio_phys_segments(struct request_queue *, struct bio *);
@@ -1642,8 +1695,10 @@
extern void __bio_clone(struct bio *, struct bio *);
extern struct bio *bio_clone(struct bio *, gfp_t);
---- a/include/linux/blkdev.h
-+++ b/include/linux/blkdev.h
+Index: linux-2.6.27/include/linux/blkdev.h
+===================================================================
+--- linux-2.6.27.orig/include/linux/blkdev.h
++++ linux-2.6.27/include/linux/blkdev.h
@@ -54,7 +54,6 @@ enum rq_cmd_type_bits {
REQ_TYPE_PM_SUSPEND, /* suspend request */
REQ_TYPE_PM_RESUME, /* resume request */
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/block-rq-affinity
^
|
@@ -9,11 +9,24 @@
Signed-off-by: Hannes Reinecke <hare@suse.de>
-diff --git a/block/as-iosched.c b/block/as-iosched.c
-index cf4eb0e..80af925 100644
+---
+ block/as-iosched.c | 6 +-
+ block/blk-core.c | 54 ++++++++++----------
+ block/blk-merge.c | 2
+ block/blk-settings.c | 2
+ block/blk-softirq.c | 126 +++++++++++++++++++++++++++++++++++------------
+ block/blk-sysfs.c | 31 +++++++++++
+ block/blk.h | 12 ++++
+ block/cfq-iosched.c | 2
+ fs/bio.c | 1
+ include/linux/bio.h | 11 ++++
+ include/linux/blkdev.h | 8 ++
+ include/linux/elevator.h | 8 +-
+ 12 files changed, 196 insertions(+), 67 deletions(-)
+
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
-@@ -462,7 +462,7 @@ static void as_antic_stop(struct as_data *ad)
+@@ -462,7 +462,7 @@ static void as_antic_stop(struct as_data
del_timer(&ad->antic_timer);
ad->antic_status = ANTIC_FINISHED;
/* see as_work_handler */
@@ -22,7 +35,7 @@
}
}
-@@ -483,7 +483,7 @@ static void as_antic_timeout(unsigned long data)
+@@ -483,7 +483,7 @@ static void as_antic_timeout(unsigned lo
aic = ad->io_context->aic;
ad->antic_status = ANTIC_FINISHED;
@@ -31,7 +44,7 @@
if (aic->ttime_samples == 0) {
/* process anticipated on has exited or timed out*/
-@@ -844,7 +844,7 @@ static void as_completed_request(struct request_queue *q, struct request *rq)
+@@ -844,7 +844,7 @@ static void as_completed_request(struct
if (ad->changed_batch && ad->nr_dispatched == 1) {
ad->current_batch_expires = jiffies +
ad->batch_expire[ad->batch_data_dir];
@@ -40,11 +53,9 @@
ad->changed_batch = 0;
if (ad->batch_data_dir == REQ_SYNC)
-diff --git a/block/blk-core.c b/block/blk-core.c
-index 4238299..6075f54 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
-@@ -109,7 +109,7 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
+@@ -109,7 +109,7 @@ void blk_rq_init(struct request_queue *q
memset(rq, 0, sizeof(*rq));
INIT_LIST_HEAD(&rq->queuelist);
@@ -53,7 +64,7 @@
rq->q = q;
rq->sector = rq->hard_sector = (sector_t) -1;
INIT_HLIST_NODE(&rq->hash);
-@@ -304,7 +304,7 @@ void blk_unplug_timeout(unsigned long data)
+@@ -304,7 +304,7 @@ void blk_unplug_timeout(unsigned long da
blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_TIMER, NULL,
q->rq.count[READ] + q->rq.count[WRITE]);
@@ -84,7 +95,7 @@
/**
* blk_start_queue - restart a previously stopped queue
* @q: The &struct request_queue in question
-@@ -335,18 +350,7 @@ void blk_start_queue(struct request_queue *q)
+@@ -335,18 +350,7 @@ void blk_start_queue(struct request_queu
WARN_ON(!irqs_disabled());
queue_flag_clear(QUEUE_FLAG_STOPPED, q);
@@ -104,7 +115,7 @@
}
EXPORT_SYMBOL(blk_start_queue);
-@@ -404,15 +408,8 @@ void __blk_run_queue(struct request_queue *q)
+@@ -404,15 +408,8 @@ void __blk_run_queue(struct request_queu
* Only recurse once to avoid overrunning the stack, let the unplug
* handling reinvoke the handler shortly if we already got there.
*/
@@ -130,7 +141,7 @@
req->cmd_type = REQ_TYPE_FS;
/*
-@@ -1142,6 +1140,8 @@ static int __make_request(struct request_queue *q, struct bio *bio)
+@@ -1142,6 +1140,8 @@ static int __make_request(struct request
req->biotail = bio;
req->nr_sectors = req->hard_nr_sectors += nr_sectors;
req->ioprio = ioprio_best(req->ioprio, prio);
@@ -139,7 +150,7 @@
drive_stat_acct(req, 0);
if (!attempt_back_merge(q, req))
elv_merged_request(q, req, el_ret);
-@@ -1169,6 +1169,8 @@ static int __make_request(struct request_queue *q, struct bio *bio)
+@@ -1169,6 +1169,8 @@ static int __make_request(struct request
req->sector = req->hard_sector = bio->bi_sector;
req->nr_sectors = req->hard_nr_sectors += nr_sectors;
req->ioprio = ioprio_best(req->ioprio, prio);
@@ -165,7 +176,7 @@
spin_unlock_irq(q->queue_lock);
return 0;
-@@ -1958,7 +1962,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
+@@ -1958,7 +1962,7 @@ void blk_rq_bio_prep(struct request_queu
rq->rq_disk = bio->bi_bdev->bd_disk;
}
@@ -174,11 +185,28 @@
{
return queue_work(kblockd_workqueue, work);
}
-diff --git a/block/blk-merge.c b/block/blk-merge.c
-index d81d914..ad271c0 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -59,4 +59,16 @@ static inline int queue_congestion_off_t
+
+ #endif /* BLK_DEV_INTEGRITY */
+
++static inline int blk_cpu_to_group(int cpu)
++{
++#ifdef CONFIG_SCHED_MC
++ cpumask_t mask = cpu_coregroup_map(cpu);
++ return first_cpu(mask);
++#elif defined(CONFIG_SCHED_SMT)
++ return first_cpu(per_cpu(cpu_sibling_map, cpu));
++#else
++ return cpu;
++#endif
++}
++
+ #endif
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
-@@ -398,6 +398,8 @@ static int attempt_merge(struct request_queue *q, struct request *req,
+@@ -413,6 +413,8 @@ static int attempt_merge(struct request_
}
req->ioprio = ioprio_best(req->ioprio, next->ioprio);
@@ -187,11 +215,9 @@
__blk_put_request(q, next);
return 1;
-diff --git a/block/blk-settings.c b/block/blk-settings.c
-index d70692b..a60e959 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
-@@ -443,7 +443,7 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask)
+@@ -443,7 +443,7 @@ void blk_queue_update_dma_alignment(stru
}
EXPORT_SYMBOL(blk_queue_update_dma_alignment);
@@ -200,8 +226,6 @@
{
blk_max_low_pfn = max_low_pfn - 1;
blk_max_pfn = max_pfn - 1;
-diff --git a/block/blk-softirq.c b/block/blk-softirq.c
-index 9e1c43b..3a1af55 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -13,6 +13,70 @@
@@ -275,7 +299,7 @@
static int __cpuinit blk_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
-@@ -33,33 +97,10 @@ static int __cpuinit blk_cpu_notify(struct notifier_block *self,
+@@ -33,33 +97,10 @@ static int __cpuinit blk_cpu_notify(stru
return NOTIFY_OK;
}
@@ -310,7 +334,7 @@
/**
* blk_complete_request - end I/O on a request
* @req: the request being processed
-@@ -71,25 +112,48 @@ static void blk_done_softirq(struct softirq_action *h)
+@@ -71,25 +112,48 @@ static void blk_done_softirq(struct soft
* through a softirq handler. The user must have registered a completion
* callback through blk_queue_softirq_done().
**/
@@ -366,11 +390,9 @@
{
int i;
-diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
-index 304ec73..196f079 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
-@@ -156,6 +156,30 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
+@@ -156,6 +156,30 @@ static ssize_t queue_nomerges_store(stru
return ret;
}
@@ -401,7 +423,7 @@
static struct queue_sysfs_entry queue_requests_entry = {
.attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
-@@ -197,6 +221,12 @@ static struct queue_sysfs_entry queue_nomerges_entry = {
+@@ -197,6 +221,12 @@ static struct queue_sysfs_entry queue_no
.store = queue_nomerges_store,
};
@@ -414,7 +436,7 @@
static struct attribute *default_attrs[] = {
&queue_requests_entry.attr,
&queue_ra_entry.attr,
-@@ -205,6 +235,7 @@ static struct attribute *default_attrs[] = {
+@@ -205,6 +235,7 @@ static struct attribute *default_attrs[]
&queue_iosched_entry.attr,
&queue_hw_sector_size_entry.attr,
&queue_nomerges_entry.attr,
@@ -422,32 +444,9 @@
NULL,
};
-diff --git a/block/blk.h b/block/blk.h
-index c79f30e..de74254 100644
---- a/block/blk.h
-+++ b/block/blk.h
-@@ -59,4 +59,16 @@ static inline int queue_congestion_off_threshold(struct request_queue *q)
-
- #endif /* BLK_DEV_INTEGRITY */
-
-+static inline int blk_cpu_to_group(int cpu)
-+{
-+#ifdef CONFIG_SCHED_MC
-+ cpumask_t mask = cpu_coregroup_map(cpu);
-+ return first_cpu(mask);
-+#elif defined(CONFIG_SCHED_SMT)
-+ return first_cpu(per_cpu(cpu_sibling_map, cpu));
-+#else
-+ return cpu;
-+#endif
-+}
-+
- #endif
-diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
-index 01ebb75..494b6fd 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
-@@ -252,7 +252,7 @@ static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
+@@ -252,7 +252,7 @@ static inline void cfq_schedule_dispatch
{
if (cfqd->busy_queues) {
cfq_log(cfqd, "schedule dispatch");
@@ -456,8 +455,6 @@
}
}
-diff --git a/fs/bio.c b/fs/bio.c
-index 9545306..7a0283d 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -111,6 +111,7 @@ void bio_init(struct bio *bio)
@@ -468,11 +465,9 @@
atomic_set(&bio->bi_cnt, 1);
}
-diff --git a/include/linux/bio.h b/include/linux/bio.h
-index 2c0c090..13aba20 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
-@@ -81,6 +81,8 @@ struct bio {
+@@ -88,6 +88,8 @@ struct bio {
unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
@@ -481,7 +476,7 @@
struct bio_vec *bi_io_vec; /* the actual vec list */
bio_end_io_t *bi_end_io;
-@@ -105,6 +107,7 @@ struct bio {
+@@ -112,6 +114,7 @@ struct bio {
#define BIO_BOUNCED 5 /* bio is a bounce bio */
#define BIO_USER_MAPPED 6 /* contains user pages */
#define BIO_EOPNOTSUPP 7 /* not supported */
@@ -489,7 +484,7 @@
#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
/*
-@@ -343,6 +346,14 @@ extern struct bio_vec *bvec_alloc_bs(gfp_t, int, unsigned long *, struct bio_set
+@@ -350,6 +353,14 @@ extern struct bio_vec *bvec_alloc_bs(gfp
extern unsigned int bvec_nr_vecs(unsigned short idx);
/*
@@ -504,8 +499,6 @@
* bio_set is used to allow other portions of the IO system to
* allocate their own private memory pools for bio and iovec structures.
* These memory pools in turn all allocate from the bio_slab
-diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
-index 1adb038..12df8ef 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -17,6 +17,7 @@
@@ -542,7 +535,7 @@
#define blk_sorted_rq(rq) ((rq)->cmd_flags & REQ_SORTED)
#define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER)
#define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA)
-@@ -912,7 +916,7 @@ static inline void put_dev_sector(Sector p)
+@@ -912,7 +916,7 @@ static inline void put_dev_sector(Sector
}
struct work_struct;
@@ -551,8 +544,6 @@
void kblockd_flush_work(struct work_struct *work);
#define MODULE_ALIAS_BLOCKDEV(major,minor) \
-diff --git a/include/linux/elevator.h b/include/linux/elevator.h
-index 639624b..bb791c3 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -173,15 +173,15 @@ enum {
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/block-use-bio_has_data
^
|
@@ -12,11 +12,9 @@
mm/bounce.c | 2 +-
4 files changed, 20 insertions(+), 19 deletions(-)
-diff --git a/block/blk-core.c b/block/blk-core.c
-index 2cba5ef..a496727 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
-@@ -624,10 +624,6 @@ blk_alloc_request(struct request_queue *q, int rw, int priv, gfp_t gfp_mask)
+@@ -624,10 +624,6 @@ blk_alloc_request(struct request_queue *
blk_rq_init(q, rq);
@@ -39,7 +37,7 @@
if (rw & WRITE) {
count_vm_events(PGPGOUT, count);
-@@ -1888,7 +1881,7 @@ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
+@@ -1888,7 +1881,7 @@ static int blk_end_io(struct request *rq
struct request_queue *q = rq->q;
unsigned long flags = 0UL;
@@ -62,7 +60,7 @@
add_disk_randomness(rq->rq_disk);
-@@ -2016,7 +2008,8 @@ EXPORT_SYMBOL_GPL(blk_end_request_callback);
+@@ -2016,7 +2008,8 @@ EXPORT_SYMBOL_GPL(blk_end_request_callba
void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
struct bio *bio)
{
@@ -72,11 +70,9 @@
rq->cmd_flags |= (bio->bi_rw & 3);
rq->nr_phys_segments = bio_phys_segments(q, bio);
-diff --git a/include/linux/bio.h b/include/linux/bio.h
-index 0933a14..17f1fbd 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
-@@ -150,8 +150,8 @@ struct bio {
+@@ -157,8 +157,8 @@ struct bio {
* bit 3 -- fail fast, don't want low level driver retries
* bit 4 -- synchronous I/O hint: the block layer will unplug immediately
*/
@@ -87,7 +83,7 @@
#define BIO_RW_BARRIER 2
#define BIO_RW_FAILFAST 3
#define BIO_RW_SYNC 4
-@@ -185,7 +185,7 @@ struct bio {
+@@ -192,7 +192,7 @@ struct bio {
#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META))
@@ -96,7 +92,7 @@
static inline unsigned int bio_cur_sectors(struct bio *bio)
{
-@@ -445,6 +445,14 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
+@@ -452,6 +452,14 @@ static inline char *__bio_kmap_irq(struc
__bio_kmap_irq((bio), (bio)->bi_idx, (flags))
#define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags)
@@ -111,8 +107,6 @@
#if defined(CONFIG_BLK_DEV_INTEGRITY)
#define bip_vec_idx(bip, idx) (&(bip->bip_vec[(idx)]))
-diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
-index 44710d7..e6c69c8 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -84,7 +84,7 @@ enum {
@@ -124,11 +118,9 @@
*/
enum rq_flag_bits {
__REQ_RW, /* not set, read. set, write */
-diff --git a/mm/bounce.c b/mm/bounce.c
-index b6d2d0f..06722c4 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
-@@ -267,7 +267,7 @@ void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
+@@ -267,7 +267,7 @@ void blk_queue_bounce(struct request_que
/*
* Data-less bio, nothing to bounce
*/
@@ -137,6 +129,3 @@
return;
/*
---
-1.5.2.4
-
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/bug-437171_1_sched_clock_lock.patch
^
|
@@ -0,0 +1,31 @@
+Subject: sched: only update rq->clock while holding rq->lock
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+References: 437171 - LTC47404
+
+Vatsa noticed rq->clock going funny and tracked it down to an update_rq_clock()
+outside a rq->lock section.
+
+This is a problem because things like double_rq_lock() update the rq->clock
+value for both rqs. Therefore disabling interrupts isn't strong enough.
+
+Reported-by: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Olaf Hering <olh@suse.de>
+
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -4454,12 +4454,9 @@ need_resched_nonpreemptible:
+ if (sched_feat(HRTICK))
+ hrtick_clear(rq);
+
+- /*
+- * Do the rq-clock update outside the rq lock:
+- */
+ local_irq_disable();
+- update_rq_clock(rq);
+ spin_lock(&rq->lock);
++ update_rq_clock(rq);
+ clear_tsk_need_resched(prev);
+
+ if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/bug-437171_2_sched_delta_weight.patch
^
|
@@ -0,0 +1,109 @@
+Subject: sched: revert back to per-rq vruntime
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+References: 437171 - LTC47404
+
+Vatsa rightly points out that having the runqueue weight in the vruntime
+calculations can cause unfairness in the face of task joins/leaves.
+
+Suppose: dv = dt * rw / w
+
+Then take 10 tasks t_n, each of similar weight. If the first will run 1
+then its vruntime will increase by 10. Now, if the next 8 tasks leave after
+having run their 1, then the last task will get a vruntime increase of 2
+after having run 1.
+
+Which will leave us with 2 tasks of equal weight and equal runtime, of which
+one will not be scheduled for 8/2=4 units of time.
+
+Ergo, we cannot do that and must use: dv = dt / w.
+
+This means we cannot have a global vruntime based on effective priority, but
+must instead go back to the vruntime per rq model we started out with.
+
+This patch was lightly tested by doing starting while loops on each nice level
+and observing their execution time, and a simple group scenario of 1:2:3 pinned
+to a single cpu.
+
+Reported-by: Srivatsa Vaddagiri <vatsa@in.ibm.com>
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Olaf Hering <olh@suse.de>
+---
+ kernel/sched_fair.c | 32 +++++++++++++++-----------------
+ 1 file changed, 15 insertions(+), 17 deletions(-)
+
+--- a/kernel/sched_fair.c
++++ b/kernel/sched_fair.c
+@@ -334,7 +334,7 @@ int sched_nr_latency_handler(struct ctl_
+ #endif
+
+ /*
+- * delta *= w / rw
++ * delta *= P[w / rw]
+ */
+ static inline unsigned long
+ calc_delta_weight(unsigned long delta, struct sched_entity *se)
+@@ -348,15 +348,13 @@ calc_delta_weight(unsigned long delta, s
+ }
+
+ /*
+- * delta *= rw / w
++ * delta /= w
+ */
+ static inline unsigned long
+ calc_delta_fair(unsigned long delta, struct sched_entity *se)
+ {
+- for_each_sched_entity(se) {
+- delta = calc_delta_mine(delta,
+- cfs_rq_of(se)->load.weight, &se->load);
+- }
++ if (unlikely(se->load.weight != NICE_0_LOAD))
++ delta = calc_delta_mine(delta, NICE_0_LOAD, &se->load);
+
+ return delta;
+ }
+@@ -386,26 +384,26 @@ static u64 __sched_period(unsigned long
+ * We calculate the wall-time slice from the period by taking a part
+ * proportional to the weight.
+ *
+- * s = p*w/rw
++ * s = p*P[w/rw]
+ */
+ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
+ {
+- return calc_delta_weight(__sched_period(cfs_rq->nr_running), se);
++ unsigned long nr_running = cfs_rq->nr_running;
++
++ if (unlikely(!se->on_rq))
++ nr_running++;
++
++ return calc_delta_weight(__sched_period(nr_running), se);
+ }
+
+ /*
+ * We calculate the vruntime slice of a to be inserted task
+ *
+- * vs = s*rw/w = p
++ * vs = s/w
+ */
+-static u64 sched_vslice_add(struct cfs_rq *cfs_rq, struct sched_entity *se)
++static u64 sched_vslice(struct cfs_rq *cfs_rq, struct sched_entity *se)
+ {
+- unsigned long nr_running = cfs_rq->nr_running;
+-
+- if (!se->on_rq)
+- nr_running++;
+-
+- return __sched_period(nr_running);
++ return calc_delta_fair(sched_slice(cfs_rq, se), se);
+ }
+
+ /*
+@@ -683,7 +681,7 @@ place_entity(struct cfs_rq *cfs_rq, stru
+ * stays open at the end.
+ */
+ if (initial && sched_feat(START_DEBIT))
+- vruntime += sched_vslice_add(cfs_rq, se);
++ vruntime += sched_vslice(cfs_rq, se);
+
+ if (!initial) {
+ /* sleeps upto a single latency don't count. */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/bug-437171_3_rework_wakeup_preemption.patch
^
|
@@ -0,0 +1,184 @@
+Subject: sched: rework wakeup preemption
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+References: 437171 - LTC47404
+
+
+ Rework the wakeup preemption to work on real runtime instead of
+ the virtual runtime. This greatly simplifies the code.
+
+ Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+ Signed-off-by: Ingo Molnar <mingo@elte.hu>
+
+Signed-off-by: Olaf Hering <olh@suse.de>
+---
+ kernel/sched_fair.c | 133 +---------------------------------------------------
+ 1 file changed, 4 insertions(+), 129 deletions(-)
+
+--- a/kernel/sched_fair.c
++++ b/kernel/sched_fair.c
+@@ -407,64 +407,6 @@ static u64 sched_vslice(struct cfs_rq *c
+ }
+
+ /*
+- * The goal of calc_delta_asym() is to be asymmetrically around NICE_0_LOAD, in
+- * that it favours >=0 over <0.
+- *
+- * -20 |
+- * |
+- * 0 --------+-------
+- * .'
+- * 19 .'
+- *
+- */
+-static unsigned long
+-calc_delta_asym(unsigned long delta, struct sched_entity *se)
+-{
+- struct load_weight lw = {
+- .weight = NICE_0_LOAD,
+- .inv_weight = 1UL << (WMULT_SHIFT-NICE_0_SHIFT)
+- };
+-
+- for_each_sched_entity(se) {
+- struct load_weight *se_lw = &se->load;
+- unsigned long rw = cfs_rq_of(se)->load.weight;
+-
+-#ifdef CONFIG_FAIR_SCHED_GROUP
+- struct cfs_rq *cfs_rq = se->my_q;
+- struct task_group *tg = NULL
+-
+- if (cfs_rq)
+- tg = cfs_rq->tg;
+-
+- if (tg && tg->shares < NICE_0_LOAD) {
+- /*
+- * scale shares to what it would have been had
+- * tg->weight been NICE_0_LOAD:
+- *
+- * weight = 1024 * shares / tg->weight
+- */
+- lw.weight *= se->load.weight;
+- lw.weight /= tg->shares;
+-
+- lw.inv_weight = 0;
+-
+- se_lw = &lw;
+- rw += lw.weight - se->load.weight;
+- } else
+-#endif
+-
+- if (se->load.weight < NICE_0_LOAD) {
+- se_lw = &lw;
+- rw += NICE_0_LOAD - se->load.weight;
+- }
+-
+- delta = calc_delta_mine(delta, rw, se_lw);
+- }
+-
+- return delta;
+-}
+-
+-/*
+ * Update the current task's runtime statistics. Skip current tasks that
+ * are not in our scheduling class.
+ */
+@@ -1279,54 +1221,12 @@ static unsigned long wakeup_gran(struct
+ * + nice tasks.
+ */
+ if (sched_feat(ASYM_GRAN))
+- gran = calc_delta_asym(sysctl_sched_wakeup_granularity, se);
+- else
+- gran = calc_delta_fair(sysctl_sched_wakeup_granularity, se);
++ gran = calc_delta_mine(gran, NICE_0_LOAD, &se->load);
+
+ return gran;
+ }
+
+ /*
+- * Should 'se' preempt 'curr'.
+- *
+- * |s1
+- * |s2
+- * |s3
+- * g
+- * |<--->|c
+- *
+- * w(c, s1) = -1
+- * w(c, s2) = 0
+- * w(c, s3) = 1
+- *
+- */
+-static int
+-wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
+-{
+- s64 gran, vdiff = curr->vruntime - se->vruntime;
+-
+- if (vdiff < 0)
+- return -1;
+-
+- gran = wakeup_gran(curr);
+- if (vdiff > gran)
+- return 1;
+-
+- return 0;
+-}
+-
+-/* return depth at which a sched entity is present in the hierarchy */
+-static inline int depth_se(struct sched_entity *se)
+-{
+- int depth = 0;
+-
+- for_each_sched_entity(se)
+- depth++;
+-
+- return depth;
+-}
+-
+-/*
+ * Preempt the current task with a newly woken task if needed:
+ */
+ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
+@@ -1334,7 +1234,7 @@ static void check_preempt_wakeup(struct
+ struct task_struct *curr = rq->curr;
+ struct cfs_rq *cfs_rq = task_cfs_rq(curr);
+ struct sched_entity *se = &curr->se, *pse = &p->se;
+- int se_depth, pse_depth;
++ s64 delta_exec;
+
+ if (unlikely(rt_prio(p->prio))) {
+ update_rq_clock(rq);
+@@ -1358,33 +1258,8 @@ static void check_preempt_wakeup(struct
+ if (!sched_feat(WAKEUP_PREEMPT))
+ return;
+
+- /*
+- * preemption test can be made between sibling entities who are in the
+- * same cfs_rq i.e who have a common parent. Walk up the hierarchy of
+- * both tasks until we find their ancestors who are siblings of common
+- * parent.
+- */
+-
+- /* First walk up until both entities are at same depth */
+- se_depth = depth_se(se);
+- pse_depth = depth_se(pse);
+-
+- while (se_depth > pse_depth) {
+- se_depth--;
+- se = parent_entity(se);
+- }
+-
+- while (pse_depth > se_depth) {
+- pse_depth--;
+- pse = parent_entity(pse);
+- }
+-
+- while (!is_same_group(se, pse)) {
+- se = parent_entity(se);
+- pse = parent_entity(pse);
+- }
+-
+- if (wakeup_preempt_entity(se, pse) == 1)
++ delta_exec = se->sum_exec_runtime - se->prev_sum_exec_runtime;
++ if (delta_exec > wakeup_gran(pse))
+ resched_task(curr);
+ }
+
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/bug-437171_4_sched_reinstate_vruntime_wakeup.patch
^
|
@@ -0,0 +1,155 @@
+Subject: sched: re-instate vruntime based wakeup preemption
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+References: 437171 - LTC47404
+
+The advantage is that vruntime based wakeup preemption has a better
+conceptual model. Here wakeup_gran = 0 means: preempt when 'fair'.
+Therefore wakeup_gran is the granularity of unfairness we allow in order
+to make progress.
+
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Olaf Hering <olh@suse.de>
+---
+ kernel/sched_fair.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 92 insertions(+), 6 deletions(-)
+
+--- a/kernel/sched_fair.c
++++ b/kernel/sched_fair.c
+@@ -141,6 +141,49 @@ static inline struct sched_entity *paren
+ return se->parent;
+ }
+
++/* return depth at which a sched entity is present in the hierarchy */
++static inline int depth_se(struct sched_entity *se)
++{
++ int depth = 0;
++
++ for_each_sched_entity(se)
++ depth++;
++
++ return depth;
++}
++
++static void
++find_matching_se(struct sched_entity **se, struct sched_entity **pse)
++{
++ int se_depth, pse_depth;
++
++ /*
++ * preemption test can be made between sibling entities who are in the
++ * same cfs_rq i.e who have a common parent. Walk up the hierarchy of
++ * both tasks until we find their ancestors who are siblings of common
++ * parent.
++ */
++
++ /* First walk up until both entities are at same depth */
++ se_depth = depth_se(*se);
++ pse_depth = depth_se(*pse);
++
++ while (se_depth > pse_depth) {
++ se_depth--;
++ *se = parent_entity(*se);
++ }
++
++ while (pse_depth > se_depth) {
++ pse_depth--;
++ *pse = parent_entity(*pse);
++ }
++
++ while (!is_same_group(*se, *pse)) {
++ *se = parent_entity(*se);
++ *pse = parent_entity(*pse);
++ }
++}
++
+ #else /* CONFIG_FAIR_GROUP_SCHED */
+
+ static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
+@@ -191,6 +234,11 @@ static inline struct sched_entity *paren
+ return NULL;
+ }
+
++static inline void
++find_matching_se(struct sched_entity **se, struct sched_entity **pse)
++{
++}
++
+ #endif /* CONFIG_FAIR_GROUP_SCHED */
+
+
+@@ -1220,13 +1268,42 @@ static unsigned long wakeup_gran(struct
+ * More easily preempt - nice tasks, while not making it harder for
+ * + nice tasks.
+ */
+- if (sched_feat(ASYM_GRAN))
+- gran = calc_delta_mine(gran, NICE_0_LOAD, &se->load);
++ if (!sched_feat(ASYM_GRAN) || se->load.weight > NICE_0_LOAD)
++ gran = calc_delta_fair(sysctl_sched_wakeup_granularity, se);
+
+ return gran;
+ }
+
+ /*
++ * Should 'se' preempt 'curr'.
++ *
++ * |s1
++ * |s2
++ * |s3
++ * g
++ * |<--->|c
++ *
++ * w(c, s1) = -1
++ * w(c, s2) = 0
++ * w(c, s3) = 1
++ *
++ */
++static int
++wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
++{
++ s64 gran, vdiff = curr->vruntime - se->vruntime;
++
++ if (vdiff <= 0)
++ return -1;
++
++ gran = wakeup_gran(curr);
++ if (vdiff > gran)
++ return 1;
++
++ return 0;
++}
++
++/*
+ * Preempt the current task with a newly woken task if needed:
+ */
+ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
+@@ -1234,7 +1311,6 @@ static void check_preempt_wakeup(struct
+ struct task_struct *curr = rq->curr;
+ struct cfs_rq *cfs_rq = task_cfs_rq(curr);
+ struct sched_entity *se = &curr->se, *pse = &p->se;
+- s64 delta_exec;
+
+ if (unlikely(rt_prio(p->prio))) {
+ update_rq_clock(rq);
+@@ -1258,9 +1334,19 @@ static void check_preempt_wakeup(struct
+ if (!sched_feat(WAKEUP_PREEMPT))
+ return;
+
+- delta_exec = se->sum_exec_runtime - se->prev_sum_exec_runtime;
+- if (delta_exec > wakeup_gran(pse))
+- resched_task(curr);
++ find_matching_se(&se, &pse);
++
++ while (se) {
++ BUG_ON(!pse);
++
++ if (wakeup_preempt_entity(se, pse) == 1) {
++ resched_task(curr);
++ break;
++ }
++
++ se = parent_entity(se);
++ pse = parent_entity(pse);
++ }
+ }
+
+ static struct task_struct *pick_next_task_fair(struct rq *rq)
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/cxgb3-remove-duplicate-tests-in-lro
^
|
@@ -12,11 +12,13 @@
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
-diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
-index 1b0861d..f78a42c 100644
+---
+ drivers/net/cxgb3/sge.c | 35 -----------------------------------
+ 1 file changed, 35 deletions(-)
+
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
-@@ -1937,38 +1937,6 @@ static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
+@@ -1934,38 +1934,6 @@ static inline int lro_frame_ok(const str
eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
}
@@ -55,7 +57,7 @@
static int t3_get_lro_header(void **eh, void **iph, void **tcph,
u64 *hdr_flags, void *priv)
{
-@@ -1981,9 +1949,6 @@ static int t3_get_lro_header(void **eh, void **iph, void **tcph,
+@@ -1978,9 +1946,6 @@ static int t3_get_lro_header(void **eh,
*iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
*tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/dcb-fix-setpfcstate
^
|
@@ -0,0 +1,53 @@
+Subject: Fix setpfcstate
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri Nov 7 15:36:08 2008 +0100:
+Git: f7e09ce313fdc4f79403d43b1ac570f6807973bd
+References: bnc#438954
+
+Fixup setpfcstate and setnumtcs command.
+
+Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
+index f5e2b0b..be9dcbb 100644
+--- a/net/dcb/dcbnl.c
++++ b/net/dcb/dcbnl.c
+@@ -435,7 +435,6 @@ static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb,
+ struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1];
+ int ret = -EINVAL;
+ u8 value;
+- u8 status;
+ int i;
+
+ if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->setstate)
+@@ -458,14 +457,11 @@ static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb,
+ ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value);
+
+ if (ret)
+- goto err;
++ goto operr;
+ }
+
+- value = nla_get_u8(tb[DCB_ATTR_STATE]);
+-
+- status = netdev->dcbnl_ops->setnumtcs(netdev, i, value);
+-
+- ret = dcbnl_reply(!!status, RTM_SETDCB, DCB_CMD_SNUMTCS,
++operr:
++ ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SNUMTCS,
+ DCB_ATTR_NUMTCS, pid, seq, flags);
+
+ err:
+@@ -496,9 +492,9 @@ static int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb,
+ if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate)
+ return ret;
+
+- value = nla_get_u8(tb[DCB_ATTR_STATE]);
++ value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]);
+
+- netdev->dcbnl_ops->setstate(netdev, value);
++ netdev->dcbnl_ops->setpfcstate(netdev, value);
+
+ ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE,
+ pid, seq, flags);
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/dcb-setting-pg-will-cause-tx-hang
^
|
@@ -0,0 +1,74 @@
+Subject: DCB: setting pg will cause tx unit hangs
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+References: bnc#438954
+
+It seems like the configuration may be doing things while the adapter is
+still up that it shouldn't.
+
+Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Acked-by: Hannes Reinecke <hare@suse.de>
+---
+
+ drivers/net/ixgbe/ixgbe_dcb_nl.c | 16 ++++++++++------
+ 1 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
+index 32d11e5..ca2537e 100644
+--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
++++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
+@@ -135,7 +135,7 @@ static void ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ return;
+ } else {
+- if (netdev->flags & IFF_UP)
++ if (netif_running(netdev))
+ netdev->stop(netdev);
+ ixgbe_reset_interrupt_capability(adapter);
+ ixgbe_napi_del_all(adapter);
+@@ -149,13 +149,13 @@ static void ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
+ adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
+ ixgbe_init_interrupt_scheme(adapter);
+ ixgbe_napi_add_all(adapter);
+- if (netdev->flags & IFF_UP)
++ if (netif_running(netdev))
+ netdev->open(netdev);
+ }
+ } else {
+ /* Turn off DCB */
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+- if (netdev->flags & IFF_UP)
++ if (netif_running(netdev))
+ netdev->stop(netdev);
+ ixgbe_reset_interrupt_capability(adapter);
+ ixgbe_napi_del_all(adapter);
+@@ -169,7 +169,7 @@ static void ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
+ adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
+ ixgbe_init_interrupt_scheme(adapter);
+ ixgbe_napi_add_all(adapter);
+- if (netdev->flags & IFF_UP)
++ if (netif_running(netdev))
+ netdev->open(netdev);
+ } else {
+ return;
+@@ -338,6 +338,9 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
+ while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
+ msleep(1);
+
++ if (netif_running(netdev))
++ ixgbe_down(adapter);
++
+ ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
+ adapter->ring_feature[RING_F_DCB].indices);
+ if (ret) {
+@@ -345,8 +348,9 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
+ return ret;
+ }
+
+- ixgbe_down(adapter);
+- ixgbe_up(adapter);
++ if (netif_running(netdev))
++ ixgbe_up(adapter);
++
+ adapter->dcb_set_bitmap = 0x00;
+ clear_bit(__IXGBE_RESETTING, &adapter->state);
+ return ret;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/dm-mpath-NULL-pgpath-in-activate_path
^
|
@@ -0,0 +1,36 @@
+Subject: Do not call activate_path() if pgpath is NULL
+From: Chandra Seetharaman <sekharan@us.ibm.com>
+Date: Thu Nov 20 14:34:34 2008 +0100:
+References: bnc#442676
+
+Path activation code is called even when the pgpath is NULL. This could
+lead to a panic in activate_path(). Such a panic is seen in -rt kernel.
+
+This problem has been there before the pg_init() was moved to a
+workqueue.
+
+Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+ drivers/md/dm-mpath.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -440,13 +440,13 @@ static void process_queued_ios(struct wo
+ __choose_pgpath(m);
+
+ pgpath = m->current_pgpath;
+- m->pgpath_to_activate = m->current_pgpath;
+
+ if ((pgpath && !m->queue_io) ||
+ (!pgpath && !m->queue_if_no_path))
+ must_queue = 0;
+
+- if (m->pg_init_required && !m->pg_init_in_progress) {
++ if (m->pg_init_required && !m->pg_init_in_progress && pgpath) {
++ m->pgpath_to_activate = pgpath;
+ m->pg_init_count++;
+ m->pg_init_required = 0;
+ m->pg_init_in_progress = 1;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/dm-mpath-reattach-dh
^
|
@@ -0,0 +1,77 @@
+From: Hannes Reinecke <hare@suse.de>
+Subject: Reattach device handler for multipath devices
+References: bnc#435688
+
+The multipath daemon might have specified a different device_handler
+than the one a device is attached to by default.
+So we should try to re-attach with the user-specified device_handler
+and only return an error if that fails.
+And we should _not_ detach existing hardware handlers. This will
+set the path to failed during failover.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de
+
+---
+ drivers/md/dm-mpath.c | 16 ++++++++++++----
+ drivers/scsi/device_handler/scsi_dh.c | 10 +++-------
+ 2 files changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -163,8 +163,6 @@ static void free_pgpaths(struct list_hea
+
+ list_for_each_entry_safe(pgpath, tmp, pgpaths, list) {
+ list_del(&pgpath->list);
+- if (m->hw_handler_name)
+- scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
+ dm_put_device(ti, pgpath->path.dev);
+ spin_lock_irqsave(&m->lock, flags);
+ if (m->pgpath_to_activate == pgpath)
+@@ -593,9 +591,19 @@ static struct pgpath *parse_path(struct
+ }
+
+ if (m->hw_handler_name) {
+- r = scsi_dh_attach(bdev_get_queue(p->path.dev->bdev),
+- m->hw_handler_name);
++ struct request_queue *q = bdev_get_queue(p->path.dev->bdev);
++
++ r = scsi_dh_attach(q, m->hw_handler_name);
++ if (r == -EBUSY) {
++ /*
++ * Already attached to different hw_handler,
++ * try to reattach with correct one.
++ */
++ scsi_dh_detach(q);
++ r = scsi_dh_attach(q, m->hw_handler_name);
++ }
+ if (r < 0) {
++ ti->error = "error attaching hardware handler";
+ dm_put_device(ti, p->path.dev);
+ goto bad;
+ }
+--- a/drivers/scsi/device_handler/scsi_dh.c
++++ b/drivers/scsi/device_handler/scsi_dh.c
+@@ -498,7 +498,6 @@ void scsi_dh_detach(struct request_queue
+ {
+ unsigned long flags;
+ struct scsi_device *sdev;
+- struct scsi_device_handler *scsi_dh = NULL;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ sdev = q->queuedata;
+@@ -509,12 +508,9 @@ void scsi_dh_detach(struct request_queue
+ if (!sdev)
+ return;
+
+- if (sdev->scsi_dh_data) {
+- /* if sdev is not on internal list, detach */
+- scsi_dh = sdev->scsi_dh_data->scsi_dh;
+- if (!device_handler_match(scsi_dh, sdev))
+- scsi_dh_handler_detach(sdev, scsi_dh);
+- }
++ if (sdev->scsi_dh_data)
++ scsi_dh_handler_detach(sdev, sdev->scsi_dh_data->scsi_dh);
++
+ put_device(&sdev->sdev_gendev);
+ }
+ EXPORT_SYMBOL_GPL(scsi_dh_detach);
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/dm-table-switch-to-readonly
^
|
@@ -0,0 +1,88 @@
+From: Hannes Reinecke <hare@suse.de>
+Subject: dm multipath devices are not getting created for readonly devices
+References: bnc#382705
+
+Currently we cannot create device-mapper tables for multipath devices
+whenever they are read-only.
+This patch modifies the device-mapper to set the 'READ-ONLY' flag
+automatically whenever a read-only is added to the table.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+Index: linux-2.6.16-SLES10_SP2_BRANCH/drivers/md/dm-table.c
+===================================================================
+--- linux-2.6.16-SLES10_SP2_BRANCH.orig/drivers/md/dm-table.c
++++ linux-2.6.16-SLES10_SP2_BRANCH/drivers/md/dm-table.c
+@@ -461,11 +461,19 @@ static int __table_get_device(struct dm_
+ dd->mode = mode;
+ dd->bdev = NULL;
+
+- if ((r = open_dev(dd, dev, t->md))) {
++ r = open_dev(dd, dev, t->md);
++ if (r == -EROFS) {
++ dd->mode &= ~FMODE_WRITE;
++ r = open_dev(dd, dev, t->md);
++ }
++ if (r) {
+ kfree(dd);
+ return r;
+ }
+
++ if (dd->mode != mode)
++ t->mode = dd->mode;
++
+ format_dev_t(dd->name, dev);
+
+ atomic_set(&dd->count, 0);
+Index: linux-2.6.16-SLES10_SP2_BRANCH/drivers/md/dm.c
+===================================================================
+--- linux-2.6.16-SLES10_SP2_BRANCH.orig/drivers/md/dm.c
++++ linux-2.6.16-SLES10_SP2_BRANCH/drivers/md/dm.c
+@@ -221,16 +221,25 @@ static void __exit dm_exit(void)
+ static int dm_blk_open(struct inode *inode, struct file *file)
+ {
+ struct mapped_device *md;
++ int retval = 0;
+
+ spin_lock(&_minor_lock);
+
+ md = inode->i_bdev->bd_disk->private_data;
+- if (!md)
++ if (!md) {
++ retval = -ENXIO;
+ goto out;
++ }
+
+ if (test_bit(DMF_FREEING, &md->flags) ||
+ test_bit(DMF_DELETING, &md->flags)) {
+ md = NULL;
++ retval = -ENXIO;
++ goto out;
++ }
++ if (md->disk->policy && (file->f_mode & FMODE_WRITE)) {
++ md = NULL;
++ retval = -EROFS;
+ goto out;
+ }
+
+@@ -240,7 +249,7 @@ static int dm_blk_open(struct inode *ino
+ out:
+ spin_unlock(&_minor_lock);
+
+- return md ? 0 : -ENXIO;
++ return retval;
+ }
+
+ static int dm_blk_close(struct inode *inode, struct file *file)
+@@ -1089,6 +1098,11 @@ static int __bind(struct mapped_device *
+ write_lock(&md->map_lock);
+ md->map = t;
+ dm_table_set_restrictions(t, q);
++ if (!(dm_table_get_mode(t) & FMODE_WRITE)) {
++ set_disk_ro(md->disk, 1);
++ } else {
++ set_disk_ro(md->disk, 0);
++ }
+ write_unlock(&md->map_lock);
+
+ return 0;
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4-Add-inode-to-journal-handle-after-block-alloca.patch
^
|
@@ -17,7 +17,7 @@
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
-@@ -2060,7 +2060,7 @@ ext4_fsblk_t ext4_new_meta_blocks(handle
+@@ -2062,7 +2062,7 @@ ext4_fsblk_t ext4_new_meta_blocks(handle
/*
* Account for the allocated meta blocks
*/
@@ -62,7 +62,7 @@
/*
* Update on-disk size along with block allocation
* we don't use 'extend_disksize' as size may change
-@@ -2407,18 +2413,6 @@ restart_loop:
+@@ -2409,18 +2415,6 @@ restart_loop:
dump_stack();
goto out_writepages;
}
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4-Add-percpu-dirty-block-accounting.patch
^
|
@@ -22,7 +22,7 @@
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
-@@ -1605,26 +1605,38 @@ out:
+@@ -1607,26 +1607,38 @@ out:
int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
ext4_fsblk_t nblocks)
{
@@ -69,7 +69,7 @@
return 0;
}
-@@ -1640,23 +1652,28 @@ int ext4_claim_free_blocks(struct ext4_s
+@@ -1642,23 +1654,28 @@ int ext4_claim_free_blocks(struct ext4_s
ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
ext4_fsblk_t nblocks)
{
@@ -105,7 +105,7 @@
return free_blocks - root_blocks;
return nblocks;
}
-@@ -1943,13 +1960,11 @@ allocated:
+@@ -1945,13 +1962,11 @@ allocated:
le16_add_cpu(&gdp->bg_free_blocks_count, -num);
gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
spin_unlock(sb_bgl_lock(sbi, group_no));
@@ -176,7 +176,7 @@
/* update per-inode reservations */
BUG_ON(to_free > EXT4_I(inode)->i_reserved_data_blocks);
-@@ -2471,7 +2472,6 @@ static int ext4_da_write_begin(struct fi
+@@ -2473,7 +2474,6 @@ static int ext4_da_write_begin(struct fi
index = pos >> PAGE_CACHE_SHIFT;
from = pos & (PAGE_CACHE_SIZE - 1);
to = from + len;
@@ -186,7 +186,7 @@
* With delayed allocation, we don't log the i_disksize update
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
-@@ -2969,22 +2969,11 @@ ext4_mb_mark_diskspace_used(struct ext4_
+@@ -2981,22 +2981,11 @@ ext4_mb_mark_diskspace_used(struct ext4_
le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len);
gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
@@ -222,7 +222,7 @@
brelse(sbi->s_sbh);
#ifdef CONFIG_QUOTA
for (i = 0; i < MAXQUOTAS; i++)
-@@ -2259,6 +2260,9 @@ static int ext4_fill_super(struct super_
+@@ -2263,6 +2264,9 @@ static int ext4_fill_super(struct super_
err = percpu_counter_init(&sbi->s_dirs_counter,
ext4_count_dirs(sb));
}
@@ -232,7 +232,7 @@
if (err) {
printk(KERN_ERR "EXT4-fs: insufficient memory\n");
goto failed_mount3;
-@@ -2491,6 +2495,7 @@ failed_mount3:
+@@ -2500,6 +2504,7 @@ failed_mount3:
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -240,7 +240,7 @@
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sbi->s_group_desc[i]);
-@@ -3169,7 +3174,8 @@ static int ext4_statfs(struct dentry *de
+@@ -3196,7 +3201,8 @@ static int ext4_statfs(struct dentry *de
buf->f_type = EXT4_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize;
buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4-Make-sure-all-the-block-allocation-paths-reser.patch
^
|
@@ -17,17 +17,15 @@
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
- fs/ext4/balloc.c | 58 ++++++++++++++++++++++++++++++++++++++--------------
- fs/ext4/ext4.h | 13 +++++++++++
- fs/ext4/inode.c | 5 +---
- fs/ext4/mballoc.c | 23 +++++++++++---------
+ fs/ext4/balloc.c | 58 +++++++++++++++++++++++++++++++++++++++---------------
+ fs/ext4/ext4.h | 13 ++++++++++++
+ fs/ext4/inode.c | 5 ----
+ fs/ext4/mballoc.c | 23 ++++++++++++---------
4 files changed, 69 insertions(+), 30 deletions(-)
-Index: linux-2.6.26/fs/ext4/balloc.c
-===================================================================
---- linux-2.6.26.orig/fs/ext4/balloc.c 2008-09-11 18:03:57.000000000 +0200
-+++ linux-2.6.26/fs/ext4/balloc.c 2008-09-11 18:04:30.000000000 +0200
-@@ -1602,6 +1602,32 @@
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -1604,6 +1604,32 @@ out:
return ret;
}
@@ -60,7 +58,7 @@
/**
* ext4_has_free_blocks()
* @sbi: in-core super block structure.
-@@ -1623,18 +1649,17 @@
+@@ -1625,18 +1651,17 @@ ext4_fsblk_t ext4_has_free_blocks(struct
sbi->s_resuid != current->fsuid &&
(sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid)))
root_blocks = ext4_r_blocks_count(sbi->s_es);
@@ -84,7 +82,7 @@
/**
-@@ -1713,14 +1738,11 @@
+@@ -1715,14 +1740,11 @@ ext4_fsblk_t ext4_old_new_blocks(handle_
/*
* With delalloc we already reserved the blocks
*/
@@ -103,7 +101,7 @@
/*
* Check quota for allocation of this block.
*/
-@@ -1915,9 +1937,13 @@
+@@ -1917,9 +1939,13 @@ allocated:
le16_add_cpu(&gdp->bg_free_blocks_count, -num);
gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
spin_unlock(sb_bgl_lock(sbi, group_no));
@@ -120,11 +118,9 @@
if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, group_no);
spin_lock(sb_bgl_lock(sbi, flex_group));
-Index: linux-2.6.26/fs/ext4/ext4.h
-===================================================================
---- linux-2.6.26.orig/fs/ext4/ext4.h 2008-09-11 18:03:57.000000000 +0200
-+++ linux-2.6.26/fs/ext4/ext4.h 2008-09-11 18:05:05.000000000 +0200
-@@ -983,6 +983,8 @@
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -984,6 +984,8 @@ extern ext4_fsblk_t ext4_new_blocks(hand
unsigned long *count, int *errp);
extern ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, unsigned long *count, int *errp);
@@ -132,8 +128,8 @@
+ ext4_fsblk_t nblocks);
extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
ext4_fsblk_t nblocks);
- extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
-@@ -1207,6 +1209,17 @@
+ extern void ext4_free_blocks (handle_t *handle, struct inode *inode,
+@@ -1207,6 +1209,17 @@ do { \
__ext4_std_error((sb), __func__, (errno)); \
} while (0)
@@ -151,11 +147,9 @@
/*
* Inodes and files operations
*/
-Index: linux-2.6.26/fs/ext4/inode.c
-===================================================================
---- linux-2.6.26.orig/fs/ext4/inode.c 2008-09-11 18:03:57.000000000 +0200
-+++ linux-2.6.26/fs/ext4/inode.c 2008-09-11 18:04:30.000000000 +0200
-@@ -1537,13 +1537,10 @@
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1537,13 +1537,10 @@ static int ext4_da_reserve_space(struct
md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
total = md_needed + nrblocks;
@@ -170,11 +164,9 @@
EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
EXT4_I(inode)->i_reserved_meta_blocks = mdblocks;
-Index: linux-2.6.26/fs/ext4/mballoc.c
-===================================================================
---- linux-2.6.26.orig/fs/ext4/mballoc.c 2008-09-11 18:03:57.000000000 +0200
-+++ linux-2.6.26/fs/ext4/mballoc.c 2008-09-11 18:04:30.000000000 +0200
-@@ -2975,9 +2975,15 @@
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2987,9 +2987,15 @@ ext4_mb_mark_diskspace_used(struct ext4_
* at write_begin() time for delayed allocation
* do not double accounting
*/
@@ -193,7 +185,7 @@
if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi,
-@@ -4389,14 +4395,11 @@
+@@ -4401,14 +4407,11 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t
/*
* With delalloc we already reserved the blocks
*/
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4-Retry-block-allocation-if-we-have-free-blocks.patch
^
|
@@ -17,11 +17,9 @@
fs/ext4/inode.c | 81 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 57 insertions(+), 24 deletions(-)
-Index: linux-2.6.27-rc3/fs/ext4/inode.c
-===================================================================
---- linux-2.6.27-rc3.orig/fs/ext4/inode.c 2008-08-28 13:08:06.000000000 -0700
-+++ linux-2.6.27-rc3/fs/ext4/inode.c 2008-08-28 13:30:15.000000000 -0700
-@@ -1634,6 +1634,7 @@
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1634,6 +1634,7 @@ struct mpage_da_data {
struct writeback_control *wbc;
int io_done;
long pages_written;
@@ -29,7 +27,7 @@
};
/*
-@@ -1820,6 +1821,24 @@
+@@ -1820,6 +1821,24 @@ static void ext4_da_block_invalidatepage
return;
}
@@ -54,7 +52,7 @@
/*
* mpage_da_map_blocks - go through given space
*
-@@ -1834,7 +1853,7 @@
+@@ -1834,7 +1853,7 @@ static int mpage_da_map_blocks(struct m
int err = 0;
struct buffer_head new;
struct buffer_head *lbh = &mpd->lbh;
@@ -63,7 +61,7 @@
/*
* We consider only non-mapped and non-allocated blocks
-@@ -1844,6 +1863,7 @@
+@@ -1844,6 +1863,7 @@ static int mpage_da_map_blocks(struct m
new.b_state = lbh->b_state;
new.b_blocknr = 0;
new.b_size = lbh->b_size;
@@ -71,7 +69,7 @@
/*
* If we didn't accumulate anything
* to write simply return
-@@ -1860,6 +1880,13 @@
+@@ -1860,6 +1880,13 @@ static int mpage_da_map_blocks(struct m
*/
if (err == -EAGAIN)
return 0;
@@ -85,7 +83,7 @@
/*
* get block failure will cause us
* to loop in writepages. Because
-@@ -1877,8 +1904,7 @@
+@@ -1877,8 +1904,7 @@ static int mpage_da_map_blocks(struct m
printk(KERN_EMERG "This should not happen.!! "
"Data will be lost\n");
if (err == -ENOSPC) {
@@ -95,7 +93,7 @@
}
/* invlaidate all the pages */
ext4_da_block_invalidatepages(mpd, next,
-@@ -2085,39 +2111,36 @@
+@@ -2085,39 +2111,36 @@ static int __mpage_da_writepage(struct p
*/
static int mpage_da_writepages(struct address_space *mapping,
struct writeback_control *wbc,
@@ -150,7 +148,7 @@
return ret;
}
-@@ -2357,6 +2380,7 @@
+@@ -2359,6 +2382,7 @@ static int ext4_da_writepages(struct add
{
handle_t *handle = NULL;
loff_t range_start = 0;
@@ -158,7 +156,7 @@
struct inode *inode = mapping->host;
int needed_blocks, ret = 0, nr_to_writebump = 0;
long to_write, pages_skipped = 0;
-@@ -2390,6 +2414,9 @@
+@@ -2392,6 +2416,9 @@ static int ext4_da_writepages(struct add
range_start = wbc->range_start;
pages_skipped = wbc->pages_skipped;
@@ -168,7 +166,7 @@
restart_loop:
to_write = wbc->nr_to_write;
while (!ret && to_write > 0) {
-@@ -2413,11 +2440,17 @@
+@@ -2415,11 +2442,17 @@ restart_loop:
dump_stack();
goto out_writepages;
}
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4-Retry-block-reservation.patch
^
|
@@ -22,7 +22,7 @@
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
-@@ -1738,10 +1738,16 @@ ext4_fsblk_t ext4_old_new_blocks(handle_
+@@ -1740,10 +1740,16 @@ ext4_fsblk_t ext4_old_new_blocks(handle_
/*
* With delalloc we already reserved the blocks
*/
@@ -104,7 +104,7 @@
lbh->b_size >> mpd->inode->i_blkbits);
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
-@@ -4395,7 +4395,12 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t
+@@ -4407,7 +4407,12 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t
/*
* With delalloc we already reserved the blocks
*/
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4-Signed-arithematic-fix.patch
^
|
@@ -10,11 +10,14 @@
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
-diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
-index 87b198c..e4274aa 100644
+---
+ fs/ext4/balloc.c | 19 ++++++++++---------
+ fs/ext4/ext4.h | 5 ++---
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
-@@ -1603,10 +1603,10 @@ out:
+@@ -1605,10 +1605,10 @@ out:
}
int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
@@ -27,7 +30,7 @@
struct percpu_counter *fbc = &sbi->s_freeblocks_counter;
struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter;
-@@ -1631,7 +1631,7 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
+@@ -1633,7 +1633,7 @@ int ext4_claim_free_blocks(struct ext4_s
/* Check whether we have space after
* accounting for current dirty blocks
*/
@@ -36,7 +39,7 @@
/* we don't have free space */
return -ENOSPC;
-@@ -1650,10 +1650,10 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
+@@ -1652,10 +1652,10 @@ int ext4_claim_free_blocks(struct ext4_s
* On success, return nblocks
*/
ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
@@ -50,7 +53,7 @@
struct percpu_counter *fbc = &sbi->s_freeblocks_counter;
struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter;
-@@ -1667,14 +1667,15 @@ ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
+@@ -1669,14 +1669,15 @@ ext4_fsblk_t ext4_has_free_blocks(struct
if (free_blocks - (nblocks + root_blocks + dirty_blocks) <
EXT4_FREEBLOCKS_WATERMARK) {
@@ -69,11 +72,9 @@
return nblocks;
}
-diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index 0154c2d..e13b9de 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
-@@ -983,10 +983,9 @@ extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
+@@ -984,10 +984,9 @@ extern ext4_fsblk_t ext4_new_blocks(hand
unsigned long *count, int *errp);
extern ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, unsigned long *count, int *errp);
@@ -82,7 +83,7 @@
+extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks);
extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
- ext4_fsblk_t nblocks);
-+ s64 nblocks);
- extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
++ s64 nblocks);
+ extern void ext4_free_blocks (handle_t *handle, struct inode *inode,
ext4_fsblk_t block, unsigned long count, int metadata);
- extern void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
+ extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb,
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4-Switch-to-non-delalloc-mode-when-we-are-low-on.patch
^
|
@@ -17,11 +17,9 @@
fs/ext4/inode.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
-Index: linux-2.6.26/fs/ext4/inode.c
-===================================================================
---- linux-2.6.26.orig/fs/ext4/inode.c 2008-09-11 18:05:39.000000000 +0200
-+++ linux-2.6.26/fs/ext4/inode.c 2008-09-11 18:07:44.000000000 +0200
-@@ -2458,6 +2458,33 @@
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -2460,6 +2460,33 @@ out_writepages:
return ret;
}
@@ -55,7 +53,7 @@
static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
-@@ -2472,6 +2499,13 @@
+@@ -2474,6 +2501,13 @@ static int ext4_da_write_begin(struct fi
index = pos >> PAGE_CACHE_SHIFT;
from = pos & (PAGE_CACHE_SIZE - 1);
to = from + len;
@@ -69,7 +67,7 @@
retry:
/*
* With delayed allocation, we don't log the i_disksize update
-@@ -2540,6 +2574,19 @@
+@@ -2542,6 +2576,19 @@ static int ext4_da_write_end(struct file
handle_t *handle = ext4_journal_current_handle();
loff_t new_i_size;
unsigned long start, end;
@@ -88,8 +86,8 @@
+ }
start = pos & (PAGE_CACHE_SIZE - 1);
- end = start + copied - 1;
-@@ -4877,6 +4924,7 @@
+ end = start + copied -1;
+@@ -4880,6 +4927,7 @@ int ext4_page_mkwrite(struct vm_area_str
loff_t size;
unsigned long len;
int ret = -EINVAL;
@@ -97,7 +95,7 @@
struct file *file = vma->vm_file;
struct inode *inode = file->f_path.dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
-@@ -4915,11 +4963,11 @@
+@@ -4918,11 +4966,11 @@ int ext4_page_mkwrite(struct vm_area_str
* on the same page though
*/
ret = mapping->a_ops->write_begin(file, mapping, page_offset(page),
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/ext4_add-missing-unlock-to-ext4-check-descriptors
^
|
@@ -1,30 +0,0 @@
-From: Li Zefan <lizf@cn.fujitsu.com>
-Subject: ext4: add missing unlock in ext4_check_descriptors() on error path
-References: fate#303783
-
-If there group descriptors are corrupted we need unlock the block
-group lock before returning from the function; else we will oops when
-freeing a spinlock which is still being held.
-
-Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-Acked-by: Jan Kara <jack@suse.cz>
-
----
- fs/ext4/super.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/fs/ext4/super.c
-+++ b/fs/ext4/super.c
-@@ -1629,8 +1629,10 @@ static int ext4_check_descriptors(struct
- "Checksum for group %lu failed (%u!=%u)\n",
- i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
- gdp)), le16_to_cpu(gdp->bg_checksum));
-- if (!(sb->s_flags & MS_RDONLY))
-+ if (!(sb->s_flags & MS_RDONLY)) {
-+ spin_unlock(sb_bgl_lock(sbi, i));
- return 0;
-+ }
- }
- spin_unlock(sb_bgl_lock(sbi, i));
- if (!flexbg_flag)
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/ext4_create-proc-ext4-stats-file-more-carefully
^
|
@@ -1,66 +0,0 @@
-From: Alexey Dobriyan <adobriyan@gmail.com>
-Subject: ext4: fix #11321: create /proc/ext4/*/stats more carefully
-References: fate#303783
-
-ext4 creates per-suberblock directory in /proc/ext4/ . Name used as
-basis is taken from bdevname, which, surprise, can contain slash.
-
-However, proc while allowing to use proc_create("a/b", parent) form of
-PDE creation, assumes that parent/a was already created.
-
-bdevname in question is 'cciss/c0d0p9', directory is not created and all
-this stuff goes directly into /proc (which is real bug).
-
-Warning comes when _second_ partition is mounted.
-
-http://bugzilla.kernel.org/show_bug.cgi?id=11321
-
-Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-Acked-by: Jan Kara <jack@suse.cz>
-
----
- fs/ext4/mballoc.c | 11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
---- a/fs/ext4/mballoc.c
-+++ b/fs/ext4/mballoc.c
-@@ -2786,14 +2786,20 @@ static int ext4_mb_init_per_dev_proc(str
- mode_t mode = S_IFREG | S_IRUGO | S_IWUSR;
- struct ext4_sb_info *sbi = EXT4_SB(sb);
- struct proc_dir_entry *proc;
-- char devname[64];
-+ char devname[64], *p;
-
- if (proc_root_ext4 == NULL) {
- sbi->s_mb_proc = NULL;
- return -EINVAL;
- }
- bdevname(sb->s_bdev, devname);
-+ p = devname;
-+ while ((p = strchr(p, '/')))
-+ *p = '!';
-+
- sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4);
-+ if (!sbi->s_mb_proc)
-+ goto err_create_dir;
-
- MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats);
- MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan);
-@@ -2805,7 +2811,6 @@ static int ext4_mb_init_per_dev_proc(str
- return 0;
-
- err_out:
-- printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname);
- remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
-@@ -2814,6 +2819,8 @@ err_out:
- remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
- remove_proc_entry(devname, proc_root_ext4);
- sbi->s_mb_proc = NULL;
-+err_create_dir:
-+ printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname);
-
- return -ENOMEM;
- }
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4_fix_longlong_checkpatch_issues
^
|
@@ -11,7 +11,7 @@
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
-@@ -1716,9 +1716,9 @@ static void ext4_orphan_cleanup(struct s
+@@ -1720,9 +1720,9 @@ static void ext4_orphan_cleanup(struct s
DQUOT_INIT(inode);
if (inode->i_nlink) {
printk(KERN_DEBUG
@@ -23,7 +23,7 @@
inode->i_ino, inode->i_size);
ext4_truncate(inode);
nr_truncates++;
-@@ -2554,7 +2554,7 @@ static journal_t *ext4_get_journal(struc
+@@ -2563,7 +2563,7 @@ static journal_t *ext4_get_journal(struc
return NULL;
}
@@ -32,7 +32,7 @@
journal_inode, journal_inode->i_size);
if (!S_ISREG(journal_inode->i_mode)) {
printk(KERN_ERR "EXT4-fs: invalid journal inode.\n");
-@@ -3439,7 +3439,7 @@ static ssize_t ext4_quota_write(struct s
+@@ -3466,7 +3466,7 @@ static ssize_t ext4_quota_write(struct s
handle_t *handle = journal_current_handle();
if (!handle) {
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4_fix_printk_checkpatch_issues
^
|
@@ -17,7 +17,7 @@
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
-@@ -379,26 +379,28 @@ restart:
+@@ -381,26 +381,28 @@ restart:
bad = 0;
prev = NULL;
@@ -52,7 +52,7 @@
verbose = 1;
goto restart;
}
-@@ -406,7 +408,7 @@ restart:
+@@ -408,7 +410,7 @@ restart:
n = rb_next(n);
prev = rsv;
}
@@ -61,7 +61,7 @@
BUG_ON(bad);
}
#define rsv_window_dump(root, verbose) \
-@@ -1702,7 +1704,7 @@ ext4_fsblk_t ext4_old_new_blocks(handle_
+@@ -1704,7 +1706,7 @@ ext4_fsblk_t ext4_old_new_blocks(handle_
sb = inode->i_sb;
if (!sb) {
*errp = -ENODEV;
@@ -70,7 +70,7 @@
return 0;
}
-@@ -1884,8 +1886,8 @@ allocated:
+@@ -1886,8 +1888,8 @@ allocated:
for (i = 0; i < num; i++) {
if (ext4_test_bit(grp_alloc_blk+i,
bh2jh(bitmap_bh)->b_committed_data)) {
@@ -81,7 +81,7 @@
}
}
}
-@@ -2093,10 +2095,9 @@ ext4_fsblk_t ext4_count_free_blocks(stru
+@@ -2095,10 +2097,9 @@ ext4_fsblk_t ext4_count_free_blocks(stru
bitmap_count += x;
}
brelse(bitmap_bh);
@@ -134,7 +134,7 @@
#endif
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
-@@ -170,17 +170,18 @@ void ext4_free_inode (handle_t *handle,
+@@ -172,17 +172,18 @@ void ext4_free_inode (handle_t *handle,
ext4_group_t flex_group;
if (atomic_read(&inode->i_count) > 1) {
@@ -158,7 +158,7 @@
return;
}
sbi = EXT4_SB(sb);
-@@ -989,8 +990,9 @@ unsigned long ext4_count_free_inodes (st
+@@ -993,8 +994,9 @@ unsigned long ext4_count_free_inodes (st
bitmap_count += x;
}
brelse(bitmap_bh);
@@ -186,7 +186,7 @@
BUG();
}
}
-@@ -2560,7 +2561,7 @@ int ext4_mb_init(struct super_block *sb,
+@@ -2562,7 +2563,7 @@ int ext4_mb_init(struct super_block *sb,
ext4_mb_init_per_dev_proc(sb);
ext4_mb_history_init(sb);
@@ -365,7 +365,7 @@
}
return res;
}
-@@ -2715,6 +2717,11 @@ static int ext4_load_journal(struct supe
+@@ -2724,6 +2726,11 @@ static int ext4_load_journal(struct supe
return -EINVAL;
}
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/ext4_fix_whitespace_checkpatch_issues
^
|
@@ -1,2061 +0,0 @@
-From: "Theodore Ts'o" <tytso@mit.edu>
-Subject: ext4: Fix whitespace checkpatch warnings/errors
-References: fate#303783
-
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-Acked-by: Jan Kara <jack@suse.cz>
-
----
- fs/ext4/acl.h | 6 -
- fs/ext4/balloc.c | 70 ++++++------
- fs/ext4/bitmap.c | 6 -
- fs/ext4/dir.c | 50 ++++----
- fs/ext4/ext4.h | 68 ++++++------
- fs/ext4/ext4_sb.h | 8 -
- fs/ext4/extents.c | 6 -
- fs/ext4/file.c | 2
- fs/ext4/fsync.c | 2
- fs/ext4/hash.c | 8 -
- fs/ext4/ialloc.c | 50 ++++----
- fs/ext4/inode.c | 96 ++++++++---------
- fs/ext4/ioctl.c | 4
- fs/ext4/namei.c | 302 +++++++++++++++++++++++++++---------------------------
- fs/ext4/resize.c | 6 -
- fs/ext4/super.c | 6 -
- fs/ext4/symlink.c | 4
- fs/ext4/xattr.h | 4
- 18 files changed, 349 insertions(+), 349 deletions(-)
-
---- a/fs/ext4/acl.h
-+++ b/fs/ext4/acl.h
-@@ -58,9 +58,9 @@ static inline int ext4_acl_count(size_t
- #define EXT4_ACL_NOT_CACHED ((void *)-1)
-
- /* acl.c */
--extern int ext4_permission (struct inode *, int);
--extern int ext4_acl_chmod (struct inode *);
--extern int ext4_init_acl (handle_t *, struct inode *, struct inode *);
-+extern int ext4_permission(struct inode *, int);
-+extern int ext4_acl_chmod(struct inode *);
-+extern int ext4_init_acl(handle_t *, struct inode *, struct inode *);
-
- #else /* CONFIG_EXT4DEV_FS_POSIX_ACL */
- #include <linux/sched.h>
---- a/fs/ext4/balloc.c
-+++ b/fs/ext4/balloc.c
-@@ -132,7 +132,7 @@ unsigned ext4_init_block_bitmap(struct s
- */
- group_blocks = ext4_blocks_count(sbi->s_es) -
- le32_to_cpu(sbi->s_es->s_first_data_block) -
-- (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count -1));
-+ (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1));
- } else {
- group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
- }
-@@ -200,20 +200,20 @@ unsigned ext4_init_block_bitmap(struct s
- * @bh: pointer to the buffer head to store the block
- * group descriptor
- */
--struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
-+struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
- ext4_group_t block_group,
-- struct buffer_head ** bh)
-+ struct buffer_head **bh)
- {
- unsigned long group_desc;
- unsigned long offset;
-- struct ext4_group_desc * desc;
-+ struct ext4_group_desc *desc;
- struct ext4_sb_info *sbi = EXT4_SB(sb);
-
- if (block_group >= sbi->s_groups_count) {
-- ext4_error (sb, "ext4_get_group_desc",
-- "block_group >= groups_count - "
-- "block_group = %lu, groups_count = %lu",
-- block_group, sbi->s_groups_count);
-+ ext4_error(sb, "ext4_get_group_desc",
-+ "block_group >= groups_count - "
-+ "block_group = %lu, groups_count = %lu",
-+ block_group, sbi->s_groups_count);
-
- return NULL;
- }
-@@ -222,10 +222,10 @@ struct ext4_group_desc * ext4_get_group_
- group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
- offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
- if (!sbi->s_group_desc[group_desc]) {
-- ext4_error (sb, "ext4_get_group_desc",
-- "Group descriptor not loaded - "
-- "block_group = %lu, group_desc = %lu, desc = %lu",
-- block_group, group_desc, offset);
-+ ext4_error(sb, "ext4_get_group_desc",
-+ "Group descriptor not loaded - "
-+ "block_group = %lu, group_desc = %lu, desc = %lu",
-+ block_group, group_desc, offset);
- return NULL;
- }
-
-@@ -302,8 +302,8 @@ err_out:
- struct buffer_head *
- ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
- {
-- struct ext4_group_desc * desc;
-- struct buffer_head * bh = NULL;
-+ struct ext4_group_desc *desc;
-+ struct buffer_head *bh = NULL;
- ext4_fsblk_t bitmap_blk;
-
- desc = ext4_get_group_desc(sb, block_group, NULL);
-@@ -506,8 +506,8 @@ void ext4_rsv_window_add(struct super_bl
- struct rb_node *node = &rsv->rsv_node;
- ext4_fsblk_t start = rsv->rsv_start;
-
-- struct rb_node ** p = &root->rb_node;
-- struct rb_node * parent = NULL;
-+ struct rb_node **p = &root->rb_node;
-+ struct rb_node *parent = NULL;
- struct ext4_reserve_window_node *this;
-
- while (*p)
-@@ -661,8 +661,8 @@ void ext4_free_blocks_sb(handle_t *handl
- ext4_grpblk_t bit;
- unsigned long i;
- unsigned long overflow;
-- struct ext4_group_desc * desc;
-- struct ext4_super_block * es;
-+ struct ext4_group_desc *desc;
-+ struct ext4_super_block *es;
- struct ext4_sb_info *sbi;
- int err = 0, ret;
- ext4_grpblk_t group_freed;
-@@ -673,13 +673,13 @@ void ext4_free_blocks_sb(handle_t *handl
- if (block < le32_to_cpu(es->s_first_data_block) ||
- block + count < block ||
- block + count > ext4_blocks_count(es)) {
-- ext4_error (sb, "ext4_free_blocks",
-- "Freeing blocks not in datazone - "
-- "block = %llu, count = %lu", block, count);
-+ ext4_error(sb, "ext4_free_blocks",
-+ "Freeing blocks not in datazone - "
-+ "block = %llu, count = %lu", block, count);
- goto error_return;
- }
-
-- ext4_debug ("freeing block(s) %llu-%llu\n", block, block + count - 1);
-+ ext4_debug("freeing block(s) %llu-%llu\n", block, block + count - 1);
-
- do_more:
- overflow = 0;
-@@ -696,7 +696,7 @@ do_more:
- bitmap_bh = ext4_read_block_bitmap(sb, block_group);
- if (!bitmap_bh)
- goto error_return;
-- desc = ext4_get_group_desc (sb, block_group, &gd_bh);
-+ desc = ext4_get_group_desc(sb, block_group, &gd_bh);
- if (!desc)
- goto error_return;
-
-@@ -705,10 +705,10 @@ do_more:
- in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
- in_range(block + count - 1, ext4_inode_table(sb, desc),
- sbi->s_itb_per_group)) {
-- ext4_error (sb, "ext4_free_blocks",
-- "Freeing blocks in system zones - "
-- "Block = %llu, count = %lu",
-- block, count);
-+ ext4_error(sb, "ext4_free_blocks",
-+ "Freeing blocks in system zones - "
-+ "Block = %llu, count = %lu",
-+ block, count);
- goto error_return;
- }
-
-@@ -850,7 +850,7 @@ void ext4_free_blocks(handle_t *handle,
- ext4_fsblk_t block, unsigned long count,
- int metadata)
- {
-- struct super_block * sb;
-+ struct super_block *sb;
- unsigned long dquot_freed_blocks;
-
- /* this isn't the right place to decide whether block is metadata
-@@ -1019,7 +1019,7 @@ claim_block(spinlock_t *lock, ext4_grpbl
- if (ext4_set_bit_atomic(lock, block, bh->b_data))
- return 0;
- jbd_lock_bh_state(bh);
-- if (jh->b_committed_data && ext4_test_bit(block,jh->b_committed_data)) {
-+ if (jh->b_committed_data && ext4_test_bit(block, jh->b_committed_data)) {
- ext4_clear_bit_atomic(lock, block, bh->b_data);
- ret = 0;
- } else {
-@@ -1170,7 +1170,7 @@ fail_access:
- static int find_next_reservable_window(
- struct ext4_reserve_window_node *search_head,
- struct ext4_reserve_window_node *my_rsv,
-- struct super_block * sb,
-+ struct super_block *sb,
- ext4_fsblk_t start_block,
- ext4_fsblk_t last_block)
- {
-@@ -1204,7 +1204,7 @@ static int find_next_reservable_window(
-
- prev = rsv;
- next = rb_next(&rsv->rsv_node);
-- rsv = rb_entry(next,struct ext4_reserve_window_node,rsv_node);
-+ rsv = rb_entry(next, struct ext4_reserve_window_node, rsv_node);
-
- /*
- * Reached the last reservation, we can just append to the
-@@ -1342,7 +1342,7 @@ static int alloc_new_reservation(struct
- size = size * 2;
- if (size > EXT4_MAX_RESERVE_BLOCKS)
- size = EXT4_MAX_RESERVE_BLOCKS;
-- my_rsv->rsv_goal_size= size;
-+ my_rsv->rsv_goal_size = size;
- }
- }
-
-@@ -1491,7 +1491,7 @@ static ext4_grpblk_t
- ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
- ext4_group_t group, struct buffer_head *bitmap_bh,
- ext4_grpblk_t grp_goal,
-- struct ext4_reserve_window_node * my_rsv,
-+ struct ext4_reserve_window_node *my_rsv,
- unsigned long *count, int *errp)
- {
- ext4_fsblk_t group_first_block, group_last_block;
-@@ -1519,7 +1519,7 @@ ext4_try_to_allocate_with_rsv(struct sup
- * or the file is not a regular file
- * or last attempt to allocate a block with reservation turned on failed
- */
-- if (my_rsv == NULL ) {
-+ if (my_rsv == NULL) {
- ret = ext4_try_to_allocate(sb, handle, group, bitmap_bh,
- grp_goal, count, NULL);
- goto out;
-@@ -2184,7 +2184,7 @@ unsigned long ext4_bg_num_gdb(struct sup
-
- if (!EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG) ||
- metagroup < first_meta_bg)
-- return ext4_bg_num_gdb_nometa(sb,group);
-+ return ext4_bg_num_gdb_nometa(sb, group);
-
- return ext4_bg_num_gdb_meta(sb,group);
-
---- a/fs/ext4/bitmap.c
-+++ b/fs/ext4/bitmap.c
-@@ -15,17 +15,17 @@
-
- static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
-
--unsigned long ext4_count_free (struct buffer_head * map, unsigned int numchars)
-+unsigned long ext4_count_free(struct buffer_head *map, unsigned int numchars)
- {
- unsigned int i;
- unsigned long sum = 0;
-
- if (!map)
-- return (0);
-+ return 0;
- for (i = 0; i < numchars; i++)
- sum += nibblemap[map->b_data[i] & 0xf] +
- nibblemap[(map->b_data[i] >> 4) & 0xf];
-- return (sum);
-+ return sum;
- }
-
- #endif /* EXT4FS_DEBUG */
---- a/fs/ext4/dir.c
-+++ b/fs/ext4/dir.c
-@@ -33,10 +33,10 @@ static unsigned char ext4_filetype_table
- };
-
- static int ext4_readdir(struct file *, void *, filldir_t);
--static int ext4_dx_readdir(struct file * filp,
-- void * dirent, filldir_t filldir);
--static int ext4_release_dir (struct inode * inode,
-- struct file * filp);
-+static int ext4_dx_readdir(struct file *filp,
-+ void *dirent, filldir_t filldir);
-+static int ext4_release_dir(struct inode *inode,
-+ struct file *filp);
-
- const struct file_operations ext4_dir_operations = {
- .llseek = generic_file_llseek,
-@@ -61,12 +61,12 @@ static unsigned char get_dtype(struct su
- }
-
-
--int ext4_check_dir_entry (const char * function, struct inode * dir,
-- struct ext4_dir_entry_2 * de,
-- struct buffer_head * bh,
-- unsigned long offset)
-+int ext4_check_dir_entry(const char *function, struct inode *dir,
-+ struct ext4_dir_entry_2 *de,
-+ struct buffer_head *bh,
-+ unsigned long offset)
- {
-- const char * error_msg = NULL;
-+ const char *error_msg = NULL;
- const int rlen = ext4_rec_len_from_disk(de->rec_len);
-
- if (rlen < EXT4_DIR_REC_LEN(1))
-@@ -82,7 +82,7 @@ int ext4_check_dir_entry (const char * f
- error_msg = "inode out of bounds";
-
- if (error_msg != NULL)
-- ext4_error (dir->i_sb, function,
-+ ext4_error(dir->i_sb, function,
- "bad entry in directory #%lu: %s - "
- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
- dir->i_ino, error_msg, offset,
-@@ -91,8 +91,8 @@ int ext4_check_dir_entry (const char * f
- return error_msg == NULL ? 1 : 0;
- }
-
--static int ext4_readdir(struct file * filp,
-- void * dirent, filldir_t filldir)
-+static int ext4_readdir(struct file *filp,
-+ void *dirent, filldir_t filldir)
- {
- int error = 0;
- unsigned long offset;
-@@ -192,14 +192,14 @@ revalidate:
- while (!error && filp->f_pos < inode->i_size
- && offset < sb->s_blocksize) {
- de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
-- if (!ext4_check_dir_entry ("ext4_readdir", inode, de,
-- bh, offset)) {
-+ if (!ext4_check_dir_entry("ext4_readdir", inode, de,
-+ bh, offset)) {
- /*
- * On error, skip the f_pos to the next block
- */
- filp->f_pos = (filp->f_pos |
- (sb->s_blocksize - 1)) + 1;
-- brelse (bh);
-+ brelse(bh);
- ret = stored;
- goto out;
- }
-@@ -223,12 +223,12 @@ revalidate:
- break;
- if (version != filp->f_version)
- goto revalidate;
-- stored ++;
-+ stored++;
- }
- filp->f_pos += ext4_rec_len_from_disk(de->rec_len);
- }
- offset = 0;
-- brelse (bh);
-+ brelse(bh);
- }
- out:
- return ret;
-@@ -295,9 +295,9 @@ static void free_rb_tree_fname(struct rb
- parent = rb_parent(n);
- fname = rb_entry(n, struct fname, rb_hash);
- while (fname) {
-- struct fname * old = fname;
-+ struct fname *old = fname;
- fname = fname->next;
-- kfree (old);
-+ kfree(old);
- }
- if (!parent)
- root->rb_node = NULL;
-@@ -336,7 +336,7 @@ int ext4_htree_store_dirent(struct file
- struct ext4_dir_entry_2 *dirent)
- {
- struct rb_node **p, *parent = NULL;
-- struct fname * fname, *new_fn;
-+ struct fname *fname, *new_fn;
- struct dir_private_info *info;
- int len;
-
-@@ -393,13 +393,13 @@ int ext4_htree_store_dirent(struct file
- * for all entres on the fname linked list. (Normally there is only
- * one entry on the linked list, unless there are 62 bit hash collisions.)
- */
--static int call_filldir(struct file * filp, void * dirent,
-+static int call_filldir(struct file *filp, void *dirent,
- filldir_t filldir, struct fname *fname)
- {
- struct dir_private_info *info = filp->private_data;
- loff_t curr_pos;
- struct inode *inode = filp->f_path.dentry->d_inode;
-- struct super_block * sb;
-+ struct super_block *sb;
- int error;
-
- sb = inode->i_sb;
-@@ -425,8 +425,8 @@ static int call_filldir(struct file * fi
- return 0;
- }
-
--static int ext4_dx_readdir(struct file * filp,
-- void * dirent, filldir_t filldir)
-+static int ext4_dx_readdir(struct file *filp,
-+ void *dirent, filldir_t filldir)
- {
- struct dir_private_info *info = filp->private_data;
- struct inode *inode = filp->f_path.dentry->d_inode;
-@@ -517,7 +517,7 @@ finished:
- return 0;
- }
-
--static int ext4_release_dir (struct inode * inode, struct file * filp)
-+static int ext4_release_dir(struct inode *inode, struct file *filp)
- {
- if (filp->private_data)
- ext4_htree_free_dir_info(filp->private_data);
---- a/fs/ext4/ext4.h
-+++ b/fs/ext4/ext4.h
-@@ -44,9 +44,9 @@
- #ifdef EXT4FS_DEBUG
- #define ext4_debug(f, a...) \
- do { \
-- printk (KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:", \
-+ printk(KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:", \
- __FILE__, __LINE__, __func__); \
-- printk (KERN_DEBUG f, ## a); \
-+ printk(KERN_DEBUG f, ## a); \
- } while (0)
- #else
- #define ext4_debug(f, a...) do {} while (0)
-@@ -128,7 +128,7 @@ struct ext4_allocation_request {
- #else
- # define EXT4_BLOCK_SIZE(s) (EXT4_MIN_BLOCK_SIZE << (s)->s_log_block_size)
- #endif
--#define EXT4_ADDR_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / sizeof (__u32))
-+#define EXT4_ADDR_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / sizeof(__u32))
- #ifdef __KERNEL__
- # define EXT4_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
- #else
-@@ -292,7 +292,7 @@ struct ext4_new_group_data {
- #define EXT4_IOC_GETVERSION _IOR('f', 3, long)
- #define EXT4_IOC_SETVERSION _IOW('f', 4, long)
- #define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
--#define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input)
-+#define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input)
- #define EXT4_IOC_GETVERSION_OLD FS_IOC_GETVERSION
- #define EXT4_IOC_SETVERSION_OLD FS_IOC_SETVERSION
- #ifdef CONFIG_JBD2_DEBUG
-@@ -667,7 +667,7 @@ struct ext4_super_block {
- };
-
- #ifdef __KERNEL__
--static inline struct ext4_sb_info * EXT4_SB(struct super_block *sb)
-+static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
- {
- return sb->s_fs_info;
- }
-@@ -725,11 +725,11 @@ static inline int ext4_valid_inum(struct
- */
-
- #define EXT4_HAS_COMPAT_FEATURE(sb,mask) \
-- ( EXT4_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
-+ (EXT4_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask))
- #define EXT4_HAS_RO_COMPAT_FEATURE(sb,mask) \
-- ( EXT4_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
-+ (EXT4_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask))
- #define EXT4_HAS_INCOMPAT_FEATURE(sb,mask) \
-- ( EXT4_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
-+ (EXT4_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask))
- #define EXT4_SET_COMPAT_FEATURE(sb,mask) \
- EXT4_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
- #define EXT4_SET_RO_COMPAT_FEATURE(sb,mask) \
-@@ -985,13 +985,13 @@ extern ext4_fsblk_t ext4_old_new_blocks(
- ext4_fsblk_t goal, unsigned long *count, int *errp);
- extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
- ext4_fsblk_t nblocks);
--extern void ext4_free_blocks (handle_t *handle, struct inode *inode,
-+extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
- ext4_fsblk_t block, unsigned long count, int metadata);
--extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb,
-- ext4_fsblk_t block, unsigned long count,
-+extern void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
-+ ext4_fsblk_t block, unsigned long count,
- unsigned long *pdquot_freed_blocks);
--extern ext4_fsblk_t ext4_count_free_blocks (struct super_block *);
--extern void ext4_check_blocks_bitmap (struct super_block *);
-+extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *);
-+extern void ext4_check_blocks_bitmap(struct super_block *);
- extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
- ext4_group_t block_group,
- struct buffer_head ** bh);
-@@ -1009,20 +1009,20 @@ extern int ext4_htree_store_dirent(struc
- extern void ext4_htree_free_dir_info(struct dir_private_info *p);
-
- /* fsync.c */
--extern int ext4_sync_file (struct file *, struct dentry *, int);
-+extern int ext4_sync_file(struct file *, struct dentry *, int);
-
- /* hash.c */
- extern int ext4fs_dirhash(const char *name, int len, struct
- dx_hash_info *hinfo);
-
- /* ialloc.c */
--extern struct inode * ext4_new_inode (handle_t *, struct inode *, int);
--extern void ext4_free_inode (handle_t *, struct inode *);
--extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
--extern unsigned long ext4_count_free_inodes (struct super_block *);
--extern unsigned long ext4_count_dirs (struct super_block *);
--extern void ext4_check_inodes_bitmap (struct super_block *);
--extern unsigned long ext4_count_free (struct buffer_head *, unsigned);
-+extern struct inode * ext4_new_inode(handle_t *, struct inode *, int);
-+extern void ext4_free_inode(handle_t *, struct inode *);
-+extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
-+extern unsigned long ext4_count_free_inodes(struct super_block *);
-+extern unsigned long ext4_count_dirs(struct super_block *);
-+extern void ext4_check_inodes_bitmap(struct super_block *);
-+extern unsigned long ext4_count_free(struct buffer_head *, unsigned);
-
- /* mballoc.c */
- extern long ext4_mb_stats;
-@@ -1056,18 +1056,18 @@ int ext4_get_blocks_handle(handle_t *han
- int create, int extend_disksize);
-
- extern struct inode *ext4_iget(struct super_block *, unsigned long);
--extern int ext4_write_inode (struct inode *, int);
--extern int ext4_setattr (struct dentry *, struct iattr *);
-+extern int ext4_write_inode(struct inode *, int);
-+extern int ext4_setattr(struct dentry *, struct iattr *);
- extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
- struct kstat *stat);
--extern void ext4_delete_inode (struct inode *);
--extern int ext4_sync_inode (handle_t *, struct inode *);
--extern void ext4_discard_reservation (struct inode *);
-+extern void ext4_delete_inode(struct inode *);
-+extern int ext4_sync_inode(handle_t *, struct inode *);
-+extern void ext4_discard_reservation(struct inode *);
- extern void ext4_dirty_inode(struct inode *);
- extern int ext4_change_inode_journal_flag(struct inode *, int);
- extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *);
- extern int ext4_can_truncate(struct inode *inode);
--extern void ext4_truncate (struct inode *);
-+extern void ext4_truncate(struct inode *);
- extern void ext4_set_inode_flags(struct inode *);
- extern void ext4_get_inode_flags(struct ext4_inode_info *);
- extern void ext4_set_aops(struct inode *inode);
-@@ -1080,7 +1080,7 @@ extern int ext4_page_mkwrite(struct vm_a
-
- /* ioctl.c */
- extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
--extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long);
-+extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
-
- /* migrate.c */
- extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
-@@ -1099,14 +1099,14 @@ extern int ext4_group_extend(struct supe
- ext4_fsblk_t n_blocks_count);
-
- /* super.c */
--extern void ext4_error (struct super_block *, const char *, const char *, ...)
-+extern void ext4_error(struct super_block *, const char *, const char *, ...)
- __attribute__ ((format (printf, 3, 4)));
--extern void __ext4_std_error (struct super_block *, const char *, int);
--extern void ext4_abort (struct super_block *, const char *, const char *, ...)
-+extern void __ext4_std_error(struct super_block *, const char *, int);
-+extern void ext4_abort(struct super_block *, const char *, const char *, ...)
- __attribute__ ((format (printf, 3, 4)));
--extern void ext4_warning (struct super_block *, const char *, const char *, ...)
-+extern void ext4_warning(struct super_block *, const char *, const char *, ...)
- __attribute__ ((format (printf, 3, 4)));
--extern void ext4_update_dynamic_rev (struct super_block *sb);
-+extern void ext4_update_dynamic_rev(struct super_block *sb);
- extern int ext4_update_compat_feature(handle_t *handle, struct super_block *sb,
- __u32 compat);
- extern int ext4_update_rocompat_feature(handle_t *handle,
-@@ -1179,7 +1179,7 @@ static inline void ext4_isize_set(struct
-
- static inline
- struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
-- ext4_group_t group)
-+ ext4_group_t group)
- {
- struct ext4_group_info ***grp_info;
- long indexv, indexh;
---- a/fs/ext4/ext4_sb.h
-+++ b/fs/ext4/ext4_sb.h
-@@ -40,8 +40,8 @@ struct ext4_sb_info {
- unsigned long s_blocks_last; /* Last seen block count */
- loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */
- struct buffer_head * s_sbh; /* Buffer containing the super block */
-- struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */
-- struct buffer_head ** s_group_desc;
-+ struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */
-+ struct buffer_head **s_group_desc;
- unsigned long s_mount_opt;
- ext4_fsblk_t s_sb_block;
- uid_t s_resuid;
-@@ -67,8 +67,8 @@ struct ext4_sb_info {
- struct ext4_reserve_window_node s_rsv_window_head;
-
- /* Journaling */
-- struct inode * s_journal_inode;
-- struct journal_s * s_journal;
-+ struct inode *s_journal_inode;
-+ struct journal_s *s_journal;
- struct list_head s_orphan;
- unsigned long s_commit_interval;
- struct block_device *journal_bdev;
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -383,8 +383,8 @@ static void ext4_ext_show_leaf(struct in
- ext_debug("\n");
- }
- #else
--#define ext4_ext_show_path(inode,path)
--#define ext4_ext_show_leaf(inode,path)
-+#define ext4_ext_show_path(inode, path)
-+#define ext4_ext_show_leaf(inode, path)
- #endif
-
- void ext4_ext_drop_refs(struct ext4_ext_path *path)
-@@ -1476,7 +1476,7 @@ int ext4_ext_insert_extent(handle_t *han
- struct ext4_ext_path *path,
- struct ext4_extent *newext)
- {
-- struct ext4_extent_header * eh;
-+ struct ext4_extent_header *eh;
- struct ext4_extent *ex, *fex;
- struct ext4_extent *nearex; /* nearest extent */
- struct ext4_ext_path *npath = NULL;
---- a/fs/ext4/file.c
-+++ b/fs/ext4/file.c
-@@ -31,7 +31,7 @@
- * from ext4_file_open: open gets called at every open, but release
- * gets called only when /all/ the files are closed.
- */
--static int ext4_release_file (struct inode * inode, struct file * filp)
-+static int ext4_release_file(struct inode *inode, struct file *filp)
- {
- /* if we are the last writer on the inode, drop the block reservation */
- if ((filp->f_mode & FMODE_WRITE) &&
---- a/fs/ext4/fsync.c
-+++ b/fs/ext4/fsync.c
-@@ -43,7 +43,7 @@
- * inode to disk.
- */
-
--int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync)
-+int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
- {
- struct inode *inode = dentry->d_inode;
- journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
---- a/fs/ext4/hash.c
-+++ b/fs/ext4/hash.c
-@@ -27,7 +27,7 @@ static void TEA_transform(__u32 buf[4],
- sum += DELTA;
- b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
- b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
-- } while(--n);
-+ } while (--n);
-
- buf[0] += b0;
- buf[1] += b1;
-@@ -35,7 +35,7 @@ static void TEA_transform(__u32 buf[4],
-
-
- /* The old legacy hash */
--static __u32 dx_hack_hash (const char *name, int len)
-+static __u32 dx_hack_hash(const char *name, int len)
- {
- __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
- while (len--) {
-@@ -59,7 +59,7 @@ static void str2hashbuf(const char *msg,
- val = pad;
- if (len > num*4)
- len = num * 4;
-- for (i=0; i < len; i++) {
-+ for (i = 0; i < len; i++) {
- if ((i % 4) == 0)
- val = pad;
- val = msg[i] + (val << 8);
-@@ -104,7 +104,7 @@ int ext4fs_dirhash(const char *name, int
-
- /* Check to see if the seed is all zero's */
- if (hinfo->seed) {
-- for (i=0; i < 4; i++) {
-+ for (i = 0; i < 4; i++) {
- if (hinfo->seed[i])
- break;
- }
---- a/fs/ext4/ialloc.c
-+++ b/fs/ext4/ialloc.c
-@@ -154,17 +154,17 @@ ext4_read_inode_bitmap(struct super_bloc
- * though), and then we'd have two inodes sharing the
- * same inode number and space on the harddisk.
- */
--void ext4_free_inode (handle_t *handle, struct inode * inode)
-+void ext4_free_inode(handle_t *handle, struct inode *inode)
- {
-- struct super_block * sb = inode->i_sb;
-+ struct super_block *sb = inode->i_sb;
- int is_directory;
- unsigned long ino;
- struct buffer_head *bitmap_bh = NULL;
- struct buffer_head *bh2;
- ext4_group_t block_group;
- unsigned long bit;
-- struct ext4_group_desc * gdp;
-- struct ext4_super_block * es;
-+ struct ext4_group_desc *gdp;
-+ struct ext4_super_block *es;
- struct ext4_sb_info *sbi;
- int fatal = 0, err;
- ext4_group_t flex_group;
-@@ -187,7 +187,7 @@ void ext4_free_inode (handle_t *handle,
- sbi = EXT4_SB(sb);
-
- ino = inode->i_ino;
-- ext4_debug ("freeing inode %lu\n", ino);
-+ ext4_debug("freeing inode %lu\n", ino);
-
- /*
- * Note: we must free any quota before locking the superblock,
-@@ -201,12 +201,12 @@ void ext4_free_inode (handle_t *handle,
- is_directory = S_ISDIR(inode->i_mode);
-
- /* Do this BEFORE marking the inode not in use or returning an error */
-- clear_inode (inode);
-+ clear_inode(inode);
-
- es = EXT4_SB(sb)->s_es;
- if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
-- ext4_error (sb, "ext4_free_inode",
-- "reserved or nonexistent inode %lu", ino);
-+ ext4_error(sb, "ext4_free_inode",
-+ "reserved or nonexistent inode %lu", ino);
- goto error_return;
- }
- block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
-@@ -223,10 +223,10 @@ void ext4_free_inode (handle_t *handle,
- /* Ok, now we can actually update the inode bitmaps.. */
- if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
- bit, bitmap_bh->b_data))
-- ext4_error (sb, "ext4_free_inode",
-- "bit already cleared for inode %lu", ino);
-+ ext4_error(sb, "ext4_free_inode",
-+ "bit already cleared for inode %lu", ino);
- else {
-- gdp = ext4_get_group_desc (sb, block_group, &bh2);
-+ gdp = ext4_get_group_desc(sb, block_group, &bh2);
-
- BUFFER_TRACE(bh2, "get_write_access");
- fatal = ext4_journal_get_write_access(handle, bh2);
-@@ -288,7 +288,7 @@ static int find_group_dir(struct super_b
- avefreei = freei / ngroups;
-
- for (group = 0; group < ngroups; group++) {
-- desc = ext4_get_group_desc (sb, group, NULL);
-+ desc = ext4_get_group_desc(sb, group, NULL);
- if (!desc || !desc->bg_free_inodes_count)
- continue;
- if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
-@@ -577,16 +577,16 @@ static int find_group_other(struct super
- * For other inodes, search forward from the parent directory's block
- * group to find a free inode.
- */
--struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
-+struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
- {
- struct super_block *sb;
- struct buffer_head *bitmap_bh = NULL;
- struct buffer_head *bh2;
- ext4_group_t group = 0;
- unsigned long ino = 0;
-- struct inode * inode;
-- struct ext4_group_desc * gdp = NULL;
-- struct ext4_super_block * es;
-+ struct inode *inode;
-+ struct ext4_group_desc *gdp = NULL;
-+ struct ext4_super_block *es;
- struct ext4_inode_info *ei;
- struct ext4_sb_info *sbi;
- int ret2, err = 0;
-@@ -614,7 +614,7 @@ struct inode *ext4_new_inode(handle_t *h
- }
-
- if (S_ISDIR(mode)) {
-- if (test_opt (sb, OLDALLOC))
-+ if (test_opt(sb, OLDALLOC))
- ret2 = find_group_dir(sb, dir, &group);
- else
- ret2 = find_group_orlov(sb, dir, &group);
-@@ -784,7 +784,7 @@ got:
- }
-
- inode->i_uid = current->fsuid;
-- if (test_opt (sb, GRPID))
-+ if (test_opt(sb, GRPID))
- inode->i_gid = dir->i_gid;
- else if (dir->i_mode & S_ISGID) {
- inode->i_gid = dir->i_gid;
-@@ -833,7 +833,7 @@ got:
- ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
-
- ret = inode;
-- if(DQUOT_ALLOC_INODE(inode)) {
-+ if (DQUOT_ALLOC_INODE(inode)) {
- err = -EDQUOT;
- goto fail_drop;
- }
-@@ -842,7 +842,7 @@ got:
- if (err)
- goto fail_free_drop;
-
-- err = ext4_init_security(handle,inode, dir);
-+ err = ext4_init_security(handle, inode, dir);
- if (err)
- goto fail_free_drop;
-
-@@ -960,7 +960,7 @@ error:
- return ERR_PTR(err);
- }
-
--unsigned long ext4_count_free_inodes (struct super_block * sb)
-+unsigned long ext4_count_free_inodes(struct super_block *sb)
- {
- unsigned long desc_count;
- struct ext4_group_desc *gdp;
-@@ -975,7 +975,7 @@ unsigned long ext4_count_free_inodes (st
- bitmap_count = 0;
- gdp = NULL;
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
-- gdp = ext4_get_group_desc (sb, i, NULL);
-+ gdp = ext4_get_group_desc(sb, i, NULL);
- if (!gdp)
- continue;
- desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
-@@ -997,7 +997,7 @@ unsigned long ext4_count_free_inodes (st
- #else
- desc_count = 0;
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
-- gdp = ext4_get_group_desc (sb, i, NULL);
-+ gdp = ext4_get_group_desc(sb, i, NULL);
- if (!gdp)
- continue;
- desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
-@@ -1008,13 +1008,13 @@ unsigned long ext4_count_free_inodes (st
- }
-
- /* Called at mount-time, super-block is locked */
--unsigned long ext4_count_dirs (struct super_block * sb)
-+unsigned long ext4_count_dirs(struct super_block * sb)
- {
- unsigned long count = 0;
- ext4_group_t i;
-
- for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
-- struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL);
-+ struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL);
- if (!gdp)
- continue;
- count += le16_to_cpu(gdp->bg_used_dirs_count);
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -190,7 +190,7 @@ static int ext4_journal_test_restart(han
- /*
- * Called at the last iput() if i_nlink is zero.
- */
--void ext4_delete_inode (struct inode * inode)
-+void ext4_delete_inode(struct inode *inode)
- {
- handle_t *handle;
- int err;
-@@ -330,11 +330,11 @@ static int ext4_block_to_path(struct ino
- int final = 0;
-
- if (i_block < 0) {
-- ext4_warning (inode->i_sb, "ext4_block_to_path", "block < 0");
-+ ext4_warning(inode->i_sb, "ext4_block_to_path", "block < 0");
- } else if (i_block < direct_blocks) {
- offsets[n++] = i_block;
- final = direct_blocks;
-- } else if ( (i_block -= direct_blocks) < indirect_blocks) {
-+ } else if ((i_block -= direct_blocks) < indirect_blocks) {
- offsets[n++] = EXT4_IND_BLOCK;
- offsets[n++] = i_block;
- final = ptrs;
-@@ -400,14 +400,14 @@ static Indirect *ext4_get_branch(struct
-
- *err = 0;
- /* i_data is not going away, no lock needed */
-- add_chain (chain, NULL, EXT4_I(inode)->i_data + *offsets);
-+ add_chain(chain, NULL, EXT4_I(inode)->i_data + *offsets);
- if (!p->key)
- goto no_block;
- while (--depth) {
- bh = sb_bread(sb, le32_to_cpu(p->key));
- if (!bh)
- goto failure;
-- add_chain(++p, bh, (__le32*)bh->b_data + *++offsets);
-+ add_chain(++p, bh, (__le32 *)bh->b_data + *++offsets);
- /* Reader: end */
- if (!p->key)
- goto no_block;
-@@ -443,7 +443,7 @@ no_block:
- static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
- {
- struct ext4_inode_info *ei = EXT4_I(inode);
-- __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data;
-+ __le32 *start = ind->bh ? (__le32 *) ind->bh->b_data : ei->i_data;
- __le32 *p;
- ext4_fsblk_t bg_start;
- ext4_fsblk_t last_block;
-@@ -630,7 +630,7 @@ allocated:
- *err = 0;
- return ret;
- failed_out:
-- for (i = 0; i <index; i++)
-+ for (i = 0; i < index; i++)
- ext4_free_blocks(handle, inode, new_blocks[i], 1, 0);
- return ret;
- }
-@@ -703,7 +703,7 @@ static int ext4_alloc_branch(handle_t *h
- branch[n].p = (__le32 *) bh->b_data + offsets[n];
- branch[n].key = cpu_to_le32(new_blocks[n]);
- *branch[n].p = branch[n].key;
-- if ( n == indirect_blks) {
-+ if (n == indirect_blks) {
- current_block = new_blocks[n];
- /*
- * End of chain, update the last new metablock of
-@@ -730,7 +730,7 @@ failed:
- BUFFER_TRACE(branch[i].bh, "call jbd2_journal_forget");
- ext4_journal_forget(handle, branch[i].bh);
- }
-- for (i = 0; i <indirect_blks; i++)
-+ for (i = 0; i < indirect_blks; i++)
- ext4_free_blocks(handle, inode, new_blocks[i], 1, 0);
-
- ext4_free_blocks(handle, inode, new_blocks[i], num, 0);
-@@ -783,7 +783,7 @@ static int ext4_splice_branch(handle_t *
- if (num == 0 && blks > 1) {
- current_block = le32_to_cpu(where->key) + 1;
- for (i = 1; i < blks; i++)
-- *(where->p + i ) = cpu_to_le32(current_block++);
-+ *(where->p + i) = cpu_to_le32(current_block++);
- }
-
- /*
-@@ -1241,7 +1241,7 @@ struct buffer_head *ext4_getblk(handle_t
- BUFFER_TRACE(bh, "call get_create_access");
- fatal = ext4_journal_get_create_access(handle, bh);
- if (!fatal && !buffer_uptodate(bh)) {
-- memset(bh->b_data,0,inode->i_sb->s_blocksize);
-+ memset(bh->b_data, 0, inode->i_sb->s_blocksize);
- set_buffer_uptodate(bh);
- }
- unlock_buffer(bh);
-@@ -1266,7 +1266,7 @@ err:
- struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
- ext4_lblk_t block, int create, int *err)
- {
-- struct buffer_head * bh;
-+ struct buffer_head *bh;
-
- bh = ext4_getblk(handle, inode, block, create, err);
- if (!bh)
-@@ -1282,13 +1282,13 @@ struct buffer_head *ext4_bread(handle_t
- return NULL;
- }
-
--static int walk_page_buffers( handle_t *handle,
-- struct buffer_head *head,
-- unsigned from,
-- unsigned to,
-- int *partial,
-- int (*fn)( handle_t *handle,
-- struct buffer_head *bh))
-+static int walk_page_buffers(handle_t *handle,
-+ struct buffer_head *head,
-+ unsigned from,
-+ unsigned to,
-+ int *partial,
-+ int (*fn)(handle_t *handle,
-+ struct buffer_head *bh))
- {
- struct buffer_head *bh;
- unsigned block_start, block_end;
-@@ -1296,9 +1296,9 @@ static int walk_page_buffers( handle_t *
- int err, ret = 0;
- struct buffer_head *next;
-
-- for ( bh = head, block_start = 0;
-- ret == 0 && (bh != head || !block_start);
-- block_start = block_end, bh = next)
-+ for (bh = head, block_start = 0;
-+ ret == 0 && (bh != head || !block_start);
-+ block_start = block_end, bh = next)
- {
- next = bh->b_this_page;
- block_end = block_start + blocksize;
-@@ -1351,23 +1351,23 @@ static int ext4_write_begin(struct file
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
- {
-- struct inode *inode = mapping->host;
-+ struct inode *inode = mapping->host;
- int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
- handle_t *handle;
- int retries = 0;
-- struct page *page;
-+ struct page *page;
- pgoff_t index;
-- unsigned from, to;
-+ unsigned from, to;
-
- index = pos >> PAGE_CACHE_SHIFT;
-- from = pos & (PAGE_CACHE_SIZE - 1);
-- to = from + len;
-+ from = pos & (PAGE_CACHE_SIZE - 1);
-+ to = from + len;
-
- retry:
-- handle = ext4_journal_start(inode, needed_blocks);
-- if (IS_ERR(handle)) {
-- ret = PTR_ERR(handle);
-- goto out;
-+ handle = ext4_journal_start(inode, needed_blocks);
-+ if (IS_ERR(handle)) {
-+ ret = PTR_ERR(handle);
-+ goto out;
- }
-
- page = __grab_cache_page(mapping, index);
-@@ -1387,9 +1387,9 @@ retry:
- }
-
- if (ret) {
-- unlock_page(page);
-+ unlock_page(page);
- ext4_journal_stop(handle);
-- page_cache_release(page);
-+ page_cache_release(page);
- }
-
- if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
-@@ -2456,7 +2456,7 @@ static int ext4_da_should_update_i_disks
- bh = page_buffers(page);
- idx = offset >> inode->i_blkbits;
-
-- for (i=0; i < idx; i++)
-+ for (i = 0; i < idx; i++)
- bh = bh->b_this_page;
-
- if (!buffer_mapped(bh) || (buffer_delay(bh)))
-@@ -2476,7 +2476,7 @@ static int ext4_da_write_end(struct file
- unsigned long start, end;
-
- start = pos & (PAGE_CACHE_SIZE - 1);
-- end = start + copied -1;
-+ end = start + copied - 1;
-
- /*
- * generic_write_end() will run mark_inode_dirty() if i_size
-@@ -2591,7 +2591,7 @@ static sector_t ext4_bmap(struct address
- return 0;
- }
-
-- return generic_block_bmap(mapping,block,ext4_get_block);
-+ return generic_block_bmap(mapping, block, ext4_get_block);
- }
-
- static int bget_one(handle_t *handle, struct buffer_head *bh)
-@@ -3197,7 +3197,7 @@ static Indirect *ext4_find_shared(struct
- if (!partial->key && *partial->p)
- /* Writer: end */
- goto no_top;
-- for (p=partial; p>chain && all_zeroes((__le32*)p->bh->b_data,p->p); p--)
-+ for (p = partial; (p > chain) && all_zeroes((__le32 *) p->bh->b_data, p->p); p--)
- ;
- /*
- * OK, we've found the last block that must survive. The rest of our
-@@ -3216,7 +3216,7 @@ static Indirect *ext4_find_shared(struct
- }
- /* Writer: end */
-
-- while(partial > p) {
-+ while (partial > p) {
- brelse(partial->bh);
- partial--;
- }
-@@ -3408,9 +3408,9 @@ static void ext4_free_branches(handle_t
- /* This zaps the entire block. Bottom up. */
- BUFFER_TRACE(bh, "free child branches");
- ext4_free_branches(handle, inode, bh,
-- (__le32*)bh->b_data,
-- (__le32*)bh->b_data + addr_per_block,
-- depth);
-+ (__le32 *) bh->b_data,
-+ (__le32 *) bh->b_data + addr_per_block,
-+ depth);
-
- /*
- * We've probably journalled the indirect block several
-@@ -3927,7 +3927,7 @@ struct inode *ext4_iget(struct super_blo
- inode->i_mode = le16_to_cpu(raw_inode->i_mode);
- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
-- if(!(test_opt (inode->i_sb, NO_UID32))) {
-+ if (!(test_opt(inode->i_sb, NO_UID32))) {
- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
- }
-@@ -3945,7 +3945,7 @@ struct inode *ext4_iget(struct super_blo
- if (inode->i_mode == 0 ||
- !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) {
- /* this inode is deleted */
-- brelse (bh);
-+ brelse(bh);
- ret = -ESTALE;
- goto bad_inode;
- }
-@@ -3978,7 +3978,7 @@ struct inode *ext4_iget(struct super_blo
- ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
- if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
- EXT4_INODE_SIZE(inode->i_sb)) {
-- brelse (bh);
-+ brelse(bh);
- ret = -EIO;
- goto bad_inode;
- }
-@@ -4031,7 +4031,7 @@ struct inode *ext4_iget(struct super_blo
- init_special_inode(inode, inode->i_mode,
- new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
- }
-- brelse (iloc.bh);
-+ brelse(iloc.bh);
- ext4_set_inode_flags(inode);
- unlock_new_inode(inode);
- return inode;
-@@ -4113,14 +4113,14 @@ static int ext4_do_update_inode(handle_t
-
- ext4_get_inode_flags(ei);
- raw_inode->i_mode = cpu_to_le16(inode->i_mode);
-- if(!(test_opt(inode->i_sb, NO_UID32))) {
-+ if (!(test_opt(inode->i_sb, NO_UID32))) {
- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
- /*
- * Fix up interoperability with old kernels. Otherwise, old inodes get
- * re-used with the upper 16 bits of the uid/gid intact
- */
-- if(!ei->i_dtime) {
-+ if (!ei->i_dtime) {
- raw_inode->i_uid_high =
- cpu_to_le16(high_16_bits(inode->i_uid));
- raw_inode->i_gid_high =
-@@ -4208,7 +4208,7 @@ static int ext4_do_update_inode(handle_t
- ei->i_state &= ~EXT4_STATE_NEW;
-
- out_brelse:
-- brelse (bh);
-+ brelse(bh);
- ext4_std_error(inode->i_sb, err);
- return err;
- }
---- a/fs/ext4/ioctl.c
-+++ b/fs/ext4/ioctl.c
-@@ -25,7 +25,7 @@ long ext4_ioctl(struct file *filp, unsig
- unsigned int flags;
- unsigned short rsv_window_size;
-
-- ext4_debug ("cmd = %u, arg = %lu\n", cmd, arg);
-+ ext4_debug("cmd = %u, arg = %lu\n", cmd, arg);
-
- switch (cmd) {
- case EXT4_IOC_GETFLAGS:
-@@ -186,7 +186,7 @@ setversion_out:
- case EXT4_IOC_SETRSVSZ: {
- int err;
-
-- if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
-+ if (!test_opt(inode->i_sb, RESERVATION) || !S_ISREG(inode->i_mode))
- return -ENOTTY;
-
- if (!is_owner_or_cap(inode))
---- a/fs/ext4/namei.c
-+++ b/fs/ext4/namei.c
-@@ -151,26 +151,26 @@ struct dx_map_entry
-
- static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
- static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
--static inline unsigned dx_get_hash (struct dx_entry *entry);
--static void dx_set_hash (struct dx_entry *entry, unsigned value);
--static unsigned dx_get_count (struct dx_entry *entries);
--static unsigned dx_get_limit (struct dx_entry *entries);
--static void dx_set_count (struct dx_entry *entries, unsigned value);
--static void dx_set_limit (struct dx_entry *entries, unsigned value);
--static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
--static unsigned dx_node_limit (struct inode *dir);
-+static inline unsigned dx_get_hash(struct dx_entry *entry);
-+static void dx_set_hash(struct dx_entry *entry, unsigned value);
-+static unsigned dx_get_count(struct dx_entry *entries);
-+static unsigned dx_get_limit(struct dx_entry *entries);
-+static void dx_set_count(struct dx_entry *entries, unsigned value);
-+static void dx_set_limit(struct dx_entry *entries, unsigned value);
-+static unsigned dx_root_limit(struct inode *dir, unsigned infosize);
-+static unsigned dx_node_limit(struct inode *dir);
- static struct dx_frame *dx_probe(struct dentry *dentry,
- struct inode *dir,
- struct dx_hash_info *hinfo,
- struct dx_frame *frame,
- int *err);
--static void dx_release (struct dx_frame *frames);
--static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
-- struct dx_hash_info *hinfo, struct dx_map_entry map[]);
-+static void dx_release(struct dx_frame *frames);
-+static int dx_make_map(struct ext4_dir_entry_2 *de, int size,
-+ struct dx_hash_info *hinfo, struct dx_map_entry map[]);
- static void dx_sort_map(struct dx_map_entry *map, unsigned count);
--static struct ext4_dir_entry_2 *dx_move_dirents (char *from, char *to,
-+static struct ext4_dir_entry_2 *dx_move_dirents(char *from, char *to,
- struct dx_map_entry *offsets, int count);
--static struct ext4_dir_entry_2* dx_pack_dirents (char *base, int size);
-+static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size);
- static void dx_insert_block(struct dx_frame *frame,
- u32 hash, ext4_lblk_t block);
- static int ext4_htree_next_block(struct inode *dir, __u32 hash,
-@@ -207,44 +207,44 @@ static inline void dx_set_block(struct d
- entry->block = cpu_to_le32(value);
- }
-
--static inline unsigned dx_get_hash (struct dx_entry *entry)
-+static inline unsigned dx_get_hash(struct dx_entry *entry)
- {
- return le32_to_cpu(entry->hash);
- }
-
--static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
-+static inline void dx_set_hash(struct dx_entry *entry, unsigned value)
- {
- entry->hash = cpu_to_le32(value);
- }
-
--static inline unsigned dx_get_count (struct dx_entry *entries)
-+static inline unsigned dx_get_count(struct dx_entry *entries)
- {
- return le16_to_cpu(((struct dx_countlimit *) entries)->count);
- }
-
--static inline unsigned dx_get_limit (struct dx_entry *entries)
-+static inline unsigned dx_get_limit(struct dx_entry *entries)
- {
- return le16_to_cpu(((struct dx_countlimit *) entries)->limit);
- }
-
--static inline void dx_set_count (struct dx_entry *entries, unsigned value)
-+static inline void dx_set_count(struct dx_entry *entries, unsigned value)
- {
- ((struct dx_countlimit *) entries)->count = cpu_to_le16(value);
- }
-
--static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
-+static inline void dx_set_limit(struct dx_entry *entries, unsigned value)
- {
- ((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
- }
-
--static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
-+static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)
- {
- unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) -
- EXT4_DIR_REC_LEN(2) - infosize;
- return entry_space / sizeof(struct dx_entry);
- }
-
--static inline unsigned dx_node_limit (struct inode *dir)
-+static inline unsigned dx_node_limit(struct inode *dir)
- {
- unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
- return entry_space / sizeof(struct dx_entry);
-@@ -306,7 +306,7 @@ struct stats dx_show_entries(struct dx_h
- struct dx_entry *entries, int levels)
- {
- unsigned blocksize = dir->i_sb->s_blocksize;
-- unsigned count = dx_get_count (entries), names = 0, space = 0, i;
-+ unsigned count = dx_get_count(entries), names = 0, space = 0, i;
- unsigned bcount = 0;
- struct buffer_head *bh;
- int err;
-@@ -325,7 +325,7 @@ struct stats dx_show_entries(struct dx_h
- names += stats.names;
- space += stats.space;
- bcount += stats.bcount;
-- brelse (bh);
-+ brelse(bh);
- }
- if (bcount)
- printk(KERN_DEBUG "%snames %u, fullness %u (%u%%)\n",
-@@ -407,7 +407,7 @@ dx_probe(struct dentry *dentry, struct i
- goto fail;
- }
-
-- dxtrace (printk("Look up %x", hash));
-+ dxtrace(printk("Look up %x", hash));
- while (1)
- {
- count = dx_get_count(entries);
-@@ -556,7 +556,7 @@ static int ext4_htree_next_block(struct
- 0, &err)))
- return err; /* Failure */
- p++;
-- brelse (p->bh);
-+ brelse(p->bh);
- p->bh = bh;
- p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
- }
-@@ -594,7 +594,7 @@ static int htree_dirblock_to_tree(struct
- /* On error, skip the f_pos to the next block. */
- dir_file->f_pos = (dir_file->f_pos |
- (dir->i_sb->s_blocksize - 1)) + 1;
-- brelse (bh);
-+ brelse(bh);
- return count;
- }
- ext4fs_dirhash(de->name, de->name_len, hinfo);
-@@ -803,7 +803,7 @@ static inline int ext4_match (int len, c
- /*
- * Returns 0 if not found, -1 on failure, and 1 on success
- */
--static inline int search_dirblock(struct buffer_head * bh,
-+static inline int search_dirblock(struct buffer_head *bh,
- struct inode *dir,
- struct dentry *dentry,
- unsigned long offset,
-@@ -855,9 +855,9 @@ static inline int search_dirblock(struct
- static struct buffer_head * ext4_find_entry (struct dentry *dentry,
- struct ext4_dir_entry_2 ** res_dir)
- {
-- struct super_block * sb;
-- struct buffer_head * bh_use[NAMEI_RA_SIZE];
-- struct buffer_head * bh, *ret = NULL;
-+ struct super_block *sb;
-+ struct buffer_head *bh_use[NAMEI_RA_SIZE];
-+ struct buffer_head *bh, *ret = NULL;
- ext4_lblk_t start, block, b;
- int ra_max = 0; /* Number of bh's in the readahead
- buffer, bh_use[] */
-@@ -958,7 +958,7 @@ restart:
- cleanup_and_exit:
- /* Clean up the read-ahead blocks */
- for (; ra_ptr < ra_max; ra_ptr++)
-- brelse (bh_use[ra_ptr]);
-+ brelse(bh_use[ra_ptr]);
- return ret;
- }
-
-@@ -1012,7 +1012,7 @@ static struct buffer_head * ext4_dx_find
- return bh;
- }
- }
-- brelse (bh);
-+ brelse(bh);
- /* Check to see if we should continue to search */
- retval = ext4_htree_next_block(dir, hash, frame,
- frames, NULL);
-@@ -1032,11 +1032,11 @@ errout:
- return NULL;
- }
-
--static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
-+static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
- {
-- struct inode * inode;
-- struct ext4_dir_entry_2 * de;
-- struct buffer_head * bh;
-+ struct inode *inode;
-+ struct ext4_dir_entry_2 *de;
-+ struct buffer_head *bh;
-
- if (dentry->d_name.len > EXT4_NAME_LEN)
- return ERR_PTR(-ENAMETOOLONG);
-@@ -1045,7 +1045,7 @@ static struct dentry *ext4_lookup(struct
- inode = NULL;
- if (bh) {
- unsigned long ino = le32_to_cpu(de->inode);
-- brelse (bh);
-+ brelse(bh);
- if (!ext4_valid_inum(dir->i_sb, ino)) {
- ext4_error(dir->i_sb, "ext4_lookup",
- "bad inode number: %lu", ino);
-@@ -1203,10 +1203,10 @@ static struct ext4_dir_entry_2 *do_split
-
- /* create map in the end of data2 block */
- map = (struct dx_map_entry *) (data2 + blocksize);
-- count = dx_make_map ((struct ext4_dir_entry_2 *) data1,
-+ count = dx_make_map((struct ext4_dir_entry_2 *) data1,
- blocksize, hinfo, map);
- map -= count;
-- dx_sort_map (map, count);
-+ dx_sort_map(map, count);
- /* Split the existing block in the middle, size-wise */
- size = 0;
- move = 0;
-@@ -1227,7 +1227,7 @@ static struct ext4_dir_entry_2 *do_split
-
- /* Fancy dance to stay within two buffers */
- de2 = dx_move_dirents(data1, data2, map + split, count - split);
-- de = dx_pack_dirents(data1,blocksize);
-+ de = dx_pack_dirents(data1, blocksize);
- de->rec_len = ext4_rec_len_to_disk(data1 + blocksize - (char *) de);
- de2->rec_len = ext4_rec_len_to_disk(data2 + blocksize - (char *) de2);
- dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1));
-@@ -1239,15 +1239,15 @@ static struct ext4_dir_entry_2 *do_split
- swap(*bh, bh2);
- de = de2;
- }
-- dx_insert_block (frame, hash2 + continued, newblock);
-- err = ext4_journal_dirty_metadata (handle, bh2);
-+ dx_insert_block(frame, hash2 + continued, newblock);
-+ err = ext4_journal_dirty_metadata(handle, bh2);
- if (err)
- goto journal_error;
-- err = ext4_journal_dirty_metadata (handle, frame->bh);
-+ err = ext4_journal_dirty_metadata(handle, frame->bh);
- if (err)
- goto journal_error;
-- brelse (bh2);
-- dxtrace(dx_show_index ("frame", frame->entries));
-+ brelse(bh2);
-+ dxtrace(dx_show_index("frame", frame->entries));
- return de;
-
- journal_error:
-@@ -1273,7 +1273,7 @@ errout:
- */
- static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
- struct inode *inode, struct ext4_dir_entry_2 *de,
-- struct buffer_head * bh)
-+ struct buffer_head *bh)
- {
- struct inode *dir = dentry->d_parent->d_inode;
- const char *name = dentry->d_name.name;
-@@ -1290,11 +1290,11 @@ static int add_dirent_to_buf(handle_t *h
- while ((char *) de <= top) {
- if (!ext4_check_dir_entry("ext4_add_entry", dir, de,
- bh, offset)) {
-- brelse (bh);
-+ brelse(bh);
- return -EIO;
- }
-- if (ext4_match (namelen, name, de)) {
-- brelse (bh);
-+ if (ext4_match(namelen, name, de)) {
-+ brelse(bh);
- return -EEXIST;
- }
- nlen = EXT4_DIR_REC_LEN(de->name_len);
-@@ -1331,7 +1331,7 @@ static int add_dirent_to_buf(handle_t *h
- } else
- de->inode = 0;
- de->name_len = namelen;
-- memcpy (de->name, name, namelen);
-+ memcpy(de->name, name, namelen);
- /*
- * XXX shouldn't update any times until successful
- * completion of syscall, but too many callers depend
-@@ -1388,7 +1388,7 @@ static int make_indexed_dir(handle_t *ha
- }
- root = (struct dx_root *) bh->b_data;
-
-- bh2 = ext4_append (handle, dir, &block, &retval);
-+ bh2 = ext4_append(handle, dir, &block, &retval);
- if (!(bh2)) {
- brelse(bh);
- return retval;
-@@ -1414,9 +1414,9 @@ static int make_indexed_dir(handle_t *ha
- root->info.info_length = sizeof(root->info);
- root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
- entries = root->entries;
-- dx_set_block (entries, 1);
-- dx_set_count (entries, 1);
-- dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
-+ dx_set_block(entries, 1);
-+ dx_set_count(entries, 1);
-+ dx_set_limit(entries, dx_root_limit(dir, sizeof(root->info)));
-
- /* Initialize as for dx_probe */
- hinfo.hash_version = root->info.hash_version;
-@@ -1445,14 +1445,14 @@ static int make_indexed_dir(handle_t *ha
- * may not sleep between calling this and putting something into
- * the entry, as someone else might have used it while you slept.
- */
--static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
-- struct inode *inode)
-+static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
-+ struct inode *inode)
- {
- struct inode *dir = dentry->d_parent->d_inode;
- unsigned long offset;
-- struct buffer_head * bh;
-+ struct buffer_head *bh;
- struct ext4_dir_entry_2 *de;
-- struct super_block * sb;
-+ struct super_block *sb;
- int retval;
- int dx_fallback=0;
- unsigned blocksize;
-@@ -1502,9 +1502,9 @@ static int ext4_dx_add_entry(handle_t *h
- struct dx_frame frames[2], *frame;
- struct dx_entry *entries, *at;
- struct dx_hash_info hinfo;
-- struct buffer_head * bh;
-+ struct buffer_head *bh;
- struct inode *dir = dentry->d_parent->d_inode;
-- struct super_block * sb = dir->i_sb;
-+ struct super_block *sb = dir->i_sb;
- struct ext4_dir_entry_2 *de;
- int err;
-
-@@ -1570,11 +1570,11 @@ static int ext4_dx_add_entry(handle_t *h
- if (err)
- goto journal_error;
-
-- memcpy ((char *) entries2, (char *) (entries + icount1),
-- icount2 * sizeof(struct dx_entry));
-- dx_set_count (entries, icount1);
-- dx_set_count (entries2, icount2);
-- dx_set_limit (entries2, dx_node_limit(dir));
-+ memcpy((char *) entries2, (char *) (entries + icount1),
-+ icount2 * sizeof(struct dx_entry));
-+ dx_set_count(entries, icount1);
-+ dx_set_count(entries2, icount2);
-+ dx_set_limit(entries2, dx_node_limit(dir));
-
- /* Which index block gets the new entry? */
- if (at - entries >= icount1) {
-@@ -1582,9 +1582,9 @@ static int ext4_dx_add_entry(handle_t *h
- frame->entries = entries = entries2;
- swap(frame->bh, bh2);
- }
-- dx_insert_block (frames + 0, hash2, newblock);
-- dxtrace(dx_show_index ("node", frames[1].entries));
-- dxtrace(dx_show_index ("node",
-+ dx_insert_block(frames + 0, hash2, newblock);
-+ dxtrace(dx_show_index("node", frames[1].entries));
-+ dxtrace(dx_show_index("node",
- ((struct dx_node *) bh2->b_data)->entries));
- err = ext4_journal_dirty_metadata(handle, bh2);
- if (err)
-@@ -1634,12 +1634,12 @@ cleanup:
- * ext4_delete_entry deletes a directory entry by merging it with the
- * previous entry
- */
--static int ext4_delete_entry (handle_t *handle,
-- struct inode * dir,
-- struct ext4_dir_entry_2 * de_del,
-- struct buffer_head * bh)
-+static int ext4_delete_entry(handle_t *handle,
-+ struct inode *dir,
-+ struct ext4_dir_entry_2 *de_del,
-+ struct buffer_head *bh)
- {
-- struct ext4_dir_entry_2 * de, * pde;
-+ struct ext4_dir_entry_2 *de, *pde;
- int i;
-
- i = 0;
-@@ -1720,11 +1720,11 @@ static int ext4_add_nondir(handle_t *han
- * If the create succeeds, we fill in the inode information
- * with d_instantiate().
- */
--static int ext4_create (struct inode * dir, struct dentry * dentry, int mode,
-- struct nameidata *nd)
-+static int ext4_create(struct inode *dir, struct dentry *dentry, int mode,
-+ struct nameidata *nd)
- {
- handle_t *handle;
-- struct inode * inode;
-+ struct inode *inode;
- int err, retries = 0;
-
- retry:
-@@ -1751,8 +1751,8 @@ retry:
- return err;
- }
-
--static int ext4_mknod (struct inode * dir, struct dentry *dentry,
-- int mode, dev_t rdev)
-+static int ext4_mknod(struct inode *dir, struct dentry *dentry,
-+ int mode, dev_t rdev)
- {
- handle_t *handle;
- struct inode *inode;
-@@ -1771,7 +1771,7 @@ retry:
- if (IS_DIRSYNC(dir))
- handle->h_sync = 1;
-
-- inode = ext4_new_inode (handle, dir, mode);
-+ inode = ext4_new_inode(handle, dir, mode);
- err = PTR_ERR(inode);
- if (!IS_ERR(inode)) {
- init_special_inode(inode, inode->i_mode, rdev);
-@@ -1786,12 +1786,12 @@ retry:
- return err;
- }
-
--static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
-+static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
- {
- handle_t *handle;
-- struct inode * inode;
-- struct buffer_head * dir_block;
-- struct ext4_dir_entry_2 * de;
-+ struct inode *inode;
-+ struct buffer_head *dir_block;
-+ struct ext4_dir_entry_2 *de;
- int err, retries = 0;
-
- if (EXT4_DIR_LINK_MAX(dir))
-@@ -1807,7 +1807,7 @@ retry:
- if (IS_DIRSYNC(dir))
- handle->h_sync = 1;
-
-- inode = ext4_new_inode (handle, dir, S_IFDIR | mode);
-+ inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
- err = PTR_ERR(inode);
- if (IS_ERR(inode))
- goto out_stop;
-@@ -1815,7 +1815,7 @@ retry:
- inode->i_op = &ext4_dir_inode_operations;
- inode->i_fop = &ext4_dir_operations;
- inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-- dir_block = ext4_bread (handle, inode, 0, 1, &err);
-+ dir_block = ext4_bread(handle, inode, 0, 1, &err);
- if (!dir_block)
- goto out_clear_inode;
- BUFFER_TRACE(dir_block, "get_write_access");
-@@ -1824,26 +1824,26 @@ retry:
- de->inode = cpu_to_le32(inode->i_ino);
- de->name_len = 1;
- de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len));
-- strcpy (de->name, ".");
-+ strcpy(de->name, ".");
- ext4_set_de_type(dir->i_sb, de, S_IFDIR);
- de = ext4_next_entry(de);
- de->inode = cpu_to_le32(dir->i_ino);
- de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
- EXT4_DIR_REC_LEN(1));
- de->name_len = 2;
-- strcpy (de->name, "..");
-+ strcpy(de->name, "..");
- ext4_set_de_type(dir->i_sb, de, S_IFDIR);
- inode->i_nlink = 2;
- BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
- ext4_journal_dirty_metadata(handle, dir_block);
-- brelse (dir_block);
-+ brelse(dir_block);
- ext4_mark_inode_dirty(handle, inode);
-- err = ext4_add_entry (handle, dentry, inode);
-+ err = ext4_add_entry(handle, dentry, inode);
- if (err) {
- out_clear_inode:
- clear_nlink(inode);
- ext4_mark_inode_dirty(handle, inode);
-- iput (inode);
-+ iput(inode);
- goto out_stop;
- }
- ext4_inc_count(handle, dir);
-@@ -1860,17 +1860,17 @@ out_stop:
- /*
- * routine to check that the specified directory is empty (for rmdir)
- */
--static int empty_dir (struct inode * inode)
-+static int empty_dir(struct inode *inode)
- {
- unsigned long offset;
-- struct buffer_head * bh;
-- struct ext4_dir_entry_2 * de, * de1;
-- struct super_block * sb;
-+ struct buffer_head *bh;
-+ struct ext4_dir_entry_2 *de, *de1;
-+ struct super_block *sb;
- int err = 0;
-
- sb = inode->i_sb;
- if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
-- !(bh = ext4_bread (NULL, inode, 0, 0, &err))) {
-+ !(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
- if (err)
- ext4_error(inode->i_sb, __func__,
- "error %d reading directory #%lu offset 0",
-@@ -1885,23 +1885,23 @@ static int empty_dir (struct inode * ino
- de1 = ext4_next_entry(de);
- if (le32_to_cpu(de->inode) != inode->i_ino ||
- !le32_to_cpu(de1->inode) ||
-- strcmp (".", de->name) ||
-- strcmp ("..", de1->name)) {
-- ext4_warning (inode->i_sb, "empty_dir",
-- "bad directory (dir #%lu) - no `.' or `..'",
-- inode->i_ino);
-- brelse (bh);
-+ strcmp(".", de->name) ||
-+ strcmp("..", de1->name)) {
-+ ext4_warning(inode->i_sb, "empty_dir",
-+ "bad directory (dir #%lu) - no `.' or `..'",
-+ inode->i_ino);
-+ brelse(bh);
- return 1;
- }
- offset = ext4_rec_len_from_disk(de->rec_len) +
- ext4_rec_len_from_disk(de1->rec_len);
- de = ext4_next_entry(de1);
-- while (offset < inode->i_size ) {
-+ while (offset < inode->i_size) {
- if (!bh ||
- (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
- err = 0;
-- brelse (bh);
-- bh = ext4_bread (NULL, inode,
-+ brelse(bh);
-+ bh = ext4_bread(NULL, inode,
- offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err);
- if (!bh) {
- if (err)
-@@ -1921,13 +1921,13 @@ static int empty_dir (struct inode * ino
- continue;
- }
- if (le32_to_cpu(de->inode)) {
-- brelse (bh);
-+ brelse(bh);
- return 0;
- }
- offset += ext4_rec_len_from_disk(de->rec_len);
- de = ext4_next_entry(de);
- }
-- brelse (bh);
-+ brelse(bh);
- return 1;
- }
-
-@@ -1958,8 +1958,8 @@ int ext4_orphan_add(handle_t *handle, st
- * ->i_nlink. For, say it, character device. Not a regular file,
- * not a directory, not a symlink and ->i_nlink > 0.
- */
-- J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-- S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
-+ J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-+ S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
-
- BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
- err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
-@@ -2073,12 +2073,12 @@ out_brelse:
- goto out_err;
- }
-
--static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
-+static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
- {
- int retval;
-- struct inode * inode;
-- struct buffer_head * bh;
-- struct ext4_dir_entry_2 * de;
-+ struct inode *inode;
-+ struct buffer_head *bh;
-+ struct ext4_dir_entry_2 *de;
- handle_t *handle;
-
- /* Initialize quotas before so that eventual writes go in
-@@ -2089,7 +2089,7 @@ static int ext4_rmdir (struct inode * di
- return PTR_ERR(handle);
-
- retval = -ENOENT;
-- bh = ext4_find_entry (dentry, &de);
-+ bh = ext4_find_entry(dentry, &de);
- if (!bh)
- goto end_rmdir;
-
-@@ -2103,16 +2103,16 @@ static int ext4_rmdir (struct inode * di
- goto end_rmdir;
-
- retval = -ENOTEMPTY;
-- if (!empty_dir (inode))
-+ if (!empty_dir(inode))
- goto end_rmdir;
-
- retval = ext4_delete_entry(handle, dir, de, bh);
- if (retval)
- goto end_rmdir;
- if (!EXT4_DIR_LINK_EMPTY(inode))
-- ext4_warning (inode->i_sb, "ext4_rmdir",
-- "empty directory has too many links (%d)",
-- inode->i_nlink);
-+ ext4_warning(inode->i_sb, "ext4_rmdir",
-+ "empty directory has too many links (%d)",
-+ inode->i_nlink);
- inode->i_version++;
- clear_nlink(inode);
- /* There's no need to set i_disksize: the fact that i_nlink is
-@@ -2128,16 +2128,16 @@ static int ext4_rmdir (struct inode * di
-
- end_rmdir:
- ext4_journal_stop(handle);
-- brelse (bh);
-+ brelse(bh);
- return retval;
- }
-
--static int ext4_unlink(struct inode * dir, struct dentry *dentry)
-+static int ext4_unlink(struct inode *dir, struct dentry *dentry)
- {
- int retval;
-- struct inode * inode;
-- struct buffer_head * bh;
-- struct ext4_dir_entry_2 * de;
-+ struct inode *inode;
-+ struct buffer_head *bh;
-+ struct ext4_dir_entry_2 *de;
- handle_t *handle;
-
- /* Initialize quotas before so that eventual writes go
-@@ -2151,7 +2151,7 @@ static int ext4_unlink(struct inode * di
- handle->h_sync = 1;
-
- retval = -ENOENT;
-- bh = ext4_find_entry (dentry, &de);
-+ bh = ext4_find_entry(dentry, &de);
- if (!bh)
- goto end_unlink;
-
-@@ -2162,9 +2162,9 @@ static int ext4_unlink(struct inode * di
- goto end_unlink;
-
- if (!inode->i_nlink) {
-- ext4_warning (inode->i_sb, "ext4_unlink",
-- "Deleting nonexistent file (%lu), %d",
-- inode->i_ino, inode->i_nlink);
-+ ext4_warning(inode->i_sb, "ext4_unlink",
-+ "Deleting nonexistent file (%lu), %d",
-+ inode->i_ino, inode->i_nlink);
- inode->i_nlink = 1;
- }
- retval = ext4_delete_entry(handle, dir, de, bh);
-@@ -2182,15 +2182,15 @@ static int ext4_unlink(struct inode * di
-
- end_unlink:
- ext4_journal_stop(handle);
-- brelse (bh);
-+ brelse(bh);
- return retval;
- }
-
--static int ext4_symlink (struct inode * dir,
-- struct dentry *dentry, const char * symname)
-+static int ext4_symlink(struct inode *dir,
-+ struct dentry *dentry, const char *symname)
- {
- handle_t *handle;
-- struct inode * inode;
-+ struct inode *inode;
- int l, err, retries = 0;
-
- l = strlen(symname)+1;
-@@ -2207,12 +2207,12 @@ retry:
- if (IS_DIRSYNC(dir))
- handle->h_sync = 1;
-
-- inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
-+ inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
- err = PTR_ERR(inode);
- if (IS_ERR(inode))
- goto out_stop;
-
-- if (l > sizeof (EXT4_I(inode)->i_data)) {
-+ if (l > sizeof(EXT4_I(inode)->i_data)) {
- inode->i_op = &ext4_symlink_inode_operations;
- ext4_set_aops(inode);
- /*
-@@ -2225,14 +2225,14 @@ retry:
- if (err) {
- clear_nlink(inode);
- ext4_mark_inode_dirty(handle, inode);
-- iput (inode);
-+ iput(inode);
- goto out_stop;
- }
- } else {
- /* clear the extent format for fast symlink */
- EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL;
- inode->i_op = &ext4_fast_symlink_inode_operations;
-- memcpy((char*)&EXT4_I(inode)->i_data,symname,l);
-+ memcpy((char *)&EXT4_I(inode)->i_data, symname, l);
- inode->i_size = l-1;
- }
- EXT4_I(inode)->i_disksize = inode->i_size;
-@@ -2244,8 +2244,8 @@ out_stop:
- return err;
- }
-
--static int ext4_link (struct dentry * old_dentry,
-- struct inode * dir, struct dentry *dentry)
-+static int ext4_link(struct dentry *old_dentry,
-+ struct inode *dir, struct dentry *dentry)
- {
- handle_t *handle;
- struct inode *inode = old_dentry->d_inode;
-@@ -2288,13 +2288,13 @@ retry:
- * Anybody can rename anything with this: the permission checks are left to the
- * higher-level routines.
- */
--static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
-- struct inode * new_dir,struct dentry *new_dentry)
-+static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
-+ struct inode *new_dir, struct dentry *new_dentry)
- {
- handle_t *handle;
-- struct inode * old_inode, * new_inode;
-- struct buffer_head * old_bh, * new_bh, * dir_bh;
-- struct ext4_dir_entry_2 * old_de, * new_de;
-+ struct inode *old_inode, *new_inode;
-+ struct buffer_head *old_bh, *new_bh, *dir_bh;
-+ struct ext4_dir_entry_2 *old_de, *new_de;
- int retval;
-
- old_bh = new_bh = dir_bh = NULL;
-@@ -2312,7 +2312,7 @@ static int ext4_rename (struct inode * o
- if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
- handle->h_sync = 1;
-
-- old_bh = ext4_find_entry (old_dentry, &old_de);
-+ old_bh = ext4_find_entry(old_dentry, &old_de);
- /*
- * Check for inode number is _not_ due to possible IO errors.
- * We might rmdir the source, keep it as pwd of some process
-@@ -2325,32 +2325,32 @@ static int ext4_rename (struct inode * o
- goto end_rename;
-
- new_inode = new_dentry->d_inode;
-- new_bh = ext4_find_entry (new_dentry, &new_de);
-+ new_bh = ext4_find_entry(new_dentry, &new_de);
- if (new_bh) {
- if (!new_inode) {
-- brelse (new_bh);
-+ brelse(new_bh);
- new_bh = NULL;
- }
- }
- if (S_ISDIR(old_inode->i_mode)) {
- if (new_inode) {
- retval = -ENOTEMPTY;
-- if (!empty_dir (new_inode))
-+ if (!empty_dir(new_inode))
- goto end_rename;
- }
- retval = -EIO;
-- dir_bh = ext4_bread (handle, old_inode, 0, 0, &retval);
-+ dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval);
- if (!dir_bh)
- goto end_rename;
- if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
- goto end_rename;
- retval = -EMLINK;
-- if (!new_inode && new_dir!=old_dir &&
-+ if (!new_inode && new_dir != old_dir &&
- new_dir->i_nlink >= EXT4_LINK_MAX)
- goto end_rename;
- }
- if (!new_bh) {
-- retval = ext4_add_entry (handle, new_dentry, old_inode);
-+ retval = ext4_add_entry(handle, new_dentry, old_inode);
- if (retval)
- goto end_rename;
- } else {
-@@ -2437,9 +2437,9 @@ static int ext4_rename (struct inode * o
- retval = 0;
-
- end_rename:
-- brelse (dir_bh);
-- brelse (old_bh);
-- brelse (new_bh);
-+ brelse(dir_bh);
-+ brelse(old_bh);
-+ brelse(new_bh);
- ext4_journal_stop(handle);
- return retval;
- }
---- a/fs/ext4/resize.c
-+++ b/fs/ext4/resize.c
-@@ -416,8 +416,8 @@ static int add_new_gdb(handle_t *handle,
- "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n",
- gdb_num);
-
-- /*
-- * If we are not using the primary superblock/GDT copy don't resize,
-+ /*
-+ * If we are not using the primary superblock/GDT copy don't resize,
- * because the user tools have no way of handling this. Probably a
- * bad time to do it anyways.
- */
-@@ -964,7 +964,7 @@ int ext4_group_extend(struct super_block
- ext4_group_t o_groups_count;
- ext4_grpblk_t last;
- ext4_grpblk_t add;
-- struct buffer_head * bh;
-+ struct buffer_head *bh;
- handle_t *handle;
- int err;
- unsigned long freed_blocks;
---- a/fs/ext4/super.c
-+++ b/fs/ext4/super.c
-@@ -654,7 +654,7 @@ static inline void ext4_show_quota_optio
-
- if (sbi->s_jquota_fmt)
- seq_printf(seq, ",jqfmt=%s",
-- (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");
-+ (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold" : "vfsv0");
-
- if (sbi->s_qf_names[USRQUOTA])
- seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
-@@ -822,7 +822,7 @@ static struct dentry *ext4_fh_to_parent(
- }
-
- #ifdef CONFIG_QUOTA
--#define QTYPE2NAME(t) ((t) == USRQUOTA?"user":"group")
-+#define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
- #define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
-
- static int ext4_dquot_initialize(struct inode *inode, int type);
-@@ -1586,7 +1586,7 @@ static int ext4_check_descriptors(struct
- if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
- flexbg_flag = 1;
-
-- ext4_debug ("Checking group descriptors");
-+ ext4_debug("Checking group descriptors");
-
- for (i = 0; i < sbi->s_groups_count; i++) {
- struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL);
---- a/fs/ext4/symlink.c
-+++ b/fs/ext4/symlink.c
-@@ -23,10 +23,10 @@
- #include "ext4.h"
- #include "xattr.h"
-
--static void * ext4_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static void *ext4_follow_link(struct dentry *dentry, struct nameidata *nd)
- {
- struct ext4_inode_info *ei = EXT4_I(dentry->d_inode);
-- nd_set_link(nd, (char*)ei->i_data);
-+ nd_set_link(nd, (char *) ei->i_data);
- return NULL;
- }
-
---- a/fs/ext4/xattr.h
-+++ b/fs/ext4/xattr.h
-@@ -51,8 +51,8 @@ struct ext4_xattr_entry {
- (((name_len) + EXT4_XATTR_ROUND + \
- sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND)
- #define EXT4_XATTR_NEXT(entry) \
-- ( (struct ext4_xattr_entry *)( \
-- (char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)) )
-+ ((struct ext4_xattr_entry *)( \
-+ (char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)))
- #define EXT4_XATTR_SIZE(size) \
- (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
-
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4_i_disksize_lock_race_fix.patch
^
|
@@ -63,7 +63,21 @@
}
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -1434,16 +1434,18 @@ static int ext4_ordered_write_end(struct
+@@ -1391,6 +1391,13 @@ retry:
+ unlock_page(page);
+ ext4_journal_stop(handle);
+ page_cache_release(page);
++ /*
++ * block_write_begin may have instantiated a few blocks
++ * outside i_size. Trim these off again. Don't need
++ * i_size_read because we hold i_mutex.
++ */
++ if (pos + len > inode->i_size)
++ vmtruncate(inode, inode->i_size);
+ }
+
+ if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+@@ -1427,16 +1434,18 @@ static int ext4_ordered_write_end(struct
ret = ext4_jbd2_file_inode(handle, inode);
if (ret == 0) {
@@ -89,7 +103,7 @@
ret2 = generic_write_end(file, mapping, pos, len, copied,
page, fsdata);
copied = ret2;
-@@ -1468,8 +1470,14 @@ static int ext4_writeback_write_end(stru
+@@ -1461,8 +1470,14 @@ static int ext4_writeback_write_end(stru
loff_t new_i_size;
new_i_size = pos + copied;
@@ -106,7 +120,7 @@
ret2 = generic_write_end(file, mapping, pos, len, copied,
page, fsdata);
-@@ -1494,6 +1502,7 @@ static int ext4_journalled_write_end(str
+@@ -1487,6 +1502,7 @@ static int ext4_journalled_write_end(str
int ret = 0, ret2;
int partial = 0;
unsigned from, to;
@@ -114,7 +128,7 @@
from = pos & (PAGE_CACHE_SIZE - 1);
to = from + len;
-@@ -1508,11 +1517,12 @@ static int ext4_journalled_write_end(str
+@@ -1501,11 +1517,12 @@ static int ext4_journalled_write_end(str
to, &partial, write_end_fn);
if (!partial)
SetPageUptodate(page);
@@ -130,7 +144,7 @@
ret2 = ext4_mark_inode_dirty(handle, inode);
if (!ret)
ret = ret2;
-@@ -2227,18 +2237,9 @@ static int ext4_da_get_block_write(struc
+@@ -2220,18 +2237,9 @@ static int ext4_da_get_block_write(struc
if (disksize > i_size_read(inode))
disksize = i_size_read(inode);
if (disksize > EXT4_I(inode)->i_disksize) {
@@ -152,21 +166,7 @@
}
ret = 0;
}
-@@ -2567,6 +2568,13 @@ retry:
- unlock_page(page);
- ext4_journal_stop(handle);
- page_cache_release(page);
-+ /*
-+ * block_write_begin may have instantiated a few blocks
-+ * outside i_size. Trim these off again. Don't need
-+ * i_size_read because we hold i_mutex.
-+ */
-+ if (pos + len > inode->i_size)
-+ vmtruncate(inode, inode->i_size);
- }
-
- if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
-@@ -2647,6 +2655,11 @@ static int ext4_da_write_end(struct file
+@@ -2649,6 +2657,11 @@ static int ext4_da_write_end(struct file
EXT4_I(inode)->i_disksize = new_i_size;
}
up_write(&EXT4_I(inode)->i_data_sem);
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4_nonmballoc_reservation_ENOSPC_fix.patch
^
|
@@ -27,7 +27,7 @@
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
-@@ -1804,15 +1804,17 @@ retry_alloc:
+@@ -1806,15 +1806,17 @@ retry_alloc:
goto io_error;
free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
@@ -52,7 +52,7 @@
bitmap_bh = ext4_read_block_bitmap(sb, group_no);
if (!bitmap_bh)
goto io_error;
-@@ -1845,7 +1847,7 @@ retry_alloc:
+@@ -1847,7 +1849,7 @@ retry_alloc:
* free blocks is less than half of the reservation
* window size.
*/
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/ext4_truncate_block_allocated_on_a_failed_ext4_write_begin.patch
^
|
@@ -12,11 +12,13 @@
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index 5a595af..6cfe142 100644
+---
+ fs/ext4/inode.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -1391,6 +1391,13 @@ retry:
+@@ -2562,6 +2562,13 @@ retry:
unlock_page(page);
ext4_journal_stop(handle);
page_cache_release(page);
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/ext4_update-flex-bg-counters-when-resizing
^
|
@@ -1,49 +0,0 @@
-From: Frederic Bohe <frederic.bohe@bull.net>
-Subject: Update flex_bg free blocks and free inodes counters when resizing.
-References: fate#303783
-
-This fixes a bug which prevented the newly created inodes after a
-resize from being used on filesystems with flex_bg.
-
-Signed-off-by: Frederic Bohe <frederic.bohe@bull.net>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-Acked-by: Jan Kara <jack@suse.cz>
-
-Index: linux-2.6.27-rc5+patch_queue/fs/ext4/resize.c
-===================================================================
---- linux-2.6.27-rc5+patch_queue.orig/fs/ext4/resize.c 2008-09-01 11:23:09.000000000 +0200
-+++ linux-2.6.27-rc5+patch_queue/fs/ext4/resize.c 2008-09-01 13:16:03.000000000 +0200
-@@ -929,6 +929,15 @@ int ext4_group_add(struct super_block *s
- percpu_counter_add(&sbi->s_freeinodes_counter,
- EXT4_INODES_PER_GROUP(sb));
-
-+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
-+ ext4_group_t flex_group;
-+ flex_group = ext4_flex_group(sbi, input->group);
-+ sbi->s_flex_groups[flex_group].free_blocks +=
-+ input->free_blocks_count;
-+ sbi->s_flex_groups[flex_group].free_inodes +=
-+ EXT4_INODES_PER_GROUP(sb);
-+ }
-+
- ext4_journal_dirty_metadata(handle, sbi->s_sbh);
- sb->s_dirt = 1;
-
-Index: linux-2.6.27-rc5+patch_queue/fs/ext4/super.c
-===================================================================
---- linux-2.6.27-rc5+patch_queue.orig/fs/ext4/super.c 2008-09-01 12:38:03.000000000 +0200
-+++ linux-2.6.27-rc5+patch_queue/fs/ext4/super.c 2008-09-01 13:29:39.000000000 +0200
-@@ -1507,8 +1507,11 @@ static int ext4_fill_flex_info(struct su
- sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
- groups_per_flex = 1 << sbi->s_log_groups_per_flex;
-
-- flex_group_count = (sbi->s_groups_count + groups_per_flex - 1) /
-- groups_per_flex;
-+ /* We allocate both existing and potentially added groups */
-+ flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
-+ ((sbi->s_es->s_reserved_gdt_blocks +1 ) <<
-+ EXT4_DESC_PER_BLOCK_BITS(sb))) /
-+ groups_per_flex;
- sbi->s_flex_groups = kzalloc(flex_group_count *
- sizeof(struct flex_groups), GFP_KERNEL);
- if (sbi->s_flex_groups == NULL) {
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/firmware-memmap-64bit.diff
^
|
@@ -0,0 +1,121 @@
+From 383e07a1dc4b5656fc32abaa6304804f4b683910 Mon Sep 17 00:00:00 2001
+From: Bernhard Walle <bwalle@suse.de>
+Date: Wed, 12 Nov 2008 20:39:17 +0100
+Subject: [PATCH] Always use 64 bit addresses for the firmware memory map
+
+I had a problem that on i386 without PAE enabled the firmware memory map was
+wrong because a 64 bit address has been truncated:
+
+ 0000000000000000-000000000009f400 (System RAM)
+ 000000000009f400-00000000000a0000 (reserved)
+ 00000000fec10000-00000000fec11000 (reserved)
+ 00000000fec20000-00000000fec21000 (reserved)
+ 00000000fee00000-00000000fee10000 (reserved)
+ 00000000ff800000-0000000100000000 (reserved)
+ ---> 0000000000000000-00000000fffff000 (System RAM) <---
+ 00000000000f0000-0000000000100000 (reserved)
+ 0000000000100000-00000000f57fa000 (System RAM)
+ 00000000f57fa000-00000000f5800000 (ACPI Tables)
+ 00000000fdc00000-00000000fdc01000 (reserved)
+ 00000000fdc10000-00000000fdc11000 (reserved)
+ 00000000fdc20000-00000000fdc21000 (reserved)
+ 00000000fdc30000-00000000fdc31000 (reserved)
+ 00000000fec00000-00000000fec01000 (reserved)
+
+Just always using 64 bit is the most sane approach in my opinion.
+
+
+Signed-off-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ drivers/firmware/memmap.c | 17 +++++++----------
+ include/linux/firmware-map.h | 12 +++++-------
+ 2 files changed, 12 insertions(+), 17 deletions(-)
+
+--- a/drivers/firmware/memmap.c
++++ b/drivers/firmware/memmap.c
+@@ -31,8 +31,8 @@
+ * information is necessary as for the resource tree.
+ */
+ struct firmware_map_entry {
+- resource_size_t start; /* start of the memory range */
+- resource_size_t end; /* end of the memory range (incl.) */
++ uint64_t start; /* start of the memory range */
++ uint64_t end; /* end of the memory range (incl.) */
+ const char *type; /* type of the memory range */
+ struct list_head list; /* entry for the linked list */
+ struct kobject kobj; /* kobject for each entry */
+@@ -101,7 +101,7 @@ static LIST_HEAD(map_entries);
+ * Common implementation of firmware_map_add() and firmware_map_add_early()
+ * which expects a pre-allocated struct firmware_map_entry.
+ **/
+-static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
++static int firmware_map_add_entry(uint64_t start, uint64_t end,
+ const char *type,
+ struct firmware_map_entry *entry)
+ {
+@@ -132,8 +132,7 @@ static int firmware_map_add_entry(resour
+ *
+ * Returns 0 on success, or -ENOMEM if no memory could be allocated.
+ **/
+-int firmware_map_add(resource_size_t start, resource_size_t end,
+- const char *type)
++int firmware_map_add(uint64_t start, uint64_t end, const char *type)
+ {
+ struct firmware_map_entry *entry;
+
+@@ -157,7 +156,7 @@ int firmware_map_add(resource_size_t sta
+ *
+ * Returns 0 on success, or -ENOMEM if no memory could be allocated.
+ **/
+-int __init firmware_map_add_early(resource_size_t start, resource_size_t end,
++int __init firmware_map_add_early(uint64_t start, uint64_t end,
+ const char *type)
+ {
+ struct firmware_map_entry *entry;
+@@ -175,14 +174,12 @@ int __init firmware_map_add_early(resour
+
+ static ssize_t start_show(struct firmware_map_entry *entry, char *buf)
+ {
+- return snprintf(buf, PAGE_SIZE, "0x%llx\n",
+- (unsigned long long)entry->start);
++ return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->start);
+ }
+
+ static ssize_t end_show(struct firmware_map_entry *entry, char *buf)
+ {
+- return snprintf(buf, PAGE_SIZE, "0x%llx\n",
+- (unsigned long long)entry->end);
++ return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->end);
+ }
+
+ static ssize_t type_show(struct firmware_map_entry *entry, char *buf)
+--- a/include/linux/firmware-map.h
++++ b/include/linux/firmware-map.h
+@@ -24,21 +24,19 @@
+ */
+ #ifdef CONFIG_FIRMWARE_MEMMAP
+
+-int firmware_map_add(resource_size_t start, resource_size_t end,
+- const char *type);
+-int firmware_map_add_early(resource_size_t start, resource_size_t end,
+- const char *type);
++int firmware_map_add(uint64_t start, uint64_t end, const char *type);
++int firmware_map_add_early(uint64_t start, uint64_t end, const char *type);
+
+ #else /* CONFIG_FIRMWARE_MEMMAP */
+
+-static inline int firmware_map_add(resource_size_t start, resource_size_t end,
++static inline int firmware_map_add(uint64_t start, uint64_t end,
+ const char *type)
+ {
+ return 0;
+ }
+
+-static inline int firmware_map_add_early(resource_size_t start,
+- resource_size_t end, const char *type)
++static inline int firmware_map_add_early(uint64_t start, uint64_t end,
++ const char *type)
+ {
+ return 0;
+ }
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/hid-rdesc-quirk-for-sony-vaio-VGX-TP1E.patch
^
|
@@ -17,9 +17,9 @@
include/linux/hid.h | 1 +
2 files changed, 17 insertions(+)
---- linux-2.6.27.orig/drivers/hid/usbhid/hid-quirks.c
-+++ linux-2.6.27/drivers/hid/usbhid/hid-quirks.c
-@@ -384,6 +384,7 @@
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -382,6 +382,7 @@
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
#define USB_VENDOR_ID_SONY 0x054c
@@ -27,7 +27,7 @@
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
-@@ -763,6 +764,8 @@ static const struct hid_rdesc_blacklist
+@@ -759,6 +760,8 @@ static const struct hid_rdesc_blacklist
{ USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP, HID_QUIRK_RDESC_SUNPLUS_WDESKTOP },
@@ -36,7 +36,7 @@
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
-@@ -1135,6 +1138,16 @@ static void usbhid_fixup_button_consumer
+@@ -1131,6 +1134,16 @@ static void usbhid_fixup_button_consumer
}
}
@@ -53,7 +53,7 @@
/*
* Microsoft Wireless Desktop Receiver (Model 1028) has several
* 'Usage Min/Max' where it ought to have 'Physical Min/Max'
-@@ -1185,6 +1198,9 @@ static void __usbhid_fixup_report_descri
+@@ -1181,6 +1194,9 @@ static void __usbhid_fixup_report_descri
if (quirks & HID_QUIRK_RDESC_SUNPLUS_WDESKTOP)
usbhid_fixup_sunplus_wdesktop(rdesc, rsize);
@@ -63,8 +63,8 @@
}
/**
---- linux-2.6.27.orig/include/linux/hid.h
-+++ linux-2.6.27/include/linux/hid.h
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
@@ -298,6 +298,7 @@ struct hid_item {
#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040
#define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/hpwdt-kdump.diff
^
|
@@ -1,55 +0,0 @@
-From: Bernhard Walle <bwalle@suse.de>
-Subject: [PATCH] [WATCHDOG] Fix kdump when using hpwdt
-Patch-mainline: not yet
-References: bnc#436786
-
-When the "hpwdt" module is loaded (even if the /dev/watchdog device is not
-opened), then kdump does not work. The panic kernel either does not start at
-all or crash in various places.
-
-The problem is that hpwdt_pretimeout is registered with register_die_notifier()
-with the highest possible priority. Because it returns NOTIFY_STOP, the
-crash_nmi_callback which is also registered with register_die_notifier()
-is never executed. This causes the shutdown of other CPUs to fail.
-
-Reverting the order is no option: The crash_nmi_callback executes HLT
-and so never returns normally. Because of that, it must be executed as
-last notifier, which currently is done.
-
-So, that patch returns NOTIFY_OK in case allow_kdump is set as module parameter
-in the hpwdt module. Also, it changes the default of allow_kdump to 1. Kdump is
-quite common and should be working as default.
-
-Signed-off-by: Bernhard Walle <bwalle@suse.de>
-Cc: Wim Van Sebroeck <wim@iguana.be>
-Cc: Thomas Mingarelli <thomas.mingarelli@hp.com>
-Cc: Vivek Goyal <vgoyal@redhat.com>
-
----
- drivers/watchdog/hpwdt.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/drivers/watchdog/hpwdt.c
-+++ b/drivers/watchdog/hpwdt.c
-@@ -116,7 +116,7 @@ static unsigned int reload; /* the com
- static int nowayout = WATCHDOG_NOWAYOUT;
- static char expect_release;
- static unsigned long hpwdt_is_open;
--static unsigned int allow_kdump;
-+static unsigned int allow_kdump = 1;
-
- static void __iomem *pci_mem_addr; /* the PCI-memory address */
- static unsigned long __iomem *hpwdt_timer_reg;
-@@ -482,7 +482,11 @@ static int hpwdt_pretimeout(struct notif
- "Management Log for details.\n");
- }
-
-- return NOTIFY_STOP;
-+ /*
-+ * for kdump, we must return NOTIFY_OK here to execute the
-+ * crash_nmi_callback afterwards, see arch/x86/kernel/crash.c
-+ */
-+ return allow_kdump ? NOTIFY_OK : NOTIFY_STOP;
- }
-
- /*
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/ia64_uv_partition_id.diff
^
|
@@ -0,0 +1,35 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: Add partition id, coherence id, and region size to UV
+References: bnc#442455
+
+Add partition id, coherence id, and region size to UV.
+
+The SGI xp drivers (drivers/misc/sgi-xp) are used on both
+sn (Itanium) and uv (Tukwilla). Using the same names
+(sn_partition_id, sn_coherency_id, sn_region_size)
+simplifies the driver code.
+
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+
+ arch/ia64/uv/kernel/setup.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/ia64/uv/kernel/setup.c
++++ b/arch/ia64/uv/kernel/setup.c
+@@ -19,6 +19,12 @@ EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info)
+
+ #ifdef CONFIG_IA64_SGI_UV
+ int sn_prom_type;
++long sn_partition_id;
++EXPORT_SYMBOL(sn_partition_id);
++long sn_coherency_id;
++EXPORT_SYMBOL_GPL(sn_coherency_id);
++long sn_region_size;
++EXPORT_SYMBOL(sn_region_size);
+ #endif
+
+ struct redir_addr {
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/ia64_uv_watchlist.diff
^
|
@@ -0,0 +1,78 @@
+From: Bernhard Walle <bwalle@suse.de>
+Subject: Add UV watchlist support
+References: bnc#442455
+
+Add UV watchlist support.
+
+This is used by SGI xp drivers (drivers/misc/sgi-xp).
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+
+---
+
+ arch/ia64/include/asm/sn/sn_sal.h | 45 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+Index: linux/arch/ia64/include/asm/sn/sn_sal.h
+===================================================================
+--- linux.orig/arch/ia64/include/asm/sn/sn_sal.h 2008-11-05 09:21:48.690243174 -0600
++++ linux/arch/ia64/include/asm/sn/sn_sal.h 2008-11-05 09:22:01.847928152 -0600
+@@ -90,6 +90,8 @@
+ #define SN_SAL_SET_CPU_NUMBER 0x02000068
+
+ #define SN_SAL_KERNEL_LAUNCH_EVENT 0x02000069
++#define SN_SAL_WATCHLIST_ALLOC 0x02000070
++#define SN_SAL_WATCHLIST_FREE 0x02000071
+
+ /*
+ * Service-specific constants
+@@ -1183,6 +1185,49 @@ ia64_sn_kernel_launch_event(void)
+ {
+ struct ia64_sal_retval rv;
+ SAL_CALL_NOLOCK(rv, SN_SAL_KERNEL_LAUNCH_EVENT, 0, 0, 0, 0, 0, 0, 0);
++ return rv.status;
++}
++
++union sn_watchlist_u {
++ u64 val;
++ struct {
++ u64 blade : 16,
++ size : 32,
++ filler : 16;
++ };
++};
++
++static inline int
++sn_mq_watchlist_alloc(int blade, void *mq, unsigned int mq_size,
++ unsigned long *intr_mmr_offset)
++{
++ struct ia64_sal_retval rv;
++ unsigned long addr;
++ union sn_watchlist_u size_blade;
++ int watchlist;
++
++ addr = (unsigned long)mq;
++ size_blade.size = mq_size;
++ size_blade.blade = blade;
++
++ /*
++ * bios returns watchlist number or negative error number.
++ */
++ ia64_sal_oemcall_nolock(&rv, SN_SAL_WATCHLIST_ALLOC, addr,
++ size_blade.val, (u64)intr_mmr_offset,
++ (u64)&watchlist, 0, 0, 0);
++ if (rv.status < 0)
++ return rv.status;
++
++ return watchlist;
++}
++
++static inline int
++sn_mq_watchlist_free(int blade, int watchlist_num)
++{
++ struct ia64_sal_retval rv;
++ ia64_sal_oemcall_nolock(&rv, SN_SAL_WATCHLIST_FREE, blade,
++ watchlist_num, 0, 0, 0, 0, 0);
+ return rv.status;
+ }
+ #endif /* _ASM_IA64_SN_SN_SAL_H */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/igb_ethtool.patch
^
|
@@ -0,0 +1,26 @@
+From: John Ronciak <john.ronciak@intel.com>
+Subject: add missing ethtool hooks
+Acked-by: Karsten Keil <kkeil@novell.com>
+Reference: bnc#435551
+
+
+Patch to fix the missing ethtool_ops_[sg]et function pointers
+
+This patch needs to be applied to the igb driver to add the function pointers
+to the ethtool_ops_[gs]et funcitons.
+
+Index: linux-2.6.27/drivers/net/igb/igb_ethtool.c
+===================================================================
+--- linux-2.6.27.orig/drivers/net/igb/igb_ethtool.c
++++ linux-2.6.27/drivers/net/igb/igb_ethtool.c
+@@ -2025,6 +2025,10 @@ static struct ethtool_ops igb_ethtool_op
+ .get_ethtool_stats = igb_get_ethtool_stats,
+ .get_coalesce = igb_get_coalesce,
+ .set_coalesce = igb_set_coalesce,
++#ifdef NETIF_F_LRO
++ .get_flags = ethtool_op_get_flags,
++ .set_flags = ethtool_op_set_flags,
++#endif
+ };
+
+ void igb_set_ethtool_ops(struct net_device *netdev)
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/ipw2200-send-noassoc.patch
^
|
@@ -0,0 +1,30 @@
+From: Zhu Yi <yi.zhu@intel.com>
+Subject: ipw2200: fix oops in ipw_tx_skb
+Patch-mainline: not yet
+References: bnc#397390
+
+Fixes Oops in ipw2200:ipw_tx_skb when pinging through
+a WPA enterprise connection.
+
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Tested-by: Frank Seidel <fseidel@suse.de>
+Signed-off-by: Ffrank Seidel <fseidel@suse.de>
+
+---
+ drivers/net/wireless/ipw2200.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/wireless/ipw2200.c
++++ b/drivers/net/wireless/ipw2200.c
+@@ -10190,6 +10190,11 @@ static int ipw_tx_skb(struct ipw_priv *p
+ u16 remaining_bytes;
+ int fc;
+
++ if (!(priv->status & STATUS_ASSOCIATED)) {
++ IPW_DEBUG_TX("Tx attempt while not associated.\n");
++ goto drop;
++ }
++
+ hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ switch (priv->ieee->iw_mode) {
+ case IW_MODE_ADHOC:
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/jbd2-create-proc-entry-fix.patch
^
|
@@ -1,87 +0,0 @@
-From: Joel Becker <Joel.Becker@oracle.com>
-Subject: [PATCH] jbd2: Create proc entry with bdevname+i_ino.
-Patch-mainline: 2.6.28?
-References: FATE302877
-
-jbd2 currently creates statistics files for each loaded journal in
-/proc/fs/jbd2/<bdevname>. ocfs2 loads multiple journals when recovering
-other nodes, and the multiple journals on a given bdev collide in the
-proc namespace.
-
-This patch changes the location to /proc/fs/jbd2/<bdevname>-<i_ino> as
-proposed by Jan Kara. ocfs2 can load multiple journals safely without
-collision. There are, to my knowledge, no programmatic users, so the
-name change shouldn't (haha) cause any problems.
-
-ocfs2 has 64bit inode numbers, so a collision could theoretically happen
-with inodes above 32bits, but ocfs2 journals are generally created at
-the front of the volume during mkfs(8). In addition, ocfs2 restricts
-inodes to 32bits unless the 'inode64' option is specified.
-
-Signed-off-by: Joel Becker <joel.becker@oracle.com>
-Acked-by: Mark Fasheh <mfasheh@suse.com>
----
- fs/jbd2/journal.c | 12 ++++++++----
- 1 files changed, 8 insertions(+), 4 deletions(-)
-
-diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
-index 8207a01..18d3063 100644
---- a/fs/jbd2/journal.c
-+++ b/fs/jbd2/journal.c
-@@ -901,9 +901,11 @@ static struct proc_dir_entry *proc_jbd2_stats;
-
- static void jbd2_stats_proc_init(journal_t *journal)
- {
-- char name[BDEVNAME_SIZE];
-+ char dname[BDEVNAME_SIZE];
-+ char name[NAME_MAX];
-
-- bdevname(journal->j_dev, name);
-+ bdevname(journal->j_dev, dname);
-+ snprintf(name, NAME_MAX, "%s-%lu", dname, journal->j_inode->i_ino);
- journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats);
- if (journal->j_proc_entry) {
- proc_create_data("history", S_IRUGO, journal->j_proc_entry,
-@@ -915,9 +917,11 @@ static void jbd2_stats_proc_init(journal_t *journal)
-
- static void jbd2_stats_proc_exit(journal_t *journal)
- {
-- char name[BDEVNAME_SIZE];
-+ char dname[BDEVNAME_SIZE];
-+ char name[NAME_MAX];
-
-- bdevname(journal->j_dev, name);
-+ bdevname(journal->j_dev, dname);
-+ snprintf(name, NAME_MAX, "%s-%lu", dname, journal->j_inode->i_ino);
- remove_proc_entry("info", journal->j_proc_entry);
- remove_proc_entry("history", journal->j_proc_entry);
- remove_proc_entry(name, proc_jbd2_stats);
---
-1.5.6.3
-
-
---
-
-None of our men are "experts." We have most unfortunately found
-it necessary to get rid of a man as soon as he thinks himself an
-expert -- because no one ever considers himself expert if he really
-knows his job. A man who knows a job sees so much more to be done
-than he has done, that he is always pressing forward and never
-gives up an instant of thought to how good and how efficient he is.
-Thinking always ahead, thinking always of trying to do more, brings
-a state of mind in which nothing is impossible. The moment one gets
-into the "expert" state of mind a great number of things become
-impossible.
- - From Henry Ford Sr., "My Life and Work"
-
-Joel Becker
-Principal Software Developer
-Oracle
-E-mail: joel.becker@oracle.com
-Phone: (650) 506-8127
-
-_______________________________________________
-Ocfs2-devel mailing list
-Ocfs2-devel@oss.oracle.com
-http://oss.oracle.com/mailman/listinfo/ocfs2-devel
-
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/kdb-oops-panic.diff
^
|
@@ -42,7 +42,7 @@
--- a/arch/x86/kdb/kdbasupport_64.c
+++ b/arch/x86/kdb/kdbasupport_64.c
-@@ -500,6 +500,11 @@ kdba_dumpregs(struct pt_regs *regs,
+@@ -501,6 +501,11 @@ kdba_dumpregs(struct pt_regs *regs,
struct kdbregs *rlp;
kdb_machreg_t contents;
@@ -54,7 +54,7 @@
for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
kdb_printf("%8s = ", rlp->reg_name);
kdba_getregcontents(rlp->reg_name, regs, &contents);
-@@ -553,7 +558,7 @@ EXPORT_SYMBOL(kdba_dumpregs);
+@@ -554,7 +559,7 @@ EXPORT_SYMBOL(kdba_dumpregs);
kdb_machreg_t
kdba_getpc(struct pt_regs *regs)
{
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/kdb-read-CR.diff
^
|
@@ -0,0 +1,29 @@
+From: Jay Lan <jlan@sgi.com>
+Subject: [PATCH] Support '\n' in KDB
+Patch-mainline: 2.6.28-rc3-*-1 patchset
+References: bnc#442808
+
+Cliff tried to use KDB on medusa to verify a UV/KDB compatibility fix and found
+KDB needs to support '\n' in kdb_read() for medusa.
+
+I have integrated his patch to kdb mainline at 2.6.28-rc3-*-1 patchset.
+
+
+Signed-off-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ kdb/kdb_io.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kdb/kdb_io.c
++++ b/kdb/kdb_io.c
+@@ -246,7 +246,8 @@ kdb_read(char *buffer, size_t bufsize)
+ *cp = tmp;
+ }
+ break;
+- case 13: /* enter */
++ case 13: /* enter \r */
++ case 10: /* enter \n */
+ *lastchar++ = '\n';
+ *lastchar++ = '\0';
+ kdb_printf("\n");
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/kdump-x86-sparsemem.diff
^
|
@@ -0,0 +1,41 @@
+From e7706fc691513b0f06adb3de3d6ac04293180146 Mon Sep 17 00:00:00 2001
+From: Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
+Date: Mon, 20 Oct 2008 13:51:52 +0900
+Subject: [PATCH] x86, kdump: fix invalid access on i386 sparsemem
+References: bnc#440525
+
+Impact: fix kdump crash on 32-bit sparsemem kernels
+
+Since linux-2.6.27, kdump has failed on i386 sparsemem kernel.
+1st-kernel gets a panic just before switching to 2nd-kernel.
+
+The cause is that a kernel accesses invalid mem_section by
+page_to_pfn(image->swap_page) at machine_kexec().
+image->swap_page is allocated if kexec for hibernation, but
+it is not allocated if kdump. So if kdump, a kernel should
+not access the mem_section corresponding to image->swap_page.
+
+The attached patch fixes this invalid access.
+
+Signed-off-by: Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
+Cc: kexec-ml <kexec@lists.infradead.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
+index 0732adb..7a38574 100644
+--- a/arch/x86/kernel/machine_kexec_32.c
++++ b/arch/x86/kernel/machine_kexec_32.c
+@@ -162,7 +162,10 @@ void machine_kexec(struct kimage *image)
+ page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
+ page_list[PA_PTE_1] = __pa(kexec_pte1);
+ page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
+- page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) << PAGE_SHIFT);
++
++ if (image->type == KEXEC_TYPE_DEFAULT)
++ page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page)
++ << PAGE_SHIFT);
+
+ /* The segment registers are funny things, they have both a
+ * visible and an invisible part. Whenever the visible part is
|
[-]
[+]
|
Deleted |
patches.fixes.tar.bz2/libiscsi-iscsi_pool_free-api-change
^
|
@@ -1,25 +0,0 @@
-From: Jeff Mahoney <jeffm@suse.com>
-Subject: [PATCH] libiscsi: fix use of old iscsi_pool API
-
- With the update to 2.6.23, patches.drivers/open-iscsi-git-update missed
- a usage of the old iscsi_pool_free API. This patch fixes it.
-
-Signed-offo-by: Jeff Mahoney <jeffm@suse.com>
----
-
- drivers/scsi/libiscsi.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/scsi/libiscsi.c 2007-10-31 17:44:52.000000000 -0400
-+++ b/drivers/scsi/libiscsi.c 2007-10-31 17:44:53.000000000 -0400
-@@ -1563,8 +1563,8 @@ void iscsi_session_teardown(struct iscsi
- iscsi_unblock_session(cls_session);
- scsi_remove_host(shost);
-
-- iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
-- iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
-+ iscsi_pool_free(&session->mgmtpool);
-+ iscsi_pool_free(&session->cmdpool);
-
- kfree(session->password);
- kfree(session->password_in);
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/mm-madvise-fix.patch
^
|
@@ -0,0 +1,55 @@
+From: Nick Piggin <npiggin@suse.de>
+Subject: mm: madvise correct return code
+References: bnc#352998
+
+madvise should return -EINVAL if passed in an invalid flag, even if the
+requested range is 0.
+
+Signed-off-by: Nick Piggin <npiggin@suse.de>
+---
+Index: linux-2.6.27/mm/madvise.c
+===================================================================
+--- linux-2.6.27.orig/mm/madvise.c
++++ linux-2.6.27/mm/madvise.c
+@@ -239,12 +239,30 @@ madvise_vma(struct vm_area_struct *vma,
+ break;
+
+ default:
+- error = -EINVAL;
++ BUG();
+ break;
+ }
+ return error;
+ }
+
++static int
++madvise_behavior_valid(int behavior)
++{
++ switch (behavior) {
++ case MADV_DOFORK:
++ case MADV_DONTFORK:
++ case MADV_NORMAL:
++ case MADV_SEQUENTIAL:
++ case MADV_RANDOM:
++ case MADV_REMOVE:
++ case MADV_WILLNEED:
++ case MADV_DONTNEED:
++ return 1;
++
++ default:
++ return 0;
++ }
++}
+ /*
+ * The madvise(2) system call.
+ *
+@@ -290,6 +308,9 @@ asmlinkage long sys_madvise(unsigned lon
+ int write;
+ size_t len;
+
++ if (!madvise_behavior_valid(behavior))
++ return error;
++
+ write = madvise_need_mmap_write(behavior);
+ if (write)
+ down_write(¤t->mm->mmap_sem);
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/multiq-requeue-should-rewind-current_band
^
|
@@ -0,0 +1,38 @@
+Subject: multiq: requeue should rewind the current_band
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+References: bnc#438954
+
+Currently dequeueing a packet and requeueing the same packet will cause a
+different packet to be pulled on the next dequeue. This change forces
+requeue to rewind the current_band.
+
+Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+
+ net/sched/sch_multiq.c | 5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
+index ce00df4..7f4dbf0 100644
+--- a/net/sched/sch_multiq.c
++++ b/net/sched/sch_multiq.c
+@@ -97,6 +97,7 @@ static int
+ multiq_requeue(struct sk_buff *skb, struct Qdisc *sch)
+ {
+ struct Qdisc *qdisc;
++ struct multiq_sched_data *q = qdisc_priv(sch);
+ int ret;
+
+ qdisc = multiq_classify(skb, sch, &ret);
+@@ -113,6 +114,10 @@ multiq_requeue(struct sk_buff *skb, struct Qdisc *sch)
+ if (ret == NET_XMIT_SUCCESS) {
+ sch->q.qlen++;
+ sch->qstats.requeues++;
++ if (q->curband)
++ q->curband--;
++ else
++ q->curband = q->bands - 1;
+ return NET_XMIT_SUCCESS;
+ }
+ if (net_xmit_drop_count(ret))
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/nfs-write.c-bug-removal.patch
^
|
@@ -0,0 +1,170 @@
+From: ffilz@us.ibm.com
+Subject: Revert "NFS: Allow redirtying of a completed unstable write."
+Patch-mainline: REVERT patch from 2.6.27
+References: 442267
+
+mainline commit e468bae97d243fe0e1515abaa1f7d0edf1476ad0
+introduces a BUG() that is apprently fairly easy to trigger.
+As it is just making a minor performance enhancement, it is best to
+revert the patch until the issue is better understood.
+
+Acked-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Neil Brown <neilb@suse.de>
+
+---
+ fs/nfs/write.c | 65 ++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 33 insertions(+), 32 deletions(-)
+
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -284,9 +284,12 @@ static int nfs_page_async_flush(struct n
+ return ret;
+ spin_lock(&inode->i_lock);
+ }
+- if (test_bit(PG_CLEAN, &req->wb_flags)) {
++ if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
++ /* This request is marked for commit */
+ spin_unlock(&inode->i_lock);
+- BUG();
++ nfs_clear_page_tag_locked(req);
++ nfs_pageio_complete(pgio);
++ return 0;
+ }
+ if (nfs_set_page_writeback(page) != 0) {
+ spin_unlock(&inode->i_lock);
+@@ -460,6 +463,19 @@ nfs_mark_request_dirty(struct nfs_page *
+ __set_page_dirty_nobuffers(req->wb_page);
+ }
+
++/*
++ * Check if a request is dirty
++ */
++static inline int
++nfs_dirty_request(struct nfs_page *req)
++{
++ struct page *page = req->wb_page;
++
++ if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags))
++ return 0;
++ return !PageWriteback(page);
++}
++
+ #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+ /*
+ * Add a request to the inode's commit list.
+@@ -472,7 +488,7 @@ nfs_mark_request_commit(struct nfs_page
+
+ spin_lock(&inode->i_lock);
+ nfsi->ncommit++;
+- set_bit(PG_CLEAN, &(req)->wb_flags);
++ set_bit(PG_NEED_COMMIT, &(req)->wb_flags);
+ radix_tree_tag_set(&nfsi->nfs_page_tree,
+ req->wb_index,
+ NFS_PAGE_TAG_COMMIT);
+@@ -483,19 +499,6 @@ nfs_mark_request_commit(struct nfs_page
+ __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
+ }
+
+-static int
+-nfs_clear_request_commit(struct nfs_page *req)
+-{
+- struct page *page = req->wb_page;
+-
+- if (test_and_clear_bit(PG_CLEAN, &(req)->wb_flags)) {
+- dec_zone_page_state(page, NR_UNSTABLE_NFS);
+- dec_bdi_stat(page_file_mapping(page)->backing_dev_info, BDI_RECLAIMABLE);
+- return 1;
+- }
+- return 0;
+-}
+-
+ static inline
+ int nfs_write_need_commit(struct nfs_write_data *data)
+ {
+@@ -505,7 +508,7 @@ int nfs_write_need_commit(struct nfs_wri
+ static inline
+ int nfs_reschedule_unstable_write(struct nfs_page *req)
+ {
+- if (test_and_clear_bit(PG_NEED_COMMIT, &req->wb_flags)) {
++ if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
+ nfs_mark_request_commit(req);
+ return 1;
+ }
+@@ -521,12 +524,6 @@ nfs_mark_request_commit(struct nfs_page
+ {
+ }
+
+-static inline int
+-nfs_clear_request_commit(struct nfs_page *req)
+-{
+- return 0;
+-}
+-
+ static inline
+ int nfs_write_need_commit(struct nfs_write_data *data)
+ {
+@@ -584,8 +581,11 @@ static void nfs_cancel_commit_list(struc
+
+ while(!list_empty(head)) {
+ req = nfs_list_entry(head->next);
++ dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
++ dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
++ BDI_RECLAIMABLE);
+ nfs_list_remove_request(req);
+- nfs_clear_request_commit(req);
++ clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
+ nfs_inode_remove_request(req);
+ nfs_unlock_request(req);
+ }
+@@ -657,7 +657,8 @@ static struct nfs_page *nfs_try_to_updat
+ * Note: nfs_flush_incompatible() will already
+ * have flushed out requests having wrong owners.
+ */
+- if (offset > rqend
++ if (!nfs_dirty_request(req)
++ || offset > rqend
+ || end < req->wb_offset)
+ goto out_flushme;
+
+@@ -673,10 +674,6 @@ static struct nfs_page *nfs_try_to_updat
+ spin_lock(&inode->i_lock);
+ }
+
+- if (nfs_clear_request_commit(req))
+- radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree,
+- req->wb_index, NFS_PAGE_TAG_COMMIT);
+-
+ /* Okay, the request matches. Update the region */
+ if (offset < req->wb_offset) {
+ req->wb_offset = offset;
+@@ -758,7 +755,8 @@ int nfs_flush_incompatible(struct file *
+ req = nfs_page_find_request(page);
+ if (req == NULL)
+ return 0;
+- do_flush = req->wb_page != page || req->wb_context != ctx;
++ do_flush = req->wb_page != page || req->wb_context != ctx
++ || !nfs_dirty_request(req);
+ nfs_release_request(req);
+ if (!do_flush)
+ return 0;
+@@ -1363,7 +1361,10 @@ static void nfs_commit_release(void *cal
+ while (!list_empty(&data->pages)) {
+ req = nfs_list_entry(data->pages.next);
+ nfs_list_remove_request(req);
+- nfs_clear_request_commit(req);
++ clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
++ dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
++ dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
++ BDI_RECLAIMABLE);
+
+ dprintk("NFS: commit (%s/%lld %d@%lld)",
+ req->wb_context->path.dentry->d_inode->i_sb->s_id,
+@@ -1539,7 +1540,7 @@ int nfs_wb_page_cancel(struct inode *ino
+ req = nfs_page_find_request(page);
+ if (req == NULL)
+ goto out;
+- if (test_bit(PG_CLEAN, &req->wb_flags)) {
++ if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
+ nfs_release_request(req);
+ break;
+ }
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/null_irq_desc_name.diff
^
|
@@ -0,0 +1,40 @@
+From: Dean Nelson <dcn@sgi.com>
+Date: Sat, 18 Oct 2008 23:06:56 +0000 (-0700)
+Subject: genirq: NULL struct irq_desc's member 'name' in dynamic_irq_cleanup()
+X-Git-Tag: v2.6.28-rc1~44^2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=b6f3b7803a9231eddc36d0a2a6d2d8105ef89344
+References: bnc#442461
+
+genirq: NULL struct irq_desc's member 'name' in dynamic_irq_cleanup()
+
+If the member 'name' of the irq_desc structure happens to point to a
+character string that is resident within a kernel module, problems ensue
+if that module is rmmod'd (at which time dynamic_irq_cleanup() is called)
+and then later show_interrupts() is called by someone.
+
+It is also not a good thing if the character string resided in kmalloc'd
+space that has been kfree'd (after having called dynamic_irq_cleanup()).
+dynamic_irq_cleanup() fails to NULL the 'name' member and
+show_interrupts() references it on a few architectures (like h8300, sh and
+x86).
+
+Signed-off-by: Dean Nelson <dcn@sgi.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ kernel/irq/chip.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -78,6 +78,7 @@ void dynamic_irq_cleanup(unsigned int ir
+ desc->chip_data = NULL;
+ desc->handle_irq = handle_bad_irq;
+ desc->chip = &no_irq_chip;
++ desc->name = NULL;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ }
+
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/oom-warning
^
|
@@ -13,7 +13,7 @@
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
-@@ -1643,7 +1643,13 @@ nofail_alloc:
+@@ -1645,7 +1645,13 @@ nofail_alloc:
nopage:
if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit()) {
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/qla2xxx-disable-automatic-queue-tracking
^
|
@@ -0,0 +1,91 @@
+From: Mike Reed <mdr@sgi.com>
+Subject: qla2xxx: Conditionally disable queue_full tracking
+References: bnc#449386
+
+Changing a lun's queue depth (/sys/block/sdX/device/queue_depth) isn't
+sticky when the device is connected via a QLogic fibre channel adapter.
+
+The QLogic qla2xxx fibre channel driver dynamically adjusts a lun's queue
+depth. If a user has a specific need to limit the number of commands issued
+to a lun (say a tape drive, or a shared raid where the total commands issued
+to all luns is limited at the controller level, for example) and writes a
+limiting value to /sys/block/sdXX/device/queue_depth, the qla2xxx driver will
+silently and gradually increase the queue depth back to the driver limit
+of ql2xmaxqdepth. While reducing this value (module parameter) or increasing
+the interval between ramp ups (ql2xqfullrampup) offers the potential for a
+work around it would be better to have the option of just disabling the
+dynamic adjustment of queue depth.
+
+This patch implements an "off switch" as a module parameter. Applies to
+2.6.28-rc6-git1.
+
+Signed-off-by: Michael Reed <mdr@sgi.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+--- linux-2.6.16.60-0.29/drivers/scsi/qla2xxx/qla_gbl.h 2008-08-29 08:24:34.000000000 -0500
++++ linux-2.6.16.60-0.29-modified/drivers/scsi/qla2xxx/qla_gbl.h 2008-10-09 14:27:30.475858567 -0500
+@@ -63,6 +63,7 @@ extern int ql2xfdmienable;
+ extern int ql2xextended_error_logging;
+ extern int ql2xqfullrampup;
+ extern int ql2xiidmaenable;
++extern int ql2xqfulltracking;
+
+ extern int qla2x00_loop_reset(scsi_qla_host_t *);
+ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
+--- linux-2.6.16.60-0.29/drivers/scsi/qla2xxx/qla_isr.c 2008-08-29 08:24:34.000000000 -0500
++++ linux-2.6.16.60-0.29-modified/drivers/scsi/qla2xxx/qla_isr.c 2008-10-09 13:56:12.302061528 -0500
+@@ -663,6 +663,9 @@ qla2x00_adjust_sdev_qdepth_up(struct scs
+ {
+ fc_port_t *fcport = data;
+
++ if (!ql2xqfulltracking)
++ return;
++
+ if (fcport->ha->max_q_depth <= sdev->queue_depth)
+ return;
+
+@@ -701,6 +704,9 @@ qla2x00_ramp_up_queue_depth(scsi_qla_hos
+ fc_port_t *fcport;
+ struct scsi_device *sdev;
+
++ if (!ql2xqfulltracking)
++ return;
++
+ sdev = sp->cmd->device;
+ if (sdev->queue_depth >= ha->max_q_depth)
+ return;
+@@ -988,6 +994,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha
+ scsi_status));
+
+ /* Adjust queue depth for all luns on the port. */
++ if (!ql2xqfulltracking)
++ break;
+ fcport->last_queue_full = jiffies;
+ starget_for_each_device(cp->device->sdev_target,
+ fcport, qla2x00_adjust_sdev_qdepth_down);
+@@ -1071,6 +1079,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha
+ * Adjust queue depth for all luns on the
+ * port.
+ */
++ if (!ql2xqfulltracking)
++ break;
+ fcport->last_queue_full = jiffies;
+ starget_for_each_device(
+ cp->device->sdev_target, fcport,
+--- linux-2.6.16.60-0.29/drivers/scsi/qla2xxx/qla_os.c 2008-08-29 08:24:44.000000000 -0500
++++ linux-2.6.16.60-0.29-modified/drivers/scsi/qla2xxx/qla_os.c 2008-11-21 13:53:31.961367347 -0600
+@@ -83,6 +83,14 @@ module_param(ql2xmaxqdepth, int, S_IRUGO
+ MODULE_PARM_DESC(ql2xmaxqdepth,
+ "Maximum queue depth to report for target devices.");
+
++int ql2xqfulltracking = 1;
++module_param(ql2xqfulltracking, int, S_IRUGO|S_IWUSR);
++MODULE_PARM_DESC(ql2xqfulltracking,
++ "Controls whether the driver tracks queue full status "
++ "returns and dynamically adjusts a scsi device's queue "
++ "depth. Default is 1, perform tracking. Set to 0 to "
++ "disable dynamic tracking and adjustment of queue depth.");
++
+ int ql2xqfullrampup = 120;
+ module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(ql2xqfullrampup,
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/reiserfs-error-buffer-locking
^
|
@@ -0,0 +1,41 @@
+From: Jeff Mahoney <jeffm@suse.com>
+Subject: [PATCH] reiserfs: add locking around error buffer
+
+ The formatting of the error buffer is race prone. It uses static buffers
+ for both formatting and output. While overwriting the error buffer
+ can product garbled output, overwriting the format buffer with incompatible
+ % directives can cause crashes.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+---
+ fs/reiserfs/prints.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/reiserfs/prints.c
++++ b/fs/reiserfs/prints.c
+@@ -184,7 +184,7 @@ static char *is_there_reiserfs_struct(ch
+ printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid,
+ key->k_offset, key->k_uniqueness);
+ */
+-
++static DEFINE_SPINLOCK(error_lock);
+ static void prepare_error_buf(const char *fmt, va_list args)
+ {
+ char *fmt1 = fmt_buf;
+@@ -192,6 +192,8 @@ static void prepare_error_buf(const char
+ char *p = error_buf;
+ int what;
+
++ spin_lock(&error_lock);
++
+ strcpy(fmt1, fmt);
+
+ while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
+@@ -237,6 +239,7 @@ static void prepare_error_buf(const char
+ fmt1 = k + 2;
+ }
+ vsprintf(p, fmt1, args);
++ spin_unlock(&error_lock);
+
+ }
+
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/reiserfs-varargs-fix
^
|
@@ -0,0 +1,60 @@
+From: Jeff Mahoney <jeffm@suse.com>
+Subject: [PATCH] reiserfs: prepare_error_buf wrongly consumes va_arg
+
+ vsprintf will consume varargs on its own. Skipping them manually
+ results in garbage in the error buffer, or Oopses in the case of
+ pointers.
+
+ This patch removes the advancement and fixes a number of bugs where
+ crashes were observed as side effects of a regular error report.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ fs/reiserfs/prints.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+--- a/fs/reiserfs/prints.c
++++ b/fs/reiserfs/prints.c
+@@ -157,19 +157,16 @@ static void sprintf_disk_child(char *buf
+ dc_size(dc));
+ }
+
+-static char *is_there_reiserfs_struct(char *fmt, int *what, int *skip)
++static char *is_there_reiserfs_struct(char *fmt, int *what)
+ {
+ char *k = fmt;
+
+- *skip = 0;
+-
+ while ((k = strchr(k, '%')) != NULL) {
+ if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
+ k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') {
+ *what = k[1];
+ break;
+ }
+- (*skip)++;
+ k++;
+ }
+ return k;
+@@ -193,18 +190,15 @@ static void prepare_error_buf(const char
+ char *fmt1 = fmt_buf;
+ char *k;
+ char *p = error_buf;
+- int i, j, what, skip;
++ int what;
+
+ strcpy(fmt1, fmt);
+
+- while ((k = is_there_reiserfs_struct(fmt1, &what, &skip)) != NULL) {
++ while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
+ *k = 0;
+
+ p += vsprintf(p, fmt1, args);
+
+- for (i = 0; i < skip; i++)
+- j = va_arg(args, int);
+-
+ switch (what) {
+ case 'k':
+ sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/sched-fix-bug-in-sched-domain-degenerate.patch
^
|
@@ -0,0 +1,49 @@
+From: Li Zefan <lizf@cn.fujitsu.com>
+Subject: sched: fix a bug in sched domain degenerate
+
+(1) on i386 with SCHED_SMT and SCHED_MC enabled
+ # mount -t cgroup -o cpuset xxx /mnt
+ # echo 0 > /mnt/cpuset.sched_load_balance
+ # mkdir /mnt/0
+ # echo 0 > /mnt/0/cpuset.cpus
+ # dmesg
+ CPU0 attaching sched-domain:
+ domain 0: span 0 level CPU
+ groups: 0
+(2) on i386 with SCHED_MC enabled but SCHED_SMT disabled
+ # same with (1)
+ # dmesg
+ CPU0 attaching NULL sched-domain.
+
+The bug is some sched domains may be skipped unintentionally when
+doing sched domain degenerating.
+
+Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
+Signed-off-by: Gregory Haskins <ghaskins@novell.com>
+---
+ kernel/sched.c | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+diff --git a/kernel/sched.c b/kernel/sched.c
+index dee79ad..b13f45a 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -6875,15 +6875,17 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
+ struct sched_domain *tmp;
+
+ /* Remove the sched domains which do not contribute to scheduling. */
+- for (tmp = sd; tmp; tmp = tmp->parent) {
++ for (tmp = sd; tmp; ) {
+ struct sched_domain *parent = tmp->parent;
+ if (!parent)
+ break;
++
+ if (sd_parent_degenerate(tmp, parent)) {
+ tmp->parent = parent->parent;
+ if (parent->parent)
+ parent->parent->child = tmp;
+- }
++ } else
++ tmp = tmp->parent;
+ }
+
+ if (sd && sd_degenerate(sd)) {
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-add-tgps-setting
^
|
@@ -0,0 +1,293 @@
+Subject: Add TGPS setting to scsi devices
+From: Hannes Reinecke <hare@suse.de>
+
+Some multipath-capable storage arrays are capable of running
+in compatible mode, ie supporting both the original vendor-specific
+failover mode and the SPC-3 compliant ALUA mode.
+This patch stores the TGPS setting in the sdev so that we can directly
+match onto it and select the correct device handler automatically.
+And we can save code in the ALUA device handler.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+ drivers/scsi/device_handler/scsi_dh.c | 9 ++-
+ drivers/scsi/device_handler/scsi_dh_alua.c | 67 +++-------------------------
+ drivers/scsi/device_handler/scsi_dh_emc.c | 8 +--
+ drivers/scsi/device_handler/scsi_dh_hp_sw.c | 10 ++--
+ drivers/scsi/device_handler/scsi_dh_rdac.c | 34 +++++++-------
+ drivers/scsi/scsi_scan.c | 1
+ drivers/scsi/scsi_sysfs.c | 2
+ include/scsi/scsi_device.h | 4 +
+ 8 files changed, 48 insertions(+), 87 deletions(-)
+
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -118,43 +118,6 @@ static struct request *get_alua_req(stru
+ }
+
+ /*
+- * submit_std_inquiry - Issue a standard INQUIRY command
+- * @sdev: sdev the command should be send to
+- */
+-static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
+-{
+- struct request *rq;
+- int err = SCSI_DH_RES_TEMP_UNAVAIL;
+-
+- rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ);
+- if (!rq)
+- goto done;
+-
+- /* Prepare the command. */
+- rq->cmd[0] = INQUIRY;
+- rq->cmd[1] = 0;
+- rq->cmd[2] = 0;
+- rq->cmd[4] = ALUA_INQUIRY_SIZE;
+- rq->cmd_len = COMMAND_SIZE(INQUIRY);
+-
+- rq->sense = h->sense;
+- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+- rq->sense_len = h->senselen = 0;
+-
+- err = blk_execute_rq(rq->q, NULL, rq, 1);
+- if (err == -EIO) {
+- sdev_printk(KERN_INFO, sdev,
+- "%s: std inquiry failed with %x\n",
+- ALUA_DH_NAME, rq->errors);
+- h->senselen = rq->sense_len;
+- err = SCSI_DH_IO;
+- }
+- blk_put_request(rq);
+-done:
+- return err;
+-}
+-
+-/*
+ * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command
+ * @sdev: sdev the command should be sent to
+ */
+@@ -281,23 +244,19 @@ done:
+ }
+
+ /*
+- * alua_std_inquiry - Evaluate standard INQUIRY command
++ * alua_check_tgps - Evaluate TGPS setting
+ * @sdev: device to be checked
+ *
+- * Just extract the TPGS setting to find out if ALUA
++ * Just examine the TPGS setting of the device to find out if ALUA
+ * is supported.
+ */
+-static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
++static int alua_check_tgps(struct scsi_device *sdev, struct alua_dh_data *h)
+ {
+- int err;
+-
+- err = submit_std_inquiry(sdev, h);
+-
+- if (err != SCSI_DH_OK)
+- return err;
++ int err = SCSI_DH_OK;
+
+ /* Check TPGS setting */
+- h->tpgs = (h->inq[5] >> 4) & 0x3;
++ h->tpgs = sdev->tgps;
++
+ switch (h->tpgs) {
+ case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
+ sdev_printk(KERN_INFO, sdev,
+@@ -603,7 +562,7 @@ static int alua_initialize(struct scsi_d
+ {
+ int err;
+
+- err = alua_std_inquiry(sdev, h);
++ err = alua_check_tgps(sdev, h);
+ if (err != SCSI_DH_OK)
+ goto out;
+
+@@ -668,16 +627,8 @@ static int alua_prep_fn(struct scsi_devi
+ }
+
+ static const struct scsi_dh_devlist alua_dev_list[] = {
+- {"HP", "MSA VOLUME" },
+- {"HP", "HSV101" },
+- {"HP", "HSV111" },
+- {"HP", "HSV200" },
+- {"HP", "HSV210" },
+- {"HP", "HSV300" },
+- {"IBM", "2107900" },
+- {"IBM", "2145" },
+- {"Pillar", "Axiom" },
+- {NULL, NULL}
++ {"", "", 3 },
++ {NULL, NULL, 0}
+ };
+
+ static int alua_bus_attach(struct scsi_device *sdev);
+--- a/drivers/scsi/device_handler/scsi_dh.c
++++ b/drivers/scsi/device_handler/scsi_dh.c
+@@ -28,6 +28,7 @@ struct scsi_dh_devinfo_list {
+ struct list_head node;
+ char vendor[9];
+ char model[17];
++ char tgps;
+ struct scsi_device_handler *handler;
+ };
+
+@@ -60,7 +61,8 @@ scsi_dh_cache_lookup(struct scsi_device
+ spin_lock(&list_lock);
+ list_for_each_entry(tmp, &scsi_dh_dev_list, node) {
+ if (!strncmp(sdev->vendor, tmp->vendor, strlen(tmp->vendor)) &&
+- !strncmp(sdev->model, tmp->model, strlen(tmp->model))) {
++ !strncmp(sdev->model, tmp->model, strlen(tmp->model)) &&
++ (!tmp->tgps || (sdev->tgps & tmp->tgps) != 0)) {
+ found_dh = tmp->handler;
+ break;
+ }
+@@ -79,7 +81,9 @@ static int scsi_dh_handler_lookup(struct
+ if (!strncmp(sdev->vendor, scsi_dh->devlist[i].vendor,
+ strlen(scsi_dh->devlist[i].vendor)) &&
+ !strncmp(sdev->model, scsi_dh->devlist[i].model,
+- strlen(scsi_dh->devlist[i].model))) {
++ strlen(scsi_dh->devlist[i].model)) &&
++ (!scsi_dh->devlist[i].tgps ||
++ (sdev->tgps & scsi_dh->devlist[i].tgps) != 0)) {
+ found = 1;
+ break;
+ }
+@@ -128,6 +132,7 @@ device_handler_match(struct scsi_device_
+ strncpy(tmp->model, sdev->model, 16);
+ tmp->vendor[8] = '\0';
+ tmp->model[16] = '\0';
++ tmp->tgps = sdev->tgps;
+ tmp->handler = found_dh;
+ spin_lock(&list_lock);
+ list_add(&tmp->node, &scsi_dh_dev_list);
+--- a/drivers/scsi/device_handler/scsi_dh_emc.c
++++ b/drivers/scsi/device_handler/scsi_dh_emc.c
+@@ -563,10 +563,10 @@ done:
+ }
+
+ static const struct scsi_dh_devlist clariion_dev_list[] = {
+- {"DGC", "RAID"},
+- {"DGC", "DISK"},
+- {"DGC", "VRAID"},
+- {NULL, NULL},
++ {"DGC", "RAID", 0},
++ {"DGC", "DISK", 0},
++ {"DGC", "VRAID", 0},
++ {NULL, NULL, 0},
+ };
+
+ static int clariion_bus_attach(struct scsi_device *sdev);
+--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
++++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+@@ -283,11 +283,11 @@ static int hp_sw_activate(struct scsi_de
+ }
+
+ static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
+- {"COMPAQ", "MSA1000 VOLUME"},
+- {"COMPAQ", "HSV110"},
+- {"HP", "HSV100"},
+- {"DEC", "HSG80"},
+- {NULL, NULL},
++ {"COMPAQ", "MSA1000 VOLUME", 0},
++ {"COMPAQ", "HSV110", 0},
++ {"HP", "HSV100", 0},
++ {"DEC", "HSG80", 0},
++ {NULL, NULL, 0},
+ };
+
+ static int hp_sw_bus_attach(struct scsi_device *sdev);
+--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
+@@ -583,23 +583,23 @@ static int rdac_check_sense(struct scsi_
+ }
+
+ static const struct scsi_dh_devlist rdac_dev_list[] = {
+- {"IBM", "1722"},
+- {"IBM", "1724"},
+- {"IBM", "1726"},
+- {"IBM", "1742"},
+- {"IBM", "1814"},
+- {"IBM", "1815"},
+- {"IBM", "1818"},
+- {"IBM", "3526"},
+- {"SGI", "TP9400"},
+- {"SGI", "TP9500"},
+- {"SGI", "IS"},
+- {"STK", "OPENstorage D280"},
+- {"SUN", "CSM200_R"},
+- {"SUN", "LCSM100_F"},
+- {"DELL", "MD3000"},
+- {"DELL", "MD3000i"},
+- {NULL, NULL},
++ {"IBM", "1722", 0},
++ {"IBM", "1724", 0},
++ {"IBM", "1726", 0},
++ {"IBM", "1742", 0},
++ {"IBM", "1814", 0},
++ {"IBM", "1815", 0},
++ {"IBM", "1818", 0},
++ {"IBM", "3526", 0},
++ {"SGI", "TP9400", 0},
++ {"SGI", "TP9500", 0},
++ {"SGI", "IS", 0},
++ {"STK", "OPENstorage D280", 0},
++ {"SUN", "CSM200_R", 0},
++ {"SUN", "LCSM100_F", 0},
++ {"DELL", "MD3000", 0},
++ {"DELL", "MD3000i", 0},
++ {NULL, NULL, 0},
+ };
+
+ static int rdac_bus_attach(struct scsi_device *sdev);
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -821,6 +821,7 @@ static int scsi_add_lun(struct scsi_devi
+ sdev->inq_periph_qual = (inq_result[0] >> 5) & 7;
+ sdev->lockable = sdev->removable;
+ sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2);
++ sdev->tgps = (inq_result[5] >> 4) & 3;
+
+ if (sdev->scsi_level >= SCSI_3 ||
+ (sdev->inquiry_len > 56 && inq_result[56] & 0x04))
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -543,6 +543,7 @@ sdev_rd_attr (scsi_level, "%d\n");
+ sdev_rd_attr (vendor, "%.8s\n");
+ sdev_rd_attr (model, "%.16s\n");
+ sdev_rd_attr (rev, "%.4s\n");
++sdev_rd_attr (tgps, "%d\n");
+
+ /*
+ * TODO: can we make these symlinks to the block layer ones?
+@@ -728,6 +729,7 @@ static struct attribute *scsi_sdev_attrs
+ &dev_attr_vendor.attr,
+ &dev_attr_model.attr,
+ &dev_attr_rev.attr,
++ &dev_attr_tgps.attr,
+ &dev_attr_rescan.attr,
+ &dev_attr_delete.attr,
+ &dev_attr_state.attr,
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -96,7 +96,8 @@ struct scsi_device {
+ void *hostdata; /* available to low-level driver */
+ char type;
+ char scsi_level;
+- char inq_periph_qual; /* PQ from INQUIRY data */
++ char inq_periph_qual; /* PQ from INQUIRY data */
++ char tgps; /* Target port group support */
+ unsigned char inquiry_len; /* valid bytes in 'inquiry' */
+ unsigned char * inquiry; /* INQUIRY response data */
+ const char * vendor; /* [back_compat] point into 'inquiry' ... */
+@@ -174,6 +175,7 @@ struct scsi_device {
+ struct scsi_dh_devlist {
+ char *vendor;
+ char *model;
++ char tgps;
+ };
+
+ struct scsi_device_handler {
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-dh-alua-retry-UA
^
|
@@ -0,0 +1,41 @@
+From: Hannes Reinecke <hare@suse.de>
+Subject: Retry ALUA device handler initialization on Unit Attention
+
+Whenever we receive a UNIT ATTENTION sense code we should just retry
+the command. No point in checking the various sense codes here.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index e356b43..a3660a6 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -444,24 +444,10 @@ static int alua_check_sense(struct scsi_device *sdev,
+ return SUCCESS;
+ break;
+ case UNIT_ATTENTION:
+- if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
+- /*
+- * Power On, Reset, or Bus Device Reset, just retry.
+- */
+- return ADD_TO_MLQUEUE;
+- if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
+- /*
+- * ALUA state changed
+- */
+- return ADD_TO_MLQUEUE;
+- }
+- if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
+- /*
+- * Implicit ALUA state transition failed
+- */
+- return ADD_TO_MLQUEUE;
+- }
+- break;
++ /*
++ * Just retry for UNIT_ATTENTION
++ */
++ return ADD_TO_MLQUEUE;
+ }
+
+ return SCSI_RETURN_NOT_HANDLED;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-dh-alua-send-stpg
^
|
@@ -0,0 +1,32 @@
+From: Hannes Reinecke <hare@suse.de>
+Subject: Always send STPG for explicit tgps mode
+
+When we are in explicit tgps mode we should always send an STPG
+command to enable the active/optimized mode.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+ drivers/scsi/device_handler/scsi_dh_alua.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -593,13 +593,11 @@ static int alua_activate(struct scsi_dev
+ struct alua_dh_data *h = get_alua_data(sdev);
+ int err = SCSI_DH_OK;
+
+- if (h->group_id != -1) {
+- err = alua_rtpg(sdev, h);
+- if (err != SCSI_DH_OK)
+- goto out;
+- }
++ err = alua_rtpg(sdev, h);
++ if (err != SCSI_DH_OK)
++ goto out;
+
+- if (h->tpgs == TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED)
++ if ((h->tpgs & TPGS_MODE_EXPLICIT) && h->state != TPGS_STATE_OPTIMIZED)
+ err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h);
+
+ out:
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-dh-rdac-initialize-passive-path
^
|
@@ -0,0 +1,30 @@
+Subject: Initialize path state to be passive when path is not owned
+From: Chandra Seetharaman <sekharan@us.ibm.com>
+Date: Thu Nov 20 14:14:39 2008 +0100:
+References: bnc#442676
+
+Set the path state to be passive when we learn that the controller does
+not own the path to the LUN.
+
+This will avoid sending even a single i/o thru the passive path at the
+probe time.
+
+Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+ drivers/scsi/device_handler/scsi_dh_rdac.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
+@@ -403,6 +403,9 @@ static int check_ownership(struct scsi_d
+ }
+ }
+
++ if (h->lun_state == RDAC_LUN_UNOWNED)
++ h->state = RDAC_STATE_PASSIVE;
++
+ return err;
+ }
+
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-dh-rdac-retry-mode-select
^
|
@@ -0,0 +1,58 @@
+Subject: Retry mode select in RDAC device handler
+From: Chandra Seetharaman <sekharan@us.ibm.com>
+References: bnc#441337
+
+When the mode select sent to the controller fails with the retryable
+error, it is better to retry the mode_select from the hardware handler
+itself, instead of propagating the failure to dm-multipath.
+
+Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+---
+ drivers/scsi/device_handler/scsi_dh_rdac.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
+@@ -24,6 +24,7 @@
+ #include <scsi/scsi_dh.h>
+
+ #define RDAC_NAME "rdac"
++#define RDAC_RETRY_COUNT 5
+
+ /*
+ * LSI mode page stuff
+@@ -475,21 +476,27 @@ static int send_mode_select(struct scsi_
+ {
+ struct request *rq;
+ struct request_queue *q = sdev->request_queue;
+- int err = SCSI_DH_RES_TEMP_UNAVAIL;
++ int err, retry_cnt = RDAC_RETRY_COUNT;
+
++retry:
++ err = SCSI_DH_RES_TEMP_UNAVAIL;
+ rq = rdac_failover_get(sdev, h);
+ if (!rq)
+ goto done;
+
+- sdev_printk(KERN_INFO, sdev, "queueing MODE_SELECT command.\n");
++ sdev_printk(KERN_INFO, sdev, "%s MODE_SELECT command.\n",
++ (retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
+
+ err = blk_execute_rq(q, NULL, rq, 1);
+- if (err != SCSI_DH_OK)
++ blk_put_request(rq);
++ if (err != SCSI_DH_OK) {
+ err = mode_select_handle_sense(sdev, h->sense);
++ if (err == SCSI_DH_RETRY && retry_cnt--)
++ goto retry;
++ }
+ if (err == SCSI_DH_OK)
+ h->state = RDAC_STATE_ACTIVE;
+
+- blk_put_request(rq);
+ done:
+ return err;
+ }
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-dh-rdac-set-default-ownership
^
|
@@ -0,0 +1,29 @@
+Subject: scsi_dh_rdac: make sure the ownership is set correctly
+From: Chandra Seetharaman <sekharan@us.ibm.com>
+Patch-Mainline: 2.6.28
+References: bnc#441337
+
+When the controller ownership is changed (from passive to active),
+check_ownership() doesn't set the state of the device to ACTIVE.
+
+This patch fixes the problem.
+
+Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
+Reported and tested by: "Moger, Babu" <Babu.Moger@lsi.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+---
+ drivers/scsi/device_handler/scsi_dh_rdac.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
+@@ -386,6 +386,7 @@ static int check_ownership(struct scsi_d
+ struct c9_inquiry *inqp;
+
+ h->lun_state = RDAC_LUN_UNOWNED;
++ h->state = RDAC_STATE_ACTIVE;
+ err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
+ if (err == SCSI_DH_OK) {
+ inqp = &h->inq.c9;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-eh-timed-out-missing-braces
^
|
@@ -0,0 +1,35 @@
+Subject: scsi_error: fix indentation and braces disagreement - add braces
+From: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
+Date: Fri Nov 7 11:18:27 2008 -0600:
+Git: 6ec39f02cf48df89c3cbab4aeef521569fec00e4
+
+...and the list of recent breakage goes on and on, this time
+it's 242f9dcb8ba6f (block: unify request timeout handling)
+which broke it.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
+Acked-by: Jens Axboe <jens.axboe@oracle.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 3863617..9fba798 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -136,7 +136,7 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)
+ else
+ eh_timed_out = NULL;
+
+- if (eh_timed_out)
++ if (eh_timed_out) {
+ rtn = eh_timed_out(scmd);
+ switch (rtn) {
+ case BLK_EH_NOT_HANDLED:
+@@ -144,6 +144,7 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)
+ default:
+ return rtn;
+ }
++ }
+
+ if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
+ scmd->result |= DID_TIME_OUT << 16;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-eh_stu-timeout
^
|
@@ -0,0 +1,39 @@
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+Date: Sun, 30 Nov 2008 16:32:26 +0000 (-0600)
+Subject: make scsi_eh_try_stu use block timeout
+References: bnc#447249,bnc#441335
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjejb%2Fscsi-rc-fixes-2.6.git;a=commitdiff_plain;h=9728c0814ecb505546696a659858fdb761375544
+
+[SCSI] make scsi_eh_try_stu use block timeout
+
+scsi_eh_try_stu() was still using the timeout parameter in the device
+which is now not set (i.e. zero filled) meaning that it waited no time
+at all for the start unit command to complete (leading the routine to
+conclude failure every time). This lead to a 2.6.27 regression:
+
+http://bugzilla.kernel.org/show_bug.cgi?id=12120
+
+Where firewire devices that were non spec compliant wouldn't spin up.
+
+Fix this by using the block queue timeout value instead.
+
+Reported-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Mike Anderson <andmike@us.ibm.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 3863617..edfaf24 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -932,8 +932,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
+ int i, rtn = NEEDS_RETRY;
+
+ for (i = 0; rtn == NEEDS_RETRY && i < 2; i++)
+- rtn = scsi_send_eh_cmnd(scmd, stu_command, 6,
+- scmd->device->timeout, 0);
++ rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, scmd->device->request_queue->rq_timeout, 0);
+
+ if (rtn == SUCCESS)
+ return 0;
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/scsi-enhance-error-codes
^
|
@@ -120,7 +120,7 @@
cqr->memdev = memdev;
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
-@@ -1683,7 +1683,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
+@@ -1700,7 +1700,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
recid++;
}
}
@@ -948,7 +948,7 @@
if (!sshdr)
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
-@@ -121,21 +121,36 @@ struct bio {
+@@ -128,21 +128,36 @@ struct bio {
/*
* bio bi_rw flags
*
@@ -994,7 +994,7 @@
/*
* upper 16 bits of bi_rw define the io priority of this bio
-@@ -162,7 +177,10 @@ struct bio {
+@@ -169,7 +184,10 @@ struct bio {
#define bio_sectors(bio) ((bio)->bi_size >> 9)
#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER))
#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC))
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-fixup-failfast-definitions
^
|
@@ -0,0 +1,28 @@
+From: James Smart <James.Smart@Emulex.Com>
+Date: Thu, 20 Nov 2008 15:58:01 +0000 (-0500)
+Subject: fc_transport: fix old bug on bitflag definitions
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjejb%2Fscsi-rc-fixes-2.6.git;a=commitdiff_plain;h=21098c68df7115554fe041170899bdff709efd08
+References: bnc#447814
+
+When the fastfail flag was added, it did not account for the flags
+being bit fields. Correct the definition so there is no longer a
+conflict.
+
+Signed-off-by: James Smart <james.smart@emulex.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+
+diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
+index 49d8913..6e04e6f 100644
+--- a/include/scsi/scsi_transport_fc.h
++++ b/include/scsi/scsi_transport_fc.h
+@@ -357,7 +357,7 @@ struct fc_rport { /* aka fc_starget_attrs */
+ /* bit field values for struct fc_rport "flags" field: */
+ #define FC_RPORT_DEVLOSS_PENDING 0x01
+ #define FC_RPORT_SCAN_PENDING 0x02
+-#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x03
++#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x04
+
+ #define dev_to_rport(d) \
+ container_of(d, struct fc_rport, dev)
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/scsi-misc-git-update
^
|
@@ -1037,7 +1037,7 @@
#include <asm/uaccess.h>
#include <scsi/scsi.h>
-@@ -1427,27 +1428,21 @@ got_data:
+@@ -1435,27 +1436,21 @@ got_data:
*/
sector_size = 512;
}
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-retry-TASK_ABORTED
^
|
@@ -0,0 +1,40 @@
+Subject: scsi_error: TASK ABORTED status handling improvement
+From: Vladislav Bolkhovitin <vst@vlnb.net>
+Date: Fri Nov 7 11:21:03 2008 -0600:
+Git: ab2d67aa39bc63a60fba748b27cf4d962d0dc7f8
+
+This patch improves handling of TASK ABORTED status by Linux SCSI
+mid-layer. Currently, command returned with this status considered
+failed and returned to upper layers. It leads to additional error
+recovery load on file systems and block layer, which sometimes can
+cause undesired side effects, like I/O errors and file systems
+corruptions. See http://lkml.org/lkml/2008/11/1/38, for instance.
+
+From other side, TASK ABORTED status is returned by SCSI target if the
+corresponding command was aborted by another initiator and the target
+has TAS bit set in the control mode page. So, in the majority of cases
+commands with TASK ABORTED status should be simply retried. In other
+cases, maybe_retry path will not retry if no retries are allowed.
+
+This patch implement suggestion by James Bottomley from
+http://marc.info/?l=linux-scsi&m=121932916906009&w=2.
+
+Signed-off-by: Vladislav Bolkhovitin <vst@vlnb.net>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 9fba798..d07bb3e 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1407,8 +1407,9 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
+ return ADD_TO_MLQUEUE;
+ case GOOD:
+ case COMMAND_TERMINATED:
+- case TASK_ABORTED:
+ return SUCCESS;
++ case TASK_ABORTED:
++ goto maybe_retry;
+ case CHECK_CONDITION:
+ rtn = scsi_check_sense(scmd);
+ if (rtn == NEEDS_RETRY)
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-retry-transport-error
^
|
@@ -0,0 +1,37 @@
+Subject: scsi_error regression: Fix idempotent command handling
+From: Mike Christie <mchristi@redhat.com>
+Date: Wed Nov 5 12:48:23 2008 -0500:
+Git: 939c2288c35132fe340b2694c7d02cacf7593723
+
+Drivers want to be able to return DID_TRANSPORT_DISRUPTED and
+have it do the right thing for commands like tape and passthrouh
+as far as retries go. The LLDs previously used DID_BUS_BUSY or DID_ERROR
+which followed the cmd->retries limit, but DID_TRANSPORT_DISRUPTED
+was skipping that check so it could have caused a problem with tape
+commands.
+
+This patch has DID_TRANSPORT_DISRUPTED check the cmd->retries/cmd->allowed.
+
+Signed-off-by: Mike Christie <mchristi@redhat.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+ drivers/scsi/scsi_error.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1341,9 +1341,10 @@ int scsi_decide_disposition(struct scsi_
+ * LLD/transport was disrupted during processing of the IO.
+ * The transport class is now blocked/blocking,
+ * and the transport will decide what to do with the IO
+- * based on its timers and recovery capablilities.
++ * based on its timers and recovery capablilities if
++ * there are enough retries.
+ */
+- return ADD_TO_MLQUEUE;
++ goto maybe_retry;
+ case DID_TRANSPORT_FAILFAST:
+ /*
+ * The transport decided to failfast the IO (most likely
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/scsi-skip-nonscsi-device-for-dma
^
|
@@ -0,0 +1,106 @@
+From: James Smart <james.smart@emulex.com>
+Subject: scsi_lib_dma.c : fix bug w/ dma on virtual fc ports
+References: bnc#431294
+
+When the updated scsi dma code was introduced recently, it assumed
+the physical host/adapter was the parent of the scsi host.
+Unfortunately, on FC virtual ports, the parent of the scsi host is
+the virtual port, which does not have dma information.
+
+I have updated the dma routines to use a function that finds the
+first non-scsi object. A non-scsi object is defined to be an object
+that has a non-NULL type (assumes all transport objects have NULL
+types) or a non-scsi_host type.
+
+-- james s
+
+Unfortunately the original patch is not correct, as eg the PCI device
+doesn't set the 'type' pointer, so the system will crash miserably.
+We should rather check for the 'bus' argument, and return the original
+argument if we don't find anything.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 69321e3..208e7df 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -1713,7 +1713,7 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
+ request_fn_proc *request_fn)
+ {
+ struct request_queue *q;
+- struct device *dev = shost->shost_gendev.parent;
++ struct device *dev = dev_to_nonscsi_dev(shost->shost_gendev.parent);
+
+ q = blk_init_queue(request_fn, NULL);
+ if (!q)
+diff --git a/drivers/scsi/scsi_lib_dma.c b/drivers/scsi/scsi_lib_dma.c
+index ac6855c..567cdbc 100644
+--- a/drivers/scsi/scsi_lib_dma.c
++++ b/drivers/scsi/scsi_lib_dma.c
+@@ -23,7 +23,8 @@ int scsi_dma_map(struct scsi_cmnd *cmd)
+ int nseg = 0;
+
+ if (scsi_sg_count(cmd)) {
+- struct device *dev = cmd->device->host->shost_gendev.parent;
++ struct device *dev = dev_to_nonscsi_dev(
++ cmd->device->host->shost_gendev.parent);
+
+ nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+ cmd->sc_data_direction);
+@@ -41,10 +42,12 @@ EXPORT_SYMBOL(scsi_dma_map);
+ void scsi_dma_unmap(struct scsi_cmnd *cmd)
+ {
+ if (scsi_sg_count(cmd)) {
+- struct device *dev = cmd->device->host->shost_gendev.parent;
++ struct device *dev = dev_to_nonscsi_dev(
++ cmd->device->host->shost_gendev.parent);
+
+ dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+ cmd->sc_data_direction);
+ }
+ }
+ EXPORT_SYMBOL(scsi_dma_unmap);
++
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index d123ca8..55d74c8 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -689,6 +689,10 @@ static inline void *shost_priv(struct Scsi_Host *shost)
+
+ int scsi_is_host_device(const struct device *);
+
++/*
++ * walks object list backward, to find the first shost object.
++ * Skips over transport objects that may not be stargets, etc
++ */
+ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
+ {
+ while (!scsi_is_host_device(dev)) {
+@@ -699,6 +703,26 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
+ return container_of(dev, struct Scsi_Host, shost_gendev);
+ }
+
++/*
++ * walks object list backward, to find the first physical
++ * device object. If none is found return the original device.
++ */
++static inline struct device *dev_to_nonscsi_dev(struct device *dev)
++{
++ struct device *orig = dev;
++
++ while (dev && (dev->bus == NULL || scsi_is_host_device(dev))) {
++ if (dev->dma_parms) {
++ dev_printk(KERN_WARNING, dev,
++ "dma_parms set, bus %p\n",
++ dev->bus);
++ break;
++ }
++ dev = dev->parent;
++ }
++ return dev?dev:orig;
++}
++
+ static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
+ {
+ return shost->shost_state == SHOST_RECOVERY ||
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/sd-needs-updating
^
|
@@ -74,7 +74,7 @@
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
-@@ -1901,6 +1901,8 @@ static int sd_remove(struct device *dev)
+@@ -1909,6 +1909,8 @@ static int sd_remove(struct device *dev)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/sd_liberal_28_sense_invalid.diff
^
|
@@ -9,11 +9,13 @@
Signed-off-by: Brandon Philips <bphilips@suse.de>
-diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
-index e5e7d78..ac119a0 100644
+---
+ drivers/scsi/sd.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
-@@ -1204,8 +1204,7 @@ sd_spinup_disk(struct scsi_disk *sdkp)
+@@ -1211,8 +1211,7 @@ sd_spinup_disk(struct scsi_disk *sdkp)
* Yes, this sense key/ASC combination shouldn't
* occur here. It's characteristic of these devices.
*/
|
[-]
[+]
|
Changed |
patches.fixes.tar.bz2/seccomp-disable-tsc-option
^
|
@@ -19,7 +19,7 @@
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
-@@ -1205,6 +1205,18 @@ config SECCOMP
+@@ -1225,6 +1225,18 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/slab-alloc_slabmgmt-fix.patch
^
|
@@ -0,0 +1,38 @@
+From: Pekka Enberg <penberg@cs.helsinki.fi>
+Date: Tue, 25 Nov 2008 00:33:28 +0200
+Subject: slab: remove GFP_THISNODE clearing from alloc_slabmgmt()
+Patch-mainline: 2.6.28?
+References: bnc#444597
+
+Commit 6cb062296f73e74768cca2f3eaf90deac54de02d ("Categorize GFP flags")
+left one call-site in alloc_slabmgmt() to clear GFP_THISNODE instead of
+GFP_CONSTRAINT_MASK. Unfortunately, that ends up clearing __GFP_NOWARN
+and __GFP_NORETRY as well which is not what we want. As the only caller
+of alloc_slabmgmt() already clears GFP_CONSTRAINT_MASK before passing
+local_flags to it, we can just remove the clearing of GFP_THISNODE.
+
+This patch should fix spurious page allocation failure warnings on the
+mempool_alloc() path. See the following URL for an example:
+
+ http://lkml.org/lkml/2008/10/27/100
+
+Reported-by: Miklos Szeredi <miklos@szeredi.hu>
+Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
+Acked-by: Miklos Szeredi <mszeredi@suse.cz>
+---
+ mm/slab.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/mm/slab.c b/mm/slab.c
+index 918f04f..98d3024 100644
+--- a/mm/slab.c
++++ b/mm/slab.c
+@@ -2608,7 +2608,7 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
+ if (OFF_SLAB(cachep)) {
+ /* Slab management obj is off-slab. */
+ slabp = kmem_cache_alloc_node(cachep->slabp_cache,
+- local_flags & ~GFP_THISNODE, nodeid);
++ local_flags, nodeid);
+ if (!slabp)
+ return NULL;
+ } else {
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-bios_call_memprotect.diff
^
|
@@ -0,0 +1,69 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: Add UV bios call to change memory protections.
+References: bnc#442455
+
+
+Add UV bios call to change memory protections.
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/bios_uv.c | 8 ++++++++
+ include/asm-x86/uv/bios.h | 10 +++++++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+Index: linux/arch/x86/kernel/bios_uv.c
+===================================================================
+--- linux.orig/arch/x86/kernel/bios_uv.c 2008-11-05 11:12:16.101949483 -0600
++++ linux/arch/x86/kernel/bios_uv.c 2008-11-05 11:13:15.289411601 -0600
+@@ -134,6 +134,14 @@ uv_bios_mq_watchlist_free(int blade, int
+ }
+ EXPORT_SYMBOL_GPL(uv_bios_mq_watchlist_free);
+
++s64
++uv_bios_change_memprotect(u64 paddr, u64 len, enum uv_memprotect perms)
++{
++ return uv_bios_call_irqsave(UV_BIOS_MEMPROTECT, paddr, len,
++ perms, 0, 0);
++}
++EXPORT_SYMBOL_GPL(uv_bios_change_memprotect);
++
+ s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second)
+ {
+ return uv_bios_call(UV_BIOS_FREQ_BASE, clock_type,
+Index: linux/include/asm-x86/uv/bios.h
+===================================================================
+--- linux.orig/include/asm-x86/uv/bios.h 2008-11-05 11:12:16.117951501 -0600
++++ linux/include/asm-x86/uv/bios.h 2008-11-05 11:13:15.301413114 -0600
+@@ -34,7 +34,8 @@ enum uv_bios_cmd {
+ UV_BIOS_GET_SN_INFO,
+ UV_BIOS_FREQ_BASE,
+ UV_BIOS_WATCHLIST_ALLOC,
+- UV_BIOS_WATCHLIST_FREE
++ UV_BIOS_WATCHLIST_FREE,
++ UV_BIOS_MEMPROTECT
+ };
+
+ /*
+@@ -82,6 +83,12 @@ union uv_watchlist_u {
+ };
+ };
+
++enum uv_memprotect {
++ UV_MEMPROT_RESTRICT_ACCESS,
++ UV_MEMPROT_ALLOW_AMO,
++ UV_MEMPROT_ALLOW_RW
++};
++
+ /*
+ * bios calls have 6 parameters
+ */
+@@ -94,6 +101,7 @@ extern s64 uv_bios_freq_base(u64, u64 *)
+ extern int uv_bios_mq_watchlist_alloc(int, void *, unsigned int,
+ unsigned long *);
+ extern int uv_bios_mq_watchlist_free(int, int);
++extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect);
+
+ extern void uv_bios_init(void);
+
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-bios_call_partition.diff
^
|
@@ -0,0 +1,155 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: x86: Add UV partition call
+References: bnc#442455
+
+Add a bios call to return partitioning related info.
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/bios_uv.c | 44 ++++++++++++++++++++++++++++++++++-----
+ arch/x86/kernel/genx2apic_uv_x.c | 14 +++++++-----
+ include/asm-x86/uv/bios.h | 22 ++++++++++++++++---
+ 3 files changed, 66 insertions(+), 14 deletions(-)
+
+--- a/arch/x86/kernel/bios_uv.c
++++ b/arch/x86/kernel/bios_uv.c
+@@ -23,6 +23,7 @@
+ #include <asm/efi.h>
+ #include <linux/io.h>
+ #include <asm/uv/bios.h>
++#include <asm/uv/uv_hub.h>
+
+ struct uv_systab uv_systab;
+
+@@ -65,14 +66,47 @@ s64 uv_bios_call_reentrant(enum uv_bios_
+ return ret;
+ }
+
+-long
+-x86_bios_freq_base(unsigned long clock_type, unsigned long *ticks_per_second,
+- unsigned long *drift_info)
++
++long sn_partition_id;
++EXPORT_SYMBOL_GPL(sn_partition_id);
++long uv_coherency_id;
++EXPORT_SYMBOL_GPL(uv_coherency_id);
++long uv_region_size;
++EXPORT_SYMBOL_GPL(uv_region_size);
++int uv_type;
++
++
++s64 uv_bios_get_sn_info(int fc, int *uvtype, long *partid, long *coher,
++ long *region)
++{
++ s64 ret;
++ u64 v0, v1;
++ union partition_info_u part;
++
++ ret = uv_bios_call_irqsave(UV_BIOS_GET_SN_INFO, fc,
++ (u64)(&v0), (u64)(&v1), 0, 0);
++ if (ret != BIOS_STATUS_SUCCESS)
++ return ret;
++
++ part.val = v0;
++ if (uvtype)
++ *uvtype = part.hub_version;
++ if (partid)
++ *partid = part.partition_id;
++ if (coher)
++ *coher = part.coherence_id;
++ if (region)
++ *region = part.region_size;
++ return ret;
++}
++
++
++s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second)
+ {
+ return uv_bios_call(UV_BIOS_FREQ_BASE, clock_type,
+- (u64)ticks_per_second, 0, 0, 0);
++ (u64)ticks_per_second, 0, 0, 0);
+ }
+-EXPORT_SYMBOL_GPL(x86_bios_freq_base);
++EXPORT_SYMBOL_GPL(uv_bios_freq_base);
+
+
+ #ifdef CONFIG_EFI
+--- a/arch/x86/kernel/genx2apic_uv_x.c
++++ b/arch/x86/kernel/genx2apic_uv_x.c
+@@ -353,12 +353,12 @@ static __init void map_mmioh_high(int ma
+
+ static __init void uv_rtc_init(void)
+ {
+- long status, ticks_per_sec, drift;
++ long status;
++ u64 ticks_per_sec;
+
+- status =
+- x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
+- &drift);
+- if (status != 0 || ticks_per_sec < 100000) {
++ status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK,
++ &ticks_per_sec);
++ if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) {
+ printk(KERN_WARNING
+ "unable to determine platform RTC clock frequency, "
+ "guessing.\n");
+@@ -522,6 +522,8 @@ void __init uv_system_init(void)
+ ~((1 << n_val) - 1)) << m_val;
+
+ uv_bios_init();
++ uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
++ &uv_coherency_id, &uv_region_size);
+ uv_rtc_init();
+
+ for_each_present_cpu(cpu) {
+@@ -543,7 +545,7 @@ void __init uv_system_init(void)
+ uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
+ uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
+ uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
+- uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */
++ uv_cpu_hub_info(cpu)->coherency_domain_number = uv_coherency_id;
+ uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
+ uv_node_to_blade[nid] = blade;
+ uv_cpu_to_blade[cpu] = blade;
+--- a/include/asm-x86/uv/bios.h
++++ b/include/asm-x86/uv/bios.h
+@@ -61,6 +61,16 @@ enum {
+ BIOS_FREQ_BASE_REALTIME_CLOCK = 2
+ };
+
++union partition_info_u {
++ u64 val;
++ struct {
++ u64 hub_version : 8,
++ partition_id : 16,
++ coherence_id : 16,
++ region_size : 24;
++ };
++};
++
+ /*
+ * bios calls have 6 parameters
+ */
+@@ -68,10 +78,16 @@ extern s64 uv_bios_call(enum uv_bios_cmd
+ extern s64 uv_bios_call_irqsave(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+ extern s64 uv_bios_call_reentrant(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+
++extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
++extern s64 uv_bios_freq_base(u64, u64 *);
++
+ extern void uv_bios_init(void);
+
+-extern long
+-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+- unsigned long *drift_info);
++extern int uv_type;
++extern long sn_partition_id;
++extern long uv_coherency_id;
++extern long uv_region_size;
++#define partition_coherence_id() (uv_coherency_id)
++
+
+ #endif /* _ASM_X86_BIOS_H */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-bios_call_reserve_page.diff
^
|
@@ -0,0 +1,66 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: Add UV bios call to get the address of the reserved page.
+References: bnc#442455
+
+Add UV bios call to get the address of the reserved page.
+
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/bios_uv.c | 11 +++++++++++
+ include/asm-x86/uv/bios.h | 5 ++++-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+Index: linux/arch/x86/kernel/bios_uv.c
+===================================================================
+--- linux.orig/arch/x86/kernel/bios_uv.c 2008-11-05 11:13:15.289411601 -0600
++++ linux/arch/x86/kernel/bios_uv.c 2008-11-05 11:14:11.428488248 -0600
+@@ -142,6 +142,17 @@ uv_bios_change_memprotect(u64 paddr, u64
+ }
+ EXPORT_SYMBOL_GPL(uv_bios_change_memprotect);
+
++s64
++uv_bios_reserved_page_pa(u64 buf, u64 *cookie, u64 *addr, u64 *len)
++{
++ s64 ret;
++
++ ret = uv_bios_call_irqsave(UV_BIOS_GET_PARTITION_ADDR, (u64)cookie,
++ (u64)addr, buf, (u64)len, 0);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(uv_bios_reserved_page_pa);
++
+ s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second)
+ {
+ return uv_bios_call(UV_BIOS_FREQ_BASE, clock_type,
+Index: linux/include/asm-x86/uv/bios.h
+===================================================================
+--- linux.orig/include/asm-x86/uv/bios.h 2008-11-05 11:13:15.301413114 -0600
++++ linux/include/asm-x86/uv/bios.h 2008-11-05 11:14:11.436489257 -0600
+@@ -35,13 +35,15 @@ enum uv_bios_cmd {
+ UV_BIOS_FREQ_BASE,
+ UV_BIOS_WATCHLIST_ALLOC,
+ UV_BIOS_WATCHLIST_FREE,
+- UV_BIOS_MEMPROTECT
++ UV_BIOS_MEMPROTECT,
++ UV_BIOS_GET_PARTITION_ADDR
+ };
+
+ /*
+ * Status values returned from a BIOS call.
+ */
+ enum {
++ BIOS_STATUS_MORE_PASSES = 1,
+ BIOS_STATUS_SUCCESS = 0,
+ BIOS_STATUS_UNIMPLEMENTED = -ENOSYS,
+ BIOS_STATUS_EINVAL = -EINVAL,
+@@ -102,6 +104,7 @@ extern int uv_bios_mq_watchlist_alloc(in
+ unsigned long *);
+ extern int uv_bios_mq_watchlist_free(int, int);
+ extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect);
++extern s64 uv_bios_reserved_page_pa(u64, u64 *, u64 *, u64 *);
+
+ extern void uv_bios_init(void);
+
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-bios_call_watchlist.diff
^
|
@@ -0,0 +1,100 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: Add UV bios calls to allocate and free watchlists.
+References: bnc#442455
+
+Add UV bios calls to allocate and free watchlists.
+
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/bios_uv.c | 33 +++++++++++++++++++++++++++++++++
+ include/asm-x86/uv/bios.h | 17 ++++++++++++++++-
+ 2 files changed, 49 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/bios_uv.c
++++ b/arch/x86/kernel/bios_uv.c
+@@ -100,6 +100,39 @@ s64 uv_bios_get_sn_info(int fc, int *uvt
+ return ret;
+ }
+
++int
++uv_bios_mq_watchlist_alloc(int blade, void *mq, unsigned int mq_size,
++ unsigned long *intr_mmr_offset)
++{
++ union uv_watchlist_u size_blade;
++ unsigned long addr;
++ u64 watchlist;
++ s64 ret;
++
++ addr = (unsigned long)mq;
++ size_blade.size = mq_size;
++ size_blade.blade = blade;
++
++ /*
++ * bios returns watchlist number or negative error number.
++ */
++ ret = (int)uv_bios_call_irqsave(UV_BIOS_WATCHLIST_ALLOC, addr,
++ size_blade.val, (u64)intr_mmr_offset,
++ (u64)&watchlist, 0);
++ if (ret < BIOS_STATUS_SUCCESS)
++ return ret;
++
++ return watchlist;
++}
++EXPORT_SYMBOL_GPL(uv_bios_mq_watchlist_alloc);
++
++int
++uv_bios_mq_watchlist_free(int blade, int watchlist_num)
++{
++ return (int)uv_bios_call_irqsave(UV_BIOS_WATCHLIST_FREE,
++ blade, watchlist_num, 0, 0, 0);
++}
++EXPORT_SYMBOL_GPL(uv_bios_mq_watchlist_free);
+
+ s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second)
+ {
+--- a/include/asm-x86/uv/bios.h
++++ b/include/asm-x86/uv/bios.h
+@@ -32,7 +32,9 @@
+ enum uv_bios_cmd {
+ UV_BIOS_COMMON,
+ UV_BIOS_GET_SN_INFO,
+- UV_BIOS_FREQ_BASE
++ UV_BIOS_FREQ_BASE,
++ UV_BIOS_WATCHLIST_ALLOC,
++ UV_BIOS_WATCHLIST_FREE
+ };
+
+ /*
+@@ -71,6 +73,15 @@ union partition_info_u {
+ };
+ };
+
++union uv_watchlist_u {
++ u64 val;
++ struct {
++ u64 blade : 16,
++ size : 32,
++ filler : 16;
++ };
++};
++
+ /*
+ * bios calls have 6 parameters
+ */
+@@ -80,9 +91,13 @@ extern s64 uv_bios_call_reentrant(enum u
+
+ extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
+ extern s64 uv_bios_freq_base(u64, u64 *);
++extern int uv_bios_mq_watchlist_alloc(int, void *, unsigned int,
++ unsigned long *);
++extern int uv_bios_mq_watchlist_free(int, int);
+
+ extern void uv_bios_init(void);
+
++extern unsigned long sn_rtc_cycles_per_second;
+ extern int uv_type;
+ extern long sn_partition_id;
+ extern long sn_coherency_id;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-bios_common.diff
^
|
@@ -0,0 +1,280 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: x86: Add UV bios call infrastructure
+References: bnc#442455
+
+Add the EFI callback function and associated wrapper code.
+Initialize SAL system table entry info at boot time.
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Signed-off-by: Paul Jackson <pj@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/bios_uv.c | 101 ++++++++++++++++++++++++++++++---------
+ arch/x86/kernel/genx2apic_uv_x.c | 1
+ include/asm-x86/efi.h | 14 +++++
+ include/asm-x86/uv/bios.h | 73 +++++++++++++++-------------
+ 4 files changed, 136 insertions(+), 53 deletions(-)
+
+--- a/arch/x86/kernel/bios_uv.c
++++ b/arch/x86/kernel/bios_uv.c
+@@ -1,8 +1,6 @@
+ /*
+ * BIOS run time interface routines.
+ *
+- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+- *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+@@ -16,33 +14,94 @@
+ * 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
++ *
++ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) Russ Anderson
+ */
+
++#include <linux/efi.h>
++#include <asm/efi.h>
++#include <linux/io.h>
+ #include <asm/uv/bios.h>
+
+-const char *
+-x86_bios_strerror(long status)
++struct uv_systab uv_systab;
++
++s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
+ {
+- const char *str;
+- switch (status) {
+- case 0: str = "Call completed without error"; break;
+- case -1: str = "Not implemented"; break;
+- case -2: str = "Invalid argument"; break;
+- case -3: str = "Call completed with error"; break;
+- default: str = "Unknown BIOS status code"; break;
+- }
+- return str;
++ struct uv_systab *tab = &uv_systab;
++
++ if (!tab->function)
++ /*
++ * BIOS does not support UV systab
++ */
++ return BIOS_STATUS_UNIMPLEMENTED;
++
++ return efi_call6((void *)__va(tab->function),
++ (u64)which, a1, a2, a3, a4, a5);
+ }
+
+-long
+-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+- unsigned long *drift_info)
++s64 uv_bios_call_irqsave(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3,
++ u64 a4, u64 a5)
+ {
+- struct uv_bios_retval isrv;
++ unsigned long bios_flags;
++ s64 ret;
++
++ local_irq_save(bios_flags);
++ ret = uv_bios_call(which, a1, a2, a3, a4, a5);
++ local_irq_restore(bios_flags);
++
++ return ret;
++}
++
++s64 uv_bios_call_reentrant(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3,
++ u64 a4, u64 a5)
++{
++ s64 ret;
++
++ preempt_disable();
++ ret = uv_bios_call(which, a1, a2, a3, a4, a5);
++ preempt_enable();
+
+- BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
+- *ticks_per_second = isrv.v0;
+- *drift_info = isrv.v1;
+- return isrv.status;
++ return ret;
++}
++
++long
++x86_bios_freq_base(unsigned long clock_type, unsigned long *ticks_per_second,
++ unsigned long *drift_info)
++{
++ return uv_bios_call(UV_BIOS_FREQ_BASE, clock_type,
++ (u64)ticks_per_second, 0, 0, 0);
+ }
+ EXPORT_SYMBOL_GPL(x86_bios_freq_base);
++
++
++#ifdef CONFIG_EFI
++void uv_bios_init(void)
++{
++ struct uv_systab *tab;
++
++ if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) ||
++ (efi.uv_systab == (unsigned long)NULL)) {
++ printk(KERN_CRIT "No EFI UV System Table.\n");
++ uv_systab.function = (unsigned long)NULL;
++ return;
++ }
++
++ tab = (struct uv_systab *)ioremap(efi.uv_systab,
++ sizeof(struct uv_systab));
++ if (strncmp(tab->signature, "UVST", 4) != 0)
++ printk(KERN_ERR "bad signature in UV system table!");
++
++ /*
++ * Copy table to permanent spot for later use.
++ */
++ memcpy(&uv_systab, tab, sizeof(struct uv_systab));
++ iounmap(tab);
++
++ printk(KERN_INFO "EFI UV System Table Revision %d\n", tab->revision);
++}
++#else /* !CONFIG_EFI */
++
++void uv_bios_init(void) { }
++#endif
++
+--- a/arch/x86/kernel/genx2apic_uv_x.c
++++ b/arch/x86/kernel/genx2apic_uv_x.c
+@@ -421,6 +421,7 @@ void __init uv_system_init(void)
+ gnode_upper = (((unsigned long)node_id.s.node_id) &
+ ~((1 << n_val) - 1)) << m_val;
+
++ uv_bios_init();
+ uv_rtc_init();
+
+ for_each_present_cpu(cpu) {
+--- a/include/asm-x86/efi.h
++++ b/include/asm-x86/efi.h
+@@ -49,6 +49,20 @@ extern u64 efi_call5(void *fp, u64 arg1,
+ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
+ u64 arg4, u64 arg5, u64 arg6);
+
++
++#ifndef CONFIG_EFI
++/*
++ * IF EFI is not configured, have the EFI calls return -ENOSYS.
++ */
++#define efi_call0(_f) (-ENOSYS)
++#define efi_call1(_f, _a1) (-ENOSYS)
++#define efi_call2(_f, _a1, _a2) (-ENOSYS)
++#define efi_call3(_f, _a1, _a2, _a3) (-ENOSYS)
++#define efi_call4(_f, _a1, _a2, _a3, _a4) (-ENOSYS)
++#define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS)
++#define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS)
++#endif /* CONFIG_EFI */
++
+ #define efi_call_phys0(f) \
+ efi_call0((void *)(f))
+ #define efi_call_phys1(f, a1) \
+--- a/include/asm-x86/uv/bios.h
++++ b/include/asm-x86/uv/bios.h
+@@ -2,9 +2,7 @@
+ #define _ASM_X86_BIOS_H
+
+ /*
+- * BIOS layer definitions.
+- *
+- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
++ * UV BIOS layer definitions.
+ *
+ * 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
+@@ -19,50 +17,61 @@
+ * 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
++ *
++ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) Russ Anderson
+ */
+
+ #include <linux/rtc.h>
+
+-#define BIOS_FREQ_BASE 0x01000001
++/*
++ * Values for the BIOS calls. It is passed as the first * argument in the
++ * BIOS call. Passing any other value in the first argument will result
++ * in a BIOS_STATUS_UNIMPLEMENTED return status.
++ */
++enum uv_bios_cmd {
++ UV_BIOS_COMMON,
++ UV_BIOS_GET_SN_INFO,
++ UV_BIOS_FREQ_BASE
++};
+
++/*
++ * Status values returned from a BIOS call.
++ */
+ enum {
+- BIOS_FREQ_BASE_PLATFORM = 0,
+- BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
+- BIOS_FREQ_BASE_REALTIME_CLOCK = 2
++ BIOS_STATUS_SUCCESS = 0,
++ BIOS_STATUS_UNIMPLEMENTED = -ENOSYS,
++ BIOS_STATUS_EINVAL = -EINVAL,
++ BIOS_STATUS_UNAVAIL = -EBUSY
+ };
+
+-# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7) \
+- do { \
+- /* XXX - the real call goes here */ \
+- result.status = BIOS_STATUS_UNIMPLEMENTED; \
+- isrv.v0 = 0; \
+- isrv.v1 = 0; \
+- } while (0)
++/*
++ * The UV system table describes specific firmware
++ * capabilities available to the Linux kernel at runtime.
++ */
++struct uv_systab {
++ char signature[4]; /* must be "UVST" */
++ u32 revision; /* distinguish different firmware revs */
++ u64 function; /* BIOS runtime callback function ptr */
++};
+
+ enum {
+- BIOS_STATUS_SUCCESS = 0,
+- BIOS_STATUS_UNIMPLEMENTED = -1,
+- BIOS_STATUS_EINVAL = -2,
+- BIOS_STATUS_ERROR = -3
++ BIOS_FREQ_BASE_PLATFORM = 0,
++ BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
++ BIOS_FREQ_BASE_REALTIME_CLOCK = 2
+ };
+
+-struct uv_bios_retval {
+- /*
+- * A zero status value indicates call completed without error.
+- * A negative status value indicates reason of call failure.
+- * A positive status value indicates success but an
+- * informational value should be printed (e.g., "reboot for
+- * change to take effect").
+- */
+- s64 status;
+- u64 v0;
+- u64 v1;
+- u64 v2;
+-};
++/*
++ * bios calls have 6 parameters
++ */
++extern s64 uv_bios_call(enum uv_bios_cmd, u64, u64, u64, u64, u64);
++extern s64 uv_bios_call_irqsave(enum uv_bios_cmd, u64, u64, u64, u64, u64);
++extern s64 uv_bios_call_reentrant(enum uv_bios_cmd, u64, u64, u64, u64, u64);
++
++extern void uv_bios_init(void);
+
+ extern long
+ x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+ unsigned long *drift_info);
+-extern const char *x86_bios_strerror(long status);
+
+ #endif /* _ASM_X86_BIOS_H */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-efi_bios.diff
^
|
@@ -0,0 +1,53 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: x86: Add UV EFI table entry
+References: bnc#442455
+
+Add an EFI table entry for SGI UV system.
+Look for the entry in the EFI tables.
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Signed-off-by: Paul Jackson <pj@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/efi.c | 4 ++++
+ include/linux/efi.h | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+Index: linux/arch/x86/kernel/efi.c
+===================================================================
+--- linux.orig/arch/x86/kernel/efi.c 2008-10-15 09:56:13.000000000 -0500
++++ linux/arch/x86/kernel/efi.c 2008-10-15 09:56:23.000000000 -0500
+@@ -367,6 +367,10 @@ void __init efi_init(void)
+ efi.smbios = config_tables[i].table;
+ printk(" SMBIOS=0x%lx ", config_tables[i].table);
+ } else if (!efi_guidcmp(config_tables[i].guid,
++ UV_SYSTEM_TABLE_GUID)) {
++ efi.uv_systab = config_tables[i].table;
++ printk(" UVsystab=0x%lx ", config_tables[i].table);
++ } else if (!efi_guidcmp(config_tables[i].guid,
+ HCDP_TABLE_GUID)) {
+ efi.hcdp = config_tables[i].table;
+ printk(" HCDP=0x%lx ", config_tables[i].table);
+Index: linux/include/linux/efi.h
+===================================================================
+--- linux.orig/include/linux/efi.h 2008-10-15 09:56:13.000000000 -0500
++++ linux/include/linux/efi.h 2008-10-15 09:56:23.000000000 -0500
+@@ -208,6 +208,9 @@ typedef efi_status_t efi_set_virtual_add
+ #define EFI_GLOBAL_VARIABLE_GUID \
+ EFI_GUID( 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c )
+
++#define UV_SYSTEM_TABLE_GUID \
++ EFI_GUID( 0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 )
++
+ typedef struct {
+ efi_guid_t guid;
+ unsigned long table;
+@@ -255,6 +258,7 @@ extern struct efi {
+ unsigned long boot_info; /* boot info table */
+ unsigned long hcdp; /* HCDP table */
+ unsigned long uga; /* UGA table */
++ unsigned long uv_systab; /* UV system table */
+ efi_get_time_t *get_time;
+ efi_set_time_t *set_time;
+ efi_get_wakeup_time_t *get_wakeup_time;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-redundant-creation-of-proc-dir
^
|
@@ -0,0 +1,55 @@
+Subject: [PATCH] UV: redundant creation of sgi_uv
+To: linux-kernel@vger.kernel.org
+Cc: mingo@elte.hu
+From: Cliff Wickman <cpw@sgi.com>
+Patch-mainline: 2.6.28?
+References: bnc#444799
+
+There is a collision between two UV functions:
+ both uv_ptc_init() and gru_proc_init() try to make /proc/sgi_uv
+
+So move it's creation to a single place: uv_system_init()
+
+Diffed against 2.6.28-rc3
+
+Signed-off-by: Cliff Wickman <cpw@sgi.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ arch/x86/kernel/genx2apic_uv_x.c | 2 ++
+ arch/x86/kernel/tlb_uv.c | 4 ----
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/kernel/genx2apic_uv_x.c
++++ b/arch/x86/kernel/genx2apic_uv_x.c
+@@ -20,6 +20,7 @@
+ #include <linux/module.h>
+ #include <linux/hardirq.h>
+ #include <linux/timer.h>
++#include <linux/proc_fs.h>
+ #include <asm/current.h>
+ #include <asm/smp.h>
+ #include <asm/ipi.h>
+@@ -574,5 +575,6 @@ void __init uv_system_init(void)
+ uv_scir_register_cpu_notifier();
+
+ uv_cpu_init();
++ proc_mkdir("sgi_uv", NULL);
+ }
+
+--- a/arch/x86/kernel/tlb_uv.c
++++ b/arch/x86/kernel/tlb_uv.c
+@@ -566,14 +566,10 @@ static int __init uv_ptc_init(void)
+ if (!is_uv_system())
+ return 0;
+
+- if (!proc_mkdir("sgi_uv", NULL))
+- return -EINVAL;
+-
+ proc_uv_ptc = create_proc_entry(UV_PTC_BASENAME, 0444, NULL);
+ if (!proc_uv_ptc) {
+ printk(KERN_ERR "unable to create %s proc entry\n",
+ UV_PTC_BASENAME);
+- remove_proc_entry("sgi_uv", NULL);
+ return -EINVAL;
+ }
+ proc_uv_ptc->proc_fops = &proc_uv_ptc_operations;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-sn_region_size.diff
^
|
@@ -0,0 +1,70 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: Use consistent names for region size and conherence id on x86 and ia64.
+References: bnc#442455
+
+The SGI xp drivers are used on both ia64 and x86. Using the same
+names (sn_coherency_id, sn_region_size) simplies the driver code.
+
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+
+ arch/x86/kernel/bios_uv.c | 8 ++++----
+ arch/x86/kernel/genx2apic_uv_x.c | 4 ++--
+ include/asm-x86/uv/bios.h | 6 +++---
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+--- a/arch/x86/kernel/bios_uv.c
++++ b/arch/x86/kernel/bios_uv.c
+@@ -69,10 +69,10 @@ s64 uv_bios_call_reentrant(enum uv_bios_
+
+ long sn_partition_id;
+ EXPORT_SYMBOL_GPL(sn_partition_id);
+-long uv_coherency_id;
+-EXPORT_SYMBOL_GPL(uv_coherency_id);
+-long uv_region_size;
+-EXPORT_SYMBOL_GPL(uv_region_size);
++long sn_coherency_id;
++EXPORT_SYMBOL_GPL(sn_coherency_id);
++long sn_region_size;
++EXPORT_SYMBOL_GPL(sn_region_size);
+ int uv_type;
+
+
+--- a/arch/x86/kernel/genx2apic_uv_x.c
++++ b/arch/x86/kernel/genx2apic_uv_x.c
+@@ -523,7 +523,7 @@ void __init uv_system_init(void)
+
+ uv_bios_init();
+ uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
+- &uv_coherency_id, &uv_region_size);
++ &sn_coherency_id, &sn_region_size);
+ uv_rtc_init();
+
+ for_each_present_cpu(cpu) {
+@@ -545,7 +545,7 @@ void __init uv_system_init(void)
+ uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
+ uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
+ uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
+- uv_cpu_hub_info(cpu)->coherency_domain_number = uv_coherency_id;
++ uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
+ uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
+ uv_node_to_blade[nid] = blade;
+ uv_cpu_to_blade[cpu] = blade;
+--- a/include/asm-x86/uv/bios.h
++++ b/include/asm-x86/uv/bios.h
+@@ -85,9 +85,9 @@ extern void uv_bios_init(void);
+
+ extern int uv_type;
+ extern long sn_partition_id;
+-extern long uv_coherency_id;
+-extern long uv_region_size;
+-#define partition_coherence_id() (uv_coherency_id)
++extern long sn_coherency_id;
++extern long sn_region_size;
++#define partition_coherence_id() (sn_coherency_id)
+
+ extern struct kobject *sgi_uv_kobj; /* /sys/firmware/sgi_uv */
+
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-sysfs.diff
^
|
@@ -0,0 +1,109 @@
+From: Russ Anderson <rja@sgi.com>
+Subject: x86: Add UV sysfs entries
+References: bnc#442455
+
+Create /sys/firmware/sgi_uv sysfs entries for partition_id and coherence_id.
+
+Signed-off-by: Russ Anderson <rja@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/Makefile | 1
+ arch/x86/kernel/uv_sysfs.c | 72 +++++++++++++++++++++++++++++++++++++++++++++
+ include/asm-x86/uv/bios.h | 1
+ 3 files changed, 74 insertions(+)
+
+--- a/arch/x86/kernel/Makefile
++++ b/arch/x86/kernel/Makefile
+@@ -103,6 +103,7 @@ obj-$(CONFIG_OLPC) += olpc.o
+ # 64 bit specific files
+ ifeq ($(CONFIG_X86_64),y)
+ obj-y += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
++ obj-y += uv_sysfs.o
+ obj-y += genx2apic_cluster.o
+ obj-y += genx2apic_phys.o
+ obj-y += bios_uv.o
+--- /dev/null
++++ b/arch/x86/kernel/uv_sysfs.c
+@@ -0,0 +1,72 @@
++/*
++ * This file supports the /sys/firmware/sgi_uv interfaces for SGI UV.
++ *
++ * 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
++ *
++ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
++ * Copyright (c) Russ Anderson
++ */
++
++#include <linux/sysdev.h>
++#include <asm/uv/bios.h>
++
++struct kobject *sgi_uv_kobj;
++
++static ssize_t partition_id_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return snprintf(buf, PAGE_SIZE, "%ld\n", sn_partition_id);
++}
++
++static ssize_t coherence_id_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return snprintf(buf, PAGE_SIZE, "%ld\n", partition_coherence_id());
++}
++
++static struct kobj_attribute partition_id_attr =
++ __ATTR(partition_id, S_IRUGO, partition_id_show, NULL);
++
++static struct kobj_attribute coherence_id_attr =
++ __ATTR(coherence_id, S_IRUGO, coherence_id_show, NULL);
++
++
++static int __init sgi_uv_sysfs_init(void)
++{
++ unsigned long ret;
++
++ if (!sgi_uv_kobj)
++ sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj);
++ if (!sgi_uv_kobj) {
++ printk(KERN_WARNING "kobject_create_and_add sgi_uv failed \n");
++ return -EINVAL;
++ }
++
++ ret = sysfs_create_file(sgi_uv_kobj, &partition_id_attr.attr);
++ if (ret) {
++ printk(KERN_WARNING "sysfs_create_file partition_id failed \n");
++ return ret;
++ }
++
++ ret = sysfs_create_file(sgi_uv_kobj, &coherence_id_attr.attr);
++ if (ret) {
++ printk(KERN_WARNING "sysfs_create_file coherence_id failed \n");
++ return ret;
++ }
++
++ return 0;
++}
++
++device_initcall(sgi_uv_sysfs_init);
+--- a/include/asm-x86/uv/bios.h
++++ b/include/asm-x86/uv/bios.h
+@@ -89,5 +89,6 @@ extern long uv_coherency_id;
+ extern long uv_region_size;
+ #define partition_coherence_id() (uv_coherency_id)
+
++extern struct kobject *sgi_uv_kobj; /* /sys/firmware/sgi_uv */
+
+ #endif /* _ASM_X86_BIOS_H */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-xp-change_memprotect.diff
^
|
@@ -0,0 +1,228 @@
+From: Dean Nelson <dcn@sgi.com>
+Subject: Define xp_expand_memprotect() and xp_restrict_memprotect()
+References: bnc#442461
+
+Define xp_expand_memprotect() and xp_restrict_memprotect() so they can be
+tailered to the hardware they are run on.
+
+Signed-off-by: Dean Nelson <dcn@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+
+ drivers/misc/sgi-xp/xp.h | 7 +++-
+ drivers/misc/sgi-xp/xp_main.c | 7 ++++
+ drivers/misc/sgi-xp/xp_sn2.c | 34 +++++++++++++++++++++
+ drivers/misc/sgi-xp/xp_uv.c | 66 ++++++++++++++++++++++++++++++++++++++++++
+ drivers/misc/sgi-xp/xpc_sn2.c | 15 +++------
+ 5 files changed, 117 insertions(+), 12 deletions(-)
+
+--- a/drivers/misc/sgi-xp/xp.h
++++ b/drivers/misc/sgi-xp/xp.h
+@@ -190,9 +190,10 @@ enum xp_retval {
+ xpGruSendMqError, /* 59: gru send message queue related error */
+
+ xpBadChannelNumber, /* 60: invalid channel number */
+- xpBadMsgType, /* 60: invalid message type */
++ xpBadMsgType, /* 61: invalid message type */
++ xpBiosError, /* 62: BIOS error */
+
+- xpUnknownReason /* 61: unknown reason - must be last in enum */
++ xpUnknownReason /* 63: unknown reason - must be last in enum */
+ };
+
+ /*
+@@ -341,6 +342,8 @@ extern unsigned long (*xp_pa) (void *);
+ extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
+ size_t);
+ extern int (*xp_cpu_to_nasid) (int);
++extern enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long);
++extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long);
+
+ extern u64 xp_nofault_PIOR_target;
+ extern int xp_nofault_PIOR(void *);
+--- a/drivers/misc/sgi-xp/xp_main.c
++++ b/drivers/misc/sgi-xp/xp_main.c
+@@ -51,6 +51,13 @@ EXPORT_SYMBOL_GPL(xp_remote_memcpy);
+ int (*xp_cpu_to_nasid) (int cpuid);
+ EXPORT_SYMBOL_GPL(xp_cpu_to_nasid);
+
++enum xp_retval (*xp_expand_memprotect) (unsigned long phys_addr,
++ unsigned long size);
++EXPORT_SYMBOL_GPL(xp_expand_memprotect);
++enum xp_retval (*xp_restrict_memprotect) (unsigned long phys_addr,
++ unsigned long size);
++EXPORT_SYMBOL_GPL(xp_restrict_memprotect);
++
+ /*
+ * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
+ * users of XPC.
+--- a/drivers/misc/sgi-xp/xp_sn2.c
++++ b/drivers/misc/sgi-xp/xp_sn2.c
+@@ -120,6 +120,38 @@ xp_cpu_to_nasid_sn2(int cpuid)
+ return cpuid_to_nasid(cpuid);
+ }
+
++static enum xp_retval
++xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size)
++{
++ u64 nasid_array = 0;
++ int ret;
++
++ ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
++ &nasid_array);
++ if (ret != 0) {
++ dev_err(xp, "sn_change_memprotect(,, "
++ "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
++ return xpSalError;
++ }
++ return xpSuccess;
++}
++
++static enum xp_retval
++xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size)
++{
++ u64 nasid_array = 0;
++ int ret;
++
++ ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
++ &nasid_array);
++ if (ret != 0) {
++ dev_err(xp, "sn_change_memprotect(,, "
++ "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
++ return xpSalError;
++ }
++ return xpSuccess;
++}
++
+ enum xp_retval
+ xp_init_sn2(void)
+ {
+@@ -132,6 +164,8 @@ xp_init_sn2(void)
+ xp_pa = xp_pa_sn2;
+ xp_remote_memcpy = xp_remote_memcpy_sn2;
+ xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
++ xp_expand_memprotect = xp_expand_memprotect_sn2;
++ xp_restrict_memprotect = xp_restrict_memprotect_sn2;
+
+ return xp_register_nofault_code_sn2();
+ }
+--- a/drivers/misc/sgi-xp/xp_uv.c
++++ b/drivers/misc/sgi-xp/xp_uv.c
+@@ -15,6 +15,11 @@
+
+ #include <linux/device.h>
+ #include <asm/uv/uv_hub.h>
++#if defined CONFIG_X86_64
++#include <asm/uv/bios.h>
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++#include <asm/sn/sn_sal.h>
++#endif
+ #include "../sgi-gru/grukservices.h"
+ #include "xp.h"
+
+@@ -49,6 +54,65 @@ xp_cpu_to_nasid_uv(int cpuid)
+ return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
+ }
+
++static enum xp_retval
++xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
++{
++ int ret;
++
++#if defined CONFIG_X86_64
++ ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
++ if (ret != BIOS_STATUS_SUCCESS) {
++ dev_err(xp, "uv_bios_change_memprotect(,, "
++ "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
++ return xpBiosError;
++ }
++
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++ u64 nasid_array;
++
++ ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
++ &nasid_array);
++ if (ret != 0) {
++ dev_err(xp, "sn_change_memprotect(,, "
++ "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
++ return xpSalError;
++ }
++#else
++ #error not a supported configuration
++#endif
++ return xpSuccess;
++}
++
++static enum xp_retval
++xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
++{
++ int ret;
++
++#if defined CONFIG_X86_64
++ ret = uv_bios_change_memprotect(phys_addr, size,
++ UV_MEMPROT_RESTRICT_ACCESS);
++ if (ret != BIOS_STATUS_SUCCESS) {
++ dev_err(xp, "uv_bios_change_memprotect(,, "
++ "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
++ return xpBiosError;
++ }
++
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++ u64 nasid_array;
++
++ ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
++ &nasid_array);
++ if (ret != 0) {
++ dev_err(xp, "sn_change_memprotect(,, "
++ "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
++ return xpSalError;
++ }
++#else
++ #error not a supported configuration
++#endif
++ return xpSuccess;
++}
++
+ enum xp_retval
+ xp_init_uv(void)
+ {
+@@ -61,6 +125,8 @@ xp_init_uv(void)
+ xp_pa = xp_pa_uv;
+ xp_remote_memcpy = xp_remote_memcpy_uv;
+ xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
++ xp_expand_memprotect = xp_expand_memprotect_uv;
++ xp_restrict_memprotect = xp_restrict_memprotect_uv;
+
+ return xpSuccess;
+ }
+--- a/drivers/misc/sgi-xp/xpc_sn2.c
++++ b/drivers/misc/sgi-xp/xpc_sn2.c
+@@ -553,22 +553,17 @@ static u64 xpc_prot_vec_sn2[MAX_NUMNODES
+ static enum xp_retval
+ xpc_allow_amo_ops_sn2(struct amo *amos_page)
+ {
+- u64 nasid_array = 0;
+- int ret;
++ enum xp_retval ret = xpSuccess;
+
+ /*
+ * On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST
+ * collides with memory operations. On those systems we call
+ * xpc_allow_amo_ops_shub_wars_1_1_sn2() instead.
+ */
+- if (!enable_shub_wars_1_1()) {
+- ret = sn_change_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE,
+- SN_MEMPROT_ACCESS_CLASS_1,
+- &nasid_array);
+- if (ret != 0)
+- return xpSalError;
+- }
+- return xpSuccess;
++ if (!enable_shub_wars_1_1())
++ ret = xp_expand_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE);
++
++ return ret;
+ }
+
+ /*
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-xpc-get_sn_info.diff
^
|
@@ -0,0 +1,28 @@
+From: Dean Nelson <dcn@sgi.com>
+Subject: [PATCH] Define xp_partition_id and xp_region_size
+References: bnc#442461
+
+
+Define xp_partition_id and xp_region_size to their correct values.
+
+Signed-off-by: Dean Nelson <dcn@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+
+ drivers/misc/sgi-xp/xp_uv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/misc/sgi-xp/xp_uv.c
++++ b/drivers/misc/sgi-xp/xp_uv.c
+@@ -119,8 +119,8 @@ xp_init_uv(void)
+ BUG_ON(!is_uv());
+
+ xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
+- xp_partition_id = 0; /* !!! not correct value */
+- xp_region_size = 0; /* !!! not correct value */
++ xp_partition_id = sn_partition_id;
++ xp_region_size = sn_region_size;
+
+ xp_pa = xp_pa_uv;
+ xp_remote_memcpy = xp_remote_memcpy_uv;
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-xpc_create_gru_mq_uv.diff
^
|
@@ -0,0 +1,388 @@
+From: Dean Nelson <dcn@sgi.com>
+Subject: [PATCH] Add the code to create the activate and notify gru message queues
+References: bnc#442461
+
+For UV add the code to create the activate and notify gru message queues.
+
+Signed-off-by: Dean Nelson <dcn@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+
+ drivers/misc/sgi-xp/xpc.h | 12 +
+ drivers/misc/sgi-xp/xpc_uv.c | 259 ++++++++++++++++++++++++++++++++++---------
+ 2 files changed, 218 insertions(+), 53 deletions(-)
+
+--- a/drivers/misc/sgi-xp/xpc.h
++++ b/drivers/misc/sgi-xp/xpc.h
+@@ -181,6 +181,18 @@ struct xpc_vars_part_sn2 {
+ xpc_nasid_mask_nlongs))
+
+ /*
++ * Info pertinent to a GRU message queue using a watch list for irq generation.
++ */
++struct xpc_gru_mq_uv {
++ void *address; /* address of GRU message queue */
++ unsigned int order; /* size of GRU message queue as a power of 2 */
++ int irq; /* irq raised when message is received in mq */
++ int mmr_blade; /* blade where watchlist was allocated from */
++ unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
++ int watchlist_num; /* number of watchlist allocatd by BIOS */
++};
++
++/*
+ * The activate_mq is used to send/receive GRU messages that affect XPC's
+ * heartbeat, partition active state, and channel state. This is UV only.
+ */
+--- a/drivers/misc/sgi-xp/xpc_uv.c
++++ b/drivers/misc/sgi-xp/xpc_uv.c
+@@ -18,7 +18,15 @@
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
++#include <linux/err.h>
+ #include <asm/uv/uv_hub.h>
++#if defined CONFIG_X86_64
++#include <asm/uv/bios.h>
++#include <asm/uv/uv_irq.h>
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++#include <asm/sn/intr.h>
++#include <asm/sn/sn_sal.h>
++#endif
+ #include "../sgi-gru/gru.h"
+ #include "../sgi-gru/grukservices.h"
+ #include "xpc.h"
+@@ -27,15 +35,17 @@ static atomic64_t xpc_heartbeat_uv;
+ static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
+
+ #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES)
+-#define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES)
++#define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
++ XPC_ACTIVATE_MSG_SIZE_UV)
++#define XPC_ACTIVATE_IRQ_NAME "xpc_activate"
+
+-#define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
+- XPC_ACTIVATE_MSG_SIZE_UV)
+-#define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
+- XPC_NOTIFY_MSG_SIZE_UV)
++#define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES)
++#define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
++ XPC_NOTIFY_MSG_SIZE_UV)
++#define XPC_NOTIFY_IRQ_NAME "xpc_notify"
+
+-static void *xpc_activate_mq_uv;
+-static void *xpc_notify_mq_uv;
++static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
++static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
+
+ static int
+ xpc_setup_partitions_sn_uv(void)
+@@ -52,62 +62,209 @@ xpc_setup_partitions_sn_uv(void)
+ return 0;
+ }
+
+-static void *
+-xpc_create_gru_mq_uv(unsigned int mq_size, int cpuid, unsigned int irq,
++static int
++xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
++{
++#if defined CONFIG_X86_64
++ mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset);
++ if (mq->irq < 0) {
++ dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
++ mq->irq);
++ }
++
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++ int mmr_pnode;
++ unsigned long mmr_value;
++
++ if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
++ mq->irq = SGI_XPC_ACTIVATE;
++ else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
++ mq->irq = SGI_XPC_NOTIFY;
++ else
++ return -EINVAL;
++
++ mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
++ mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
++
++ uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
++#else
++ #error not a supported configuration
++#endif
++
++ return 0;
++}
++
++static void
++xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
++{
++#if defined CONFIG_X86_64
++ uv_teardown_irq(mq->irq, mq->mmr_blade, mq->mmr_offset);
++
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++ int mmr_pnode;
++ unsigned long mmr_value;
++
++ mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
++ mmr_value = 1UL << 16;
++
++ uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
++#else
++ #error not a supported configuration
++#endif
++}
++
++static int
++xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
++{
++ int ret;
++
++#if defined CONFIG_X86_64
++ ret = uv_bios_mq_watchlist_alloc(mq->mmr_blade, mq->address, mq->order,
++ &mq->mmr_offset);
++ if (ret < 0) {
++ dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
++ "ret=%d\n", ret);
++ return ret;
++ }
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++ ret = sn_mq_watchlist_alloc(mq->mmr_blade, mq->address, mq->order,
++ &mq->mmr_offset);
++ if (ret < 0) {
++ dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
++ ret);
++ return -EBUSY;
++ }
++#else
++ #error not a supported configuration
++#endif
++
++ mq->watchlist_num = ret;
++ return 0;
++}
++
++static void
++xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
++{
++ int ret;
++
++#if defined CONFIG_X86_64
++ ret = uv_bios_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
++ BUG_ON(ret != BIOS_STATUS_SUCCESS);
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++ ret = sn_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
++ BUG_ON(ret != SALRET_OK);
++#else
++ #error not a supported configuration
++#endif
++}
++
++static struct xpc_gru_mq_uv *
++xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
+ irq_handler_t irq_handler)
+ {
++ enum xp_retval xp_ret;
+ int ret;
+ int nid;
+- int mq_order;
++ int pg_order;
+ struct page *page;
+- void *mq;
++ struct xpc_gru_mq_uv *mq;
++
++ mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL);
++ if (mq == NULL) {
++ dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
++ "a xpc_gru_mq_uv structure\n");
++ ret = -ENOMEM;
++ goto out_1;
++ }
++
++ pg_order = get_order(mq_size);
++ mq->order = pg_order + PAGE_SHIFT;
++ mq_size = 1UL << mq->order;
+
+- nid = cpu_to_node(cpuid);
+- mq_order = get_order(mq_size);
++ mq->mmr_blade = uv_cpu_to_blade_id(cpu);
++
++ nid = cpu_to_node(cpu);
+ page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+- mq_order);
++ pg_order);
+ if (page == NULL) {
+ dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
+ "bytes of memory on nid=%d for GRU mq\n", mq_size, nid);
+- return NULL;
++ ret = -ENOMEM;
++ goto out_2;
+ }
++ mq->address = page_address(page);
+
+- mq = page_address(page);
+- ret = gru_create_message_queue(mq, mq_size);
++ ret = gru_create_message_queue(mq->address, mq_size);
+ if (ret != 0) {
+ dev_err(xpc_part, "gru_create_message_queue() returned "
+ "error=%d\n", ret);
+- free_pages((unsigned long)mq, mq_order);
+- return NULL;
++ ret = -EINVAL;
++ goto out_3;
+ }
+
+- /* !!! Need to do some other things to set up IRQ */
++ /* enable generation of irq when GRU mq operation occurs to this mq */
++ ret = xpc_gru_mq_watchlist_alloc_uv(mq);
++ if (ret != 0)
++ goto out_3;
++
++ ret = xpc_get_gru_mq_irq_uv(mq, cpu, irq_name);
++ if (ret != 0)
++ goto out_4;
+
+- ret = request_irq(irq, irq_handler, 0, "xpc", NULL);
++ ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL);
+ if (ret != 0) {
+ dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n",
+- irq, ret);
+- free_pages((unsigned long)mq, mq_order);
+- return NULL;
++ mq->irq, ret);
++ goto out_5;
+ }
+
+- /* !!! enable generation of irq when GRU mq op occurs to this mq */
+-
+- /* ??? allow other partitions to access GRU mq? */
++ /* allow other partitions to access this GRU mq */
++ xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size);
++ if (xp_ret != xpSuccess) {
++ ret = -EACCES;
++ goto out_6;
++ }
+
+ return mq;
++
++ /* something went wrong */
++out_6:
++ free_irq(mq->irq, NULL);
++out_5:
++ xpc_release_gru_mq_irq_uv(mq);
++out_4:
++ xpc_gru_mq_watchlist_free_uv(mq);
++out_3:
++ free_pages((unsigned long)mq->address, pg_order);
++out_2:
++ kfree(mq);
++out_1:
++ return ERR_PTR(ret);
+ }
+
+ static void
+-xpc_destroy_gru_mq_uv(void *mq, unsigned int mq_size, unsigned int irq)
++xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq)
+ {
+- /* ??? disallow other partitions to access GRU mq? */
++ unsigned int mq_size;
++ int pg_order;
++ int ret;
++
++ /* disallow other partitions to access GRU mq */
++ mq_size = 1UL << mq->order;
++ ret = xp_restrict_memprotect(xp_pa(mq->address), mq_size);
++ BUG_ON(ret != xpSuccess);
++
++ /* unregister irq handler and release mq irq/vector mapping */
++ free_irq(mq->irq, NULL);
++ xpc_release_gru_mq_irq_uv(mq);
+
+- /* !!! disable generation of irq when GRU mq op occurs to this mq */
++ /* disable generation of irq when GRU mq op occurs to this mq */
++ xpc_gru_mq_watchlist_free_uv(mq);
+
+- free_irq(irq, NULL);
++ pg_order = mq->order - PAGE_SHIFT;
++ free_pages((unsigned long)mq->address, pg_order);
+
+- free_pages((unsigned long)mq, get_order(mq_size));
++ kfree(mq);
+ }
+
+ static enum xp_retval
+@@ -402,7 +559,10 @@ xpc_handle_activate_IRQ_uv(int irq, void
+ struct xpc_partition *part;
+ int wakeup_hb_checker = 0;
+
+- while ((msg_hdr = gru_get_next_message(xpc_activate_mq_uv)) != NULL) {
++ while (1) {
++ msg_hdr = gru_get_next_message(xpc_activate_mq_uv->address);
++ if (msg_hdr == NULL)
++ break;
+
+ partid = msg_hdr->partid;
+ if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
+@@ -418,7 +578,7 @@ xpc_handle_activate_IRQ_uv(int irq, void
+ }
+ }
+
+- gru_free_message(xpc_activate_mq_uv, msg_hdr);
++ gru_free_message(xpc_activate_mq_uv->address, msg_hdr);
+ }
+
+ if (wakeup_hb_checker)
+@@ -507,7 +667,7 @@ xpc_get_partition_rsvd_page_pa_uv(void *
+ static int
+ xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp)
+ {
+- rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv);
++ rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv->address);
+ return 0;
+ }
+
+@@ -1411,22 +1571,18 @@ xpc_init_uv(void)
+ return -E2BIG;
+ }
+
+- /* ??? The cpuid argument's value is 0, is that what we want? */
+- /* !!! The irq argument's value isn't correct. */
+- xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, 0,
++ xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0,
++ XPC_ACTIVATE_IRQ_NAME,
+ xpc_handle_activate_IRQ_uv);
+- if (xpc_activate_mq_uv == NULL)
+- return -ENOMEM;
++ if (IS_ERR(xpc_activate_mq_uv))
++ return PTR_ERR(xpc_activate_mq_uv);
+
+- /* ??? The cpuid argument's value is 0, is that what we want? */
+- /* !!! The irq argument's value isn't correct. */
+- xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, 0,
++ xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0,
++ XPC_NOTIFY_IRQ_NAME,
+ xpc_handle_notify_IRQ_uv);
+- if (xpc_notify_mq_uv == NULL) {
+- /* !!! The irq argument's value isn't correct. */
+- xpc_destroy_gru_mq_uv(xpc_activate_mq_uv,
+- XPC_ACTIVATE_MQ_SIZE_UV, 0);
+- return -ENOMEM;
++ if (IS_ERR(xpc_notify_mq_uv)) {
++ xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
++ return PTR_ERR(xpc_notify_mq_uv);
+ }
+
+ return 0;
+@@ -1435,9 +1591,6 @@ xpc_init_uv(void)
+ void
+ xpc_exit_uv(void)
+ {
+- /* !!! The irq argument's value isn't correct. */
+- xpc_destroy_gru_mq_uv(xpc_notify_mq_uv, XPC_NOTIFY_MQ_SIZE_UV, 0);
+-
+- /* !!! The irq argument's value isn't correct. */
+- xpc_destroy_gru_mq_uv(xpc_activate_mq_uv, XPC_ACTIVATE_MQ_SIZE_UV, 0);
++ xpc_destroy_gru_mq_uv(xpc_notify_mq_uv);
++ xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
+ }
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv-xpc_get_part_rsvd_page.diff
^
|
@@ -0,0 +1,63 @@
+From: Dean Nelson <dcn@sgi.com>
+Subject: [PATCH] Add support for getting the address of a partition's reserved page.
+References: bnc#442461
+
+Add support for getting the address of a partition's reserved page.
+
+Signed-off-by: Dean Nelson <dcn@sgi.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+
+ drivers/misc/sgi-xp/xpc_uv.c | 31 ++++++++++++++++++++++++++++---
+ 1 file changed, 28 insertions(+), 3 deletions(-)
+
+Index: linux/drivers/misc/sgi-xp/xpc_uv.c
+===================================================================
+--- linux.orig/drivers/misc/sgi-xp/xpc_uv.c 2008-10-21 12:50:18.000000000 -0500
++++ linux/drivers/misc/sgi-xp/xpc_uv.c 2008-10-21 14:00:13.000000000 -0500
+@@ -642,7 +642,7 @@ xpc_send_local_activate_IRQ_uv(struct xp
+ struct xpc_partition_uv *part_uv = &part->sn.uv;
+
+ /*
+- * !!! Make our side think that the remote parition sent an activate
++ * !!! Make our side think that the remote partition sent an activate
+ * !!! message our way by doing what the activate IRQ handler would
+ * !!! do had one really been sent.
+ */
+@@ -660,8 +660,33 @@ static enum xp_retval
+ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
+ size_t *len)
+ {
+- /* !!! call the UV version of sn_partition_reserved_page_pa() */
+- return xpUnsupported;
++ s64 status;
++ enum xp_retval ret;
++
++#if defined CONFIG_X86_64
++ status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa,
++ (u64 *)len);
++ if (status == BIOS_STATUS_SUCCESS)
++ ret = xpSuccess;
++ else if (status == BIOS_STATUS_MORE_PASSES)
++ ret = xpNeedMoreInfo;
++ else
++ ret = xpBiosError;
++
++#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
++ status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len);
++ if (status == SALRET_OK)
++ ret = xpSuccess;
++ else if (status == SALRET_MORE_PASSES)
++ ret = xpNeedMoreInfo;
++ else
++ ret = xpSalError;
++
++#else
++ #error not a supported configuration
++#endif
++
++ return ret;
+ }
+
+ static int
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/uv_setup_irq.diff
^
|
@@ -0,0 +1,239 @@
+From: Dean Nelson <dcn@sgi.com>
+Date: Thu, 2 Oct 2008 17:18:21 +0000 (-0500)
+Subject: x86, UV: add uv_setup_irq() and uv_teardown_irq() functions, v3
+X-Git-Tag: v2.6.28-rc1~80^2~27
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=4173a0e7371ece227559b44943c6fd456ee470d1
+References: bnc#442461
+
+x86, UV: add uv_setup_irq() and uv_teardown_irq() functions, v3
+
+Provide a means for UV interrupt MMRs to be setup with the message to be sent
+when an MSI is raised.
+
+Signed-off-by: Dean Nelson <dcn@sgi.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+
+---
+ arch/x86/kernel/Makefile | 2 -
+ arch/x86/kernel/io_apic_64.c | 68 +++++++++++++++++++++++++++++++++++++
+ arch/x86/kernel/uv_irq.c | 79 +++++++++++++++++++++++++++++++++++++++++++
+ include/asm-x86/uv/uv_irq.h | 36 +++++++++++++++++++
+ 4 files changed, 184 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/Makefile
++++ b/arch/x86/kernel/Makefile
+@@ -106,7 +106,7 @@ ifeq ($(CONFIG_X86_64),y)
+ obj-y += uv_sysfs.o
+ obj-y += genx2apic_cluster.o
+ obj-y += genx2apic_phys.o
+- obj-y += bios_uv.o
++ obj-y += bios_uv.o uv_irq.o
+ obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
+ obj-$(CONFIG_AUDIT) += audit_64.o
+
+--- a/arch/x86/kernel/io_apic_64.c
++++ b/arch/x86/kernel/io_apic_64.c
+@@ -51,6 +51,8 @@
+ #include <asm/msidef.h>
+ #include <asm/hypertransport.h>
+ #include <asm/irq_remapping.h>
++#include <asm/uv/uv_hub.h>
++#include <asm/uv/uv_irq.h>
+
+ #include <mach_ipi.h>
+ #include <mach_apic.h>
+@@ -2787,6 +2789,72 @@ int arch_setup_ht_irq(unsigned int irq,
+ }
+ #endif /* CONFIG_HT_IRQ */
+
++#ifdef CONFIG_X86_64
++/*
++ * Re-target the irq to the specified CPU and enable the specified MMR located
++ * on the specified blade to allow the sending of MSIs to the specified CPU.
++ */
++int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
++ unsigned long mmr_offset)
++{
++ const cpumask_t *eligible_cpu = get_cpu_mask(cpu);
++ struct irq_cfg *cfg;
++ int mmr_pnode;
++ unsigned long mmr_value;
++ struct uv_IO_APIC_route_entry *entry;
++ unsigned long flags;
++ int err;
++
++ err = assign_irq_vector(irq, eligible_cpu);
++ if (err != 0)
++ return err;
++
++ spin_lock_irqsave(&vector_lock, flags);
++ set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
++ irq_name);
++ spin_unlock_irqrestore(&vector_lock, flags);
++
++ cfg = &irq_cfg[irq];
++
++ mmr_value = 0;
++ entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
++ BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
++
++ entry->vector = cfg->vector;
++ entry->delivery_mode = INT_DELIVERY_MODE;
++ entry->dest_mode = INT_DEST_MODE;
++ entry->polarity = 0;
++ entry->trigger = 0;
++ entry->mask = 0;
++ entry->dest = cpu_mask_to_apicid(eligible_cpu);
++
++ mmr_pnode = uv_blade_to_pnode(mmr_blade);
++ uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
++
++ return irq;
++}
++
++/*
++ * Disable the specified MMR located on the specified blade so that MSIs are
++ * longer allowed to be sent.
++ */
++void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
++{
++ unsigned long mmr_value;
++ struct uv_IO_APIC_route_entry *entry;
++ int mmr_pnode;
++
++ mmr_value = 0;
++ entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
++ BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
++
++ entry->mask = 1;
++
++ mmr_pnode = uv_blade_to_pnode(mmr_blade);
++ uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
++}
++#endif /* CONFIG_X86_64 */
++
+ /* --------------------------------------------------------------------------
+ ACPI-based IOAPIC Configuration
+ -------------------------------------------------------------------------- */
+--- /dev/null
++++ b/arch/x86/kernel/uv_irq.c
+@@ -0,0 +1,79 @@
++/*
++ * 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.
++ *
++ * SGI UV IRQ functions
++ *
++ * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
++ */
++
++#include <linux/module.h>
++#include <linux/irq.h>
++
++#include <asm/apic.h>
++#include <asm/uv/uv_irq.h>
++
++static void uv_noop(unsigned int irq)
++{
++}
++
++static unsigned int uv_noop_ret(unsigned int irq)
++{
++ return 0;
++}
++
++static void uv_ack_apic(unsigned int irq)
++{
++ ack_APIC_irq();
++}
++
++struct irq_chip uv_irq_chip = {
++ .name = "UV-CORE",
++ .startup = uv_noop_ret,
++ .shutdown = uv_noop,
++ .enable = uv_noop,
++ .disable = uv_noop,
++ .ack = uv_noop,
++ .mask = uv_noop,
++ .unmask = uv_noop,
++ .eoi = uv_ack_apic,
++ .end = uv_noop,
++};
++
++/*
++ * Set up a mapping of an available irq and vector, and enable the specified
++ * MMR that defines the MSI that is to be sent to the specified CPU when an
++ * interrupt is raised.
++ */
++int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
++ unsigned long mmr_offset)
++{
++ int irq;
++ int ret;
++
++ irq = create_irq();
++ if (irq < 0)
++ return -EBUSY;
++
++ ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
++ if (ret != irq)
++ destroy_irq(irq);
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(uv_setup_irq);
++
++/*
++ * Tear down a mapping of an irq and vector, and disable the specified MMR that
++ * defined the MSI that was to be sent to the specified CPU when an interrupt
++ * was raised.
++ *
++ * Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
++ */
++void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
++{
++ arch_disable_uv_irq(mmr_blade, mmr_offset);
++ destroy_irq(irq);
++}
++EXPORT_SYMBOL_GPL(uv_teardown_irq);
+--- /dev/null
++++ b/include/asm-x86/uv/uv_irq.h
+@@ -0,0 +1,36 @@
++/*
++ * 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.
++ *
++ * SGI UV IRQ definitions
++ *
++ * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
++ */
++
++#ifndef _ASM_X86_UV_UV_IRQ_H
++#define _ASM_X86_UV_UV_IRQ_H
++
++/* If a generic version of this structure gets defined, eliminate this one. */
++struct uv_IO_APIC_route_entry {
++ __u64 vector : 8,
++ delivery_mode : 3,
++ dest_mode : 1,
++ delivery_status : 1,
++ polarity : 1,
++ __reserved_1 : 1,
++ trigger : 1,
++ mask : 1,
++ __reserved_2 : 15,
++ dest : 32;
++};
++
++extern struct irq_chip uv_irq_chip;
++
++extern int arch_enable_uv_irq(char *, unsigned int, int, int, unsigned long);
++extern void arch_disable_uv_irq(int, unsigned long);
++
++extern int uv_setup_irq(char *, int, int, unsigned long);
++extern void uv_teardown_irq(unsigned int, int, unsigned long);
++
++#endif /* _ASM_X86_UV_UV_IRQ_H */
|
[-]
[+]
|
Added |
patches.fixes.tar.bz2/v4l-dvb-avoid-writing-outside-array
^
|
@@ -0,0 +1,84 @@
+From: Mauro Carvalho Chehab <mchehab@redhat.com>
+Date: Thu, 13 Nov 2008 20:03:28 +0000 (-0300)
+Subject: V4L/DVB (9621): Avoid writing outside shadow.bytes[] array
+Patch-mainline: 2.6.28
+Git-Commit: 494264379d186bf806613d27aafb7d88d42f4212
+References: bnc#445569
+
+V4L/DVB (9621): Avoid writing outside shadow.bytes[] array
+
+There were no check about the limits of shadow.bytes array. This offers
+a risk of writing values outside the limits, overriding other data
+areas.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ drivers/media/video/tvaudio.c | 30 +++++++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/video/tvaudio.c
++++ b/drivers/media/video/tvaudio.c
+@@ -152,7 +152,7 @@ static int chip_write(struct CHIPSTATE *
+ {
+ unsigned char buffer[2];
+
+- if (-1 == subaddr) {
++ if (subaddr < 0) {
+ v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n",
+ chip->c->name, val);
+ chip->shadow.bytes[1] = val;
+@@ -163,6 +163,13 @@ static int chip_write(struct CHIPSTATE *
+ return -1;
+ }
+ } else {
++ if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
++ v4l_info(chip->c,
++ "Tried to access a non-existent register: %d\n",
++ subaddr);
++ return -EINVAL;
++ }
++
+ v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n",
+ chip->c->name, subaddr, val);
+ chip->shadow.bytes[subaddr+1] = val;
+@@ -177,12 +184,20 @@ static int chip_write(struct CHIPSTATE *
+ return 0;
+ }
+
+-static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask)
++static int chip_write_masked(struct CHIPSTATE *chip,
++ int subaddr, int val, int mask)
+ {
+ if (mask != 0) {
+- if (-1 == subaddr) {
++ if (subaddr < 0) {
+ val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
+ } else {
++ if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
++ v4l_info(chip->c,
++ "Tried to access a non-existent register: %d\n",
++ subaddr);
++ return -EINVAL;
++ }
++
+ val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask);
+ }
+ }
+@@ -228,6 +243,15 @@ static int chip_cmd(struct CHIPSTATE *ch
+ if (0 == cmd->count)
+ return 0;
+
++ if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
++ v4l_info(chip->c,
++ "Tried to access a non-existent register range: %d to %d\n",
++ cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1);
++ return -EINVAL;
++ }
++
++ /* FIXME: it seems that the shadow bytes are wrong bellow !*/
++
+ /* update our shadow register set; print bytes if (debug > 0) */
+ v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:",
+ chip->c->name, name,cmd->bytes[0]);
|
[-]
[+]
|
Changed |
patches.kernel.org.tar.bz2/ipmi-section-conflict.diff
^
|
@@ -15,7 +15,7 @@
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
-@@ -1150,7 +1150,7 @@ static unsigned int num_slave_addrs;
+@@ -1152,7 +1152,7 @@ static unsigned int num_slave_addrs;
#define IPMI_MEM_ADDR_SPACE 1
static char *addr_space_to_str[] = { "i/o", "mem" };
@@ -24,7 +24,7 @@
module_param_call(hotmod, hotmod_handler, NULL, NULL, 0200);
MODULE_PARM_DESC(hotmod, "Add and remove interfaces. See"
-@@ -1572,7 +1572,7 @@ static int check_hotmod_int_op(const cha
+@@ -1574,7 +1574,7 @@ static int check_hotmod_int_op(const cha
return 0;
}
@@ -33,7 +33,6 @@
{
char *str = kstrdup(val, GFP_KERNEL);
int rv;
-
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -196,7 +196,7 @@ static void ipmi_unregister_watchdog(int
@@ -81,4 +80,3 @@
{
int rv = param_set_int(val, kp);
if (rv)
-
|
[-]
[+]
|
Added |
patches.kernel.org.tar.bz2/patch-2.6.27.4-5
^
|
@@ -0,0 +1,2563 @@
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: Linux 2.6.27.5
+
+Upstream 2.6.27.5 release from kernel.org
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+diff --git a/Documentation/i2c/busses/i2c-sis96x b/Documentation/i2c/busses/i2c-sis96x
+index 266481f..70e6a0c 100644
+--- a/Documentation/i2c/busses/i2c-sis96x
++++ b/Documentation/i2c/busses/i2c-sis96x
+@@ -42,7 +42,7 @@ I suspect that this driver could be made to work for the following SiS
+ chipsets as well: 635, and 635T. If anyone owns a board with those chips
+ AND is willing to risk crashing & burning an otherwise well-behaved kernel
+ in the name of progress... please contact me at <mhoffman@lightlink.com> or
+-via the project's mailing list: <i2c@lm-sensors.org>. Please send bug
++via the linux-i2c mailing list: <linux-i2c@vger.kernel.org>. Please send bug
+ reports and/or success stories as well.
+
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 8dae455..ff24d01 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -360,7 +360,7 @@ S: Maintained
+ ALI1563 I2C DRIVER
+ P: Rudolf Marek
+ M: r.marek@assembler.cz
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ ALPHA PORT
+@@ -1681,7 +1681,7 @@ FREESCALE I2C CPM DRIVER
+ P: Jochen Friedrich
+ M: jochen@scram.de
+ L: linuxppc-dev@ozlabs.org
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ FREESCALE SOC FS_ENET DRIVER
+@@ -1982,7 +1982,7 @@ S: Maintained
+ I2C/SMBUS STUB DRIVER
+ P: Mark M. Hoffman
+ M: mhoffman@lightlink.com
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ I2C SUBSYSTEM
+@@ -1990,14 +1990,14 @@ P: Jean Delvare (PC drivers, core)
+ M: khali@linux-fr.org
+ P: Ben Dooks (embedded platforms)
+ M: ben-linux@fluff.org
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
+ S: Maintained
+
+ I2C-TINY-USB DRIVER
+ P: Till Harbaum
+ M: till@harbaum.org
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ T: http://www.harbaum.org/till/i2c_tiny_usb
+ S: Maintained
+
+@@ -3070,7 +3070,7 @@ S: Maintained
+ OPENCORES I2C BUS DRIVER
+ P: Peter Korsgaard
+ M: jacmet@sunsite.dk
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
+@@ -3144,7 +3144,7 @@ S: Maintained
+ PA SEMI SMBUS DRIVER
+ P: Olof Johansson
+ M: olof@lixom.net
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ PARALLEL PORT SUPPORT
+@@ -3280,7 +3280,7 @@ S: Maintained
+ PNXxxxx I2C DRIVER
+ P: Vitaly Wool
+ M: vitalywool@gmail.com
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ PPP PROTOCOL DRIVERS AND COMPRESSORS
+@@ -3725,7 +3725,7 @@ S: Maintained
+ SIS 96X I2C/SMBUS DRIVER
+ P: Mark M. Hoffman
+ M: mhoffman@lightlink.com
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ SIS FRAMEBUFFER DRIVER
+@@ -4445,7 +4445,7 @@ S: Maintained
+ VIAPRO SMBUS DRIVER
+ P: Jean Delvare
+ M: khali@linux-fr.org
+-L: i2c@lm-sensors.org
++L: linux-i2c@vger.kernel.org
+ S: Maintained
+
+ VIA VELOCITY NETWORK DRIVER
+diff --git a/Makefile b/Makefile
+index 7529a72..4ea7b3c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 27
+-EXTRAVERSION = .4
++EXTRAVERSION = .5
+ NAME = Trembling Tortoise
+
+ # *DOCUMENTATION*
+diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
+index 6fc4c21..d0846ec 100644
+--- a/arch/powerpc/configs/linkstation_defconfig
++++ b/arch/powerpc/configs/linkstation_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.27-rc4
+-# Thu Aug 21 00:52:05 2008
++# Linux kernel version: 2.6.27
++# Fri Oct 24 00:42:39 2008
+ #
+ # CONFIG_PPC64 is not set
+
+@@ -934,7 +934,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ # CONFIG_SERIAL_JSM is not set
+-CONFIG_SERIAL_OF_PLATFORM=y
++# CONFIG_SERIAL_OF_PLATFORM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -1211,7 +1211,6 @@ CONFIG_USB_STORAGE=m
+ # CONFIG_USB_STORAGE_ALAUDA is not set
+ # CONFIG_USB_STORAGE_ONETOUCH is not set
+ # CONFIG_USB_STORAGE_KARMA is not set
+-# CONFIG_USB_STORAGE_SIERRA is not set
+ # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+ # CONFIG_USB_LIBUSUAL is not set
+
+diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
+index 8920eea..16319a5 100644
+--- a/arch/powerpc/mm/hash_utils_64.c
++++ b/arch/powerpc/mm/hash_utils_64.c
+@@ -381,8 +381,10 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
+ printk(KERN_INFO "Huge page(16GB) memory: "
+ "addr = 0x%lX size = 0x%lX pages = %d\n",
+ phys_addr, block_size, expected_pages);
+- lmb_reserve(phys_addr, block_size * expected_pages);
+- add_gpage(phys_addr, block_size, expected_pages);
++ if (phys_addr + (16 * GB) <= lmb_end_of_DRAM()) {
++ lmb_reserve(phys_addr, block_size * expected_pages);
++ add_gpage(phys_addr, block_size, expected_pages);
++ }
+ return 0;
+ }
+
+diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
+index d9a1813..b5ae97e 100644
+--- a/arch/powerpc/mm/numa.c
++++ b/arch/powerpc/mm/numa.c
+@@ -89,6 +89,48 @@ static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
+ return 0;
+ }
+
++/*
++ * get_active_region_work_fn - A helper function for get_node_active_region
++ * Returns datax set to the start_pfn and end_pfn if they contain
++ * the initial value of datax->start_pfn between them
++ * @start_pfn: start page(inclusive) of region to check
++ * @end_pfn: end page(exclusive) of region to check
++ * @datax: comes in with ->start_pfn set to value to search for and
++ * goes out with active range if it contains it
++ * Returns 1 if search value is in range else 0
++ */
++static int __init get_active_region_work_fn(unsigned long start_pfn,
++ unsigned long end_pfn, void *datax)
++{
++ struct node_active_region *data;
++ data = (struct node_active_region *)datax;
++
++ if (start_pfn <= data->start_pfn && end_pfn > data->start_pfn) {
++ data->start_pfn = start_pfn;
++ data->end_pfn = end_pfn;
++ return 1;
++ }
++ return 0;
++
++}
++
++/*
++ * get_node_active_region - Return active region containing start_pfn
++ * Active range returned is empty if none found.
++ * @start_pfn: The page to return the region for.
++ * @node_ar: Returned set to the active region containing start_pfn
++ */
++static void __init get_node_active_region(unsigned long start_pfn,
++ struct node_active_region *node_ar)
++{
++ int nid = early_pfn_to_nid(start_pfn);
++
++ node_ar->nid = nid;
++ node_ar->start_pfn = start_pfn;
++ node_ar->end_pfn = start_pfn;
++ work_with_active_regions(nid, get_active_region_work_fn, node_ar);
++}
++
+ static void __cpuinit map_cpu_to_node(int cpu, int node)
+ {
+ numa_cpu_lookup_table[cpu] = node;
+@@ -837,38 +879,53 @@ void __init do_init_bootmem(void)
+ start_pfn, end_pfn);
+
+ free_bootmem_with_active_regions(nid, end_pfn);
++ }
+
+- /* Mark reserved regions on this node */
+- for (i = 0; i < lmb.reserved.cnt; i++) {
+- unsigned long physbase = lmb.reserved.region[i].base;
+- unsigned long size = lmb.reserved.region[i].size;
+- unsigned long start_paddr = start_pfn << PAGE_SHIFT;
+- unsigned long end_paddr = end_pfn << PAGE_SHIFT;
+-
+- if (early_pfn_to_nid(physbase >> PAGE_SHIFT) != nid &&
+- early_pfn_to_nid((physbase+size-1) >> PAGE_SHIFT) != nid)
+- continue;
+-
+- if (physbase < end_paddr &&
+- (physbase+size) > start_paddr) {
+- /* overlaps */
+- if (physbase < start_paddr) {
+- size -= start_paddr - physbase;
+- physbase = start_paddr;
+- }
+-
+- if (size > end_paddr - physbase)
+- size = end_paddr - physbase;
+-
+- dbg("reserve_bootmem %lx %lx\n", physbase,
+- size);
+- reserve_bootmem_node(NODE_DATA(nid), physbase,
+- size, BOOTMEM_DEFAULT);
+- }
++ /* Mark reserved regions */
++ for (i = 0; i < lmb.reserved.cnt; i++) {
++ unsigned long physbase = lmb.reserved.region[i].base;
++ unsigned long size = lmb.reserved.region[i].size;
++ unsigned long start_pfn = physbase >> PAGE_SHIFT;
++ unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT);
++ struct node_active_region node_ar;
++
++ get_node_active_region(start_pfn, &node_ar);
++ while (start_pfn < end_pfn &&
++ node_ar.start_pfn < node_ar.end_pfn) {
++ unsigned long reserve_size = size;
++ /*
++ * if reserved region extends past active region
++ * then trim size to active region
++ */
++ if (end_pfn > node_ar.end_pfn)
++ reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
++ - (start_pfn << PAGE_SHIFT);
++ dbg("reserve_bootmem %lx %lx nid=%d\n", physbase,
++ reserve_size, node_ar.nid);
++ reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
++ reserve_size, BOOTMEM_DEFAULT);
++ /*
++ * if reserved region is contained in the active region
++ * then done.
++ */
++ if (end_pfn <= node_ar.end_pfn)
++ break;
++
++ /*
++ * reserved region extends past the active region
++ * get next active region that contains this
++ * reserved region
++ */
++ start_pfn = node_ar.end_pfn;
++ physbase = start_pfn << PAGE_SHIFT;
++ size = size - reserve_size;
++ get_node_active_region(start_pfn, &node_ar);
+ }
+
+- sparse_memory_present_with_active_regions(nid);
+ }
++
++ for_each_online_node(nid)
++ sparse_memory_present_with_active_regions(nid);
+ }
+
+ void __init paging_init(void)
+diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
+index eb5d74e..2ca7be6 100644
+--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
++++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
+@@ -13,6 +13,7 @@
+ #include <linux/kernel.h>
+ #include <linux/initrd.h>
+ #include <linux/mtd/physmap.h>
++#include <linux/of_platform.h>
+
+ #include <asm/time.h>
+ #include <asm/prom.h>
+@@ -54,6 +55,19 @@ static struct mtd_partition linkstation_physmap_partitions[] = {
+ },
+ };
+
++static __initdata struct of_device_id of_bus_ids[] = {
++ { .type = "soc", },
++ { .compatible = "simple-bus", },
++ {},
++};
++
++static int __init declare_of_platform_devices(void)
++{
++ of_platform_bus_probe(NULL, of_bus_ids, NULL);
++ return 0;
++}
++machine_device_initcall(linkstation, declare_of_platform_devices);
++
+ static int __init linkstation_add_bridge(struct device_node *dev)
+ {
+ #ifdef CONFIG_PCI
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 00b9b4d..fdfca4f 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -1117,9 +1117,7 @@ out:
+ return rc;
+ }
+
+-static ssize_t __ref rescan_store(struct sys_device *dev,
+- struct sysdev_attribute *attr,
+- const char *buf,
++static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
+ size_t count)
+ {
+ int rc;
+@@ -1127,12 +1125,10 @@ static ssize_t __ref rescan_store(struct sys_device *dev,
+ rc = smp_rescan_cpus();
+ return rc ? rc : count;
+ }
+-static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
++static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
+ #endif /* CONFIG_HOTPLUG_CPU */
+
+-static ssize_t dispatching_show(struct sys_device *dev,
+- struct sysdev_attribute *attr,
+- char *buf)
++static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
+ {
+ ssize_t count;
+
+@@ -1142,9 +1138,8 @@ static ssize_t dispatching_show(struct sys_device *dev,
+ return count;
+ }
+
+-static ssize_t dispatching_store(struct sys_device *dev,
+- struct sysdev_attribute *attr,
+- const char *buf, size_t count)
++static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf,
++ size_t count)
+ {
+ int val, rc;
+ char delim;
+@@ -1166,7 +1161,8 @@ out:
+ put_online_cpus();
+ return rc ? rc : count;
+ }
+-static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store);
++static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show,
++ dispatching_store);
+
+ static int __init topology_init(void)
+ {
+@@ -1176,13 +1172,11 @@ static int __init topology_init(void)
+ register_cpu_notifier(&smp_cpu_nb);
+
+ #ifdef CONFIG_HOTPLUG_CPU
+- rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+- &attr_rescan.attr);
++ rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_rescan);
+ if (rc)
+ return rc;
+ #endif
+- rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+- &attr_dispatching.attr);
++ rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_dispatching);
+ if (rc)
+ return rc;
+ for_each_present_cpu(cpu) {
+diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
+index 704a3af..83abd5a 100644
+--- a/arch/sparc64/kernel/trampoline.S
++++ b/arch/sparc64/kernel/trampoline.S
+@@ -328,6 +328,12 @@ after_lock_tlb:
+
+ wrpr %g0, 0, %wstate
+
++ sethi %hi(prom_entry_lock), %g2
++1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
++ membar #StoreLoad | #StoreStore
++ brnz,pn %g1, 1b
++ nop
++
+ /* As a hack, put &init_thread_union into %g6.
+ * prom_world() loads from here to restore the %asi
+ * register.
+@@ -337,7 +343,7 @@ after_lock_tlb:
+
+ sethi %hi(is_sun4v), %o0
+ lduw [%o0 + %lo(is_sun4v)], %o0
+- brz,pt %o0, 1f
++ brz,pt %o0, 2f
+ nop
+
+ TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
+@@ -369,10 +375,10 @@ after_lock_tlb:
+ call %o1
+ add %sp, (2047 + 128), %o0
+
+- ba,pt %xcc, 2f
++ ba,pt %xcc, 3f
+ nop
+
+-1: sethi %hi(sparc64_ttable_tl0), %o0
++2: sethi %hi(sparc64_ttable_tl0), %o0
+ set prom_set_trap_table_name, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x00]
+ mov 1, %g2
+@@ -386,7 +392,11 @@ after_lock_tlb:
+ call %o1
+ add %sp, (2047 + 128), %o0
+
+-2: ldx [%l0], %g6
++3: sethi %hi(prom_entry_lock), %g2
++ stb %g0, [%g2 + %lo(prom_entry_lock)]
++ membar #StoreStore | #StoreLoad
++
++ ldx [%l0], %g6
+ ldx [%g6 + TI_TASK], %g4
+
+ mov 1, %g5
+diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
+index e12e0e4..5a7c539 100644
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -729,12 +729,12 @@ unsigned long get_wchan(struct task_struct *p)
+ if (!p || p == current || p->state==TASK_RUNNING)
+ return 0;
+ stack = (unsigned long)task_stack_page(p);
+- if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
++ if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
+ return 0;
+ fp = *(u64 *)(p->thread.sp);
+ do {
+ if (fp < (unsigned long)stack ||
+- fp > (unsigned long)stack+THREAD_SIZE)
++ fp >= (unsigned long)stack+THREAD_SIZE)
+ return 0;
+ ip = *(u64 *)(fp+8);
+ if (!in_sched_functions(ip))
+diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
+index 05191bb..0a23b57 100644
+--- a/arch/x86/kernel/rtc.c
++++ b/arch/x86/kernel/rtc.c
+@@ -223,11 +223,25 @@ static struct platform_device rtc_device = {
+ static __init int add_rtc_cmos(void)
+ {
+ #ifdef CONFIG_PNP
+- if (!pnp_platform_devices)
+- platform_device_register(&rtc_device);
+-#else
++ static const char *ids[] __initconst =
++ { "PNP0b00", "PNP0b01", "PNP0b02", };
++ struct pnp_dev *dev;
++ struct pnp_id *id;
++ int i;
++
++ pnp_for_each_dev(dev) {
++ for (id = dev->id; id; id = id->next) {
++ for (i = 0; i < ARRAY_SIZE(ids); i++) {
++ if (compare_pnp_id(id, ids[i]) != 0)
++ return 0;
++ }
++ }
++ }
++#endif
++
+ platform_device_register(&rtc_device);
+-#endif /* CONFIG_PNP */
++ dev_info(&rtc_device.dev,
++ "registered platform RTC device (no PNP device found)\n");
+ return 0;
+ }
+ device_initcall(add_rtc_cmos);
+diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
+index 2a50e0f..ac144c2 100644
+--- a/arch/x86/mm/pat.c
++++ b/arch/x86/mm/pat.c
+@@ -403,12 +403,16 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+ return 1;
+ }
+ #else
++/* This check is needed to avoid cache aliasing when PAT is enabled */
+ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+ {
+ u64 from = ((u64)pfn) << PAGE_SHIFT;
+ u64 to = from + size;
+ u64 cursor = from;
+
++ if (!pat_enabled)
++ return 1;
++
+ while (cursor < to) {
+ if (!devmem_is_allowed(pfn)) {
+ printk(KERN_INFO
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 1dfec41..59352d9 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -262,6 +262,7 @@ static int acpi_lid_send_state(struct acpi_button *button)
+ return -ENODEV;
+ /* input layer checks if event is redundant */
+ input_report_switch(button->input, SW_LID, !state);
++ input_sync(button->input);
+ return 0;
+ }
+
+@@ -285,8 +286,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
++ input_sync(input);
+ }
+- input_sync(input);
+
+ acpi_bus_generate_proc_event(button->device, event,
+ ++button->pushed);
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 13593f9..444cd9e 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1,7 +1,7 @@
+ /*
+- * ec.c - ACPI Embedded Controller Driver (v2.0)
++ * ec.c - ACPI Embedded Controller Driver (v2.1)
+ *
+- * Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
++ * Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de>
+ * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
+ * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
+ * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+@@ -26,7 +26,7 @@
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+-/* Uncomment next line to get verbose print outs*/
++/* Uncomment next line to get verbose printout */
+ /* #define DEBUG */
+
+ #include <linux/kernel.h>
+@@ -38,6 +38,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
++#include <linux/spinlock.h>
+ #include <asm/io.h>
+ #include <acpi/acpi_bus.h>
+ #include <acpi/acpi_drivers.h>
+@@ -65,22 +66,21 @@ enum ec_command {
+ ACPI_EC_COMMAND_QUERY = 0x84,
+ };
+
+-/* EC events */
+-enum ec_event {
+- ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
+- ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
+-};
+-
+ #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
+ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
+ #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
+
++#define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts
++ per one transaction */
++
+ enum {
+- EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */
+ EC_FLAGS_QUERY_PENDING, /* Query is pending */
+- EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */
++ EC_FLAGS_GPE_MODE, /* Expect GPE to be sent
++ * for status change */
+ EC_FLAGS_NO_GPE, /* Don't use GPE mode */
+- EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */
++ EC_FLAGS_GPE_STORM, /* GPE storm detected */
++ EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and
++ * OpReg are installed */
+ };
+
+ /* If we find an EC via the ECDT, we need to keep a ptr to its context */
+@@ -95,6 +95,15 @@ struct acpi_ec_query_handler {
+ u8 query_bit;
+ };
+
++struct transaction {
++ const u8 *wdata;
++ u8 *rdata;
++ unsigned short irq_count;
++ u8 command;
++ u8 wlen;
++ u8 rlen;
++};
++
+ static struct acpi_ec {
+ acpi_handle handle;
+ unsigned long gpe;
+@@ -105,9 +114,8 @@ static struct acpi_ec {
+ struct mutex lock;
+ wait_queue_head_t wait;
+ struct list_head list;
+- struct delayed_work work;
+- atomic_t irq_count;
+- u8 handlers_installed;
++ struct transaction *curr;
++ spinlock_t curr_lock;
+ } *boot_ec, *first_ec;
+
+ /*
+@@ -150,7 +158,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
+ {
+ u8 x = inb(ec->data_addr);
+ pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
+- return inb(ec->data_addr);
++ return x;
+ }
+
+ static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
+@@ -165,158 +173,172 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
+ outb(data, ec->data_addr);
+ }
+
+-static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
++static int ec_transaction_done(struct acpi_ec *ec)
+ {
+- if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
+- return 0;
+- if (event == ACPI_EC_EVENT_OBF_1) {
+- if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
+- return 1;
+- } else if (event == ACPI_EC_EVENT_IBF_0) {
+- if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
+- return 1;
+- }
+-
+- return 0;
++ unsigned long flags;
++ int ret = 0;
++ spin_lock_irqsave(&ec->curr_lock, flags);
++ if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
++ ret = 1;
++ spin_unlock_irqrestore(&ec->curr_lock, flags);
++ return ret;
+ }
+
+-static void ec_schedule_ec_poll(struct acpi_ec *ec)
++static void gpe_transaction(struct acpi_ec *ec, u8 status)
+ {
+- if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
+- schedule_delayed_work(&ec->work,
+- msecs_to_jiffies(ACPI_EC_DELAY));
++ unsigned long flags;
++ spin_lock_irqsave(&ec->curr_lock, flags);
++ if (!ec->curr)
++ goto unlock;
++ if (ec->curr->wlen > 0) {
++ if ((status & ACPI_EC_FLAG_IBF) == 0) {
++ acpi_ec_write_data(ec, *(ec->curr->wdata++));
++ --ec->curr->wlen;
++ } else
++ /* false interrupt, state didn't change */
++ ++ec->curr->irq_count;
++
++ } else if (ec->curr->rlen > 0) {
++ if ((status & ACPI_EC_FLAG_OBF) == 1) {
++ *(ec->curr->rdata++) = acpi_ec_read_data(ec);
++ --ec->curr->rlen;
++ } else
++ /* false interrupt, state didn't change */
++ ++ec->curr->irq_count;
++ }
++unlock:
++ spin_unlock_irqrestore(&ec->curr_lock, flags);
+ }
+
+-static void ec_switch_to_poll_mode(struct acpi_ec *ec)
++static int acpi_ec_wait(struct acpi_ec *ec)
+ {
++ if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
++ msecs_to_jiffies(ACPI_EC_DELAY)))
++ return 0;
++ /* missing GPEs, switch back to poll mode */
++ if (printk_ratelimit())
++ pr_info(PREFIX "missing confirmations, "
++ "switch off interrupt mode.\n");
+ set_bit(EC_FLAGS_NO_GPE, &ec->flags);
+ clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+- acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+- set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
++ return 1;
+ }
+
+-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
++static void acpi_ec_gpe_query(void *ec_cxt);
++
++static int ec_check_sci(struct acpi_ec *ec, u8 state)
+ {
+- atomic_set(&ec->irq_count, 0);
+- if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
+- likely(!force_poll)) {
+- if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
+- msecs_to_jiffies(ACPI_EC_DELAY)))
+- return 0;
+- clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- if (acpi_ec_check_status(ec, event)) {
+- /* missing GPEs, switch back to poll mode */
+- if (printk_ratelimit())
+- pr_info(PREFIX "missing confirmations, "
+- "switch off interrupt mode.\n");
+- ec_switch_to_poll_mode(ec);
+- ec_schedule_ec_poll(ec);
+- return 0;
+- }
+- } else {
+- unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+- clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- while (time_before(jiffies, delay)) {
+- if (acpi_ec_check_status(ec, event))
+- return 0;
+- msleep(1);
+- }
+- if (acpi_ec_check_status(ec,event))
++ if (state & ACPI_EC_FLAG_SCI) {
++ if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
++ return acpi_os_execute(OSL_EC_BURST_HANDLER,
++ acpi_ec_gpe_query, ec);
++ }
++ return 0;
++}
++
++static int ec_poll(struct acpi_ec *ec)
++{
++ unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
++ msleep(1);
++ while (time_before(jiffies, delay)) {
++ gpe_transaction(ec, acpi_ec_read_status(ec));
++ msleep(1);
++ if (ec_transaction_done(ec))
+ return 0;
+ }
+- pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
+- acpi_ec_read_status(ec),
+- (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
+ return -ETIME;
+ }
+
+-static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
+- const u8 * wdata, unsigned wdata_len,
+- u8 * rdata, unsigned rdata_len,
++static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
++ struct transaction *t,
+ int force_poll)
+ {
+- int result = 0;
+- set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
++ unsigned long tmp;
++ int ret = 0;
+ pr_debug(PREFIX "transaction start\n");
+- acpi_ec_write_cmd(ec, command);
+- for (; wdata_len > 0; --wdata_len) {
+- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
+- if (result) {
+- pr_err(PREFIX
+- "write_cmd timeout, command = %d\n", command);
+- goto end;
+- }
+- set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- acpi_ec_write_data(ec, *(wdata++));
++ /* disable GPE during transaction if storm is detected */
++ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++ clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
++ acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ }
+-
+- if (!rdata_len) {
+- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
+- if (result) {
+- pr_err(PREFIX
+- "finish-write timeout, command = %d\n", command);
+- goto end;
+- }
+- } else if (command == ACPI_EC_COMMAND_QUERY)
++ /* start transaction */
++ spin_lock_irqsave(&ec->curr_lock, tmp);
++ /* following two actions should be kept atomic */
++ t->irq_count = 0;
++ ec->curr = t;
++ acpi_ec_write_cmd(ec, ec->curr->command);
++ if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
+ clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+-
+- for (; rdata_len > 0; --rdata_len) {
+- result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
+- if (result) {
+- pr_err(PREFIX "read timeout, command = %d\n", command);
+- goto end;
+- }
+- /* Don't expect GPE after last read */
+- if (rdata_len > 1)
+- set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- *(rdata++) = acpi_ec_read_data(ec);
+- }
+- end:
++ spin_unlock_irqrestore(&ec->curr_lock, tmp);
++ /* if we selected poll mode or failed in GPE-mode do a poll loop */
++ if (force_poll ||
++ !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ||
++ acpi_ec_wait(ec))
++ ret = ec_poll(ec);
+ pr_debug(PREFIX "transaction end\n");
+- return result;
++ spin_lock_irqsave(&ec->curr_lock, tmp);
++ ec->curr = NULL;
++ spin_unlock_irqrestore(&ec->curr_lock, tmp);
++ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++ /* check if we received SCI during transaction */
++ ec_check_sci(ec, acpi_ec_read_status(ec));
++ /* it is safe to enable GPE outside of transaction */
++ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
++ } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
++ t->irq_count > ACPI_EC_STORM_THRESHOLD) {
++ pr_debug(PREFIX "GPE storm detected\n");
++ set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
++ }
++ return ret;
++}
++
++static int ec_check_ibf0(struct acpi_ec *ec)
++{
++ u8 status = acpi_ec_read_status(ec);
++ return (status & ACPI_EC_FLAG_IBF) == 0;
+ }
+
+-static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
+- const u8 * wdata, unsigned wdata_len,
+- u8 * rdata, unsigned rdata_len,
++static int ec_wait_ibf0(struct acpi_ec *ec)
++{
++ unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
++ /* interrupt wait manually if GPE mode is not active */
++ unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ?
++ msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1);
++ while (time_before(jiffies, delay))
++ if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout))
++ return 0;
++ return -ETIME;
++}
++
++static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
+ int force_poll)
+ {
+ int status;
+ u32 glk;
+-
+- if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
++ if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
+ return -EINVAL;
+-
+- if (rdata)
+- memset(rdata, 0, rdata_len);
+-
++ if (t->rdata)
++ memset(t->rdata, 0, t->rlen);
+ mutex_lock(&ec->lock);
+ if (ec->global_lock) {
+ status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+ if (ACPI_FAILURE(status)) {
+- mutex_unlock(&ec->lock);
+- return -ENODEV;
++ status = -ENODEV;
++ goto unlock;
+ }
+ }
+-
+- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
+- if (status) {
++ if (ec_wait_ibf0(ec)) {
+ pr_err(PREFIX "input buffer is not empty, "
+ "aborting transaction\n");
++ status = -ETIME;
+ goto end;
+ }
+-
+- status = acpi_ec_transaction_unlocked(ec, command,
+- wdata, wdata_len,
+- rdata, rdata_len,
+- force_poll);
+-
+- end:
+-
++ status = acpi_ec_transaction_unlocked(ec, t, force_poll);
++end:
+ if (ec->global_lock)
+ acpi_release_global_lock(glk);
++unlock:
+ mutex_unlock(&ec->lock);
+-
+ return status;
+ }
+
+@@ -327,21 +349,32 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
+ int acpi_ec_burst_enable(struct acpi_ec *ec)
+ {
+ u8 d;
+- return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1, 0);
++ struct transaction t = {.command = ACPI_EC_BURST_ENABLE,
++ .wdata = NULL, .rdata = &d,
++ .wlen = 0, .rlen = 1};
++
++ return acpi_ec_transaction(ec, &t, 0);
+ }
+
+ int acpi_ec_burst_disable(struct acpi_ec *ec)
+ {
+- return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0, 0);
++ struct transaction t = {.command = ACPI_EC_BURST_DISABLE,
++ .wdata = NULL, .rdata = NULL,
++ .wlen = 0, .rlen = 0};
++
++ return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
++ acpi_ec_transaction(ec, &t, 0) : 0;
+ }
+
+ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
+ {
+ int result;
+ u8 d;
++ struct transaction t = {.command = ACPI_EC_COMMAND_READ,
++ .wdata = &address, .rdata = &d,
++ .wlen = 1, .rlen = 1};
+
+- result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
+- &address, 1, &d, 1, 0);
++ result = acpi_ec_transaction(ec, &t, 0);
+ *data = d;
+ return result;
+ }
+@@ -349,8 +382,11 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
+ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
+ {
+ u8 wdata[2] = { address, data };
+- return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
+- wdata, 2, NULL, 0, 0);
++ struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
++ .wdata = wdata, .rdata = NULL,
++ .wlen = 2, .rlen = 0};
++
++ return acpi_ec_transaction(ec, &t, 0);
+ }
+
+ /*
+@@ -412,12 +448,13 @@ int ec_transaction(u8 command,
+ u8 * rdata, unsigned rdata_len,
+ int force_poll)
+ {
++ struct transaction t = {.command = command,
++ .wdata = wdata, .rdata = rdata,
++ .wlen = wdata_len, .rlen = rdata_len};
+ if (!first_ec)
+ return -ENODEV;
+
+- return acpi_ec_transaction(first_ec, command, wdata,
+- wdata_len, rdata, rdata_len,
+- force_poll);
++ return acpi_ec_transaction(first_ec, &t, force_poll);
+ }
+
+ EXPORT_SYMBOL(ec_transaction);
+@@ -426,7 +463,9 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+ {
+ int result;
+ u8 d;
+-
++ struct transaction t = {.command = ACPI_EC_COMMAND_QUERY,
++ .wdata = NULL, .rdata = &d,
++ .wlen = 0, .rlen = 1};
+ if (!ec || !data)
+ return -EINVAL;
+
+@@ -436,7 +475,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+ * bit to be cleared (and thus clearing the interrupt source).
+ */
+
+- result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1, 0);
++ result = acpi_ec_transaction(ec, &t, 0);
+ if (result)
+ return result;
+
+@@ -513,46 +552,26 @@ static void acpi_ec_gpe_query(void *ec_cxt)
+
+ static u32 acpi_ec_gpe_handler(void *data)
+ {
+- acpi_status status = AE_OK;
+ struct acpi_ec *ec = data;
+- u8 state = acpi_ec_read_status(ec);
++ u8 status;
+
+ pr_debug(PREFIX "~~~> interrupt\n");
+- atomic_inc(&ec->irq_count);
+- if (atomic_read(&ec->irq_count) > 5) {
+- pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
+- ec_switch_to_poll_mode(ec);
+- goto end;
+- }
+- clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
++ status = acpi_ec_read_status(ec);
++
++ gpe_transaction(ec, status);
++ if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+ wake_up(&ec->wait);
+
+- if (state & ACPI_EC_FLAG_SCI) {
+- if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
+- status = acpi_os_execute(OSL_EC_BURST_HANDLER,
+- acpi_ec_gpe_query, ec);
+- } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+- !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
+- in_interrupt()) {
++ ec_check_sci(ec, status);
++ if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
++ !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
+ /* this is non-query, must be confirmation */
+ if (printk_ratelimit())
+ pr_info(PREFIX "non-query interrupt received,"
+ " switching to interrupt mode\n");
+ set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+- clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+ }
+-end:
+- ec_schedule_ec_poll(ec);
+- return ACPI_SUCCESS(status) ?
+- ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+-}
+-
+-static void do_ec_poll(struct work_struct *work)
+-{
+- struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
+- atomic_set(&ec->irq_count, 0);
+- (void)acpi_ec_gpe_handler(ec);
++ return ACPI_INTERRUPT_HANDLED;
+ }
+
+ /* --------------------------------------------------------------------------
+@@ -696,8 +715,7 @@ static struct acpi_ec *make_acpi_ec(void)
+ mutex_init(&ec->lock);
+ init_waitqueue_head(&ec->wait);
+ INIT_LIST_HEAD(&ec->list);
+- INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
+- atomic_set(&ec->irq_count, 0);
++ spin_lock_init(&ec->curr_lock);
+ return ec;
+ }
+
+@@ -736,22 +754,15 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
+ return AE_CTRL_TERMINATE;
+ }
+
+-static void ec_poll_stop(struct acpi_ec *ec)
+-{
+- clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+- cancel_delayed_work(&ec->work);
+-}
+-
+ static void ec_remove_handlers(struct acpi_ec *ec)
+ {
+- ec_poll_stop(ec);
+ if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
+ ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
+ pr_err(PREFIX "failed to remove space handler\n");
+ if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
+ &acpi_ec_gpe_handler)))
+ pr_err(PREFIX "failed to remove gpe handler\n");
+- ec->handlers_installed = 0;
++ clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
+ }
+
+ static int acpi_ec_add(struct acpi_device *device)
+@@ -846,17 +857,15 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
+ static int ec_install_handlers(struct acpi_ec *ec)
+ {
+ acpi_status status;
+- if (ec->handlers_installed)
++ if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags))
+ return 0;
+ status = acpi_install_gpe_handler(NULL, ec->gpe,
+- ACPI_GPE_EDGE_TRIGGERED,
+- &acpi_ec_gpe_handler, ec);
++ ACPI_GPE_EDGE_TRIGGERED,
++ &acpi_ec_gpe_handler, ec);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+-
+ acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+-
+ status = acpi_install_address_space_handler(ec->handle,
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler,
+@@ -866,7 +875,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
+ return -ENODEV;
+ }
+
+- ec->handlers_installed = 1;
++ set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
+ return 0;
+ }
+
+@@ -887,7 +896,6 @@ static int acpi_ec_start(struct acpi_device *device)
+
+ /* EC is fully operational, allow queries */
+ clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+- ec_schedule_ec_poll(ec);
+ return ret;
+ }
+
+@@ -906,7 +914,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
+
+ int __init acpi_boot_ec_enable(void)
+ {
+- if (!boot_ec || boot_ec->handlers_installed)
++ if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags))
+ return 0;
+ if (!ec_install_handlers(boot_ec)) {
+ first_ec = boot_ec;
+diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
+index ecb6ace..25dccdf 100644
+--- a/drivers/acpi/hardware/hwsleep.c
++++ b/drivers/acpi/hardware/hwsleep.c
+@@ -612,6 +612,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
+ }
+ /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
+
++ /*
++ * Some BIOSes assume that WAK_STS will be cleared on resume and use
++ * it to determine whether the system is rebooting or resuming. Clear
++ * it for compatibility.
++ */
++ acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
++
+ acpi_gbl_system_awake_and_running = TRUE;
+
+ /* Enable power button */
+diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
+index a6b662c..755baf2 100644
+--- a/drivers/acpi/reboot.c
++++ b/drivers/acpi/reboot.c
+@@ -15,9 +15,28 @@ void acpi_reboot(void)
+
+ rr = &acpi_gbl_FADT.reset_register;
+
+- /* Is the reset register supported? */
+- if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+- rr->bit_width != 8 || rr->bit_offset != 0)
++ /*
++ * Is the ACPI reset register supported?
++ *
++ * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates
++ * whether the ACPI reset mechanism is supported.
++ *
++ * However, some boxes have this bit clear, yet a valid
++ * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only
++ * mechanism that works for them after S3.
++ *
++ * This suggests that other operating systems may not be checking
++ * the RESET_REG_SUP bit, and are using other means to decide
++ * whether to use the ACPI reboot mechanism or not.
++ *
++ * So when acpi reboot is requested,
++ * only the reset_register is checked. If the following
++ * conditions are met, it indicates that the reset register is supported.
++ * a. reset_register is not zero
++ * b. the access width is eight
++ * c. the bit_offset is zero
++ */
++ if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0)
+ return;
+
+ reset_value = acpi_gbl_FADT.reset_value;
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 79e3a8e..8228ae3 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -5259,6 +5259,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
+
+ #ifdef CONFIG_ATA_SFF
+ INIT_DELAYED_WORK(&ap->port_task, ata_pio_task);
++#else
++ INIT_DELAYED_WORK(&ap->port_task, NULL);
+ #endif
+ INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
+ INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
+diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
+index 0221c9a..35fd67d 100644
+--- a/drivers/ata/pata_it821x.c
++++ b/drivers/ata/pata_it821x.c
+@@ -557,9 +557,8 @@ static unsigned int it821x_read_id(struct ata_device *adev,
+ if (strstr(model_num, "Integrated Technology Express")) {
+ /* Set feature bits the firmware neglects */
+ id[49] |= 0x0300; /* LBA, DMA */
+- id[82] |= 0x0400; /* LBA48 */
+ id[83] &= 0x7FFF;
+- id[83] |= 0x4000; /* Word 83 is valid */
++ id[83] |= 0x4400; /* Word 83 is valid and LBA48 */
+ id[86] |= 0x0400; /* LBA48 on */
+ id[ATA_ID_MAJOR_VER] |= 0x1F;
+ }
+diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
+index 14601dc..8714c36 100644
+--- a/drivers/ata/sata_nv.c
++++ b/drivers/ata/sata_nv.c
+@@ -307,10 +307,10 @@ static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+
+ static void nv_nf2_freeze(struct ata_port *ap);
+ static void nv_nf2_thaw(struct ata_port *ap);
++static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline);
+ static void nv_ck804_freeze(struct ata_port *ap);
+ static void nv_ck804_thaw(struct ata_port *ap);
+-static int nv_hardreset(struct ata_link *link, unsigned int *class,
+- unsigned long deadline);
+ static int nv_adma_slave_config(struct scsi_device *sdev);
+ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
+ static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
+@@ -405,17 +405,8 @@ static struct scsi_host_template nv_swncq_sht = {
+ .slave_configure = nv_swncq_slave_config,
+ };
+
+-/* OSDL bz3352 reports that some nv controllers can't determine device
+- * signature reliably and nv_hardreset is implemented to work around
+- * the problem. This was reported on nf3 and it's unclear whether any
+- * other controllers are affected. However, the workaround has been
+- * applied to all variants and there isn't much to gain by trying to
+- * find out exactly which ones are affected at this point especially
+- * because NV has moved over to ahci for newer controllers.
+- */
+ static struct ata_port_operations nv_common_ops = {
+ .inherits = &ata_bmdma_port_ops,
+- .hardreset = nv_hardreset,
+ .scr_read = nv_scr_read,
+ .scr_write = nv_scr_write,
+ };
+@@ -429,12 +420,22 @@ static struct ata_port_operations nv_generic_ops = {
+ .hardreset = ATA_OP_NULL,
+ };
+
++/* OSDL bz3352 reports that nf2/3 controllers can't determine device
++ * signature reliably. Also, the following thread reports detection
++ * failure on cold boot with the standard debouncing timing.
++ *
++ * http://thread.gmane.org/gmane.linux.ide/34098
++ *
++ * Debounce with hotplug timing and request follow-up SRST.
++ */
+ static struct ata_port_operations nv_nf2_ops = {
+ .inherits = &nv_common_ops,
+ .freeze = nv_nf2_freeze,
+ .thaw = nv_nf2_thaw,
++ .hardreset = nv_nf2_hardreset,
+ };
+
++/* CK804 finally gets hardreset right */
+ static struct ata_port_operations nv_ck804_ops = {
+ .inherits = &nv_common_ops,
+ .freeze = nv_ck804_freeze,
+@@ -443,7 +444,7 @@ static struct ata_port_operations nv_ck804_ops = {
+ };
+
+ static struct ata_port_operations nv_adma_ops = {
+- .inherits = &nv_common_ops,
++ .inherits = &nv_ck804_ops,
+
+ .check_atapi_dma = nv_adma_check_atapi_dma,
+ .sff_tf_read = nv_adma_tf_read,
+@@ -467,7 +468,7 @@ static struct ata_port_operations nv_adma_ops = {
+ };
+
+ static struct ata_port_operations nv_swncq_ops = {
+- .inherits = &nv_common_ops,
++ .inherits = &nv_generic_ops,
+
+ .qc_defer = ata_std_qc_defer,
+ .qc_prep = nv_swncq_qc_prep,
+@@ -1553,6 +1554,17 @@ static void nv_nf2_thaw(struct ata_port *ap)
+ iowrite8(mask, scr_addr + NV_INT_ENABLE);
+ }
+
++static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline)
++{
++ bool online;
++ int rc;
++
++ rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
++ &online, NULL);
++ return online ? -EAGAIN : rc;
++}
++
+ static void nv_ck804_freeze(struct ata_port *ap)
+ {
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
+@@ -1605,21 +1617,6 @@ static void nv_mcp55_thaw(struct ata_port *ap)
+ ata_sff_thaw(ap);
+ }
+
+-static int nv_hardreset(struct ata_link *link, unsigned int *class,
+- unsigned long deadline)
+-{
+- int rc;
+-
+- /* SATA hardreset fails to retrieve proper device signature on
+- * some controllers. Request follow up SRST. For more info,
+- * see http://bugzilla.kernel.org/show_bug.cgi?id=3352
+- */
+- rc = sata_sff_hardreset(link, class, deadline);
+- if (rc)
+- return rc;
+- return -EAGAIN;
+-}
+-
+ static void nv_adma_error_handler(struct ata_port *ap)
+ {
+ struct nv_adma_port_priv *pp = ap->private_data;
+diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
+index 030665b..b26885f 100644
+--- a/drivers/ata/sata_promise.c
++++ b/drivers/ata/sata_promise.c
+@@ -153,6 +153,10 @@ static void pdc_freeze(struct ata_port *ap);
+ static void pdc_sata_freeze(struct ata_port *ap);
+ static void pdc_thaw(struct ata_port *ap);
+ static void pdc_sata_thaw(struct ata_port *ap);
++static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline);
++static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline);
+ static void pdc_error_handler(struct ata_port *ap);
+ static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
+ static int pdc_pata_cable_detect(struct ata_port *ap);
+@@ -186,6 +190,7 @@ static struct ata_port_operations pdc_sata_ops = {
+ .scr_read = pdc_sata_scr_read,
+ .scr_write = pdc_sata_scr_write,
+ .port_start = pdc_sata_port_start,
++ .hardreset = pdc_sata_hardreset,
+ };
+
+ /* First-generation chips need a more restrictive ->check_atapi_dma op */
+@@ -200,6 +205,7 @@ static struct ata_port_operations pdc_pata_ops = {
+ .freeze = pdc_freeze,
+ .thaw = pdc_thaw,
+ .port_start = pdc_common_port_start,
++ .softreset = pdc_pata_softreset,
+ };
+
+ static const struct ata_port_info pdc_port_info[] = {
+@@ -691,6 +697,20 @@ static void pdc_sata_thaw(struct ata_port *ap)
+ readl(host_mmio + hotplug_offset); /* flush */
+ }
+
++static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline)
++{
++ pdc_reset_port(link->ap);
++ return ata_sff_softreset(link, class, deadline);
++}
++
++static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline)
++{
++ pdc_reset_port(link->ap);
++ return sata_sff_hardreset(link, class, deadline);
++}
++
+ static void pdc_error_handler(struct ata_port *ap)
+ {
+ if (!(ap->pflags & ATA_PFLAG_FROZEN))
+diff --git a/drivers/base/sys.c b/drivers/base/sys.c
+index 75dd6e2..70499cb 100644
+--- a/drivers/base/sys.c
++++ b/drivers/base/sys.c
+@@ -488,7 +488,8 @@ ssize_t sysdev_store_ulong(struct sys_device *sysdev,
+ if (end == buf)
+ return -EINVAL;
+ *(unsigned long *)(ea->var) = new;
+- return end - buf;
++ /* Always return full write size even if we didn't consume all */
++ return size;
+ }
+ EXPORT_SYMBOL_GPL(sysdev_store_ulong);
+
+@@ -511,7 +512,8 @@ ssize_t sysdev_store_int(struct sys_device *sysdev,
+ if (end == buf || new > INT_MAX || new < INT_MIN)
+ return -EINVAL;
+ *(int *)(ea->var) = new;
+- return end - buf;
++ /* Always return full write size even if we didn't consume all */
++ return size;
+ }
+ EXPORT_SYMBOL_GPL(sysdev_store_int);
+
+diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
+index 016fdf0..f1fe749 100644
+--- a/drivers/char/agp/intel-agp.c
++++ b/drivers/char/agp/intel-agp.c
+@@ -54,8 +54,7 @@
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
+
+ #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
+@@ -63,7 +62,8 @@
+
+ #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB)
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
+
+ extern int agp_memory_reserved;
+
+@@ -525,8 +525,10 @@ static void intel_i830_init_gtt_entries(void)
+ size += 4;
+ } else if (IS_G4X) {
+ /* On 4 series hardware, GTT stolen is separate from graphics
+- * stolen, ignore it in stolen gtt entries counting */
+- size = 0;
++ * stolen, ignore it in stolen gtt entries counting. However,
++ * 4KB of the stolen memory doesn't get mapped to the GTT.
++ */
++ size = 4;
+ } else {
+ /* On previous hardware, the GTT size was just what was
+ * required to map the aperture.
+diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
+index 64e1c16..ecaf369 100644
+--- a/drivers/char/ipmi/ipmi_devintf.c
++++ b/drivers/char/ipmi/ipmi_devintf.c
+@@ -957,3 +957,4 @@ module_exit(cleanup_ipmi);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
+ MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
++MODULE_ALIAS("platform:ipmi_si");
+diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
+index 2e6d584..ed03234 100644
+--- a/drivers/firewire/fw-cdev.c
++++ b/drivers/firewire/fw-cdev.c
+@@ -720,8 +720,8 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
+ #define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff)
+ #define GET_INTERRUPT(v) (((v) >> 16) & 0x01)
+ #define GET_SKIP(v) (((v) >> 17) & 0x01)
+-#define GET_TAG(v) (((v) >> 18) & 0x02)
+-#define GET_SY(v) (((v) >> 20) & 0x04)
++#define GET_TAG(v) (((v) >> 18) & 0x03)
++#define GET_SY(v) (((v) >> 20) & 0x0f)
+ #define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
+
+ static int ioctl_queue_iso(struct client *client, void *buffer)
+@@ -913,7 +913,7 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
+ return -EFAULT;
+ }
+
+- return 0;
++ return retval;
+ }
+
+ static long
+diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
+index aaff50e..4f73537 100644
+--- a/drivers/firewire/fw-sbp2.c
++++ b/drivers/firewire/fw-sbp2.c
+@@ -172,6 +172,9 @@ struct sbp2_target {
+ int blocked; /* ditto */
+ };
+
++/* Impossible login_id, to detect logout attempt before successful login */
++#define INVALID_LOGIN_ID 0x10000
++
+ /*
+ * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
+ * provided in the config rom. Most devices do provide a value, which
+@@ -791,9 +794,20 @@ static void sbp2_release_target(struct kref *kref)
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ }
+- sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
+- SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+-
++ if (lu->login_id != INVALID_LOGIN_ID) {
++ int generation, node_id;
++ /*
++ * tgt->node_id may be obsolete here if we failed
++ * during initial login or after a bus reset where
++ * the topology changed.
++ */
++ generation = device->generation;
++ smp_rmb(); /* node_id vs. generation */
++ node_id = device->node_id;
++ sbp2_send_management_orb(lu, node_id, generation,
++ SBP2_LOGOUT_REQUEST,
++ lu->login_id, NULL);
++ }
+ fw_core_remove_address_handler(&lu->address_handler);
+ list_del(&lu->link);
+ kfree(lu);
+@@ -808,19 +822,20 @@ static void sbp2_release_target(struct kref *kref)
+
+ static struct workqueue_struct *sbp2_wq;
+
++static void sbp2_target_put(struct sbp2_target *tgt)
++{
++ kref_put(&tgt->kref, sbp2_release_target);
++}
++
+ /*
+ * Always get the target's kref when scheduling work on one its units.
+ * Each workqueue job is responsible to call sbp2_target_put() upon return.
+ */
+ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
+ {
+- if (queue_delayed_work(sbp2_wq, &lu->work, delay))
+- kref_get(&lu->tgt->kref);
+-}
+-
+-static void sbp2_target_put(struct sbp2_target *tgt)
+-{
+- kref_put(&tgt->kref, sbp2_release_target);
++ kref_get(&lu->tgt->kref);
++ if (!queue_delayed_work(sbp2_wq, &lu->work, delay))
++ sbp2_target_put(lu->tgt);
+ }
+
+ static void
+@@ -993,6 +1008,7 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
+
+ lu->tgt = tgt;
+ lu->lun = lun_entry & 0xffff;
++ lu->login_id = INVALID_LOGIN_ID;
+ lu->retries = 0;
+ lu->has_sdev = false;
+ lu->blocked = false;
+@@ -1158,7 +1174,7 @@ static int sbp2_probe(struct device *dev)
+
+ /* Do the login in a workqueue so we can easily reschedule retries. */
+ list_for_each_entry(lu, &tgt->lu_list, link)
+- sbp2_queue_work(lu, 0);
++ sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
+ return 0;
+
+ fail_tgt_put:
+diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
+index c1b8107..5e20471 100644
+--- a/drivers/firewire/fw-topology.c
++++ b/drivers/firewire/fw-topology.c
+@@ -413,7 +413,7 @@ static void
+ update_tree(struct fw_card *card, struct fw_node *root)
+ {
+ struct list_head list0, list1;
+- struct fw_node *node0, *node1;
++ struct fw_node *node0, *node1, *next1;
+ int i, event;
+
+ INIT_LIST_HEAD(&list0);
+@@ -485,7 +485,9 @@ update_tree(struct fw_card *card, struct fw_node *root)
+ }
+
+ node0 = fw_node(node0->link.next);
+- node1 = fw_node(node1->link.next);
++ next1 = fw_node(node1->link.next);
++ fw_node_put(node1);
++ node1 = next1;
+ }
+ }
+
+diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
+index 2ae1b0d..81b15ba 100644
+--- a/drivers/firewire/fw-transaction.h
++++ b/drivers/firewire/fw-transaction.h
+@@ -248,7 +248,7 @@ struct fw_card {
+ struct fw_node *local_node;
+ struct fw_node *root_node;
+ struct fw_node *irm_node;
+- int color;
++ u8 color; /* must be u8 to match the definition in struct fw_node */
+ int gap_count;
+ bool beta_repeaters_present;
+
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index b15f882..49144cb 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -247,8 +247,6 @@
+ #define USB_DEVICE_ID_LD_MACHINETEST 0x2040
+
+ #define USB_VENDOR_ID_LOGITECH 0x046d
+-#define USB_DEVICE_ID_LOGITECH_LX3 0xc044
+-#define USB_DEVICE_ID_LOGITECH_V150 0xc047
+ #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
+ #define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110
+ #define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111
+@@ -603,8 +601,6 @@ static const struct hid_blacklist {
+
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
+- { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3, HID_QUIRK_INVERT_HWHEEL },
+- { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150, HID_QUIRK_INVERT_HWHEEL },
+
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
+diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
+index c3022a0..e4c9853 100644
+--- a/drivers/i2c/busses/scx200_i2c.c
++++ b/drivers/i2c/busses/scx200_i2c.c
+@@ -81,6 +81,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
+
+ static struct i2c_adapter scx200_i2c_ops = {
+ .owner = THIS_MODULE,
++ .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
+ .id = I2C_HW_B_SCX200,
+ .algo_data = &scx200_i2c_data,
+ .name = "NatSemi SCx200 I2C",
+diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
+index b1ce10f..e32c24d 100644
+--- a/drivers/input/keyboard/atkbd.c
++++ b/drivers/input/keyboard/atkbd.c
+@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio)
+ }
+
+ /*
+- * Most special keys (Fn+F?) on Dell Latitudes do not generate release
++ * Most special keys (Fn+F?) on Dell laptops do not generate release
+ * events so we have to do it ourselves.
+ */
+-static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
++static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
+ {
+ const unsigned int forced_release_keys[] = {
+ 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
+@@ -1461,13 +1461,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
+
+ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
+ {
+- .ident = "Dell Latitude series",
++ .ident = "Dell Laptop",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
++ DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
+ },
+ .callback = atkbd_setup_fixup,
+- .driver_data = atkbd_latitude_keymap_fixup,
++ .driver_data = atkbd_dell_laptop_keymap_fixup,
+ },
+ {
+ .ident = "HP 2133",
+diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
+index 2da1a37..a92ee16 100644
+--- a/drivers/media/dvb/frontends/s5h1411.c
++++ b/drivers/media/dvb/frontends/s5h1411.c
+@@ -471,6 +471,20 @@ static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
+ }
+
++static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial)
++{
++ struct s5h1411_state *state = fe->demodulator_priv;
++ u16 val;
++
++ dprintk("%s(%d)\n", __func__, serial);
++ val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100;
++
++ if (serial == 1)
++ val |= 0x100;
++
++ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val);
++}
++
+ static int s5h1411_enable_modulation(struct dvb_frontend *fe,
+ fe_modulation_t m)
+ {
+@@ -535,7 +549,7 @@ static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
+ }
+
+-static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
++static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable)
+ {
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+@@ -551,6 +565,11 @@ static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
+ return 0;
+ }
+
++static int s5h1411_sleep(struct dvb_frontend *fe)
++{
++ return s5h1411_set_powerstate(fe, 1);
++}
++
+ static int s5h1411_register_reset(struct dvb_frontend *fe)
+ {
+ struct s5h1411_state *state = fe->demodulator_priv;
+@@ -574,9 +593,6 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe,
+
+ s5h1411_enable_modulation(fe, p->u.vsb.modulation);
+
+- /* Allow the demod to settle */
+- msleep(100);
+-
+ if (fe->ops.tuner_ops.set_params) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+@@ -587,6 +603,10 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe,
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
++ /* Issue a reset to the demod so it knows to resync against the
++ newly tuned frequency */
++ s5h1411_softreset(fe);
++
+ return 0;
+ }
+
+@@ -599,7 +619,7 @@ static int s5h1411_init(struct dvb_frontend *fe)
+
+ dprintk("%s()\n", __func__);
+
+- s5h1411_sleep(fe, 0);
++ s5h1411_set_powerstate(fe, 0);
+ s5h1411_register_reset(fe);
+
+ for (i = 0; i < ARRAY_SIZE(init_tab); i++)
+@@ -612,10 +632,10 @@ static int s5h1411_init(struct dvb_frontend *fe)
+
+ if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
+ /* Serial */
+- s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1101);
++ s5h1411_set_serialmode(fe, 1);
+ else
+ /* Parallel */
+- s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1001);
++ s5h1411_set_serialmode(fe, 0);
+
+ s5h1411_set_spectralinversion(fe, state->config->inversion);
+ s5h1411_set_if_freq(fe, state->config->vsb_if);
+@@ -863,6 +883,7 @@ static struct dvb_frontend_ops s5h1411_ops = {
+ },
+
+ .init = s5h1411_init,
++ .sleep = s5h1411_sleep,
+ .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl,
+ .set_frontend = s5h1411_set_frontend,
+ .get_frontend = s5h1411_get_frontend,
+diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+index a1252d6..273d2a1 100644
+--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
++++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+@@ -402,6 +402,10 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
+
++ /* prevent the PTSs from slowly drifting away in the generated
++ MPEG stream */
++ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC, 2, 4, 1);
++
+ return ret;
+ }
+
+diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
+index e23ce77..b46e599 100644
+--- a/drivers/net/atlx/atl1.c
++++ b/drivers/net/atlx/atl1.c
+@@ -2317,7 +2317,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
+ if (tpd != ptpd)
+ memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
+ tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+- tpd->word2 = (cpu_to_le16(buffer_info->length) &
++ tpd->word2 &= ~(TPD_BUFLEN_MASK << TPD_BUFLEN_SHIFT);
++ tpd->word2 |= (cpu_to_le16(buffer_info->length) &
+ TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
+
+ /*
+@@ -2426,8 +2427,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+ vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
+ ((vlan_tag >> 9) & 0x8);
+ ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
+- ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) <<
+- TPD_VL_TAGGED_SHIFT;
++ ptpd->word2 |= (vlan_tag & TPD_VLANTAG_MASK) <<
++ TPD_VLANTAG_SHIFT;
+ }
+
+ tso = atl1_tso(adapter, skb, ptpd);
+diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
+index a5015b1..ffa73fc 100644
+--- a/drivers/net/atlx/atl1.h
++++ b/drivers/net/atlx/atl1.h
+@@ -504,7 +504,7 @@ struct rx_free_desc {
+ #define TPD_PKTNT_MASK 0x0001
+ #define TPD_PKTINT_SHIFT 15
+ #define TPD_VLANTAG_MASK 0xFFFF
+-#define TPD_VLAN_SHIFT 16
++#define TPD_VLANTAG_SHIFT 16
+
+ /* tpd word 3 bits 0:13 */
+ #define TPD_EOP_MASK 0x0001
+diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
+index b211486..4489e58 100644
+--- a/drivers/net/bonding/bond_alb.c
++++ b/drivers/net/bonding/bond_alb.c
+@@ -167,11 +167,14 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_
+ /* clear slave from tx_hashtbl */
+ tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
+
+- index = SLAVE_TLB_INFO(slave).head;
+- while (index != TLB_NULL_INDEX) {
+- u32 next_index = tx_hash_table[index].next;
+- tlb_init_table_entry(&tx_hash_table[index], save_load);
+- index = next_index;
++ /* skip this if we've already freed the tx hash table */
++ if (tx_hash_table) {
++ index = SLAVE_TLB_INFO(slave).head;
++ while (index != TLB_NULL_INDEX) {
++ u32 next_index = tx_hash_table[index].next;
++ tlb_init_table_entry(&tx_hash_table[index], save_load);
++ index = next_index;
++ }
+ }
+
+ tlb_init_slave(slave);
+diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
+index 4b27456..50927ea 100644
+--- a/drivers/net/wireless/libertas/scan.c
++++ b/drivers/net/wireless/libertas/scan.c
+@@ -598,8 +598,8 @@ static int lbs_process_bss(struct bss_descriptor *bss,
+
+ switch (elem->id) {
+ case MFIE_TYPE_SSID:
+- bss->ssid_len = elem->len;
+- memcpy(bss->ssid, elem->data, elem->len);
++ bss->ssid_len = min_t(int, 32, elem->len);
++ memcpy(bss->ssid, elem->data, bss->ssid_len);
+ lbs_deb_scan("got SSID IE: '%s', len %u\n",
+ escape_essid(bss->ssid, bss->ssid_len),
+ bss->ssid_len);
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 36698e5..bcafbd6 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -219,7 +219,7 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
+
+ res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
+
+- if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
++ if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
+ return pci_bar_mem64;
+ return pci_bar_mem32;
+ }
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index b184367..6ad46d7 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1030,29 +1030,32 @@ static struct platform_driver cmos_platform_driver = {
+
+ static int __init cmos_init(void)
+ {
++ int retval = 0;
++
+ #ifdef CONFIG_PNP
+- if (pnp_platform_devices)
+- return pnp_register_driver(&cmos_pnp_driver);
+- else
+- return platform_driver_probe(&cmos_platform_driver,
+- cmos_platform_probe);
+-#else
+- return platform_driver_probe(&cmos_platform_driver,
+- cmos_platform_probe);
+-#endif /* CONFIG_PNP */
++ pnp_register_driver(&cmos_pnp_driver);
++#endif
++
++ if (!cmos_rtc.dev)
++ retval = platform_driver_probe(&cmos_platform_driver,
++ cmos_platform_probe);
++
++ if (retval == 0)
++ return 0;
++
++#ifdef CONFIG_PNP
++ pnp_unregister_driver(&cmos_pnp_driver);
++#endif
++ return retval;
+ }
+ module_init(cmos_init);
+
+ static void __exit cmos_exit(void)
+ {
+ #ifdef CONFIG_PNP
+- if (pnp_platform_devices)
+- pnp_unregister_driver(&cmos_pnp_driver);
+- else
+- platform_driver_unregister(&cmos_platform_driver);
+-#else
++ pnp_unregister_driver(&cmos_pnp_driver);
++#endif
+ platform_driver_unregister(&cmos_platform_driver);
+-#endif /* CONFIG_PNP */
+ }
+ module_exit(cmos_exit);
+
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index e5e7d78..b7ea69c 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -1047,7 +1047,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
+ good_bytes = sd_completed_bytes(SCpnt);
+ break;
+ case RECOVERED_ERROR:
+- case NO_SENSE:
+ /* Inform the user, but make sure that it's not treated
+ * as a hard error.
+ */
+@@ -1056,6 +1055,15 @@ static int sd_done(struct scsi_cmnd *SCpnt)
+ memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ good_bytes = scsi_bufflen(SCpnt);
+ break;
++ case NO_SENSE:
++ /* This indicates a false check condition, so ignore it. An
++ * unknown amount of data was transferred so treat it as an
++ * error.
++ */
++ scsi_print_sense("sd", SCpnt);
++ SCpnt->result = 0;
++ memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
++ break;
+ case ABORTED_COMMAND:
+ if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */
+ scsi_print_result(SCpnt);
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 706f3e6..7a4ccf5 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -106,6 +106,9 @@ static DEFINE_SPINLOCK(hcd_root_hub_lock);
+ /* used when updating an endpoint's URB list */
+ static DEFINE_SPINLOCK(hcd_urb_list_lock);
+
++/* used to protect against unlinking URBs after the device is gone */
++static DEFINE_SPINLOCK(hcd_urb_unlink_lock);
++
+ /* wait queue for synchronous unlinks */
+ DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue);
+
+@@ -1377,10 +1380,25 @@ static int unlink1(struct usb_hcd *hcd, struct urb *urb, int status)
+ int usb_hcd_unlink_urb (struct urb *urb, int status)
+ {
+ struct usb_hcd *hcd;
+- int retval;
++ int retval = -EIDRM;
++ unsigned long flags;
+
+- hcd = bus_to_hcd(urb->dev->bus);
+- retval = unlink1(hcd, urb, status);
++ /* Prevent the device and bus from going away while
++ * the unlink is carried out. If they are already gone
++ * then urb->use_count must be 0, since disconnected
++ * devices can't have any active URBs.
++ */
++ spin_lock_irqsave(&hcd_urb_unlink_lock, flags);
++ if (atomic_read(&urb->use_count) > 0) {
++ retval = 0;
++ usb_get_dev(urb->dev);
++ }
++ spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags);
++ if (retval == 0) {
++ hcd = bus_to_hcd(urb->dev->bus);
++ retval = unlink1(hcd, urb, status);
++ usb_put_dev(urb->dev);
++ }
+
+ if (retval == 0)
+ retval = -EINPROGRESS;
+@@ -1529,6 +1547,17 @@ void usb_hcd_disable_endpoint(struct usb_device *udev,
+ hcd->driver->endpoint_disable(hcd, ep);
+ }
+
++/* Protect against drivers that try to unlink URBs after the device
++ * is gone, by waiting until all unlinks for @udev are finished.
++ * Since we don't currently track URBs by device, simply wait until
++ * nothing is running in the locked region of usb_hcd_unlink_urb().
++ */
++void usb_hcd_synchronize_unlinks(struct usb_device *udev)
++{
++ spin_lock_irq(&hcd_urb_unlink_lock);
++ spin_unlock_irq(&hcd_urb_unlink_lock);
++}
++
+ /*-------------------------------------------------------------------------*/
+
+ /* called in any context */
+diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
+index 2dcde61..9465e70 100644
+--- a/drivers/usb/core/hcd.h
++++ b/drivers/usb/core/hcd.h
+@@ -232,6 +232,7 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev,
+ struct usb_host_endpoint *ep);
+ extern void usb_hcd_disable_endpoint(struct usb_device *udev,
+ struct usb_host_endpoint *ep);
++extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
+ extern int usb_hcd_get_frame_number(struct usb_device *udev);
+
+ extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 875de9a..769f80f 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1349,6 +1349,7 @@ void usb_disconnect(struct usb_device **pdev)
+ */
+ dev_dbg (&udev->dev, "unregistering device\n");
+ usb_disable_device(udev, 0);
++ usb_hcd_synchronize_unlinks(udev);
+
+ usb_unlock_device(udev);
+
+diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
+index 47111e8..db72269 100644
+--- a/drivers/usb/core/urb.c
++++ b/drivers/usb/core/urb.c
+@@ -465,6 +465,12 @@ EXPORT_SYMBOL_GPL(usb_submit_urb);
+ * indicating that the request has been canceled (rather than any other
+ * code).
+ *
++ * Drivers should not call this routine or related routines, such as
++ * usb_kill_urb() or usb_unlink_anchored_urbs(), after their disconnect
++ * method has returned. The disconnect function should synchronize with
++ * a driver's I/O routines to insure that all URB-related activity has
++ * completed before it returns.
++ *
+ * This request is always asynchronous. Success is indicated by
+ * returning -EINPROGRESS, at which time the URB will probably not yet
+ * have been given back to the device driver. When it is eventually
+@@ -541,6 +547,9 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
+ * This routine may not be used in an interrupt context (such as a bottom
+ * half or a completion handler), or when holding a spinlock, or in other
+ * situations where the caller can't schedule().
++ *
++ * This routine should not be called by a driver after its disconnect
++ * method has returned.
+ */
+ void usb_kill_urb(struct urb *urb)
+ {
+@@ -568,6 +577,9 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);
+ *
+ * this allows all outstanding URBs to be killed starting
+ * from the back of the queue
++ *
++ * This routine should not be called by a driver after its disconnect
++ * method has returned.
+ */
+ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
+ {
+@@ -597,6 +609,9 @@ EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
+ * from the back of the queue. This function is asynchronous.
+ * The unlinking is just tiggered. It may happen after this
+ * function has returned.
++ *
++ * This routine should not be called by a driver after its disconnect
++ * method has returned.
+ */
+ void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
+ {
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index cd15547..061df9b 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1745,6 +1745,15 @@ UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201,
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
++/* Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
++ * JMicron responds to USN and several other SCSI ioctls with a
++ * residue that causes subsequent I/O requests to fail. */
++UNUSUAL_DEV( 0x152d, 0x2329, 0x0100, 0x0100,
++ "JMicron",
++ "USB to ATA/ATAPI Bridge",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_IGNORE_RESIDUE ),
++
+ /* Reported by Robert Schedel <r.schedel@yahoo.de>
+ * Note: this is a 'super top' device like the above 14cd/6600 device */
+ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
+diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
+index d128a25..ea30afc 100644
+--- a/fs/hfsplus/bitmap.c
++++ b/fs/hfsplus/bitmap.c
+@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
+ mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
+ mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
+ page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
++ if (IS_ERR(page)) {
++ start = size;
++ goto out;
++ }
+ pptr = kmap(page);
+ curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
+ i = offset % 32;
+@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
+ break;
+ page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
+ NULL);
++ if (IS_ERR(page)) {
++ start = size;
++ goto out;
++ }
+ curr = pptr = kmap(page);
+ if ((size ^ offset) / PAGE_CACHE_BITS)
+ end = pptr + PAGE_CACHE_BITS / 32;
+@@ -120,6 +128,10 @@ found:
+ offset += PAGE_CACHE_BITS;
+ page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
+ NULL);
++ if (IS_ERR(page)) {
++ start = size;
++ goto out;
++ }
+ pptr = kmap(page);
+ curr = pptr;
+ end = pptr + PAGE_CACHE_BITS / 32;
+diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
+index ba117c4..f6874ac 100644
+--- a/fs/hfsplus/catalog.c
++++ b/fs/hfsplus/catalog.c
+@@ -168,6 +168,11 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
+ return -EIO;
+ }
+
++ if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
++ printk(KERN_ERR "hfs: catalog name length corrupted\n");
++ return -EIO;
++ }
++
+ hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
+ &tmp.thread.nodeName);
+ return hfs_brec_find(fd);
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 3d9120c..6bfb849 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1286,7 +1286,9 @@ struct task_struct {
+ atomic_t fs_excl; /* holding fs exclusive resources */
+ struct rcu_head rcu;
+
+- /*
++ struct list_head *scm_work_list;
++
++/*
+ * cache last used pipe for splice
+ */
+ struct pipe_inode_info *splice_pipe;
+diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
+index bb46e76..408f743 100644
+--- a/include/math-emu/op-common.h
++++ b/include/math-emu/op-common.h
+@@ -139,18 +139,27 @@ do { \
+ if (X##_e <= _FP_WFRACBITS_##fs) \
+ { \
+ _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
+- _FP_ROUND(wc, X); \
+ if (_FP_FRAC_HIGH_##fs(X) \
+ & (_FP_OVERFLOW_##fs >> 1)) \
+ { \
+ X##_e = 1; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+- FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ } \
+ else \
+ { \
+- X##_e = 0; \
+- _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
++ _FP_ROUND(wc, X); \
++ if (_FP_FRAC_HIGH_##fs(X) \
++ & (_FP_OVERFLOW_##fs >> 1)) \
++ { \
++ X##_e = 1; \
++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
++ FP_SET_EXCEPTION(FP_EX_INEXACT); \
++ } \
++ else \
++ { \
++ X##_e = 0; \
++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
++ } \
+ } \
+ if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
+ (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 06df126..33e9986 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -14,8 +14,9 @@
+
+ struct scm_fp_list
+ {
+- int count;
+- struct file *fp[SCM_MAX_FD];
++ struct list_head list;
++ int count;
++ struct file *fp[SCM_MAX_FD];
+ };
+
+ struct scm_cookie
+diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
+index e8ab096..8178724 100644
+--- a/kernel/sched_clock.c
++++ b/kernel/sched_clock.c
+@@ -118,13 +118,13 @@ static u64 __update_sched_clock(struct sched_clock_data *scd, u64 now)
+
+ /*
+ * scd->clock = clamp(scd->tick_gtod + delta,
+- * max(scd->tick_gtod, scd->clock),
+- * scd->tick_gtod + TICK_NSEC);
++ * max(scd->tick_gtod, scd->clock),
++ * max(scd->clock, scd->tick_gtod + TICK_NSEC));
+ */
+
+ clock = scd->tick_gtod + delta;
+ min_clock = wrap_max(scd->tick_gtod, scd->clock);
+- max_clock = scd->tick_gtod + TICK_NSEC;
++ max_clock = wrap_max(scd->clock, scd->tick_gtod + TICK_NSEC);
+
+ clock = wrap_max(clock, min_clock);
+ clock = wrap_min(clock, max_clock);
+diff --git a/kernel/sched_features.h b/kernel/sched_features.h
+index 9353ca7..c4c88ae 100644
+--- a/kernel/sched_features.h
++++ b/kernel/sched_features.h
+@@ -5,7 +5,7 @@ SCHED_FEAT(START_DEBIT, 1)
+ SCHED_FEAT(AFFINE_WAKEUPS, 1)
+ SCHED_FEAT(CACHE_HOT_BUDDY, 1)
+ SCHED_FEAT(SYNC_WAKEUPS, 1)
+-SCHED_FEAT(HRTICK, 1)
++SCHED_FEAT(HRTICK, 0)
+ SCHED_FEAT(DOUBLE_TICK, 0)
+ SCHED_FEAT(ASYM_GRAN, 1)
+ SCHED_FEAT(LB_BIAS, 1)
+diff --git a/net/core/scm.c b/net/core/scm.c
+index 10f5c65..ab242cc 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -75,6 +75,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
+ if (!fpl)
+ return -ENOMEM;
+ *fplp = fpl;
++ INIT_LIST_HEAD(&fpl->list);
+ fpl->count = 0;
+ }
+ fpp = &fpl->fp[fpl->count];
+@@ -106,9 +107,25 @@ void __scm_destroy(struct scm_cookie *scm)
+
+ if (fpl) {
+ scm->fp = NULL;
+- for (i=fpl->count-1; i>=0; i--)
+- fput(fpl->fp[i]);
+- kfree(fpl);
++ if (current->scm_work_list) {
++ list_add_tail(&fpl->list, current->scm_work_list);
++ } else {
++ LIST_HEAD(work_list);
++
++ current->scm_work_list = &work_list;
++
++ list_add(&fpl->list, &work_list);
++ while (!list_empty(&work_list)) {
++ fpl = list_first_entry(&work_list, struct scm_fp_list, list);
++
++ list_del(&fpl->list);
++ for (i=fpl->count-1; i>=0; i--)
++ fput(fpl->fp[i]);
++ kfree(fpl);
++ }
++
++ current->scm_work_list = NULL;
++ }
+ }
+ }
+
+@@ -284,6 +301,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
+
+ new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
+ if (new_fpl) {
++ INIT_LIST_HEAD(&new_fpl->list);
+ for (i=fpl->count-1; i>=0; i--)
+ get_file(fpl->fp[i]);
+ memcpy(new_fpl, fpl, sizeof(*fpl));
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 8165f5a..d083f9a 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -357,6 +357,17 @@ struct tcp_out_options {
+ __u32 tsval, tsecr; /* need to include OPTION_TS */
+ };
+
++/* Beware: Something in the Internet is very sensitive to the ordering of
++ * TCP options, we learned this through the hard way, so be careful here.
++ * Luckily we can at least blame others for their non-compliance but from
++ * inter-operatibility perspective it seems that we're somewhat stuck with
++ * the ordering which we have been using if we want to keep working with
++ * those broken things (not that it currently hurts anybody as there isn't
++ * particular reason why the ordering would need to be changed).
++ *
++ * At least SACK_PERM as the first option is known to lead to a disaster
++ * (but it may well be that other scenarios fail similarly).
++ */
+ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
+ const struct tcp_out_options *opts,
+ __u8 **md5_hash) {
+@@ -371,6 +382,12 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
+ *md5_hash = NULL;
+ }
+
++ if (unlikely(opts->mss)) {
++ *ptr++ = htonl((TCPOPT_MSS << 24) |
++ (TCPOLEN_MSS << 16) |
++ opts->mss);
++ }
++
+ if (likely(OPTION_TS & opts->options)) {
+ if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) {
+ *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
+@@ -387,12 +404,6 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
+ *ptr++ = htonl(opts->tsecr);
+ }
+
+- if (unlikely(opts->mss)) {
+- *ptr++ = htonl((TCPOPT_MSS << 24) |
+- (TCPOLEN_MSS << 16) |
+- opts->mss);
+- }
+-
+ if (unlikely(OPTION_SACK_ADVERTISE & opts->options &&
+ !(OPTION_TS & opts->options))) {
+ *ptr++ = htonl((TCPOPT_NOP << 24) |
+@@ -2266,6 +2277,11 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
+ }
+
+ memset(&opts, 0, sizeof(opts));
++#ifdef CONFIG_SYN_COOKIES
++ if (unlikely(req->cookie_ts))
++ TCP_SKB_CB(skb)->when = cookie_init_timestamp(req);
++ else
++#endif
+ TCP_SKB_CB(skb)->when = tcp_time_stamp;
+ tcp_header_size = tcp_synack_options(sk, req,
+ dst_metric(dst, RTAX_ADVMSS),
+@@ -2292,11 +2308,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
+
+ /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
+ th->window = htons(min(req->rcv_wnd, 65535U));
+-#ifdef CONFIG_SYN_COOKIES
+- if (unlikely(req->cookie_ts))
+- TCP_SKB_CB(skb)->when = cookie_init_timestamp(req);
+- else
+-#endif
+ tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
+ th->doff = (tcp_header_size >> 2);
+ TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 10e22fd..245cbc5 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1087,7 +1087,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
+ *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+ *topt++ = htonl(tcp_time_stamp);
+- *topt = htonl(ts);
++ *topt++ = htonl(ts);
+ }
+
+ #ifdef CONFIG_TCP_MD5SIG
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index ec0a083..700ae9e 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -319,6 +319,7 @@ struct Qdisc_ops noop_qdisc_ops __read_mostly = {
+
+ static struct netdev_queue noop_netdev_queue = {
+ .qdisc = &noop_qdisc,
++ .qdisc_sleeping = &noop_qdisc,
+ };
+
+ struct Qdisc noop_qdisc = {
+@@ -344,6 +345,7 @@ static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
+ static struct Qdisc noqueue_qdisc;
+ static struct netdev_queue noqueue_netdev_queue = {
+ .qdisc = &noqueue_qdisc,
++ .qdisc_sleeping = &noqueue_qdisc,
+ };
+
+ static struct Qdisc noqueue_qdisc = {
+diff --git a/scripts/package/mkspec b/scripts/package/mkspec
+index ffd61fe..62c5ffd 100755
+--- a/scripts/package/mkspec
++++ b/scripts/package/mkspec
+@@ -64,8 +64,10 @@ fi
+ echo "%install"
+ echo "%ifarch ia64"
+ echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules'
++echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
+ echo "%else"
+ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
++echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
+ echo "%endif"
+
+ echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install'
+@@ -92,5 +94,6 @@ echo "%files"
+ echo '%defattr (-, root, root)'
+ echo "%dir /lib/modules"
+ echo "/lib/modules/$KERNELRELEASE"
++echo "/lib/firmware"
+ echo "/boot/*"
+ echo ""
+diff --git a/security/commoncap.c b/security/commoncap.c
+index e4c4b3f..378172b 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -279,10 +279,10 @@ static int get_file_caps(struct linux_binprm *bprm)
+ struct vfs_cap_data vcaps;
+ struct inode *inode;
+
+- if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
+- bprm_clear_caps(bprm);
++ bprm_clear_caps(bprm);
++
++ if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
+ return 0;
+- }
+
+ dentry = dget(bprm->file->f_dentry);
+ inode = dentry->d_inode;
+diff --git a/sound/core/control.c b/sound/core/control.c
+index 281b2e2..236bbb1 100644
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -1427,12 +1427,12 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
+ cardnum = card->number;
+ snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
+
+- down_read(&card->controls_rwsem);
++ read_lock(&card->ctl_files_rwlock);
+ list_for_each_entry(ctl, &card->ctl_files, list) {
+ wake_up(&ctl->change_sleep);
+ kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
+ }
+- up_read(&card->controls_rwsem);
++ read_unlock(&card->ctl_files_rwlock);
+
+ if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
+ card, -1)) < 0)
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 1c53e33..0f014b1 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -45,6 +45,7 @@
+ #include <linux/slab.h>
+ #include <linux/pci.h>
+ #include <linux/mutex.h>
++#include <linux/reboot.h>
+ #include <sound/core.h>
+ #include <sound/initval.h>
+ #include "hda_codec.h"
+@@ -385,6 +386,9 @@ struct azx {
+
+ /* for pending irqs */
+ struct work_struct irq_pending_work;
++
++ /* reboot notifier (for mysterious hangup problem at power-down) */
++ struct notifier_block reboot_notifier;
+ };
+
+ /* driver types */
+@@ -1890,12 +1894,36 @@ static int azx_resume(struct pci_dev *pci)
+
+
+ /*
++ * reboot notifier for hang-up problem at power-down
++ */
++static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
++{
++ struct azx *chip = container_of(nb, struct azx, reboot_notifier);
++ azx_stop_chip(chip);
++ return NOTIFY_OK;
++}
++
++static void azx_notifier_register(struct azx *chip)
++{
++ chip->reboot_notifier.notifier_call = azx_halt;
++ register_reboot_notifier(&chip->reboot_notifier);
++}
++
++static void azx_notifier_unregister(struct azx *chip)
++{
++ if (chip->reboot_notifier.notifier_call)
++ unregister_reboot_notifier(&chip->reboot_notifier);
++}
++
++/*
+ * destructor
+ */
+ static int azx_free(struct azx *chip)
+ {
+ int i;
+
++ azx_notifier_unregister(chip);
++
+ if (chip->initialized) {
+ azx_clear_irq_pending(chip);
+ for (i = 0; i < chip->num_streams; i++)
+@@ -2250,6 +2278,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
+ pci_set_drvdata(pci, card);
+ chip->running = 1;
+ power_down_all_codecs(chip);
++ azx_notifier_register(chip);
+
+ dev++;
+ return err;
|
[-]
[+]
|
Added |
patches.kernel.org.tar.bz2/patch-2.6.27.5-6
^
|
@@ -0,0 +1,2240 @@
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: Linux 2.6.27.6
+
+Upstream 2.6.27.6 release from kernel.org
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
+index 8244c64..48d80d9 100644
+--- a/Documentation/cciss.txt
++++ b/Documentation/cciss.txt
+@@ -26,6 +26,8 @@ This driver is known to work with the following cards:
+ * SA P410i
+ * SA P411
+ * SA P812
++ * SA P712m
++ * SA P711m
+
+ Detecting drive failures:
+ -------------------------
+diff --git a/Makefile b/Makefile
+index 4ea7b3c..1ea4453 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 27
+-EXTRAVERSION = .5
++EXTRAVERSION = .6
+ NAME = Trembling Tortoise
+
+ # *DOCUMENTATION*
+diff --git a/arch/arm/mach-pxa/include/mach/reset.h b/arch/arm/mach-pxa/include/mach/reset.h
+index 9489a48..7b8842c 100644
+--- a/arch/arm/mach-pxa/include/mach/reset.h
++++ b/arch/arm/mach-pxa/include/mach/reset.h
+@@ -10,9 +10,12 @@
+ extern unsigned int reset_status;
+ extern void clear_reset_status(unsigned int mask);
+
+-/*
+- * register GPIO as reset generator
++/**
++ * init_gpio_reset() - register GPIO as reset generator
++ *
++ * @gpio - gpio nr
++ * @output - set gpio as out/low instead of input during normal work
+ */
+-extern int init_gpio_reset(int gpio);
++extern int init_gpio_reset(int gpio, int output);
+
+ #endif /* __ASM_ARCH_RESET_H */
+diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
+index 9996c61..1b236a6 100644
+--- a/arch/arm/mach-pxa/reset.c
++++ b/arch/arm/mach-pxa/reset.c
+@@ -20,7 +20,7 @@ static void do_hw_reset(void);
+
+ static int reset_gpio = -1;
+
+-int init_gpio_reset(int gpio)
++int init_gpio_reset(int gpio, int output)
+ {
+ int rc;
+
+@@ -30,9 +30,12 @@ int init_gpio_reset(int gpio)
+ goto out;
+ }
+
+- rc = gpio_direction_input(gpio);
++ if (output)
++ rc = gpio_direction_output(gpio, 0);
++ else
++ rc = gpio_direction_input(gpio);
+ if (rc) {
+- printk(KERN_ERR "Can't configure reset_gpio for input\n");
++ printk(KERN_ERR "Can't configure reset_gpio\n");
+ gpio_free(gpio);
+ goto out;
+ }
+diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
+index b569f3b..32cee4c 100644
+--- a/arch/arm/mach-pxa/spitz.c
++++ b/arch/arm/mach-pxa/spitz.c
+@@ -548,7 +548,7 @@ static void spitz_restart(char mode)
+
+ static void __init common_init(void)
+ {
+- init_gpio_reset(SPITZ_GPIO_ON_RESET);
++ init_gpio_reset(SPITZ_GPIO_ON_RESET, 1);
+ pm_power_off = spitz_poweroff;
+ arm_pm_restart = spitz_restart;
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index 9f3ef9e..130e37e 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -781,7 +781,7 @@ static void __init tosa_init(void)
+ gpio_set_wake(MFP_PIN_GPIO1, 1);
+ /* We can't pass to gpio-keys since it will drop the Reset altfunc */
+
+- init_gpio_reset(TOSA_GPIO_ON_RESET);
++ init_gpio_reset(TOSA_GPIO_ON_RESET, 0);
+
+ pm_power_off = tosa_poweroff;
+ arm_pm_restart = tosa_restart;
+diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
+index 158bd96..99ec030 100644
+--- a/arch/arm/mm/cache-xsc3l2.c
++++ b/arch/arm/mm/cache-xsc3l2.c
+@@ -97,7 +97,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
+ /*
+ * Clean and invalidate partial last cache line.
+ */
+- if (end & (CACHE_LINE_SIZE - 1)) {
++ if (start < end && (end & (CACHE_LINE_SIZE - 1))) {
+ xsc3_l2_clean_pa(end & ~(CACHE_LINE_SIZE - 1));
+ xsc3_l2_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
+ end &= ~(CACHE_LINE_SIZE - 1);
+@@ -106,7 +106,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
+ /*
+ * Invalidate all full cache lines between 'start' and 'end'.
+ */
+- while (start != end) {
++ while (start < end) {
+ xsc3_l2_inv_pa(start);
+ start += CACHE_LINE_SIZE;
+ }
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index ed92864..552d2b7 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1059,6 +1059,26 @@ config HIGHPTE
+ low memory. Setting this option will put user-space page table
+ entries in high memory.
+
++config X86_RESERVE_LOW_64K
++ bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
++ default y
++ help
++ Reserve the first 64K of physical RAM on BIOSes that are known
++ to potentially corrupt that memory range. A numbers of BIOSes are
++ known to utilize this area during suspend/resume, so it must not
++ be used by the kernel.
++
++ Set this to N if you are absolutely sure that you trust the BIOS
++ to get all its memory reservations and usages right.
++
++ If you have doubts about the BIOS (e.g. suspend/resume does not
++ work or there's kernel crashes after certain hardware hotplug
++ events) and it's not AMI or Phoenix, then you might want to enable
++ X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
++ corruption patterns.
++
++ Say Y if unsure.
++
+ config MATH_EMULATION
+ bool
+ prompt "Math emulation" if X86_32
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 9838f25..64b5c42 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -578,6 +578,39 @@ static struct x86_quirks default_x86_quirks __initdata;
+
+ struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
+
++static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
++{
++ printk(KERN_NOTICE
++ "%s detected: BIOS may corrupt low RAM, working it around.\n",
++ d->ident);
++
++ e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
++ sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
++
++ return 0;
++}
++
++/* List of systems that have known low memory corruption BIOS problems */
++static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
++#ifdef CONFIG_X86_RESERVE_LOW_64K
++ {
++ .callback = dmi_low_memory_corruption,
++ .ident = "AMI BIOS",
++ .matches = {
++ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
++ },
++ },
++ {
++ .callback = dmi_low_memory_corruption,
++ .ident = "Phoenix BIOS",
++ .matches = {
++ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
++ },
++ },
++#endif
++ {}
++};
++
+ /*
+ * Determine if we were loaded by an EFI loader. If so, then we have also been
+ * passed the efi memmap, systab, etc., so we should use these data structures
+@@ -699,6 +732,10 @@ void __init setup_arch(char **cmdline_p)
+
+ finish_e820_parsing();
+
++ dmi_scan_machine();
++
++ dmi_check_system(bad_bios_dmi_table);
++
+ #ifdef CONFIG_X86_32
+ probe_roms();
+ #endif
+@@ -781,8 +818,6 @@ void __init setup_arch(char **cmdline_p)
+ vsmp_init();
+ #endif
+
+- dmi_scan_machine();
+-
+ io_delay_init();
+
+ /*
+@@ -885,3 +920,5 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ #endif
+ }
++
++
+diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
+index 8f98e9d..de850e9 100644
+--- a/arch/x86/kernel/tsc.c
++++ b/arch/x86/kernel/tsc.c
+@@ -639,10 +639,6 @@ void __init tsc_init(void)
+ cpu_khz = calibrate_cpu();
+ #endif
+
+- lpj = ((u64)tsc_khz * 1000);
+- do_div(lpj, HZ);
+- lpj_fine = lpj;
+-
+ printk("Detected %lu.%03lu MHz processor.\n",
+ (unsigned long)cpu_khz / 1000,
+ (unsigned long)cpu_khz % 1000);
+@@ -662,6 +658,10 @@ void __init tsc_init(void)
+ /* now allow native_sched_clock() to use rdtsc */
+ tsc_disabled = 0;
+
++ lpj = ((u64)tsc_khz * 1000);
++ do_div(lpj, HZ);
++ lpj_fine = lpj;
++
+ use_tsc_delay();
+ /* Check and install the TSC clocksource */
+ dmi_check_system(bad_tsc_dmi_table);
+diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
+index 7d2edf1..25d2161 100644
+--- a/drivers/acpi/dock.c
++++ b/drivers/acpi/dock.c
+@@ -604,14 +604,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
+ static void dock_notify(acpi_handle handle, u32 event, void *data)
+ {
+ struct dock_station *ds = data;
++ struct acpi_device *tmp;
+
+ switch (event) {
+ case ACPI_NOTIFY_BUS_CHECK:
+- if (!dock_in_progress(ds) && dock_present(ds)) {
++ if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
++ &tmp)) {
+ begin_dock(ds);
+ dock(ds);
+ if (!dock_present(ds)) {
+ printk(KERN_ERR PREFIX "Unable to dock!\n");
++ complete_dock(ds);
+ break;
+ }
+ atomic_notifier_call_chain(&dock_notifier_list,
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index c1db2f2..2c4ccec 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -604,9 +604,6 @@ void ata_scsi_error(struct Scsi_Host *host)
+ if (ata_ncq_enabled(dev))
+ ehc->saved_ncq_enabled |= 1 << devno;
+ }
+-
+- /* set last reset timestamp to some time in the past */
+- ehc->last_reset = jiffies - 60 * HZ;
+ }
+
+ ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
+@@ -2209,17 +2206,21 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ if (link->flags & ATA_LFLAG_NO_SRST)
+ softreset = NULL;
+
+- now = jiffies;
+- deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
+- if (time_before(now, deadline))
+- schedule_timeout_uninterruptible(deadline - now);
++ /* make sure each reset attemp is at least COOL_DOWN apart */
++ if (ehc->i.flags & ATA_EHI_DID_RESET) {
++ now = jiffies;
++ WARN_ON(time_after(ehc->last_reset, now));
++ deadline = ata_deadline(ehc->last_reset,
++ ATA_EH_RESET_COOL_DOWN);
++ if (time_before(now, deadline))
++ schedule_timeout_uninterruptible(deadline - now);
++ }
+
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags |= ATA_PFLAG_RESETTING;
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
+- ehc->last_reset = jiffies;
+
+ ata_link_for_each_dev(dev, link) {
+ /* If we issue an SRST then an ATA drive (not ATAPI)
+@@ -2285,7 +2286,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ /*
+ * Perform reset
+ */
+- ehc->last_reset = jiffies;
+ if (ata_is_host_link(link))
+ ata_eh_freeze_port(ap);
+
+@@ -2297,6 +2297,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ reset == softreset ? "soft" : "hard");
+
+ /* mark that this EH session started with reset */
++ ehc->last_reset = jiffies;
+ if (reset == hardreset)
+ ehc->i.flags |= ATA_EHI_DID_HARDRESET;
+ else
+@@ -2404,7 +2405,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
+
+ /* reset successful, schedule revalidation */
+ ata_eh_done(link, NULL, ATA_EH_RESET);
+- ehc->last_reset = jiffies;
++ ehc->last_reset = jiffies; /* update to completion time */
+ ehc->i.action |= ATA_EH_REVALIDATE;
+
+ rc = 0;
+diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
+index b73116e..2ac91b8 100644
+--- a/drivers/block/cciss.c
++++ b/drivers/block/cciss.c
+@@ -96,6 +96,8 @@ static const struct pci_device_id cciss_pci_device_id[] = {
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B},
+ {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
+ {0,}
+@@ -133,6 +135,8 @@ static struct board_type products[] = {
+ {0x3245103C, "Smart Array P410i", &SA5_access},
+ {0x3247103C, "Smart Array P411", &SA5_access},
+ {0x3249103C, "Smart Array P812", &SA5_access},
++ {0x324A103C, "Smart Array P712m", &SA5_access},
++ {0x324B103C, "Smart Array P711m", &SA5_access},
+ {0xFFFF103C, "Unknown Smart Array", &SA5_access},
+ };
+
+@@ -1365,6 +1369,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
+ disk->first_minor = drv_index << NWD_SHIFT;
+ disk->fops = &cciss_fops;
+ disk->private_data = &h->drv[drv_index];
++ disk->driverfs_dev = &h->pdev->dev;
+
+ /* Set up queue information */
+ blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
+@@ -3403,7 +3408,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
+ int i;
+ int j = 0;
+ int rc;
+- int dac;
++ int dac, return_code;
++ InquiryData_struct *inq_buff = NULL;
+
+ i = alloc_cciss_hba();
+ if (i < 0)
+@@ -3509,6 +3515,25 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
+ /* Turn the interrupts on so we can service requests */
+ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
+
++ /* Get the firmware version */
++ inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
++ if (inq_buff == NULL) {
++ printk(KERN_ERR "cciss: out of memory\n");
++ goto clean4;
++ }
++
++ return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff,
++ sizeof(InquiryData_struct), 0, 0 , 0, TYPE_CMD);
++ if (return_code == IO_OK) {
++ hba[i]->firm_ver[0] = inq_buff->data_byte[32];
++ hba[i]->firm_ver[1] = inq_buff->data_byte[33];
++ hba[i]->firm_ver[2] = inq_buff->data_byte[34];
++ hba[i]->firm_ver[3] = inq_buff->data_byte[35];
++ } else { /* send command failed */
++ printk(KERN_WARNING "cciss: unable to determine firmware"
++ " version of controller\n");
++ }
++
+ cciss_procinit(i);
+
+ hba[i]->cciss_max_sectors = 2048;
+@@ -3519,6 +3544,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
+ return 1;
+
+ clean4:
++ kfree(inq_buff);
+ #ifdef CONFIG_CISS_SCSI_TAPE
+ kfree(hba[i]->scsi_rejects.complete);
+ #endif
+diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
+index 09c1434..f5d2e54 100644
+--- a/drivers/block/cpqarray.c
++++ b/drivers/block/cpqarray.c
+@@ -567,7 +567,12 @@ static int __init cpqarray_init(void)
+ num_cntlrs_reg++;
+ }
+
+- return(num_cntlrs_reg);
++ if (num_cntlrs_reg)
++ return 0;
++ else {
++ pci_unregister_driver(&cpqarray_pci_driver);
++ return -ENODEV;
++ }
+ }
+
+ /* Function to find the first free pointer into our hba[] array */
+diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
+index ec249d2..d883e1b 100644
+--- a/drivers/dca/dca-core.c
++++ b/drivers/dca/dca-core.c
+@@ -270,6 +270,6 @@ static void __exit dca_exit(void)
+ dca_sysfs_exit();
+ }
+
+-module_init(dca_init);
++subsys_initcall(dca_init);
+ module_exit(dca_exit);
+
+diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
+index bc8c6e3..3f4db54 100644
+--- a/drivers/dma/ioat_dma.c
++++ b/drivers/dma/ioat_dma.c
+@@ -519,7 +519,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
+ }
+
+ hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+- if (new->async_tx.callback) {
++ if (first->async_tx.callback) {
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+ if (first != new) {
+ /* move callback into to last desc */
+@@ -611,7 +611,7 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx)
+ }
+
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+- if (new->async_tx.callback) {
++ if (first->async_tx.callback) {
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+ if (first != new) {
+ /* move callback into to last desc */
+@@ -801,6 +801,12 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
+ struct ioat_desc_sw *desc, *_desc;
+ int in_use_descs = 0;
+
++ /* Before freeing channel resources first check
++ * if they have been previously allocated for this channel.
++ */
++ if (ioat_chan->desccount == 0)
++ return;
++
+ tasklet_disable(&ioat_chan->cleanup_task);
+ ioat_dma_memcpy_cleanup(ioat_chan);
+
+@@ -863,6 +869,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
+ ioat_chan->last_completion = ioat_chan->completion_addr = 0;
+ ioat_chan->pending = 0;
+ ioat_chan->dmacount = 0;
++ ioat_chan->desccount = 0;
+ ioat_chan->watchdog_completion = 0;
+ ioat_chan->last_compl_desc_addr_hw = 0;
+ ioat_chan->watchdog_tcp_cookie =
+diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c
+index e763d72..9f6fe46 100644
+--- a/drivers/dma/iovlock.c
++++ b/drivers/dma/iovlock.c
+@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ int nr_iovecs = 0;
+ int iovec_len_used = 0;
+ int iovec_pages_used = 0;
+- long err;
+
+ /* don't pin down non-user-based iovecs */
+ if (segment_eq(get_fs(), KERNEL_DS))
+@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ local_list = kmalloc(sizeof(*local_list)
+ + (nr_iovecs * sizeof (struct dma_page_list))
+ + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
+- if (!local_list) {
+- err = -ENOMEM;
++ if (!local_list)
+ goto out;
+- }
+
+ /* list of pages starts right after the page list array */
+ pages = (struct page **) &local_list->page_list[nr_iovecs];
+
++ local_list->nr_iovecs = 0;
++
+ for (i = 0; i < nr_iovecs; i++) {
+ struct dma_page_list *page_list = &local_list->page_list[i];
+
+ len -= iov[i].iov_len;
+
+- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
+- err = -EFAULT;
++ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len))
+ goto unpin;
+- }
+
+ page_list->nr_pages = num_pages_spanned(&iov[i]);
+ page_list->base_address = iov[i].iov_base;
+@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ NULL);
+ up_read(¤t->mm->mmap_sem);
+
+- if (ret != page_list->nr_pages) {
+- err = -ENOMEM;
++ if (ret != page_list->nr_pages)
+ goto unpin;
+- }
+
+ local_list->nr_iovecs = i + 1;
+ }
+@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ unpin:
+ dma_unpin_iovec_pages(local_list);
+ out:
+- return ERR_PTR(err);
++ return NULL;
+ }
+
+ void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)
+diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
+index c40f040..8c030d9 100644
+--- a/drivers/hid/hidraw.c
++++ b/drivers/hid/hidraw.c
+@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
+ if (!dev->hid_output_raw_report)
+ return -ENODEV;
+
+- if (count > HID_MIN_BUFFER_SIZE) {
++ if (count > HID_MAX_BUFFER_SIZE) {
+ printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
+ task_pid_nr(current));
+ return -EINVAL;
+diff --git a/drivers/md/linear.c b/drivers/md/linear.c
+index b1eebf8..a58a19e 100644
+--- a/drivers/md/linear.c
++++ b/drivers/md/linear.c
+@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
+
+ min_spacing = conf->array_sectors / 2;
+ sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
++ if (min_spacing == 0)
++ min_spacing = 1;
+
+ /* min_spacing is the minimum spacing that will fit the hash
+ * table in one PAGE. This may be much smaller than needed.
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index e34cd0e..941576d 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1132,7 +1132,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
+ if (!enough(conf))
+ return -EINVAL;
+
+- if (rdev->raid_disk)
++ if (rdev->raid_disk >= 0)
+ first = last = rdev->raid_disk;
+
+ if (rdev->saved_raid_disk >= 0 &&
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 044d84e..f7284b9 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
+ (card->host->ios.clock / 1000);
+
+ if (data->flags & MMC_DATA_WRITE)
+- limit_us = 250000;
++ /*
++ * The limit is really 250 ms, but that is
++ * insufficient for some crappy cards.
++ */
++ limit_us = 300000;
+ else
+ limit_us = 100000;
+
+diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
+index a972cc6..9e7a236 100644
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -362,19 +362,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
+ /* Set the default CFI lock/unlock addresses */
+ cfi->addr_unlock1 = 0x555;
+ cfi->addr_unlock2 = 0x2aa;
+- /* Modify the unlock address if we are in compatibility mode */
+- if ( /* x16 in x8 mode */
+- ((cfi->device_type == CFI_DEVICETYPE_X8) &&
+- (cfi->cfiq->InterfaceDesc ==
+- CFI_INTERFACE_X8_BY_X16_ASYNC)) ||
+- /* x32 in x16 mode */
+- ((cfi->device_type == CFI_DEVICETYPE_X16) &&
+- (cfi->cfiq->InterfaceDesc ==
+- CFI_INTERFACE_X16_BY_X32_ASYNC)))
+- {
+- cfi->addr_unlock1 = 0xaaa;
+- cfi->addr_unlock2 = 0x555;
+- }
+
+ } /* CFI mode */
+ else if (cfi->cfi_mode == CFI_MODE_JEDEC) {
+diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
+index f84ab61..2f3f2f7 100644
+--- a/drivers/mtd/chips/jedec_probe.c
++++ b/drivers/mtd/chips/jedec_probe.c
+@@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base,
+ * several first banks can contain 0x7f instead of actual ID
+ */
+ do {
+- uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8),
+- cfi_interleave(cfi),
+- cfi->device_type);
++ uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
+ mask = (1 << (cfi->device_type * 8)) - 1;
+ result = map_read(map, base + ofs);
+ bank++;
+@@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct map_info *map, uint32_t base,
+ {
+ map_word result;
+ unsigned long mask;
+- u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type);
++ u32 ofs = cfi_build_cmd_addr(1, map, cfi);
+ mask = (1 << (cfi->device_type * 8)) -1;
+ result = map_read(map, base + ofs);
+ return result.x[0] & mask;
+@@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
+
+ }
+ /* Ensure the unlock addresses we try stay inside the map */
+- probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, cfi_interleave(cfi), cfi->device_type);
+- probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, cfi_interleave(cfi), cfi->device_type);
++ probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, map, cfi);
++ probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, map, cfi);
+ if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
+ ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
+ goto retry;
+diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
+index 0f6f974..39c17bb 100644
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -370,8 +370,9 @@ struct ring_info {
+ };
+
+ enum features {
+- RTL_FEATURE_WOL = (1 << 0),
+- RTL_FEATURE_MSI = (1 << 1),
++ RTL_FEATURE_WOL = (1 << 0),
++ RTL_FEATURE_MSI = (1 << 1),
++ RTL_FEATURE_GMII = (1 << 2),
+ };
+
+ struct rtl8169_private {
+@@ -406,13 +407,15 @@ struct rtl8169_private {
+ struct vlan_group *vlgrp;
+ #endif
+ int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
+- void (*get_settings)(struct net_device *, struct ethtool_cmd *);
++ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
+ void (*phy_reset_enable)(void __iomem *);
+ void (*hw_start)(struct net_device *);
+ unsigned int (*phy_reset_pending)(void __iomem *);
+ unsigned int (*link_ok)(void __iomem *);
+ struct delayed_work task;
+ unsigned features;
++
++ struct mii_if_info mii;
+ };
+
+ MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
+@@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
+ return value;
+ }
+
++static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
++ int val)
++{
++ struct rtl8169_private *tp = netdev_priv(dev);
++ void __iomem *ioaddr = tp->mmio_addr;
++
++ mdio_write(ioaddr, location, val);
++}
++
++static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
++{
++ struct rtl8169_private *tp = netdev_priv(dev);
++ void __iomem *ioaddr = tp->mmio_addr;
++
++ return mdio_read(ioaddr, location);
++}
++
+ static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
+ {
+ RTL_W16(IntrMask, 0x0000);
+@@ -720,9 +740,13 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
+
+ auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+
+- if ((tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+- (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
+- /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
++ if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
++ (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
++ (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
++ /*
++ * Wake up the PHY.
++ * Vendor specific (0x1f) and reserved (0x0e) MII registers.
++ */
+ mdio_write(ioaddr, 0x1f, 0x0000);
+ mdio_write(ioaddr, 0x0e, 0x0000);
+ }
+@@ -850,7 +874,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
+
+ #endif
+
+-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
++static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+@@ -867,65 +891,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+
+ cmd->speed = SPEED_1000;
+ cmd->duplex = DUPLEX_FULL; /* Always set */
++
++ return 0;
+ }
+
+-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
++static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+- void __iomem *ioaddr = tp->mmio_addr;
+- u8 status;
+-
+- cmd->supported = SUPPORTED_10baseT_Half |
+- SUPPORTED_10baseT_Full |
+- SUPPORTED_100baseT_Half |
+- SUPPORTED_100baseT_Full |
+- SUPPORTED_1000baseT_Full |
+- SUPPORTED_Autoneg |
+- SUPPORTED_TP;
+-
+- cmd->autoneg = 1;
+- cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
+-
+- if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
+- cmd->advertising |= ADVERTISED_10baseT_Half;
+- if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
+- cmd->advertising |= ADVERTISED_10baseT_Full;
+- if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
+- cmd->advertising |= ADVERTISED_100baseT_Half;
+- if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
+- cmd->advertising |= ADVERTISED_100baseT_Full;
+- if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
+- cmd->advertising |= ADVERTISED_1000baseT_Full;
+-
+- status = RTL_R8(PHYstatus);
+-
+- if (status & _1000bpsF)
+- cmd->speed = SPEED_1000;
+- else if (status & _100bps)
+- cmd->speed = SPEED_100;
+- else if (status & _10bps)
+- cmd->speed = SPEED_10;
+-
+- if (status & TxFlowCtrl)
+- cmd->advertising |= ADVERTISED_Asym_Pause;
+- if (status & RxFlowCtrl)
+- cmd->advertising |= ADVERTISED_Pause;
+-
+- cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
+- DUPLEX_FULL : DUPLEX_HALF;
++
++ return mii_ethtool_gset(&tp->mii, cmd);
+ }
+
+ static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+ unsigned long flags;
++ int rc;
+
+ spin_lock_irqsave(&tp->lock, flags);
+
+- tp->get_settings(dev, cmd);
++ rc = tp->get_settings(dev, cmd);
+
+ spin_unlock_irqrestore(&tp->lock, flags);
+- return 0;
++ return rc;
+ }
+
+ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+@@ -1513,7 +1501,7 @@ static const struct rtl_cfg_info {
+ unsigned int align;
+ u16 intr_event;
+ u16 napi_event;
+- unsigned msi;
++ unsigned features;
+ } rtl_cfg_infos [] = {
+ [RTL_CFG_0] = {
+ .hw_start = rtl_hw_start_8169,
+@@ -1522,7 +1510,7 @@ static const struct rtl_cfg_info {
+ .intr_event = SYSErr | LinkChg | RxOverflow |
+ RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+ .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+- .msi = 0
++ .features = RTL_FEATURE_GMII
+ },
+ [RTL_CFG_1] = {
+ .hw_start = rtl_hw_start_8168,
+@@ -1531,7 +1519,7 @@ static const struct rtl_cfg_info {
+ .intr_event = SYSErr | LinkChg | RxOverflow |
+ TxErr | TxOK | RxOK | RxErr,
+ .napi_event = TxErr | TxOK | RxOK | RxOverflow,
+- .msi = RTL_FEATURE_MSI
++ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
+ },
+ [RTL_CFG_2] = {
+ .hw_start = rtl_hw_start_8101,
+@@ -1540,7 +1528,7 @@ static const struct rtl_cfg_info {
+ .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
+ RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+ .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+- .msi = RTL_FEATURE_MSI
++ .features = RTL_FEATURE_MSI
+ }
+ };
+
+@@ -1552,7 +1540,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
+ u8 cfg2;
+
+ cfg2 = RTL_R8(Config2) & ~MSIEnable;
+- if (cfg->msi) {
++ if (cfg->features & RTL_FEATURE_MSI) {
+ if (pci_enable_msi(pdev)) {
+ dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
+ } else {
+@@ -1578,6 +1566,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
+ const unsigned int region = cfg->region;
+ struct rtl8169_private *tp;
++ struct mii_if_info *mii;
+ struct net_device *dev;
+ void __iomem *ioaddr;
+ unsigned int i;
+@@ -1602,6 +1591,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ tp->pci_dev = pdev;
+ tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
+
++ mii = &tp->mii;
++ mii->dev = dev;
++ mii->mdio_read = rtl_mdio_read;
++ mii->mdio_write = rtl_mdio_write;
++ mii->phy_id_mask = 0x1f;
++ mii->reg_num_mask = 0x1f;
++ mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
++
+ /* enable device (incl. PCI PM wakeup and hotplug setup) */
+ rc = pci_enable_device(pdev);
+ if (rc < 0) {
+@@ -2099,8 +2096,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
+
+ RTL_R8(IntrMask);
+
+- RTL_W32(RxMissed, 0);
+-
+ rtl_set_rx_mode(dev);
+
+ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+@@ -2143,8 +2138,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
+
+ RTL_R8(IntrMask);
+
+- RTL_W32(RxMissed, 0);
+-
+ rtl_set_rx_mode(dev);
+
+ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+@@ -2922,6 +2915,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
+ return work_done;
+ }
+
++static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
++{
++ struct rtl8169_private *tp = netdev_priv(dev);
++
++ if (tp->mac_version > RTL_GIGA_MAC_VER_06)
++ return;
++
++ dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
++ RTL_W32(RxMissed, 0);
++}
++
+ static void rtl8169_down(struct net_device *dev)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+@@ -2939,9 +2943,7 @@ core_down:
+
+ rtl8169_asic_down(ioaddr);
+
+- /* Update the error counts. */
+- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+- RTL_W32(RxMissed, 0);
++ rtl8169_rx_missed(dev, ioaddr);
+
+ spin_unlock_irq(&tp->lock);
+
+@@ -3063,8 +3065,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
+
+ if (netif_running(dev)) {
+ spin_lock_irqsave(&tp->lock, flags);
+- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+- RTL_W32(RxMissed, 0);
++ rtl8169_rx_missed(dev, ioaddr);
+ spin_unlock_irqrestore(&tp->lock, flags);
+ }
+
+@@ -3089,8 +3090,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
+
+ rtl8169_asic_down(ioaddr);
+
+- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+- RTL_W32(RxMissed, 0);
++ rtl8169_rx_missed(dev, ioaddr);
+
+ spin_unlock_irq(&tp->lock);
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+index 17d4f31..c479ee2 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
++++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+@@ -129,6 +129,13 @@ struct iwl5000_shared {
+ __le32 padding2;
+ } __attribute__ ((packed));
+
++/* calibrations defined for 5000 */
++/* defines the order in which results should be sent to the runtime uCode */
++enum iwl5000_calib {
++ IWL5000_CALIB_LO,
++ IWL5000_CALIB_TX_IQ,
++ IWL5000_CALIB_TX_IQ_PERD,
++};
+
+ #endif /* __iwl_5000_hw_h__ */
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
+index b08036a..79ff288 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
+@@ -445,48 +445,6 @@ static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
+ sizeof(cal_cmd), &cal_cmd);
+ }
+
+-static int iwl5000_send_calib_results(struct iwl_priv *priv)
+-{
+- int ret = 0;
+-
+- struct iwl_host_cmd hcmd = {
+- .id = REPLY_PHY_CALIBRATION_CMD,
+- .meta.flags = CMD_SIZE_HUGE,
+- };
+-
+- if (priv->calib_results.lo_res) {
+- hcmd.len = priv->calib_results.lo_res_len;
+- hcmd.data = priv->calib_results.lo_res;
+- ret = iwl_send_cmd_sync(priv, &hcmd);
+-
+- if (ret)
+- goto err;
+- }
+-
+- if (priv->calib_results.tx_iq_res) {
+- hcmd.len = priv->calib_results.tx_iq_res_len;
+- hcmd.data = priv->calib_results.tx_iq_res;
+- ret = iwl_send_cmd_sync(priv, &hcmd);
+-
+- if (ret)
+- goto err;
+- }
+-
+- if (priv->calib_results.tx_iq_perd_res) {
+- hcmd.len = priv->calib_results.tx_iq_perd_res_len;
+- hcmd.data = priv->calib_results.tx_iq_perd_res;
+- ret = iwl_send_cmd_sync(priv, &hcmd);
+-
+- if (ret)
+- goto err;
+- }
+-
+- return 0;
+-err:
+- IWL_ERROR("Error %d\n", ret);
+- return ret;
+-}
+-
+ static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
+ {
+ struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
+@@ -511,33 +469,30 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
+ int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
+-
+- iwl_free_calib_results(priv);
++ int index;
+
+ /* reduce the size of the length field itself */
+ len -= 4;
+
++ /* Define the order in which the results will be sent to the runtime
++ * uCode. iwl_send_calib_results sends them in a row according to their
++ * index. We sort them here */
+ switch (hdr->op_code) {
+ case IWL5000_PHY_CALIBRATE_LO_CMD:
+- priv->calib_results.lo_res = kzalloc(len, GFP_ATOMIC);
+- priv->calib_results.lo_res_len = len;
+- memcpy(priv->calib_results.lo_res, pkt->u.raw, len);
++ index = IWL5000_CALIB_LO;
+ break;
+ case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
+- priv->calib_results.tx_iq_res = kzalloc(len, GFP_ATOMIC);
+- priv->calib_results.tx_iq_res_len = len;
+- memcpy(priv->calib_results.tx_iq_res, pkt->u.raw, len);
++ index = IWL5000_CALIB_TX_IQ;
+ break;
+ case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
+- priv->calib_results.tx_iq_perd_res = kzalloc(len, GFP_ATOMIC);
+- priv->calib_results.tx_iq_perd_res_len = len;
+- memcpy(priv->calib_results.tx_iq_perd_res, pkt->u.raw, len);
++ index = IWL5000_CALIB_TX_IQ_PERD;
+ break;
+ default:
+ IWL_ERROR("Unknown calibration notification %d\n",
+ hdr->op_code);
+ return;
+ }
++ iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
+ }
+
+ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
+@@ -832,7 +787,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
+ iwl5000_send_Xtal_calib(priv);
+
+ if (priv->ucode_type == UCODE_RT)
+- iwl5000_send_calib_results(priv);
++ iwl_send_calib_results(priv);
+
+ return 0;
+ }
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
+index e01f048..72a6743 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -2090,7 +2090,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
+ iwl4965_error_recovery(priv);
+
+ iwl_power_update_mode(priv, 1);
+- ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+
+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+ iwl4965_set_mode(priv, priv->iw_mode);
+@@ -2342,6 +2341,7 @@ static void iwl_bg_alive_start(struct work_struct *data)
+ mutex_lock(&priv->mutex);
+ iwl_alive_start(priv);
+ mutex_unlock(&priv->mutex);
++ ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+ }
+
+ static void iwl4965_bg_rf_kill(struct work_struct *work)
+@@ -2486,6 +2486,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+ if (!priv->vif || !priv->is_open)
+ return;
+
++ iwl_power_cancel_timeout(priv);
+ iwl_scan_cancel_timeout(priv, 200);
+
+ conf = ieee80211_get_hw_conf(priv->hw);
+@@ -2503,8 +2504,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+
+ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+
+- if (priv->current_ht_config.is_ht)
+- iwl_set_rxon_ht(priv, &priv->current_ht_config);
++ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+
+ iwl_set_rxon_chain(priv);
+ priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
+@@ -2550,10 +2550,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+ break;
+ }
+
+- /* Enable Rx differential gain and sensitivity calibrations */
+- iwl_chain_noise_reset(priv);
+- priv->start_calib = 1;
+-
+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+ priv->assoc_station_added = 1;
+
+@@ -2561,7 +2557,12 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+ iwl_activate_qos(priv, 0);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+- iwl_power_update_mode(priv, 0);
++ iwl_power_enable_management(priv);
++
++ /* Enable Rx differential gain and sensitivity calibrations */
++ iwl_chain_noise_reset(priv);
++ priv->start_calib = 1;
++
+ /* we have just associated, don't start scan too early */
+ priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
+ }
+@@ -3212,18 +3213,26 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
+ goto out_unlock;
+ }
+
+- /* we don't schedule scan within next_scan_jiffies period */
++ /* We don't schedule scan within next_scan_jiffies period.
++ * Avoid scanning during possible EAPOL exchange, return
++ * success immediately.
++ */
+ if (priv->next_scan_jiffies &&
+- time_after(priv->next_scan_jiffies, jiffies)) {
+- rc = -EAGAIN;
++ time_after(priv->next_scan_jiffies, jiffies)) {
++ IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
++ queue_work(priv->workqueue, &priv->scan_completed);
++ rc = 0;
+ goto out_unlock;
+ }
+ /* if we just finished scan ask for delay */
+- if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
+- IWL_DELAY_NEXT_SCAN, jiffies)) {
+- rc = -EAGAIN;
++ if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
++ time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
++ IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
++ queue_work(priv->workqueue, &priv->scan_completed);
++ rc = 0;
+ goto out_unlock;
+ }
++
+ if (len) {
+ IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
+ iwl_escape_essid(ssid, len), (int)len);
+@@ -3546,6 +3555,16 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
+ /* Per mac80211.h: This is only used in IBSS mode... */
+ if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+
++ /* switch to CAM during association period.
++ * the ucode will block any association/authentication
++ * frome during assiciation period if it can not hear
++ * the AP because of PM. the timer enable PM back is
++ * association do not complete
++ */
++ if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
++ IEEE80211_CHAN_RADAR))
++ iwl_power_disable_management(priv, 3000);
++
+ IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+ mutex_unlock(&priv->mutex);
+ return;
+@@ -4083,6 +4102,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
+ /* FIXME : remove when resolved PENDING */
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ iwl_setup_scan_deferred_work(priv);
++ iwl_setup_power_deferred_work(priv);
+
+ if (priv->cfg->ops->lib->setup_deferred_work)
+ priv->cfg->ops->lib->setup_deferred_work(priv);
+@@ -4102,6 +4122,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
+
+ cancel_delayed_work_sync(&priv->init_alive_start);
+ cancel_delayed_work(&priv->scan_check);
++ cancel_delayed_work_sync(&priv->set_power_save);
+ cancel_delayed_work(&priv->alive_start);
+ cancel_work_sync(&priv->beacon_update);
+ del_timer_sync(&priv->statistics_periodic);
+@@ -4204,13 +4225,13 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
+
+ pci_set_master(pdev);
+
+- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
++ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
+ if (!err)
+- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
++ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
+ if (err) {
+- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
++ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (!err)
+- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
++ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ /* both attempts failed: */
+ if (err) {
+ printk(KERN_WARNING "%s: No suitable DMA available.\n",
+diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
+index ef49440..35fb4a4 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
++++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
+@@ -66,6 +66,66 @@
+ #include "iwl-core.h"
+ #include "iwl-calib.h"
+
++/*****************************************************************************
++ * INIT calibrations framework
++ *****************************************************************************/
++
++ int iwl_send_calib_results(struct iwl_priv *priv)
++{
++ int ret = 0;
++ int i = 0;
++
++ struct iwl_host_cmd hcmd = {
++ .id = REPLY_PHY_CALIBRATION_CMD,
++ .meta.flags = CMD_SIZE_HUGE,
++ };
++
++ for (i = 0; i < IWL_CALIB_MAX; i++)
++ if (priv->calib_results[i].buf) {
++ hcmd.len = priv->calib_results[i].buf_len;
++ hcmd.data = priv->calib_results[i].buf;
++ ret = iwl_send_cmd_sync(priv, &hcmd);
++ if (ret)
++ goto err;
++ }
++
++ return 0;
++err:
++ IWL_ERROR("Error %d iteration %d\n", ret, i);
++ return ret;
++}
++EXPORT_SYMBOL(iwl_send_calib_results);
++
++int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
++{
++ if (res->buf_len != len) {
++ kfree(res->buf);
++ res->buf = kzalloc(len, GFP_ATOMIC);
++ }
++ if (unlikely(res->buf == NULL))
++ return -ENOMEM;
++
++ res->buf_len = len;
++ memcpy(res->buf, buf, len);
++ return 0;
++}
++EXPORT_SYMBOL(iwl_calib_set);
++
++void iwl_calib_free_results(struct iwl_priv *priv)
++{
++ int i;
++
++ for (i = 0; i < IWL_CALIB_MAX; i++) {
++ kfree(priv->calib_results[i].buf);
++ priv->calib_results[i].buf = NULL;
++ priv->calib_results[i].buf_len = 0;
++ }
++}
++
++/*****************************************************************************
++ * RUNTIME calibrations framework
++ *****************************************************************************/
++
+ /* "false alarms" are signals that our DSP tries to lock onto,
+ * but then determines that they are either noise, or transmissions
+ * from a distant wireless network (also "noise", really) that get
+diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
+index 80f2f84..1383fd1 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -646,8 +646,14 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ u32 val;
+
+- if (!ht_info->is_ht)
++ if (!ht_info->is_ht) {
++ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
++ RXON_FLG_CHANNEL_MODE_PURE_40_MSK |
++ RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
++ RXON_FLG_FAT_PROT_MSK |
++ RXON_FLG_HT_PROT_MSK);
+ return;
++ }
+
+ /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */
+ if (iwl_is_fat_tx_allowed(priv, NULL))
+@@ -950,22 +956,6 @@ err:
+ }
+ EXPORT_SYMBOL(iwl_init_drv);
+
+-void iwl_free_calib_results(struct iwl_priv *priv)
+-{
+- kfree(priv->calib_results.lo_res);
+- priv->calib_results.lo_res = NULL;
+- priv->calib_results.lo_res_len = 0;
+-
+- kfree(priv->calib_results.tx_iq_res);
+- priv->calib_results.tx_iq_res = NULL;
+- priv->calib_results.tx_iq_res_len = 0;
+-
+- kfree(priv->calib_results.tx_iq_perd_res);
+- priv->calib_results.tx_iq_perd_res = NULL;
+- priv->calib_results.tx_iq_perd_res_len = 0;
+-}
+-EXPORT_SYMBOL(iwl_free_calib_results);
+-
+ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
+ {
+ int ret = 0;
+@@ -993,10 +983,9 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
+ }
+ EXPORT_SYMBOL(iwl_set_tx_power);
+
+-
+ void iwl_uninit_drv(struct iwl_priv *priv)
+ {
+- iwl_free_calib_results(priv);
++ iwl_calib_free_results(priv);
+ iwlcore_free_geos(priv);
+ iwl_free_channel_map(priv);
+ kfree(priv->scan);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
+index 64f139e..51b36b1 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-core.h
++++ b/drivers/net/wireless/iwlwifi/iwl-core.h
+@@ -186,7 +186,6 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
+ void iwl_hw_detect(struct iwl_priv *priv);
+
+ void iwl_clear_stations_table(struct iwl_priv *priv);
+-void iwl_free_calib_results(struct iwl_priv *priv);
+ void iwl_reset_qos(struct iwl_priv *priv);
+ void iwl_set_rxon_chain(struct iwl_priv *priv);
+ int iwl_set_rxon_channel(struct iwl_priv *priv,
+@@ -291,6 +290,13 @@ int iwl_scan_initiate(struct iwl_priv *priv);
+ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+ void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+
++/*******************************************************************************
++ * Calibrations - implemented in iwl-calib.c
++ ******************************************************************************/
++int iwl_send_calib_results(struct iwl_priv *priv);
++int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
++void iwl_calib_free_results(struct iwl_priv *priv);
++
+ /*****************************************************
+ * S e n d i n g H o s t C o m m a n d s *
+ *****************************************************/
+diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
+index cdfb343..09bdf8e 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
+@@ -745,13 +745,10 @@ struct statistics_general_data {
+ u32 beacon_energy_c;
+ };
+
+-struct iwl_calib_results {
+- void *tx_iq_res;
+- void *tx_iq_perd_res;
+- void *lo_res;
+- u32 tx_iq_res_len;
+- u32 tx_iq_perd_res_len;
+- u32 lo_res_len;
++/* Opaque calibration results */
++struct iwl_calib_result {
++ void *buf;
++ size_t buf_len;
+ };
+
+ enum ucode_type {
+@@ -813,6 +810,7 @@ enum {
+
+
+ #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
++#define IWL_CALIB_MAX 3
+
+ struct iwl_priv {
+
+@@ -857,7 +855,7 @@ struct iwl_priv {
+ s32 last_temperature;
+
+ /* init calibration results */
+- struct iwl_calib_results calib_results;
++ struct iwl_calib_result calib_results[IWL_CALIB_MAX];
+
+ /* Scan related variables */
+ unsigned long last_scan_jiffies;
+@@ -1047,6 +1045,7 @@ struct iwl_priv {
+
+ struct tasklet_struct irq_tasklet;
+
++ struct delayed_work set_power_save;
+ struct delayed_work init_alive_start;
+ struct delayed_work alive_start;
+ struct delayed_work scan_check;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
+index a099c9e..ae60bfd 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-power.c
++++ b/drivers/net/wireless/iwlwifi/iwl-power.c
+@@ -324,7 +324,7 @@ EXPORT_SYMBOL(iwl_power_update_mode);
+ * this will be usefull for rate scale to disable PM during heavy
+ * Tx/Rx activities
+ */
+-int iwl_power_disable_management(struct iwl_priv *priv)
++int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
+ {
+ u16 prev_mode;
+ int ret = 0;
+@@ -337,6 +337,11 @@ int iwl_power_disable_management(struct iwl_priv *priv)
+ ret = iwl_power_update_mode(priv, 0);
+ priv->power_data.power_disabled = 1;
+ priv->power_data.user_power_setting = prev_mode;
++ cancel_delayed_work(&priv->set_power_save);
++ if (ms)
++ queue_delayed_work(priv->workqueue, &priv->set_power_save,
++ msecs_to_jiffies(ms));
++
+
+ return ret;
+ }
+@@ -431,3 +436,35 @@ int iwl_power_temperature_change(struct iwl_priv *priv)
+ return ret;
+ }
+ EXPORT_SYMBOL(iwl_power_temperature_change);
++
++static void iwl_bg_set_power_save(struct work_struct *work)
++{
++ struct iwl_priv *priv = container_of(work,
++ struct iwl_priv, set_power_save.work);
++ IWL_DEBUG(IWL_DL_STATE, "update power\n");
++
++ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
++ return;
++
++ mutex_lock(&priv->mutex);
++
++ /* on starting association we disable power managment
++ * until association, if association failed then this
++ * timer will expire and enable PM again.
++ */
++ if (!iwl_is_associated(priv))
++ iwl_power_enable_management(priv);
++
++ mutex_unlock(&priv->mutex);
++}
++void iwl_setup_power_deferred_work(struct iwl_priv *priv)
++{
++ INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
++}
++EXPORT_SYMBOL(iwl_setup_power_deferred_work);
++
++void iwl_power_cancel_timeout(struct iwl_priv *priv)
++{
++ cancel_delayed_work(&priv->set_power_save);
++}
++EXPORT_SYMBOL(iwl_power_cancel_timeout);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
+index abcbbf9..aa99f36 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-power.h
++++ b/drivers/net/wireless/iwlwifi/iwl-power.h
+@@ -78,8 +78,10 @@ struct iwl_power_mgr {
+ u8 power_disabled; /* flag to disable using power saving level */
+ };
+
++void iwl_setup_power_deferred_work(struct iwl_priv *priv);
++void iwl_power_cancel_timeout(struct iwl_priv *priv);
+ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
+-int iwl_power_disable_management(struct iwl_priv *priv);
++int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
+ int iwl_power_enable_management(struct iwl_priv *priv);
+ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
+ int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
+index 6c8ac3a..3a90a67 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
++++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
+@@ -464,11 +464,6 @@ void iwl_init_scan_params(struct iwl_priv *priv)
+
+ int iwl_scan_initiate(struct iwl_priv *priv)
+ {
+- if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
+- IWL_ERROR("APs don't scan.\n");
+- return 0;
+- }
+-
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
+ return -EIO;
+@@ -480,8 +475,7 @@ int iwl_scan_initiate(struct iwl_priv *priv)
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+- IWL_DEBUG_SCAN("Scan request while abort pending. "
+- "Queuing.\n");
++ IWL_DEBUG_SCAN("Scan request while abort pending\n");
+ return -EAGAIN;
+ }
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+index b775d5b..752e7f8 100644
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -5761,7 +5761,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
+ if (priv->error_recovering)
+ iwl3945_error_recovery(priv);
+
+- ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+ return;
+
+ restart:
+@@ -6006,6 +6005,7 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
+ mutex_lock(&priv->mutex);
+ iwl3945_alive_start(priv);
+ mutex_unlock(&priv->mutex);
++ ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+ }
+
+ static void iwl3945_bg_rf_kill(struct work_struct *work)
+@@ -6259,6 +6259,11 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+
++ if (scan->channel_count == 0) {
++ IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
++ goto done;
++ }
++
+ cmd.len += le16_to_cpu(scan->tx_cmd.len) +
+ scan->channel_count * sizeof(struct iwl3945_scan_channel);
+ cmd.data = scan;
+diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
+index a60ae86..a3ccd8c 100644
+--- a/drivers/net/wireless/zd1211rw/zd_usb.c
++++ b/drivers/net/wireless/zd1211rw/zd_usb.c
+@@ -61,6 +61,7 @@ static struct usb_device_id usb_ids[] = {
+ { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
+ /* ZD1211B */
+ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
++ { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
+@@ -82,6 +83,7 @@ static struct usb_device_id usb_ids[] = {
+ { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
++ { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
+ /* "Driverless" devices that need ejecting */
+ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
+ { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
+diff --git a/fs/ext3/super.c b/fs/ext3/super.c
+index f38a5af..810bf7c 100644
+--- a/fs/ext3/super.c
++++ b/fs/ext3/super.c
+@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct super_block * sb)
+
+ static int ext3_sync_fs(struct super_block *sb, int wait)
+ {
+- tid_t target;
+-
+ sb->s_dirt = 0;
+- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
+- if (wait)
+- log_wait_commit(EXT3_SB(sb)->s_journal, target);
+- }
++ if (wait)
++ ext3_force_commit(sb);
++ else
++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
++
+ return 0;
+ }
+
+diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
+index ba85157..6d98f11 100644
+--- a/fs/hfs/catalog.c
++++ b/fs/hfs/catalog.c
+@@ -190,6 +190,10 @@ int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
+
+ fd->search_key->cat.ParID = rec.thread.ParID;
+ len = fd->search_key->cat.CName.len = rec.thread.CName.len;
++ if (len > HFS_NAMELEN) {
++ printk(KERN_ERR "hfs: bad catalog namelength\n");
++ return -EIO;
++ }
+ memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
+ return hfs_brec_find(fd);
+ }
+diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
+index 8adebd3..0fd792b 100644
+--- a/fs/jffs2/background.c
++++ b/fs/jffs2/background.c
+@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(void *_c)
+ for (;;) {
+ allow_signal(SIGHUP);
+ again:
++ spin_lock(&c->erase_completion_lock);
+ if (!jffs2_thread_should_wake(c)) {
+ set_current_state (TASK_INTERRUPTIBLE);
++ spin_unlock(&c->erase_completion_lock);
+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
+- /* Yes, there's a race here; we checked jffs2_thread_should_wake()
+- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
+- matter - We don't care if we miss a wakeup, because the GC thread
+- is only an optimisation anyway. */
+ schedule();
+- }
++ } else
++ spin_unlock(&c->erase_completion_lock);
++
+
+ /* This thread is purely an optimisation. But if it runs when
+ other things could be running, it actually makes things a
+diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c
+index 47b0457..90cb60d 100644
+--- a/fs/jffs2/compr_lzo.c
++++ b/fs/jffs2/compr_lzo.c
+@@ -19,7 +19,7 @@
+
+ static void *lzo_mem;
+ static void *lzo_compress_buf;
+-static DEFINE_MUTEX(deflate_mutex);
++static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */
+
+ static void free_workspace(void)
+ {
+@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out,
+
+ mutex_lock(&deflate_mutex);
+ ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
+- mutex_unlock(&deflate_mutex);
+-
+ if (ret != LZO_E_OK)
+- return -1;
++ goto fail;
+
+ if (compress_size > *dstlen)
+- return -1;
++ goto fail;
+
+ memcpy(cpage_out, lzo_compress_buf, compress_size);
+- *dstlen = compress_size;
++ mutex_unlock(&deflate_mutex);
+
++ *dstlen = compress_size;
+ return 0;
++
++ fail:
++ mutex_unlock(&deflate_mutex);
++ return -1;
+ }
+
+ static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
+diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
+index ae060c6..18546d8 100644
+--- a/include/asm-generic/memory_model.h
++++ b/include/asm-generic/memory_model.h
+@@ -34,7 +34,7 @@
+
+ #define __pfn_to_page(pfn) \
+ ({ unsigned long __pfn = (pfn); \
+- unsigned long __nid = arch_pfn_to_nid(pfn); \
++ unsigned long __nid = arch_pfn_to_nid(__pfn); \
+ NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\
+ })
+
+diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
+index d6fb115..3a16bea 100644
+--- a/include/linux/mtd/cfi.h
++++ b/include/linux/mtd/cfi.h
+@@ -281,9 +281,25 @@ struct cfi_private {
+ /*
+ * Returns the command address according to the given geometry.
+ */
+-static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type)
++static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,
++ struct map_info *map, struct cfi_private *cfi)
+ {
+- return (cmd_ofs * type) * interleave;
++ unsigned bankwidth = map_bankwidth(map);
++ unsigned interleave = cfi_interleave(cfi);
++ unsigned type = cfi->device_type;
++ uint32_t addr;
++
++ addr = (cmd_ofs * type) * interleave;
++
++ /* Modify the unlock address if we are in compatiblity mode.
++ * For 16bit devices on 8 bit busses
++ * and 32bit devices on 16 bit busses
++ * set the low bit of the alternating bit sequence of the address.
++ */
++ if (((type * interleave) > bankwidth) && ((uint8_t)cmd_ofs == 0xaa))
++ addr |= (type >> 1)*interleave;
++
++ return addr;
+ }
+
+ /*
+@@ -429,7 +445,7 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t
+ int type, map_word *prev_val)
+ {
+ map_word val;
+- uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type);
++ uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi);
+
+ val = cfi_build_cmd(cmd, map, cfi);
+
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index 7dd29b7..c29ff1d 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -54,6 +54,7 @@ struct unix_sock {
+ atomic_long_t inflight;
+ spinlock_t lock;
+ unsigned int gc_candidate : 1;
++ unsigned int gc_maybe_cycle : 1;
+ wait_queue_head_t peer_wait;
+ };
+ #define unix_sk(__sk) ((struct unix_sock *)__sk)
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index a0123d7..d68bf2b 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
+ list_del(&cgrp->sibling);
+ spin_lock(&cgrp->dentry->d_lock);
+ d = dget(cgrp->dentry);
+- cgrp->dentry = NULL;
+ spin_unlock(&d->d_lock);
+
+ cgroup_d_remove_dir(d);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 67a7119..77427c8 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -353,11 +353,26 @@ static int vma_has_reserves(struct vm_area_struct *vma)
+ return 0;
+ }
+
++static void clear_gigantic_page(struct page *page,
++ unsigned long addr, unsigned long sz)
++{
++ int i;
++ struct page *p = page;
++
++ might_sleep();
++ for (i = 0; i < sz/PAGE_SIZE; i++, p = mem_map_next(p, page, i)) {
++ cond_resched();
++ clear_user_highpage(p, addr + i * PAGE_SIZE);
++ }
++}
+ static void clear_huge_page(struct page *page,
+ unsigned long addr, unsigned long sz)
+ {
+ int i;
+
++ if (unlikely(sz > MAX_ORDER_NR_PAGES))
++ return clear_gigantic_page(page, addr, sz);
++
+ might_sleep();
+ for (i = 0; i < sz/PAGE_SIZE; i++) {
+ cond_resched();
+@@ -365,12 +380,32 @@ static void clear_huge_page(struct page *page,
+ }
+ }
+
++static void copy_gigantic_page(struct page *dst, struct page *src,
++ unsigned long addr, struct vm_area_struct *vma)
++{
++ int i;
++ struct hstate *h = hstate_vma(vma);
++ struct page *dst_base = dst;
++ struct page *src_base = src;
++ might_sleep();
++ for (i = 0; i < pages_per_huge_page(h); ) {
++ cond_resched();
++ copy_user_highpage(dst, src, addr + i*PAGE_SIZE, vma);
++
++ i++;
++ dst = mem_map_next(dst, dst_base, i);
++ src = mem_map_next(src, src_base, i);
++ }
++}
+ static void copy_huge_page(struct page *dst, struct page *src,
+ unsigned long addr, struct vm_area_struct *vma)
+ {
+ int i;
+ struct hstate *h = hstate_vma(vma);
+
++ if (unlikely(pages_per_huge_page(h) > MAX_ORDER_NR_PAGES))
++ return copy_gigantic_page(dst, src, addr, vma);
++
+ might_sleep();
+ for (i = 0; i < pages_per_huge_page(h); i++) {
+ cond_resched();
+@@ -455,6 +490,8 @@ static void update_and_free_page(struct hstate *h, struct page *page)
+ {
+ int i;
+
++ VM_BUG_ON(h->order >= MAX_ORDER);
++
+ h->nr_huge_pages--;
+ h->nr_huge_pages_node[page_to_nid(page)]--;
+ for (i = 0; i < pages_per_huge_page(h); i++) {
+@@ -969,6 +1006,14 @@ found:
+ return 1;
+ }
+
++static void prep_compound_huge_page(struct page *page, int order)
++{
++ if (unlikely(order > (MAX_ORDER - 1)))
++ prep_compound_gigantic_page(page, order);
++ else
++ prep_compound_page(page, order);
++}
++
+ /* Put bootmem huge pages into the standard lists after mem_map is up */
+ static void __init gather_bootmem_prealloc(void)
+ {
+@@ -979,7 +1024,7 @@ static void __init gather_bootmem_prealloc(void)
+ struct hstate *h = m->hstate;
+ __ClearPageReserved(page);
+ WARN_ON(page_count(page) != 1);
+- prep_compound_page(page, h->order);
++ prep_compound_huge_page(page, h->order);
+ prep_new_huge_page(h, page, page_to_nid(page));
+ }
+ }
+@@ -2103,7 +2148,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ same_page:
+ if (pages) {
+ get_page(page);
+- pages[i] = page + pfn_offset;
++ pages[i] = mem_map_offset(page, pfn_offset);
+ }
+
+ if (vmas)
+diff --git a/mm/internal.h b/mm/internal.h
+index 1f43f74..92729ea 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -17,6 +17,7 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
+ unsigned long floor, unsigned long ceiling);
+
+ extern void prep_compound_page(struct page *page, unsigned long order);
++extern void prep_compound_gigantic_page(struct page *page, unsigned long order);
+
+ static inline void set_page_count(struct page *page, int v)
+ {
+@@ -53,6 +54,34 @@ static inline unsigned long page_order(struct page *page)
+ }
+
+ /*
++ * Return the mem_map entry representing the 'offset' subpage within
++ * the maximally aligned gigantic page 'base'. Handle any discontiguity
++ * in the mem_map at MAX_ORDER_NR_PAGES boundaries.
++ */
++static inline struct page *mem_map_offset(struct page *base, int offset)
++{
++ if (unlikely(offset >= MAX_ORDER_NR_PAGES))
++ return pfn_to_page(page_to_pfn(base) + offset);
++ return base + offset;
++}
++
++/*
++ * Iterator over all subpages withing the maximally aligned gigantic
++ * page 'base'. Handle any discontiguity in the mem_map.
++ */
++static inline struct page *mem_map_next(struct page *iter,
++ struct page *base, int offset)
++{
++ if (unlikely((offset & (MAX_ORDER_NR_PAGES - 1)) == 0)) {
++ unsigned long pfn = page_to_pfn(base) + offset;
++ if (!pfn_valid(pfn))
++ return NULL;
++ return pfn_to_page(pfn);
++ }
++ return iter + 1;
++}
++
++/*
+ * FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node,
+ * so all functions starting at paging_init should be marked __init
+ * in those cases. SPARSEMEM, however, allows for memory hotplug,
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 27b8681..ed5cdae 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -268,24 +268,39 @@ void prep_compound_page(struct page *page, unsigned long order)
+ {
+ int i;
+ int nr_pages = 1 << order;
++
++ set_compound_page_dtor(page, free_compound_page);
++ set_compound_order(page, order);
++ __SetPageHead(page);
++ for (i = 1; i < nr_pages; i++) {
++ struct page *p = page + i;
++
++ __SetPageTail(p);
++ p->first_page = page;
++ }
++}
++
++#ifdef CONFIG_HUGETLBFS
++void prep_compound_gigantic_page(struct page *page, unsigned long order)
++{
++ int i;
++ int nr_pages = 1 << order;
+ struct page *p = page + 1;
+
+ set_compound_page_dtor(page, free_compound_page);
+ set_compound_order(page, order);
+ __SetPageHead(page);
+- for (i = 1; i < nr_pages; i++, p++) {
+- if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
+- p = pfn_to_page(page_to_pfn(page) + i);
++ for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
+ __SetPageTail(p);
+ p->first_page = page;
+ }
+ }
++#endif
+
+ static void destroy_compound_page(struct page *page, unsigned long order)
+ {
+ int i;
+ int nr_pages = 1 << order;
+- struct page *p = page + 1;
+
+ if (unlikely(compound_order(page) != order))
+ bad_page(page);
+@@ -293,9 +308,8 @@ static void destroy_compound_page(struct page *page, unsigned long order)
+ if (unlikely(!PageHead(page)))
+ bad_page(page);
+ __ClearPageHead(page);
+- for (i = 1; i < nr_pages; i++, p++) {
+- if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
+- p = pfn_to_page(page_to_pfn(page) + i);
++ for (i = 1; i < nr_pages; i++) {
++ struct page *p = page + i;
+
+ if (unlikely(!PageTail(p) |
+ (p->first_page != page)))
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 015606b..8bde9bf 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1300,14 +1300,23 @@ static void unix_destruct_fds(struct sk_buff *skb)
+ sock_wfree(skb);
+ }
+
+-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
++static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ {
+ int i;
++
++ /*
++ * Need to duplicate file references for the sake of garbage
++ * collection. Otherwise a socket in the fps might become a
++ * candidate for GC while the skb is not yet queued.
++ */
++ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
++ if (!UNIXCB(skb).fp)
++ return -ENOMEM;
++
+ for (i=scm->fp->count-1; i>=0; i--)
+ unix_inflight(scm->fp->fp[i]);
+- UNIXCB(skb).fp = scm->fp;
+ skb->destructor = unix_destruct_fds;
+- scm->fp = NULL;
++ return 0;
+ }
+
+ /*
+@@ -1366,8 +1375,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
+ goto out;
+
+ memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
+- if (siocb->scm->fp)
+- unix_attach_fds(siocb->scm, skb);
++ if (siocb->scm->fp) {
++ err = unix_attach_fds(siocb->scm, skb);
++ if (err)
++ goto out_free;
++ }
+ unix_get_secdata(siocb->scm, skb);
+
+ skb_reset_transport_header(skb);
+@@ -1536,8 +1548,13 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
+ size = min_t(int, size, skb_tailroom(skb));
+
+ memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
+- if (siocb->scm->fp)
+- unix_attach_fds(siocb->scm, skb);
++ if (siocb->scm->fp) {
++ err = unix_attach_fds(siocb->scm, skb);
++ if (err) {
++ kfree_skb(skb);
++ goto out_err;
++ }
++ }
+
+ if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
+ kfree_skb(skb);
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 2a27b84..6d4a9a8 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
+ */
+ struct sock *sk = unix_get_socket(*fp++);
+ if (sk) {
+- hit = true;
+- func(unix_sk(sk));
++ struct unix_sock *u = unix_sk(sk);
++
++ /*
++ * Ignore non-candidates, they could
++ * have been added to the queues after
++ * starting the garbage collection
++ */
++ if (u->gc_candidate) {
++ hit = true;
++ func(u);
++ }
+ }
+ }
+ if (hit && hitlist != NULL) {
+@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struct unix_sock *u)
+ {
+ atomic_long_inc(&u->inflight);
+ /*
+- * If this is still a candidate, move it to the end of the
+- * list, so that it's checked even if it was already passed
+- * over
++ * If this still might be part of a cycle, move it to the end
++ * of the list, so that it's checked even if it was already
++ * passed over
+ */
+- if (u->gc_candidate)
++ if (u->gc_maybe_cycle)
+ list_move_tail(&u->link, &gc_candidates);
+ }
+
+@@ -267,6 +276,7 @@ void unix_gc(void)
+ struct unix_sock *next;
+ struct sk_buff_head hitlist;
+ struct list_head cursor;
++ LIST_HEAD(not_cycle_list);
+
+ spin_lock(&unix_gc_lock);
+
+@@ -282,10 +292,14 @@ void unix_gc(void)
+ *
+ * Holding unix_gc_lock will protect these candidates from
+ * being detached, and hence from gaining an external
+- * reference. This also means, that since there are no
+- * possible receivers, the receive queues of these sockets are
+- * static during the GC, even though the dequeue is done
+- * before the detach without atomicity guarantees.
++ * reference. Since there are no possible receivers, all
++ * buffers currently on the candidates' queues stay there
++ * during the garbage collection.
++ *
++ * We also know that no new candidate can be added onto the
++ * receive queues. Other, non candidate sockets _can_ be
++ * added to queue, so we must make sure only to touch
++ * candidates.
+ */
+ list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
+ long total_refs;
+@@ -299,6 +313,7 @@ void unix_gc(void)
+ if (total_refs == inflight_refs) {
+ list_move_tail(&u->link, &gc_candidates);
+ u->gc_candidate = 1;
++ u->gc_maybe_cycle = 1;
+ }
+ }
+
+@@ -325,14 +340,24 @@ void unix_gc(void)
+ list_move(&cursor, &u->link);
+
+ if (atomic_long_read(&u->inflight) > 0) {
+- list_move_tail(&u->link, &gc_inflight_list);
+- u->gc_candidate = 0;
++ list_move_tail(&u->link, ¬_cycle_list);
++ u->gc_maybe_cycle = 0;
+ scan_children(&u->sk, inc_inflight_move_tail, NULL);
+ }
+ }
+ list_del(&cursor);
+
+ /*
++ * not_cycle_list contains those sockets which do not make up a
++ * cycle. Restore these to the inflight list.
++ */
++ while (!list_empty(¬_cycle_list)) {
++ u = list_entry(not_cycle_list.next, struct unix_sock, link);
++ u->gc_candidate = 0;
++ list_move_tail(&u->link, &gc_inflight_list);
++ }
++
++ /*
+ * Now gc_candidates contains only garbage. Restore original
+ * inflight counters for these as well, and remove the skbuffs
+ * which are creating the cycle(s).
+diff --git a/security/keys/internal.h b/security/keys/internal.h
+index b39f5c2..239098f 100644
+--- a/security/keys/internal.h
++++ b/security/keys/internal.h
+@@ -107,6 +107,7 @@ extern key_ref_t search_process_keyrings(struct key_type *type,
+
+ extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
+
++extern int install_user_keyrings(struct task_struct *tsk);
+ extern int install_thread_keyring(struct task_struct *tsk);
+ extern int install_process_keyring(struct task_struct *tsk);
+
+diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
+index 5be6d01..45b240a 100644
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -40,7 +40,7 @@ struct key_user root_key_user = {
+ /*
+ * install user and user session keyrings for a particular UID
+ */
+-static int install_user_keyrings(struct task_struct *tsk)
++int install_user_keyrings(struct task_struct *tsk)
+ {
+ struct user_struct *user = tsk->user;
+ struct key *uid_keyring, *session_keyring;
+diff --git a/security/keys/request_key.c b/security/keys/request_key.c
+index ba32ca6..abea08f 100644
+--- a/security/keys/request_key.c
++++ b/security/keys/request_key.c
+@@ -74,6 +74,10 @@ static int call_sbin_request_key(struct key_construction *cons,
+
+ kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
+
++ ret = install_user_keyrings(tsk);
++ if (ret < 0)
++ goto error_alloc;
++
+ /* allocate a new session keyring */
+ sprintf(desc, "_req.%u", key->serial);
+
+diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
+index f3da621..732ce13 100644
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -67,6 +67,7 @@ enum {
+ enum {
+ STAC_92HD73XX_REF,
+ STAC_DELL_M6,
++ STAC_DELL_EQ,
+ STAC_92HD73XX_MODELS
+ };
+
+@@ -560,9 +561,7 @@ static struct hda_verb dell_eq_core_init[] = {
+ };
+
+ static struct hda_verb dell_m6_core_init[] = {
+- /* set master volume to max value without distortion
+- * and direct control */
+- { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
++ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+ /* setup audio connections */
+ { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
+ { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
+@@ -1297,11 +1296,13 @@ static unsigned int dell_m6_pin_configs[13] = {
+ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
+ [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
+ [STAC_DELL_M6] = dell_m6_pin_configs,
++ [STAC_DELL_EQ] = dell_m6_pin_configs,
+ };
+
+ static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
+ [STAC_92HD73XX_REF] = "ref",
+ [STAC_DELL_M6] = "dell-m6",
++ [STAC_DELL_EQ] = "dell-eq",
+ };
+
+ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
+@@ -3560,8 +3561,12 @@ again:
+ spec->gpio_data = 0x01;
+
+ switch (spec->board_config) {
+- case STAC_DELL_M6:
++ case STAC_DELL_EQ:
+ spec->init = dell_eq_core_init;
++ /* fallthru */
++ case STAC_DELL_M6:
++ if (!spec->init)
++ spec->init = dell_m6_core_init;
+ switch (codec->subsystem_id) {
+ case 0x1028025e: /* Analog Mics */
+ case 0x1028025f:
+@@ -3570,8 +3575,6 @@ again:
+ break;
+ case 0x10280271: /* Digital Mics */
+ case 0x10280272:
+- spec->init = dell_m6_core_init;
+- /* fall-through */
+ case 0x10280254:
+ case 0x10280255:
+ stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
|
[-]
[+]
|
Added |
patches.kernel.org.tar.bz2/patch-2.6.27.6-7
^
|
@@ -0,0 +1,2011 @@
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: Linux 2.6.27.7
+
+Upstream 2.6.27.7 release from kernel.org
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+diff --git a/Makefile b/Makefile
+index 1ea4453..b5f52f3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 27
+-EXTRAVERSION = .6
++EXTRAVERSION = .7
+ NAME = Trembling Tortoise
+
+ # *DOCUMENTATION*
+diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
+index 7b5a25d..4f6cf46 100644
+--- a/arch/arm/mm/cache-feroceon-l2.c
++++ b/arch/arm/mm/cache-feroceon-l2.c
+@@ -148,7 +148,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end)
+ /*
+ * Clean and invalidate partial last cache line.
+ */
+- if (end & (CACHE_LINE_SIZE - 1)) {
++ if (start < end && end & (CACHE_LINE_SIZE - 1)) {
+ l2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
+ end &= ~(CACHE_LINE_SIZE - 1);
+ }
+@@ -156,7 +156,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end)
+ /*
+ * Invalidate all full cache lines between 'start' and 'end'.
+ */
+- while (start != end) {
++ while (start < end) {
+ unsigned long range_end = calc_range_end(start, end);
+ l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE);
+ start = range_end;
+diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
+index ded7dd2..c4460bf 100644
+--- a/arch/m68k/kernel/ints.c
++++ b/arch/m68k/kernel/ints.c
+@@ -133,7 +133,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
+ {
+ int i;
+
+- BUG_ON(IRQ_USER + cnt >= NR_IRQS);
++ BUG_ON(IRQ_USER + cnt > NR_IRQS);
+ m68k_first_user_vec = vec;
+ for (i = 0; i < cnt; i++)
+ irq_controller[IRQ_USER + i] = &user_irq_controller;
+diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
+index fe566a3..eb685ed 100644
+--- a/arch/powerpc/include/asm/mpic.h
++++ b/arch/powerpc/include/asm/mpic.h
+@@ -355,6 +355,8 @@ struct mpic
+ #define MPIC_NO_BIAS 0x00000400
+ /* Ignore NIRQS as reported by FRR */
+ #define MPIC_BROKEN_FRR_NIRQS 0x00000800
++/* Destination only supports a single CPU at a time */
++#define MPIC_SINGLE_DEST_CPU 0x00001000
+
+ /* MPIC HW modification ID */
+ #define MPIC_REGSET_MASK 0xf0000000
+diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+index 483b65c..613bf8c 100644
+--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
++++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+@@ -78,7 +78,8 @@ void __init mpc85xx_ds_pic_init(void)
+
+ mpic = mpic_alloc(np, r.start,
+ MPIC_PRIMARY | MPIC_WANTS_RESET |
+- MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
++ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
++ MPIC_SINGLE_DEST_CPU,
+ 0, 256, " OpenPIC ");
+ BUG_ON(mpic == NULL);
+ of_node_put(np);
+diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
+index 8881c5d..668275d 100644
+--- a/arch/powerpc/platforms/86xx/pic.c
++++ b/arch/powerpc/platforms/86xx/pic.c
+@@ -44,7 +44,8 @@ void __init mpc86xx_init_irq(void)
+
+ mpic = mpic_alloc(np, res.start,
+ MPIC_PRIMARY | MPIC_WANTS_RESET |
+- MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
++ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
++ MPIC_SINGLE_DEST_CPU,
+ 0, 256, " MPIC ");
+ of_node_put(np);
+ BUG_ON(mpic == NULL);
+diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
+index 8e3478c..f6299cc 100644
+--- a/arch/powerpc/sysdev/mpic.c
++++ b/arch/powerpc/sysdev/mpic.c
+@@ -563,6 +563,51 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
+
+ #endif /* CONFIG_MPIC_U3_HT_IRQS */
+
++#ifdef CONFIG_SMP
++static int irq_choose_cpu(unsigned int virt_irq)
++{
++ cpumask_t mask = irq_desc[virt_irq].affinity;
++ int cpuid;
++
++ if (cpus_equal(mask, CPU_MASK_ALL)) {
++ static int irq_rover;
++ static DEFINE_SPINLOCK(irq_rover_lock);
++ unsigned long flags;
++
++ /* Round-robin distribution... */
++ do_round_robin:
++ spin_lock_irqsave(&irq_rover_lock, flags);
++
++ while (!cpu_online(irq_rover)) {
++ if (++irq_rover >= NR_CPUS)
++ irq_rover = 0;
++ }
++ cpuid = irq_rover;
++ do {
++ if (++irq_rover >= NR_CPUS)
++ irq_rover = 0;
++ } while (!cpu_online(irq_rover));
++
++ spin_unlock_irqrestore(&irq_rover_lock, flags);
++ } else {
++ cpumask_t tmp;
++
++ cpus_and(tmp, cpu_online_map, mask);
++
++ if (cpus_empty(tmp))
++ goto do_round_robin;
++
++ cpuid = first_cpu(tmp);
++ }
++
++ return cpuid;
++}
++#else
++static int irq_choose_cpu(unsigned int virt_irq)
++{
++ return hard_smp_processor_id();
++}
++#endif
+
+ #define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
+
+@@ -777,12 +822,18 @@ void mpic_set_affinity(unsigned int irq, cpumask_t cpumask)
+ struct mpic *mpic = mpic_from_irq(irq);
+ unsigned int src = mpic_irq_to_hw(irq);
+
+- cpumask_t tmp;
++ if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
++ int cpuid = irq_choose_cpu(irq);
+
+- cpus_and(tmp, cpumask, cpu_online_map);
++ mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
++ } else {
++ cpumask_t tmp;
+
+- mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
+- mpic_physmask(cpus_addr(tmp)[0]));
++ cpus_and(tmp, cpumask, cpu_online_map);
++
++ mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
++ mpic_physmask(cpus_addr(tmp)[0]));
++ }
+ }
+
+ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
+diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
+index 632b13e..a947899 100644
+--- a/arch/s390/kernel/topology.c
++++ b/arch/s390/kernel/topology.c
+@@ -65,18 +65,21 @@ static int machine_has_topology_irq;
+ static struct timer_list topology_timer;
+ static void set_topology_timer(void);
+ static DECLARE_WORK(topology_work, topology_work_fn);
++/* topology_lock protects the core linked list */
++static DEFINE_SPINLOCK(topology_lock);
+
+ cpumask_t cpu_core_map[NR_CPUS];
+
+ cpumask_t cpu_coregroup_map(unsigned int cpu)
+ {
+ struct core_info *core = &core_info;
++ unsigned long flags;
+ cpumask_t mask;
+
+ cpus_clear(mask);
+ if (!machine_has_topology)
+ return cpu_present_map;
+- mutex_lock(&smp_cpu_state_mutex);
++ spin_lock_irqsave(&topology_lock, flags);
+ while (core) {
+ if (cpu_isset(cpu, core->mask)) {
+ mask = core->mask;
+@@ -84,7 +87,7 @@ cpumask_t cpu_coregroup_map(unsigned int cpu)
+ }
+ core = core->next;
+ }
+- mutex_unlock(&smp_cpu_state_mutex);
++ spin_unlock_irqrestore(&topology_lock, flags);
+ if (cpus_empty(mask))
+ mask = cpumask_of_cpu(cpu);
+ return mask;
+@@ -133,7 +136,7 @@ static void tl_to_cores(struct tl_info *info)
+ union tl_entry *tle, *end;
+ struct core_info *core = &core_info;
+
+- mutex_lock(&smp_cpu_state_mutex);
++ spin_lock_irq(&topology_lock);
+ clear_cores();
+ tle = info->tle;
+ end = (union tl_entry *)((unsigned long)info + info->length);
+@@ -157,7 +160,7 @@ static void tl_to_cores(struct tl_info *info)
+ }
+ tle = next_tle(tle);
+ }
+- mutex_unlock(&smp_cpu_state_mutex);
++ spin_unlock_irq(&topology_lock);
+ }
+
+ static void topology_update_polarization_simple(void)
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index 5efc9e7..857dce7 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -95,6 +95,9 @@ new_hw_segment:
+ nr_hw_segs++;
+ }
+
++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
++ rq->bio->bi_seg_front_size = seg_size;
++
+ nr_phys_segs++;
+ bvprv = bv;
+ seg_size = bv->bv_len;
+@@ -106,6 +109,10 @@ new_hw_segment:
+ rq->bio->bi_hw_front_size = hw_seg_size;
+ if (hw_seg_size > rq->biotail->bi_hw_back_size)
+ rq->biotail->bi_hw_back_size = hw_seg_size;
++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
++ rq->bio->bi_seg_front_size = seg_size;
++ if (seg_size > rq->biotail->bi_seg_back_size)
++ rq->biotail->bi_seg_back_size = seg_size;
+ rq->nr_phys_segments = nr_phys_segs;
+ rq->nr_hw_segments = nr_hw_segs;
+ }
+@@ -133,7 +140,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
+
+ if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
+ return 0;
+- if (bio->bi_size + nxt->bi_size > q->max_segment_size)
++ if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
++ q->max_segment_size)
+ return 0;
+
+ /*
+@@ -377,6 +385,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
+ {
+ int total_phys_segments;
+ int total_hw_segments;
++ unsigned int seg_size =
++ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
+
+ /*
+ * First check if the either of the requests are re-queued
+@@ -392,8 +402,13 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
+ return 0;
+
+ total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
+- if (blk_phys_contig_segment(q, req->biotail, next->bio))
++ if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
++ if (req->nr_phys_segments == 1)
++ req->bio->bi_seg_front_size = seg_size;
++ if (next->nr_phys_segments == 1)
++ next->biotail->bi_seg_back_size = seg_size;
+ total_phys_segments--;
++ }
+
+ if (total_phys_segments > q->max_phys_segments)
+ return 0;
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index ccae305..c54f38e 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -95,21 +95,21 @@ int acpi_bus_get_status(struct acpi_device *device)
+ }
+
+ /*
+- * Otherwise we assume the status of our parent (unless we don't
+- * have one, in which case status is implied).
++ * According to ACPI spec some device can be present and functional
++ * even if the parent is not present but functional.
++ * In such conditions the child device should not inherit the status
++ * from the parent.
+ */
+- else if (device->parent)
+- device->status = device->parent->status;
+ else
+ STRUCT_TO_INT(device->status) =
+ ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
+ ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING;
+
+ if (device->status.functional && !device->status.present) {
+- printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
+- "functional but not present; setting present\n",
+- device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
+- device->status.present = 1;
++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
++ "functional but not present;\n",
++ device->pnp.bus_id,
++ (u32) STRUCT_TO_INT(device->status)));
+ }
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 444cd9e..41b8e7c 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -70,7 +70,7 @@ enum ec_command {
+ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
+ #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
+
+-#define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts
++#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
+ per one transaction */
+
+ enum {
+@@ -100,8 +100,11 @@ struct transaction {
+ u8 *rdata;
+ unsigned short irq_count;
+ u8 command;
++ u8 wi;
++ u8 ri;
+ u8 wlen;
+ u8 rlen;
++ bool done;
+ };
+
+ static struct acpi_ec {
+@@ -178,34 +181,45 @@ static int ec_transaction_done(struct acpi_ec *ec)
+ unsigned long flags;
+ int ret = 0;
+ spin_lock_irqsave(&ec->curr_lock, flags);
+- if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
++ if (!ec->curr || ec->curr->done)
+ ret = 1;
+ spin_unlock_irqrestore(&ec->curr_lock, flags);
+ return ret;
+ }
+
++static void start_transaction(struct acpi_ec *ec)
++{
++ ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
++ ec->curr->done = false;
++ acpi_ec_write_cmd(ec, ec->curr->command);
++}
++
+ static void gpe_transaction(struct acpi_ec *ec, u8 status)
+ {
+ unsigned long flags;
+ spin_lock_irqsave(&ec->curr_lock, flags);
+ if (!ec->curr)
+ goto unlock;
+- if (ec->curr->wlen > 0) {
+- if ((status & ACPI_EC_FLAG_IBF) == 0) {
+- acpi_ec_write_data(ec, *(ec->curr->wdata++));
+- --ec->curr->wlen;
+- } else
+- /* false interrupt, state didn't change */
+- ++ec->curr->irq_count;
+-
+- } else if (ec->curr->rlen > 0) {
++ if (ec->curr->wlen > ec->curr->wi) {
++ if ((status & ACPI_EC_FLAG_IBF) == 0)
++ acpi_ec_write_data(ec,
++ ec->curr->wdata[ec->curr->wi++]);
++ else
++ goto err;
++ } else if (ec->curr->rlen > ec->curr->ri) {
+ if ((status & ACPI_EC_FLAG_OBF) == 1) {
+- *(ec->curr->rdata++) = acpi_ec_read_data(ec);
+- --ec->curr->rlen;
++ ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec);
++ if (ec->curr->rlen == ec->curr->ri)
++ ec->curr->done = true;
+ } else
+- /* false interrupt, state didn't change */
+- ++ec->curr->irq_count;
+- }
++ goto err;
++ } else if (ec->curr->wlen == ec->curr->wi &&
++ (status & ACPI_EC_FLAG_IBF) == 0)
++ ec->curr->done = true;
++ goto unlock;
++err:
++ /* false interrupt, state didn't change */
++ ++ec->curr->irq_count;
+ unlock:
+ spin_unlock_irqrestore(&ec->curr_lock, flags);
+ }
+@@ -215,6 +229,15 @@ static int acpi_ec_wait(struct acpi_ec *ec)
+ if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
+ msecs_to_jiffies(ACPI_EC_DELAY)))
+ return 0;
++ /* try restart command if we get any false interrupts */
++ if (ec->curr->irq_count &&
++ (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
++ pr_debug(PREFIX "controller reset, restart transaction\n");
++ start_transaction(ec);
++ if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
++ msecs_to_jiffies(ACPI_EC_DELAY)))
++ return 0;
++ }
+ /* missing GPEs, switch back to poll mode */
+ if (printk_ratelimit())
+ pr_info(PREFIX "missing confirmations, "
+@@ -239,10 +262,10 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
+ static int ec_poll(struct acpi_ec *ec)
+ {
+ unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+- msleep(1);
++ udelay(ACPI_EC_UDELAY);
+ while (time_before(jiffies, delay)) {
+ gpe_transaction(ec, acpi_ec_read_status(ec));
+- msleep(1);
++ udelay(ACPI_EC_UDELAY);
+ if (ec_transaction_done(ec))
+ return 0;
+ }
+@@ -264,9 +287,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+ /* start transaction */
+ spin_lock_irqsave(&ec->curr_lock, tmp);
+ /* following two actions should be kept atomic */
+- t->irq_count = 0;
+ ec->curr = t;
+- acpi_ec_write_cmd(ec, ec->curr->command);
++ start_transaction(ec);
+ if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
+ clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+ spin_unlock_irqrestore(&ec->curr_lock, tmp);
+@@ -286,7 +308,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+ t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+- pr_debug(PREFIX "GPE storm detected\n");
++ pr_info(PREFIX "GPE storm detected, "
++ "transactions will use polling mode\n");
+ set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+ }
+ return ret;
+@@ -558,17 +581,26 @@ static u32 acpi_ec_gpe_handler(void *data)
+ pr_debug(PREFIX "~~~> interrupt\n");
+ status = acpi_ec_read_status(ec);
+
+- gpe_transaction(ec, status);
+- if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+- wake_up(&ec->wait);
++ if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) {
++ gpe_transaction(ec, status);
++ if (ec_transaction_done(ec) &&
++ (status & ACPI_EC_FLAG_IBF) == 0)
++ wake_up(&ec->wait);
++ }
+
+ ec_check_sci(ec, status);
+ if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+ !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
+ /* this is non-query, must be confirmation */
+- if (printk_ratelimit())
+- pr_info(PREFIX "non-query interrupt received,"
++ if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++ if (printk_ratelimit())
++ pr_info(PREFIX "non-query interrupt received,"
++ " switching to interrupt mode\n");
++ } else {
++ /* hush, STORM switches the mode every transaction */
++ pr_debug(PREFIX "non-query interrupt received,"
+ " switching to interrupt mode\n");
++ }
+ set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+ }
+ return ACPI_INTERRUPT_HANDLED;
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index f6f52c1..0450761 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device,
+ {
+ const struct acpi_device_id *id;
+
++ /*
++ * If the device is not present, it is unnecessary to load device
++ * driver for it.
++ */
++ if (!device->status.present)
++ return -ENODEV;
++
+ if (device->flags.hardware_id) {
+ for (id = ids; id->id[0]; id++) {
+ if (!strcmp((char*)id->id, device->pnp.hardware_id))
+@@ -1221,15 +1228,18 @@ acpi_add_single_object(struct acpi_device **child,
+ result = -ENODEV;
+ goto end;
+ }
+- if (!device->status.present) {
+- /* Bay and dock should be handled even if absent */
+- if (!ACPI_SUCCESS(
+- acpi_is_child_device(device, acpi_bay_match)) &&
+- !ACPI_SUCCESS(
+- acpi_is_child_device(device, acpi_dock_match))) {
+- result = -ENODEV;
+- goto end;
+- }
++ /*
++ * When the device is neither present nor functional, the
++ * device should not be added to Linux ACPI device tree.
++ * When the status of the device is not present but functinal,
++ * it should be added to Linux ACPI tree. For example : bay
++ * device , dock device.
++ * In such conditions it is unncessary to check whether it is
++ * bay device or dock device.
++ */
++ if (!device->status.present && !device->status.functional) {
++ result = -ENODEV;
++ goto end;
+ }
+ break;
+ default:
+@@ -1402,7 +1412,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
+ * TBD: Need notifications and other detection mechanisms
+ * in place before we can fully implement this.
+ */
+- if (child->status.present) {
++ /*
++ * When the device is not present but functional, it is also
++ * necessary to scan the children of this device.
++ */
++ if (child->status.present || (!child->status.present &&
++ child->status.functional)) {
+ status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
+ NULL, NULL);
+ if (ACPI_SUCCESS(status)) {
+diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
+index 91dec44..4745792 100644
+--- a/drivers/acpi/system.c
++++ b/drivers/acpi/system.c
+@@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct kobject *kobj,
+ container_of(bin_attr, struct acpi_table_attr, attr);
+ struct acpi_table_header *table_header = NULL;
+ acpi_status status;
++ char name[ACPI_NAME_SIZE];
++
++ if (strncmp(table_attr->name, "NULL", 4))
++ memcpy(name, table_attr->name, ACPI_NAME_SIZE);
++ else
++ memcpy(name, "\0\0\0\0", 4);
+
+ status =
+- acpi_get_table(table_attr->name, table_attr->instance,
++ acpi_get_table(name, table_attr->instance,
+ &table_header);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+@@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
+ struct acpi_table_header *header = NULL;
+ struct acpi_table_attr *attr = NULL;
+
+- memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
++ if (table_header->signature[0] != '\0')
++ memcpy(table_attr->name, table_header->signature,
++ ACPI_NAME_SIZE);
++ else
++ memcpy(table_attr->name, "NULL", 4);
+
+ list_for_each_entry(attr, &acpi_table_attr_list, node) {
+- if (!memcmp(table_header->signature, attr->name,
+- ACPI_NAME_SIZE))
++ if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE))
+ if (table_attr->instance < attr->instance)
+ table_attr->instance = attr->instance;
+ }
+ table_attr->instance++;
+
+ if (table_attr->instance > 1 || (table_attr->instance == 1 &&
+- !acpi_get_table(table_header->
+- signature, 2,
+- &header)))
+- sprintf(table_attr->name + 4, "%d", table_attr->instance);
++ !acpi_get_table
++ (table_header->signature, 2, &header)))
++ sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
++ table_attr->instance);
+
+ table_attr->attr.size = 0;
+ table_attr->attr.read = acpi_table_show;
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 8a59aaa..7a88dfd 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -422,9 +422,11 @@ struct ipmi_smi {
+ /**
+ * The driver model view of the IPMI messaging driver.
+ */
+-static struct device_driver ipmidriver = {
+- .name = "ipmi",
+- .bus = &platform_bus_type
++static struct platform_driver ipmidriver = {
++ .driver = {
++ .name = "ipmi",
++ .bus = &platform_bus_type
++ }
+ };
+ static DEFINE_MUTEX(ipmidriver_mutex);
+
+@@ -2384,9 +2386,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
+ * representing the interfaced BMC already
+ */
+ if (bmc->guid_set)
+- old_bmc = ipmi_find_bmc_guid(&ipmidriver, bmc->guid);
++ old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, bmc->guid);
+ else
+- old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver,
++ old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
+ bmc->id.product_id,
+ bmc->id.device_id);
+
+@@ -2416,7 +2418,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
+ snprintf(name, sizeof(name),
+ "ipmi_bmc.%4.4x", bmc->id.product_id);
+
+- while (ipmi_find_bmc_prod_dev_id(&ipmidriver,
++ while (ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
+ bmc->id.product_id,
+ bmc->id.device_id)) {
+ if (!warn_printed) {
+@@ -2446,7 +2448,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
+ " Unable to allocate platform device\n");
+ return -ENOMEM;
+ }
+- bmc->dev->dev.driver = &ipmidriver;
++ bmc->dev->dev.driver = &ipmidriver.driver;
+ dev_set_drvdata(&bmc->dev->dev, bmc);
+ kref_init(&bmc->refcount);
+
+@@ -4247,7 +4249,7 @@ static int ipmi_init_msghandler(void)
+ if (initialized)
+ return 0;
+
+- rv = driver_register(&ipmidriver);
++ rv = driver_register(&ipmidriver.driver);
+ if (rv) {
+ printk(KERN_ERR PFX "Could not register IPMI driver\n");
+ return rv;
+@@ -4308,7 +4310,7 @@ static __exit void cleanup_ipmi(void)
+ remove_proc_entry(proc_ipmi_root->name, NULL);
+ #endif /* CONFIG_PROC_FS */
+
+- driver_unregister(&ipmidriver);
++ driver_unregister(&ipmidriver.driver);
+
+ initialized = 0;
+
+diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
+index 8e8afb6..7e860da 100644
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -114,9 +114,11 @@ static char *si_to_str[] = { "kcs", "smic", "bt" };
+
+ #define DEVICE_NAME "ipmi_si"
+
+-static struct device_driver ipmi_driver = {
+- .name = DEVICE_NAME,
+- .bus = &platform_bus_type
++static struct platform_driver ipmi_driver = {
++ .driver = {
++ .name = DEVICE_NAME,
++ .bus = &platform_bus_type
++ }
+ };
+
+
+@@ -2868,7 +2870,7 @@ static int try_smi_init(struct smi_info *new_smi)
+ goto out_err;
+ }
+ new_smi->dev = &new_smi->pdev->dev;
+- new_smi->dev->driver = &ipmi_driver;
++ new_smi->dev->driver = &ipmi_driver.driver;
+
+ rv = platform_device_add(new_smi->pdev);
+ if (rv) {
+@@ -2983,7 +2985,7 @@ static __devinit int init_ipmi_si(void)
+ initialized = 1;
+
+ /* Register the device drivers. */
+- rv = driver_register(&ipmi_driver);
++ rv = driver_register(&ipmi_driver.driver);
+ if (rv) {
+ printk(KERN_ERR
+ "init_ipmi_si: Unable to register driver: %d\n",
+@@ -3052,7 +3054,7 @@ static __devinit int init_ipmi_si(void)
+ #ifdef CONFIG_PPC_OF
+ of_unregister_platform_driver(&ipmi_of_platform_driver);
+ #endif
+- driver_unregister(&ipmi_driver);
++ driver_unregister(&ipmi_driver.driver);
+ printk(KERN_WARNING
+ "ipmi_si: Unable to find any System Interface(s)\n");
+ return -ENODEV;
+@@ -3151,7 +3153,7 @@ static __exit void cleanup_ipmi_si(void)
+ cleanup_one_si(e);
+ mutex_unlock(&smi_infos_lock);
+
+- driver_unregister(&ipmi_driver);
++ driver_unregister(&ipmi_driver.driver);
+ }
+ module_exit(cleanup_ipmi_si);
+
+diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
+index 0f70dc2..7e909e8 100644
+--- a/drivers/hwmon/ibmaem.c
++++ b/drivers/hwmon/ibmaem.c
+@@ -88,9 +88,11 @@
+ static DEFINE_IDR(aem_idr);
+ static DEFINE_SPINLOCK(aem_idr_lock);
+
+-static struct device_driver aem_driver = {
+- .name = DRVNAME,
+- .bus = &platform_bus_type,
++static struct platform_driver aem_driver = {
++ .driver = {
++ .name = DRVNAME,
++ .bus = &platform_bus_type,
++ }
+ };
+
+ struct aem_ipmi_data {
+@@ -583,7 +585,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
+ data->pdev = platform_device_alloc(DRVNAME, data->id);
+ if (!data->pdev)
+ goto dev_err;
+- data->pdev->dev.driver = &aem_driver;
++ data->pdev->dev.driver = &aem_driver.driver;
+
+ res = platform_device_add(data->pdev);
+ if (res)
+@@ -716,7 +718,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
+ data->pdev = platform_device_alloc(DRVNAME, data->id);
+ if (!data->pdev)
+ goto dev_err;
+- data->pdev->dev.driver = &aem_driver;
++ data->pdev->dev.driver = &aem_driver.driver;
+
+ res = platform_device_add(data->pdev);
+ if (res)
+@@ -1085,7 +1087,7 @@ static int __init aem_init(void)
+ {
+ int res;
+
+- res = driver_register(&aem_driver);
++ res = driver_register(&aem_driver.driver);
+ if (res) {
+ printk(KERN_ERR "Can't register aem driver\n");
+ return res;
+@@ -1097,7 +1099,7 @@ static int __init aem_init(void)
+ return 0;
+
+ ipmi_reg_err:
+- driver_unregister(&aem_driver);
++ driver_unregister(&aem_driver.driver);
+ return res;
+
+ }
+@@ -1107,7 +1109,7 @@ static void __exit aem_exit(void)
+ struct aem_data *p1, *next1;
+
+ ipmi_smi_watcher_unregister(&driver_data.bmc_events);
+- driver_unregister(&aem_driver);
++ driver_unregister(&aem_driver.driver);
+ list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list)
+ aem_delete(p1);
+ }
+diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
+index 385e32b..cbedf95 100644
+--- a/drivers/input/mouse/alps.c
++++ b/drivers/input/mouse/alps.c
+@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
+ { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
+ { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
+ { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
++ { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
+ { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
+ };
+
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index ff05fe8..97ef945 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -1598,6 +1598,7 @@ static void mirror_dtr(struct dm_target *ti)
+
+ del_timer_sync(&ms->timer);
+ flush_workqueue(ms->kmirrord_wq);
++ flush_scheduled_work();
+ dm_kcopyd_client_destroy(ms->kcopyd_client);
+ destroy_workqueue(ms->kmirrord_wq);
+ free_context(ms, ti, ms->nr_mirrors);
+diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
+index b59e472..d74df58 100644
+--- a/drivers/media/video/tvaudio.c
++++ b/drivers/media/video/tvaudio.c
+@@ -1576,13 +1576,13 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
+ return 0;
+ }
+ case V4L2_CID_AUDIO_BASS:
+- if (desc->flags & CHIP_HAS_BASSTREBLE)
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+ break;
+ ctrl->value = chip->bass;
+ return 0;
+ case V4L2_CID_AUDIO_TREBLE:
+- if (desc->flags & CHIP_HAS_BASSTREBLE)
+- return -EINVAL;
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
++ break;
+ ctrl->value = chip->treble;
+ return 0;
+ }
+@@ -1642,16 +1642,15 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
+ return 0;
+ }
+ case V4L2_CID_AUDIO_BASS:
+- if (desc->flags & CHIP_HAS_BASSTREBLE)
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+ break;
+ chip->bass = ctrl->value;
+ chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
+
+ return 0;
+ case V4L2_CID_AUDIO_TREBLE:
+- if (desc->flags & CHIP_HAS_BASSTREBLE)
+- return -EINVAL;
+-
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
++ break;
+ chip->treble = ctrl->value;
+ chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
+
+@@ -1695,7 +1694,7 @@ static int chip_command(struct i2c_client *client,
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+- if (desc->flags & CHIP_HAS_BASSTREBLE)
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+ return -EINVAL;
+ break;
+ default:
+diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
+index 60775be..b35eb92 100644
+--- a/drivers/misc/sony-laptop.c
++++ b/drivers/misc/sony-laptop.c
+@@ -2315,8 +2315,10 @@ end:
+ */
+ static int sony_pic_disable(struct acpi_device *device)
+ {
+- if (ACPI_FAILURE(acpi_evaluate_object(device->handle,
+- "_DIS", NULL, NULL)))
++ acpi_status ret = acpi_evaluate_object(device->handle, "_DIS", NULL,
++ NULL);
++
++ if (ACPI_FAILURE(ret) && ret != AE_NOT_FOUND)
+ return -ENXIO;
+
+ dprintk("Device disabled\n");
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 4a11296..60a0453 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -2046,6 +2046,7 @@ config R8169
+ tristate "Realtek 8169 gigabit ethernet support"
+ depends on PCI
+ select CRC32
++ select MII
+ ---help---
+ Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
+
+diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
+index 130927c..a6c0b3a 100644
+--- a/drivers/net/bnx2x_init.h
++++ b/drivers/net/bnx2x_init.h
+@@ -564,14 +564,15 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
+
+ static void bnx2x_init_pxp(struct bnx2x *bp)
+ {
++ u16 devctl;
+ int r_order, w_order;
+ u32 val, i;
+
+ pci_read_config_word(bp->pdev,
+- bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val);
+- DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val);
+- w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+- r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12);
++ bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
++ DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
++ w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
++ r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+
+ if (r_order > MAX_RD_ORD) {
+ DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
+diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
+index a8eb3c4..53459db 100644
+--- a/drivers/net/bnx2x_main.c
++++ b/drivers/net/bnx2x_main.c
+@@ -6480,6 +6480,7 @@ load_int_disable:
+ bnx2x_free_irq(bp);
+ load_error:
+ bnx2x_free_mem(bp);
++ bp->port.pmf = 0;
+
+ /* TBD we really need to reset the chip
+ if we want to recover from this */
+@@ -6790,6 +6791,7 @@ unload_error:
+ /* Report UNLOAD_DONE to MCP */
+ if (!BP_NOMCP(bp))
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
++ bp->port.pmf = 0;
+
+ /* Free SKBs, SGEs, TPA pool and driver internals */
+ bnx2x_free_skbs(bp);
+@@ -10203,8 +10205,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
+ return -ENOMEM;
+ }
+
+- netif_carrier_off(dev);
+-
+ bp = netdev_priv(dev);
+ bp->msglevel = debug;
+
+@@ -10228,6 +10228,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
+ goto init_one_exit;
+ }
+
++ netif_carrier_off(dev);
++
+ bp->common.name = board_info[ent->driver_data].name;
+ printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
+ " IRQ %d, ", dev->name, bp->common.name,
+diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
+index 0676c6d..a225827 100644
+--- a/drivers/net/wireless/ath5k/base.c
++++ b/drivers/net/wireless/ath5k/base.c
+@@ -294,9 +294,9 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
+ }
+
+ /* Interrupt handling */
+-static int ath5k_init(struct ath5k_softc *sc);
++static int ath5k_init(struct ath5k_softc *sc, bool is_resume);
+ static int ath5k_stop_locked(struct ath5k_softc *sc);
+-static int ath5k_stop_hw(struct ath5k_softc *sc);
++static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
+ static irqreturn_t ath5k_intr(int irq, void *dev_id);
+ static void ath5k_tasklet_reset(unsigned long data);
+
+@@ -584,7 +584,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+
+ ath5k_led_off(sc);
+
+- ath5k_stop_hw(sc);
++ ath5k_stop_hw(sc, true);
+
+ free_irq(pdev->irq, sc);
+ pci_save_state(pdev);
+@@ -599,8 +599,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
+ {
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath5k_softc *sc = hw->priv;
+- struct ath5k_hw *ah = sc->ah;
+- int i, err;
++ int err;
+
+ pci_restore_state(pdev);
+
+@@ -621,21 +620,11 @@ ath5k_pci_resume(struct pci_dev *pdev)
+ goto err_no_irq;
+ }
+
+- err = ath5k_init(sc);
++ err = ath5k_init(sc, true);
+ if (err)
+ goto err_irq;
+ ath5k_led_enable(sc);
+
+- /*
+- * Reset the key cache since some parts do not
+- * reset the contents on initial power up or resume.
+- *
+- * FIXME: This may need to be revisited when mac80211 becomes
+- * aware of suspend/resume.
+- */
+- for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+- ath5k_hw_reset_key(ah, i);
+-
+ return 0;
+ err_irq:
+ free_irq(pdev->irq, sc);
+@@ -657,7 +646,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+ struct ath5k_softc *sc = hw->priv;
+ struct ath5k_hw *ah = sc->ah;
+ u8 mac[ETH_ALEN];
+- unsigned int i;
+ int ret;
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
+@@ -676,13 +664,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+ __set_bit(ATH_STAT_MRRETRY, sc->status);
+
+ /*
+- * Reset the key cache since some parts do not
+- * reset the contents on initial power up.
+- */
+- for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+- ath5k_hw_reset_key(ah, i);
+-
+- /*
+ * Collect the channel list. The 802.11 layer
+ * is resposible for filtering this list based
+ * on settings like the phy mode and regulatory
+@@ -2197,12 +2178,18 @@ ath5k_beacon_config(struct ath5k_softc *sc)
+ \********************/
+
+ static int
+-ath5k_init(struct ath5k_softc *sc)
++ath5k_init(struct ath5k_softc *sc, bool is_resume)
+ {
+- int ret;
++ struct ath5k_hw *ah = sc->ah;
++ int ret, i;
+
+ mutex_lock(&sc->lock);
+
++ if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
++ goto out_ok;
++
++ __clear_bit(ATH_STAT_STARTED, sc->status);
++
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
+
+ /*
+@@ -2220,7 +2207,7 @@ ath5k_init(struct ath5k_softc *sc)
+ */
+ sc->curchan = sc->hw->conf.channel;
+ sc->curband = &sc->sbands[sc->curchan->band];
+- ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false);
++ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, false);
+ if (ret) {
+ ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret);
+ goto done;
+@@ -2229,7 +2216,14 @@ ath5k_init(struct ath5k_softc *sc)
+ * This is needed only to setup initial state
+ * but it's best done after a reset.
+ */
+- ath5k_hw_set_txpower_limit(sc->ah, 0);
++ ath5k_hw_set_txpower_limit(ah, 0);
++
++ /*
++ * Reset the key cache since some parts do not reset the
++ * contents on initial power up or resume from suspend.
++ */
++ for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
++ ath5k_hw_reset_key(ah, i);
+
+ /*
+ * Setup the hardware after reset: the key cache
+@@ -2249,13 +2243,17 @@ ath5k_init(struct ath5k_softc *sc)
+ AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
+ AR5K_INT_MIB;
+
+- ath5k_hw_set_intr(sc->ah, sc->imask);
++ ath5k_hw_set_intr(ah, sc->imask);
++
++ __set_bit(ATH_STAT_STARTED, sc->status);
++
+ /* Set ack to be sent at low bit-rates */
+- ath5k_hw_set_ack_bitrate_high(sc->ah, false);
++ ath5k_hw_set_ack_bitrate_high(ah, false);
+
+ mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+ msecs_to_jiffies(ath5k_calinterval * 1000)));
+
++out_ok:
+ ret = 0;
+ done:
+ mmiowb();
+@@ -2310,7 +2308,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
+ * stop is preempted).
+ */
+ static int
+-ath5k_stop_hw(struct ath5k_softc *sc)
++ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
+ {
+ int ret;
+
+@@ -2341,6 +2339,9 @@ ath5k_stop_hw(struct ath5k_softc *sc)
+ }
+ }
+ ath5k_txbuf_free(sc, sc->bbuf);
++ if (!is_suspend)
++ __clear_bit(ATH_STAT_STARTED, sc->status);
++
+ mmiowb();
+ mutex_unlock(&sc->lock);
+
+@@ -2719,12 +2720,12 @@ err:
+
+ static int ath5k_start(struct ieee80211_hw *hw)
+ {
+- return ath5k_init(hw->priv);
++ return ath5k_init(hw->priv, false);
+ }
+
+ static void ath5k_stop(struct ieee80211_hw *hw)
+ {
+- ath5k_stop_hw(hw->priv);
++ ath5k_stop_hw(hw->priv, false);
+ }
+
+ static int ath5k_add_interface(struct ieee80211_hw *hw,
+diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
+index 7ec2f37..214a565 100644
+--- a/drivers/net/wireless/ath5k/base.h
++++ b/drivers/net/wireless/ath5k/base.h
+@@ -132,11 +132,12 @@ struct ath5k_softc {
+ size_t desc_len; /* size of TX/RX descriptors */
+ u16 cachelsz; /* cache line size */
+
+- DECLARE_BITMAP(status, 4);
++ DECLARE_BITMAP(status, 5);
+ #define ATH_STAT_INVALID 0 /* disable hardware accesses */
+ #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
+ #define ATH_STAT_PROMISC 2
+ #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
++#define ATH_STAT_STARTED 4 /* opened & irqs enabled */
+
+ unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
+ unsigned int curmode; /* current phy mode */
+diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
+index ad1a5b4..9b40cbe 100644
+--- a/drivers/net/wireless/ath5k/hw.c
++++ b/drivers/net/wireless/ath5k/hw.c
+@@ -826,9 +826,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
+ mdelay(1);
+
+ /*
+- * Write some more initial register settings
++ * Write some more initial register settings for revised chips
+ */
+- if (ah->ah_version == AR5K_AR5212) {
++ if (ah->ah_version == AR5K_AR5212 &&
++ ah->ah_phy_revision > 0x41) {
+ ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
+
+ if (channel->hw_value == CHANNEL_G)
+@@ -847,19 +848,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
+ else
+ ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
+
+- /* Some bits are disabled here, we know nothing about
+- * register 0xa228 yet, most of the times this ends up
+- * with a value 0x9b5 -haven't seen any dump with
+- * a different value- */
+- /* Got this from decompiling binary HAL */
+- data = ath5k_hw_reg_read(ah, 0xa228);
+- data &= 0xfffffdff;
+- ath5k_hw_reg_write(ah, data, 0xa228);
+-
+- data = ath5k_hw_reg_read(ah, 0xa228);
+- data &= 0xfffe03ff;
+- ath5k_hw_reg_write(ah, data, 0xa228);
+- data = 0;
++ /* Got this from legacy-hal */
++ AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200);
++
++ AR5K_REG_MASKED_BITS(ah, 0xa228, 2 << 10, ~0x1fc00);
+
+ /* Just write 0x9b5 ? */
+ /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
+diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
+index 2806b21..cf7ebd1 100644
+--- a/drivers/net/wireless/ath5k/initvals.c
++++ b/drivers/net/wireless/ath5k/initvals.c
+@@ -810,6 +810,8 @@ static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { AR5K_PHY(642),
+ { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
++ { 0xa228,
++ { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
+ { 0xa23c,
+ { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+ };
+diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
+index ffdf487..a68f97c 100644
+--- a/drivers/net/wireless/hostap/hostap_wlan.h
++++ b/drivers/net/wireless/hostap/hostap_wlan.h
+@@ -918,9 +918,12 @@ struct hostap_interface {
+
+ /*
+ * TX meta data - stored in skb->cb buffer, so this must not be increased over
+- * the 40-byte limit
++ * the 48-byte limit.
++ * THE PADDING THIS STARTS WITH IS A HORRIBLE HACK THAT SHOULD NOT LIVE
++ * TO SEE THE DAY.
+ */
+ struct hostap_skb_tx_data {
++ unsigned int __padding_for_default_qdiscs;
+ u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */
+ u8 rate; /* transmit rate */
+ #define HOSTAP_TX_FLAGS_WDS BIT(0)
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
+index 72a6743..cf7056e 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -3275,7 +3275,11 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
+ return;
+ }
+
+- iwl_scan_cancel_timeout(priv, 100);
++ if (iwl_scan_cancel(priv)) {
++ /* cancel scan failed, just live w/ bad key and rely
++ briefly on SW decryption */
++ return;
++ }
+
+ key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
+index ca5deb6..0cebbc4 100644
+--- a/drivers/net/wireless/rtl8187_dev.c
++++ b/drivers/net/wireless/rtl8187_dev.c
+@@ -45,6 +45,9 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
+ {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
+ /* Sitecom */
+ {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
++ {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
++ /* Abocom */
++ {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
+ {}
+ };
+
+diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
+index c1b9ea3..98b9df7 100644
+--- a/drivers/pnp/pnpacpi/core.c
++++ b/drivers/pnp/pnpacpi/core.c
+@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
+ acpi_status status;
+ struct pnp_dev *dev;
+
++ /*
++ * If a PnPacpi device is not present , the device
++ * driver should not be loaded.
++ */
+ status = acpi_get_handle(device->handle, "_CRS", &temp);
+ if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
+- is_exclusive_device(device))
++ is_exclusive_device(device) || (!device->status.present))
+ return 0;
+
+ dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
+diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
+index 1fe0901..7716145 100644
+--- a/drivers/scsi/dpt_i2o.c
++++ b/drivers/scsi/dpt_i2o.c
+@@ -2445,7 +2445,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
+ hba_status = detailed_status >> 8;
+
+ // calculate resid for sg
+- scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5));
++ scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+20));
+
+ pHba = (adpt_hba*) cmd->device->host->hostdata[0];
+
+@@ -2456,7 +2456,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
+ case I2O_SCSI_DSC_SUCCESS:
+ cmd->result = (DID_OK << 16);
+ // handle underflow
+- if(readl(reply+5) < cmd->underflow ) {
++ if (readl(reply+20) < cmd->underflow) {
+ cmd->result = (DID_ERROR <<16);
+ printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 94a720e..00f6780 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2546,7 +2546,6 @@ typedef struct scsi_qla_host {
+ uint8_t fcode_revision[16];
+ uint32_t fw_revision[4];
+
+- uint16_t fdt_odd_index;
+ uint32_t fdt_wrt_disable;
+ uint32_t fdt_erase_cmd;
+ uint32_t fdt_block_size;
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index ee89ddd..3a0a178 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -974,7 +974,6 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
+ &ha->fw_minor_version,
+ &ha->fw_subminor_version,
+ &ha->fw_attributes, &ha->fw_memory_size);
+- qla2x00_resize_request_q(ha);
+ ha->flags.npiv_supported = 0;
+ if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) ||
+ IS_QLA84XX(ha)) &&
+@@ -986,6 +985,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
+ ha->max_npiv_vports =
+ MIN_MULTI_ID_FABRIC - 1;
+ }
++ qla2x00_resize_request_q(ha);
+
+ if (ql2xallocfwdump)
+ qla2x00_alloc_fw_dump(ha);
+diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
+index 813bc77..c07e879 100644
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -1964,7 +1964,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
+ *cur_iocb_cnt = mcp->mb[7];
+ if (orig_iocb_cnt)
+ *orig_iocb_cnt = mcp->mb[10];
+- if (max_npiv_vports)
++ if (ha->flags.npiv_supported && max_npiv_vports)
+ *max_npiv_vports = mcp->mb[11];
+ }
+
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 6d0f0e5..86e143c 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -730,6 +730,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ if (ha->isp_ops->abort_command(ha, sp)) {
+ DEBUG2(printk("%s(%ld): abort_command "
+ "mbx failed.\n", __func__, ha->host_no));
++ ret = FAILED;
+ } else {
+ DEBUG3(printk("%s(%ld): abort_command "
+ "mbx success.\n", __func__, ha->host_no));
+diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
+index 1bca744..910c3b3 100644
+--- a/drivers/scsi/qla2xxx/qla_sup.c
++++ b/drivers/scsi/qla2xxx/qla_sup.c
+@@ -546,6 +546,7 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
+ void
+ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+ {
++#define FLASH_BLK_SIZE_4K 0x1000
+ #define FLASH_BLK_SIZE_32K 0x8000
+ #define FLASH_BLK_SIZE_64K 0x10000
+ uint16_t cnt, chksum;
+@@ -577,7 +578,6 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+ goto no_flash_data;
+ }
+
+- ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f;
+ ha->fdt_wrt_disable = fdt->wrt_disable_bits;
+ ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
+ ha->fdt_block_size = le32_to_cpu(fdt->block_size);
+@@ -590,10 +590,10 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+ }
+
+ DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x "
+- "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n",
++ "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n",
+ le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd,
+ ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd,
+- ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size));
++ ha->fdt_wrt_disable, ha->fdt_block_size));
+ return;
+
+ no_flash_data:
+@@ -614,8 +614,7 @@ no_flash_data:
+ ha->fdt_block_size = FLASH_BLK_SIZE_64K;
+ break;
+ case 0x1f: /* Atmel 26DF081A. */
+- ha->fdt_odd_index = 1;
+- ha->fdt_block_size = FLASH_BLK_SIZE_64K;
++ ha->fdt_block_size = FLASH_BLK_SIZE_4K;
+ ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320);
+ ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339);
+ ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336);
+@@ -627,9 +626,9 @@ no_flash_data:
+ }
+
+ DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x "
+- "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
++ "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
+ ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
+- ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
++ ha->fdt_unprotect_sec_cmd, ha->fdt_wrt_disable,
+ ha->fdt_block_size));
+ }
+
+@@ -710,13 +709,9 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
+ qla24xx_unprotect_flash(ha);
+
+ for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
+- if (ha->fdt_odd_index) {
+- findex = faddr << 2;
+- fdata = findex & sec_mask;
+- } else {
+- findex = faddr;
+- fdata = (findex & sec_mask) << 2;
+- }
++
++ findex = faddr;
++ fdata = (findex & sec_mask) << 2;
+
+ /* Are we at the beginning of a sector? */
+ if ((findex & rest_addr) == 0) {
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index d996a61..61524fc 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -158,16 +158,12 @@ static int acm_wb_is_avail(struct acm *acm)
+ }
+
+ /*
+- * Finish write.
++ * Finish write. Caller must hold acm->write_lock
+ */
+ static void acm_write_done(struct acm *acm, struct acm_wb *wb)
+ {
+- unsigned long flags;
+-
+- spin_lock_irqsave(&acm->write_lock, flags);
+ wb->use = 0;
+ acm->transmitting--;
+- spin_unlock_irqrestore(&acm->write_lock, flags);
+ }
+
+ /*
+@@ -482,6 +478,7 @@ static void acm_write_bulk(struct urb *urb)
+ {
+ struct acm_wb *wb = urb->context;
+ struct acm *acm = wb->instance;
++ unsigned long flags;
+
+ if (verbose || urb->status
+ || (urb->actual_length != urb->transfer_buffer_length))
+@@ -490,7 +487,9 @@ static void acm_write_bulk(struct urb *urb)
+ urb->transfer_buffer_length,
+ urb->status);
+
++ spin_lock_irqsave(&acm->write_lock, flags);
+ acm_write_done(acm, wb);
++ spin_unlock_irqrestore(&acm->write_lock, flags);
+ if (ACM_READY(acm))
+ schedule_work(&acm->work);
+ else
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+index 286b443..9cfa366 100644
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
+ continue;
+ dev_dbg(&dev->dev, "unregistering interface %s\n",
+ dev_name(&interface->dev));
++ interface->unregistering = 1;
+ usb_remove_sysfs_intf_files(interface);
+ device_del(&interface->dev);
+ }
+diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
+index 5e1f5d5..668a6d6 100644
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -816,7 +816,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
+ struct usb_host_interface *alt = intf->cur_altsetting;
+ int retval;
+
+- if (intf->sysfs_files_created)
++ if (intf->sysfs_files_created || intf->unregistering)
+ return 0;
+
+ /* The interface string may be present in some altsettings
+diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
+index 5ee1590..c1d34df 100644
+--- a/drivers/usb/gadget/f_acm.c
++++ b/drivers/usb/gadget/f_acm.c
+@@ -463,7 +463,11 @@ static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
+ notify->wLength = cpu_to_le16(length);
+ memcpy(buf, data, length);
+
++ /* ep_queue() can complete immediately if it fills the fifo... */
++ spin_unlock(&acm->lock);
+ status = usb_ep_queue(ep, req, GFP_ATOMIC);
++ spin_lock(&acm->lock);
++
+ if (status < 0) {
+ ERROR(acm->port.func.config->cdev,
+ "acm ttyGS%d can't notify serial state, %d\n",
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 228797e..a657c94 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -110,29 +110,18 @@ config USB_ISP116X_HCD
+
+ config USB_ISP1760_HCD
+ tristate "ISP 1760 HCD support"
+- depends on USB && EXPERIMENTAL
++ depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
+ ---help---
+ The ISP1760 chip is a USB 2.0 host controller.
+
+ This driver does not support isochronous transfers or OTG.
++ This USB controller is usually attached to a non-DMA-Master
++ capable bus. NXP's eval kit brings this chip on PCI card
++ where the chip itself is behind a PLB to simulate such
++ a bus.
+
+ To compile this driver as a module, choose M here: the
+- module will be called isp1760-hcd.
+-
+-config USB_ISP1760_PCI
+- bool "Support for the PCI bus"
+- depends on USB_ISP1760_HCD && PCI
+- ---help---
+- Enables support for the device present on the PCI bus.
+- This should only be required if you happen to have the eval kit from
+- NXP and you are going to test it.
+-
+-config USB_ISP1760_OF
+- bool "Support for the OF platform bus"
+- depends on USB_ISP1760_HCD && PPC_OF
+- ---help---
+- Enables support for the device present on the PowerPC
+- OpenFirmware platform bus.
++ module will be called isp1760.
+
+ config USB_OHCI_HCD
+ tristate "OHCI HCD support"
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index 86e38b0..dc21ade 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd)
+ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+ {
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+- u32 status, pcd_status = 0, cmd;
++ u32 status, masked_status, pcd_status = 0, cmd;
+ int bh;
+
+ spin_lock (&ehci->lock);
+@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+ goto dead;
+ }
+
+- status &= INTR_MASK;
+- if (!status) { /* irq sharing? */
++ masked_status = status & INTR_MASK;
++ if (!masked_status) { /* irq sharing? */
+ spin_unlock(&ehci->lock);
+ return IRQ_NONE;
+ }
+
+ /* clear (just) interrupts */
+- ehci_writel(ehci, status, &ehci->regs->status);
++ ehci_writel(ehci, masked_status, &ehci->regs->status);
+ cmd = ehci_readl(ehci, &ehci->regs->command);
+ bh = 0;
+
+@@ -731,19 +731,18 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+
+ /* PCI errors [4.15.2.4] */
+ if (unlikely ((status & STS_FATAL) != 0)) {
++ ehci_err(ehci, "fatal error\n");
+ dbg_cmd (ehci, "fatal", ehci_readl(ehci,
+ &ehci->regs->command));
+ dbg_status (ehci, "fatal", status);
+- if (status & STS_HALT) {
+- ehci_err (ehci, "fatal error\n");
++ ehci_halt(ehci);
+ dead:
+- ehci_reset (ehci);
+- ehci_writel(ehci, 0, &ehci->regs->configured_flag);
+- /* generic layer kills/unlinks all urbs, then
+- * uses ehci_stop to clean up the rest
+- */
+- bh = 1;
+- }
++ ehci_reset(ehci);
++ ehci_writel(ehci, 0, &ehci->regs->configured_flag);
++ /* generic layer kills/unlinks all urbs, then
++ * uses ehci_stop to clean up the rest
++ */
++ bh = 1;
+ }
+
+ if (bh)
+diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
+index 0eba894..9c9da35 100644
+--- a/drivers/usb/host/ehci-ps3.c
++++ b/drivers/usb/host/ehci-ps3.c
+@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
+
+ tmp = hcd->irq;
+
++ ehci_shutdown(hcd);
+ usb_remove_hcd(hcd);
+
+ ps3_system_bus_set_driver_data(dev, NULL);
+diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
+index 4a0c5a7..a081ee6 100644
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -918,7 +918,7 @@ iso_stream_init (
+ */
+ stream->usecs = HS_USECS_ISO (maxp);
+ bandwidth = stream->usecs * 8;
+- bandwidth /= 1 << (interval - 1);
++ bandwidth /= interval;
+
+ } else {
+ u32 addr;
+@@ -951,7 +951,7 @@ iso_stream_init (
+ } else
+ stream->raw_mask = smask_out [hs_transfers - 1];
+ bandwidth = stream->usecs + stream->c_usecs;
+- bandwidth /= 1 << (interval + 2);
++ bandwidth /= interval << 3;
+
+ /* stream->splits gets created from raw_mask later */
+ stream->address = cpu_to_hc32(ehci, addr);
+diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
+index 051ef7b..78b8aaa 100644
+--- a/drivers/usb/host/isp1760-if.c
++++ b/drivers/usb/host/isp1760-if.c
+@@ -14,16 +14,16 @@
+ #include "../core/hcd.h"
+ #include "isp1760-hcd.h"
+
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ #include <linux/of.h>
+ #include <linux/of_platform.h>
+ #endif
+
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ #include <linux/pci.h>
+ #endif
+
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ static int of_isp1760_probe(struct of_device *dev,
+ const struct of_device_id *match)
+ {
+@@ -128,7 +128,7 @@ static struct of_platform_driver isp1760_of_driver = {
+ };
+ #endif
+
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ static u32 nxp_pci_io_base;
+ static u32 iolength;
+ static u32 pci_mem_phy0;
+@@ -287,28 +287,28 @@ static struct pci_driver isp1761_pci_driver = {
+
+ static int __init isp1760_init(void)
+ {
+- int ret = -ENODEV;
++ int ret;
+
+ init_kmem_once();
+
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ ret = of_register_platform_driver(&isp1760_of_driver);
+ if (ret) {
+ deinit_kmem_cache();
+ return ret;
+ }
+ #endif
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ ret = pci_register_driver(&isp1761_pci_driver);
+ if (ret)
+ goto unreg_of;
+ #endif
+ return ret;
+
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ unreg_of:
+ #endif
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ of_unregister_platform_driver(&isp1760_of_driver);
+ #endif
+ deinit_kmem_cache();
+@@ -318,10 +318,10 @@ module_init(isp1760_init);
+
+ static void __exit isp1760_exit(void)
+ {
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ of_unregister_platform_driver(&isp1760_of_driver);
+ #endif
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ pci_unregister_driver(&isp1761_pci_driver);
+ #endif
+ deinit_kmem_cache();
+diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
+index 2089d8a..3c1a3b5 100644
+--- a/drivers/usb/host/ohci-ps3.c
++++ b/drivers/usb/host/ohci-ps3.c
+@@ -192,7 +192,7 @@ fail_start:
+ return result;
+ }
+
+-static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
++static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
+ {
+ unsigned int tmp;
+ struct usb_hcd *hcd =
+@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
+
+ tmp = hcd->irq;
+
++ ohci_shutdown(hcd);
+ usb_remove_hcd(hcd);
+
+ ps3_system_bus_set_driver_data(dev, NULL);
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index 061df9b..ccebf89 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1251,6 +1251,13 @@ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_INQUIRY),
+
++/* Reported by Luciano Rocha <luciano@eurotux.com> */
++UNUSUAL_DEV( 0x0840, 0x0082, 0x0001, 0x0001,
++ "Argosy",
++ "Storage",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_FIX_CAPACITY),
++
+ /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
+ * Flag will support Bulk devices which use a standards-violating 32-byte
+ * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 6e283c9..1bd5ba2 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags,
+ if (!err)
+ nd->path.mnt->mnt_flags = mnt_flags;
+ up_write(&sb->s_umount);
+- if (!err)
++ if (!err) {
+ security_sb_post_remount(nd->path.mnt, flags, data);
++
++ spin_lock(&vfsmount_lock);
++ touch_mnt_namespace(nd->path.mnt->mnt_ns);
++ spin_unlock(&vfsmount_lock);
++ }
+ return err;
+ }
+
+diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
+index f9a8b89..7a510a6 100644
+--- a/fs/proc/proc_sysctl.c
++++ b/fs/proc/proc_sysctl.c
+@@ -31,6 +31,7 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */
+ inode->i_mode = table->mode;
++ inode->i_uid = inode->i_gid = 0;
+ if (!table->child) {
+ inode->i_mode |= S_IFREG;
+ inode->i_op = &proc_sys_inode_operations;
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index 0933a14..3d83947 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -98,6 +98,13 @@ struct bio {
+ unsigned int bi_size; /* residual I/O count */
+
+ /*
++ * To keep track of the max segment size, we account for the
++ * sizes of the first and last mergeable segments in this bio.
++ */
++ unsigned int bi_seg_front_size;
++ unsigned int bi_seg_back_size;
++
++ /*
+ * To keep track of the max hw size, we account for the
+ * sizes of the first and last virtually mergeable segments
+ * in this bio
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 94ac74a..2e434dc 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -108,6 +108,7 @@ enum usb_interface_condition {
+ * (in probe()), bound to a driver, or unbinding (in disconnect())
+ * @is_active: flag set when the interface is bound and not suspended.
+ * @sysfs_files_created: sysfs attributes exist
++ * @unregistering: flag set when the interface is being unregistered
+ * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
+ * capability during autosuspend.
+ * @needs_altsetting0: flag set when a set-interface request for altsetting 0
+@@ -163,6 +164,7 @@ struct usb_interface {
+ enum usb_interface_condition condition; /* state of binding */
+ unsigned is_active:1; /* the interface is not suspended */
+ unsigned sysfs_files_created:1; /* the sysfs attributes exist */
++ unsigned unregistering:1; /* unregistration is in progress */
+ unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
+ unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */
+ unsigned needs_binding:1; /* needs delayed unbind/rebind */
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 77427c8..81e9a82 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1797,6 +1797,7 @@ int unmap_ref_private(struct mm_struct *mm,
+ struct page *page,
+ unsigned long address)
+ {
++ struct hstate *h = hstate_vma(vma);
+ struct vm_area_struct *iter_vma;
+ struct address_space *mapping;
+ struct prio_tree_iter iter;
+@@ -1806,7 +1807,7 @@ int unmap_ref_private(struct mm_struct *mm,
+ * vm_pgoff is in PAGE_SIZE units, hence the different calculation
+ * from page cache lookup which is in HPAGE_SIZE units.
+ */
+- address = address & huge_page_mask(hstate_vma(vma));
++ address = address & huge_page_mask(h);
+ pgoff = ((address - vma->vm_start) >> PAGE_SHIFT)
+ + (vma->vm_pgoff >> PAGE_SHIFT);
+ mapping = (struct address_space *)page_private(page);
+@@ -1825,7 +1826,7 @@ int unmap_ref_private(struct mm_struct *mm,
+ */
+ if (!is_vma_resv_set(iter_vma, HPAGE_RESV_OWNER))
+ unmap_hugepage_range(iter_vma,
+- address, address + HPAGE_SIZE,
++ address, address + huge_page_size(h),
+ page);
+ }
+
+diff --git a/mm/page_isolation.c b/mm/page_isolation.c
+index b70a7fe..5e0ffd9 100644
+--- a/mm/page_isolation.c
++++ b/mm/page_isolation.c
+@@ -130,10 +130,11 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
+ if (page && get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
+ break;
+ }
+- if (pfn < end_pfn)
++ page = __first_valid_page(start_pfn, end_pfn - start_pfn);
++ if ((pfn < end_pfn) || !page)
+ return -EBUSY;
+ /* Check all pages are free or Marked as ISOLATED */
+- zone = page_zone(pfn_to_page(pfn));
++ zone = page_zone(page);
+ spin_lock_irqsave(&zone->lock, flags);
+ ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn);
+ spin_unlock_irqrestore(&zone->lock, flags);
+diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
+index 8f5a403..a631a1f 100644
+--- a/net/ipv4/proc.c
++++ b/net/ipv4/proc.c
+@@ -237,43 +237,45 @@ static const struct snmp_mib snmp4_net_list[] = {
+ SNMP_MIB_SENTINEL
+ };
+
++static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
++ unsigned short *type, int count)
++{
++ int j;
++
++ if (count) {
++ seq_printf(seq, "\nIcmpMsg:");
++ for (j = 0; j < count; ++j)
++ seq_printf(seq, " %sType%u",
++ type[j] & 0x100 ? "Out" : "In",
++ type[j] & 0xff);
++ seq_printf(seq, "\nIcmpMsg:");
++ for (j = 0; j < count; ++j)
++ seq_printf(seq, " %lu", vals[j]);
++ }
++}
++
+ static void icmpmsg_put(struct seq_file *seq)
+ {
+ #define PERLINE 16
+
+- int j, i, count;
+- static int out[PERLINE];
++ int i, count;
++ unsigned short type[PERLINE];
++ unsigned long vals[PERLINE], val;
+ struct net *net = seq->private;
+
+ count = 0;
+ for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
+-
+- if (snmp_fold_field((void **) net->mib.icmpmsg_statistics, i))
+- out[count++] = i;
+- if (count < PERLINE)
+- continue;
+-
+- seq_printf(seq, "\nIcmpMsg:");
+- for (j = 0; j < PERLINE; ++j)
+- seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In",
+- i & 0xff);
+- seq_printf(seq, "\nIcmpMsg: ");
+- for (j = 0; j < PERLINE; ++j)
+- seq_printf(seq, " %lu",
+- snmp_fold_field((void **) net->mib.icmpmsg_statistics,
+- out[j]));
+- seq_putc(seq, '\n');
+- }
+- if (count) {
+- seq_printf(seq, "\nIcmpMsg:");
+- for (j = 0; j < count; ++j)
+- seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" :
+- "In", out[j] & 0xff);
+- seq_printf(seq, "\nIcmpMsg:");
+- for (j = 0; j < count; ++j)
+- seq_printf(seq, " %lu", snmp_fold_field((void **)
+- net->mib.icmpmsg_statistics, out[j]));
++ val = snmp_fold_field((void **) net->mib.icmpmsg_statistics, i);
++ if (val) {
++ type[count] = i;
++ vals[count++] = val;
++ }
++ if (count == PERLINE) {
++ icmpmsg_put_line(seq, vals, type, count);
++ count = 0;
++ }
+ }
++ icmpmsg_put_line(seq, vals, type, count);
+
+ #undef PERLINE
+ }
+diff --git a/scripts/package/builddeb b/scripts/package/builddeb
+index ba6bf5d..1264b8e 100644
+--- a/scripts/package/builddeb
++++ b/scripts/package/builddeb
+@@ -15,15 +15,18 @@ set -e
+ version=$KERNELRELEASE
+ revision=`cat .version`
+ tmpdir="$objtree/debian/tmp"
++fwdir="$objtree/debian/fwtmp"
+ packagename=linux-$version
++fwpackagename=linux-firmware-image
+
+ if [ "$ARCH" == "um" ] ; then
+ packagename=user-mode-linux-$version
+ fi
+
+ # Setup the directory structure
+-rm -rf "$tmpdir"
++rm -rf "$tmpdir" "$fwdir"
+ mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot"
++mkdir -p "$fwdir/DEBIAN" "$fwdir/lib"
+ if [ "$ARCH" == "um" ] ; then
+ mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/share/doc/$packagename" "$tmpdir/usr/bin"
+ fi
+@@ -107,6 +110,7 @@ Standards-Version: 3.6.1
+
+ Package: $packagename
+ Provides: kernel-image-$version, linux-image-$version
++Suggests: $fwpackagename
+ Architecture: any
+ Description: Linux kernel, version $version
+ This package contains the Linux kernel, modules and corresponding other
+@@ -118,8 +122,24 @@ fi
+ chown -R root:root "$tmpdir"
+ chmod -R go-w "$tmpdir"
+
++# Do we have firmware? Move it out of the way and build it into a package.
++if [ -e "$tmpdir/lib/firmware" ]; then
++ mv "$tmpdir/lib/firmware" "$fwdir/lib/"
++
++ cat <<EOF >> debian/control
++
++Package: $fwpackagename
++Architecture: all
++Description: Linux kernel firmware, version $version
++ This package contains firmware from the Linux kernel, version $version
++EOF
++
++ dpkg-gencontrol -isp -p$fwpackagename -P"$fwdir"
++ dpkg --build "$fwdir" ..
++fi
++
+ # Perform the final magic
+-dpkg-gencontrol -isp
++dpkg-gencontrol -isp -p$packagename
+ dpkg --build "$tmpdir" ..
+
+ exit 0
|
[-]
[+]
|
Added |
patches.kernel.org.tar.bz2/patch-2.6.27.8-rc1
^
|
@@ -0,0 +1,7650 @@
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: Linux 2.6.27.8-rc1
+
+Upstream 2.6.27.8-rc1 release from kernel.org
+
+With makefile change taken out to make rpm happy
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
+index f566ad9..23f3edc 100644
+--- a/Documentation/filesystems/proc.txt
++++ b/Documentation/filesystems/proc.txt
+@@ -44,6 +44,7 @@ Table of Contents
+ 2.14 /proc/<pid>/io - Display the IO accounting fields
+ 2.15 /proc/<pid>/coredump_filter - Core dump filtering settings
+ 2.16 /proc/<pid>/mountinfo - Information about mounts
++ 2.17 /proc/sys/fs/epoll - Configuration options for the epoll interface
+
+ ------------------------------------------------------------------------------
+ Preface
+@@ -2471,4 +2472,30 @@ For more information on mount propagation see:
+
+ Documentation/filesystems/sharedsubtree.txt
+
++2.17 /proc/sys/fs/epoll - Configuration options for the epoll interface
++--------------------------------------------------------
++
++This directory contains configuration options for the epoll(7) interface.
++
++max_user_instances
++------------------
++
++This is the maximum number of epoll file descriptors that a single user can
++have open at a given time. The default value is 128, and should be enough
++for normal users.
++
++max_user_watches
++----------------
++
++Every epoll file descriptor can store a number of files to be monitored
++for event readiness. Each one of these monitored files constitutes a "watch".
++This configuration option sets the maximum number of "watches" that are
++allowed for each user.
++Each "watch" costs roughly 90 bytes on a 32bit kernel, and roughly 160 bytes
++on a 64bit one.
++The current default value for max_user_watches is the 1/32 of the available
++low memory, divided for the "watch" cost in bytes.
++
++
+ ------------------------------------------------------------------------------
++
+#diff --git a/Makefile b/Makefile
+#index b5f52f3..54ddc77 100644
+#--- a/Makefile
+#+++ b/Makefile
+#@@ -1,7 +1,7 @@
+# VERSION = 2
+# PATCHLEVEL = 6
+# SUBLEVEL = 27
+#-EXTRAVERSION = .7
+#+EXTRAVERSION = .8-rc1
+# NAME = Trembling Tortoise
+#
+# # *DOCUMENTATION*
+diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
+index 5d1eb7e..8a7e508 100644
+--- a/arch/ia64/kernel/acpi.c
++++ b/arch/ia64/kernel/acpi.c
+@@ -656,6 +656,30 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
+ return 0;
+ }
+
++int __init early_acpi_boot_init(void)
++{
++ int ret;
++
++ /*
++ * do a partial walk of MADT to determine how many CPUs
++ * we have including offline CPUs
++ */
++ if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
++ printk(KERN_ERR PREFIX "Can't find MADT\n");
++ return 0;
++ }
++
++ ret = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
++ acpi_parse_lsapic, NR_CPUS);
++ if (ret < 1)
++ printk(KERN_ERR PREFIX
++ "Error parsing MADT - no LAPIC entries\n");
++
++ return 0;
++}
++
++
++
+ int __init acpi_boot_init(void)
+ {
+
+@@ -679,11 +703,6 @@ int __init acpi_boot_init(void)
+ printk(KERN_ERR PREFIX
+ "Error parsing LAPIC address override entry\n");
+
+- if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, acpi_parse_lsapic, NR_CPUS)
+- < 1)
+- printk(KERN_ERR PREFIX
+- "Error parsing MADT - no LAPIC entries\n");
+-
+ if (acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0)
+ < 0)
+ printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
+diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
+index de636b2..6030236 100644
+--- a/arch/ia64/kernel/setup.c
++++ b/arch/ia64/kernel/setup.c
+@@ -549,8 +549,12 @@ setup_arch (char **cmdline_p)
+ #ifdef CONFIG_ACPI
+ /* Initialize the ACPI boot-time table parser */
+ acpi_table_init();
++ early_acpi_boot_init();
+ # ifdef CONFIG_ACPI_NUMA
+ acpi_numa_init();
++#ifdef CONFIG_ACPI_HOTPLUG_CPU
++ prefill_possible_map();
++#endif
+ per_cpu_scan_finalize((cpus_weight(early_cpu_possible_map) == 0 ?
+ 32 : cpus_weight(early_cpu_possible_map)),
+ additional_cpus > 0 ? additional_cpus : 0);
+@@ -841,9 +845,6 @@ void __init
+ setup_per_cpu_areas (void)
+ {
+ /* start_kernel() requires this... */
+-#ifdef CONFIG_ACPI_HOTPLUG_CPU
+- prefill_possible_map();
+-#endif
+ }
+
+ /*
+diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
+index 675f1d0..4c771cd 100644
+--- a/arch/parisc/kernel/traps.c
++++ b/arch/parisc/kernel/traps.c
+@@ -24,7 +24,6 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/console.h>
+-#include <linux/kallsyms.h>
+ #include <linux/bug.h>
+
+ #include <asm/assembly.h>
+@@ -51,7 +50,7 @@
+ DEFINE_SPINLOCK(pa_dbit_lock);
+ #endif
+
+-void parisc_show_stack(struct task_struct *t, unsigned long *sp,
++static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
+ struct pt_regs *regs);
+
+ static int printbinary(char *buf, unsigned long x, int nbits)
+@@ -121,18 +120,19 @@ static void print_fr(char *level, struct pt_regs *regs)
+
+ void show_regs(struct pt_regs *regs)
+ {
+- int i;
++ int i, user;
+ char *level;
+ unsigned long cr30, cr31;
+
+- level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
++ user = user_mode(regs);
++ level = user ? KERN_DEBUG : KERN_CRIT;
+
+ print_gr(level, regs);
+
+ for (i = 0; i < 8; i += 4)
+ PRINTREGS(level, regs->sr, "sr", RFMT, i);
+
+- if (user_mode(regs))
++ if (user)
+ print_fr(level, regs);
+
+ cr30 = mfctl(30);
+@@ -145,14 +145,18 @@ void show_regs(struct pt_regs *regs)
+ printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n",
+ level, current_thread_info()->cpu, cr30, cr31);
+ printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
+- printk(level);
+- print_symbol(" IAOQ[0]: %s\n", regs->iaoq[0]);
+- printk(level);
+- print_symbol(" IAOQ[1]: %s\n", regs->iaoq[1]);
+- printk(level);
+- print_symbol(" RP(r2): %s\n", regs->gr[2]);
+-
+- parisc_show_stack(current, NULL, regs);
++
++ if (user) {
++ printk("%s IAOQ[0]: " RFMT "\n", level, regs->iaoq[0]);
++ printk("%s IAOQ[1]: " RFMT "\n", level, regs->iaoq[1]);
++ printk("%s RP(r2): " RFMT "\n", level, regs->gr[2]);
++ } else {
++ printk("%s IAOQ[0]: %pS\n", level, (void *) regs->iaoq[0]);
++ printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
++ printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
++
++ parisc_show_stack(current, NULL, regs);
++ }
+ }
+
+
+@@ -173,20 +177,15 @@ static void do_show_stack(struct unwind_frame_info *info)
+ break;
+
+ if (__kernel_text_address(info->ip)) {
+- printk("%s [<" RFMT ">] ", (i&0x3)==1 ? KERN_CRIT : "", info->ip);
+-#ifdef CONFIG_KALLSYMS
+- print_symbol("%s\n", info->ip);
+-#else
+- if ((i & 0x03) == 0)
+- printk("\n");
+-#endif
++ printk(KERN_CRIT " [<" RFMT ">] %pS\n",
++ info->ip, (void *) info->ip);
+ i++;
+ }
+ }
+- printk("\n");
++ printk(KERN_CRIT "\n");
+ }
+
+-void parisc_show_stack(struct task_struct *task, unsigned long *sp,
++static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
+ struct pt_regs *regs)
+ {
+ struct unwind_frame_info info;
+diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
+index 010a51f..d5c3b45 100644
+--- a/arch/powerpc/platforms/cell/spufs/file.c
++++ b/arch/powerpc/platforms/cell/spufs/file.c
+@@ -390,6 +390,9 @@ static int spufs_ps_fault(struct vm_area_struct *vma,
+ if (offset >= ps_size)
+ return VM_FAULT_SIGBUS;
+
++ if (fatal_signal_pending(current))
++ return VM_FAULT_SIGBUS;
++
+ /*
+ * Because we release the mmap_sem, the context may be destroyed while
+ * we're in spu_wait. Grab an extra reference so it isn't destroyed
+diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
+index 690ca7b..5c73b62 100644
+--- a/arch/powerpc/platforms/cell/spufs/inode.c
++++ b/arch/powerpc/platforms/cell/spufs/inode.c
+@@ -496,6 +496,8 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
+ ret = spufs_context_open(dget(dentry), mntget(mnt));
+ if (ret < 0) {
+ WARN_ON(spufs_rmdir(inode, dentry));
++ if (affinity)
++ mutex_unlock(&gang->aff_mutex);
+ mutex_unlock(&inode->i_mutex);
+ spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
+ goto out;
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index c102af8..7d58e7f 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -1593,6 +1593,11 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+ },
+ },
++ {}
++};
++
++/* second table for DMI checks that should run after early-quirks */
++static struct dmi_system_id __initdata acpi_dmi_table_late[] = {
+ /*
+ * HP laptops which use a DSDT reporting as HP/SB400/10000,
+ * which includes some code which overrides all temperature
+@@ -1721,6 +1726,9 @@ int __init early_acpi_boot_init(void)
+
+ int __init acpi_boot_init(void)
+ {
++ /* those are executed after early-quirks are executed */
++ dmi_check_system(acpi_dmi_table_late);
++
+ /*
+ * If acpi_disabled, bail out
+ * One exception: acpi=ht continues far enough to enumerate LAPICs
+diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+index 84bb395..20bda8c 100644
+--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
++++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+@@ -116,9 +116,20 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
+ u32 i = 0;
+
+ if (cpu_family == CPU_HW_PSTATE) {
+- rdmsr(MSR_PSTATE_STATUS, lo, hi);
+- i = lo & HW_PSTATE_MASK;
+- data->currpstate = i;
++ if (data->currpstate == HW_PSTATE_INVALID) {
++ /* read (initial) hw pstate if not yet set */
++ rdmsr(MSR_PSTATE_STATUS, lo, hi);
++ i = lo & HW_PSTATE_MASK;
++
++ /*
++ * a workaround for family 11h erratum 311 might cause
++ * an "out-of-range Pstate if the core is in Pstate-0
++ */
++ if (i >= data->numps)
++ data->currpstate = HW_PSTATE_0;
++ else
++ data->currpstate = i;
++ }
+ return 0;
+ }
+ do {
+@@ -1117,6 +1128,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
+ }
+
+ data->cpu = pol->cpu;
++ data->currpstate = HW_PSTATE_INVALID;
+
+ if (powernow_k8_cpu_init_acpi(data)) {
+ /*
+diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+index ab48cfe..65cfb5d 100644
+--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
++++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+@@ -5,6 +5,19 @@
+ * http://www.gnu.org/licenses/gpl.html
+ */
+
++
++enum pstate {
++ HW_PSTATE_INVALID = 0xff,
++ HW_PSTATE_0 = 0,
++ HW_PSTATE_1 = 1,
++ HW_PSTATE_2 = 2,
++ HW_PSTATE_3 = 3,
++ HW_PSTATE_4 = 4,
++ HW_PSTATE_5 = 5,
++ HW_PSTATE_6 = 6,
++ HW_PSTATE_7 = 7,
++};
++
+ struct powernow_k8_data {
+ unsigned int cpu;
+
+@@ -23,7 +36,9 @@ struct powernow_k8_data {
+ u32 exttype; /* extended interface = 1 */
+
+ /* keep track of the current fid / vid or pstate */
+- u32 currvid, currfid, currpstate;
++ u32 currvid;
++ u32 currfid;
++ enum pstate currpstate;
+
+ /* the powernow_table includes all frequency and vid/fid pairings:
+ * fid are the lower 8 bits of the index, vid are the upper 8 bits.
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
+index 6b839b1..1b894b7 100644
+--- a/arch/x86/kernel/early-quirks.c
++++ b/arch/x86/kernel/early-quirks.c
+@@ -95,7 +95,8 @@ static void __init nvidia_bugs(int num, int slot, int func)
+
+ }
+
+-static u32 ati_ixp4x0_rev(int num, int slot, int func)
++#if defined(CONFIG_ACPI) && defined(CONFIG_X86_IO_APIC)
++static u32 __init ati_ixp4x0_rev(int num, int slot, int func)
+ {
+ u32 d;
+ u8 b;
+@@ -115,7 +116,6 @@ static u32 ati_ixp4x0_rev(int num, int slot, int func)
+
+ static void __init ati_bugs(int num, int slot, int func)
+ {
+-#if defined(CONFIG_ACPI) && defined (CONFIG_X86_IO_APIC)
+ u32 d;
+ u8 b;
+
+@@ -138,9 +138,56 @@ static void __init ati_bugs(int num, int slot, int func)
+ printk(KERN_INFO "If you got timer trouble "
+ "try acpi_use_timer_override\n");
+ }
+-#endif
+ }
+
++static u32 __init ati_sbx00_rev(int num, int slot, int func)
++{
++ u32 old, d;
++
++ d = read_pci_config(num, slot, func, 0x70);
++ old = d;
++ d &= ~(1<<8);
++ write_pci_config(num, slot, func, 0x70, d);
++ d = read_pci_config(num, slot, func, 0x8);
++ d &= 0xff;
++ write_pci_config(num, slot, func, 0x70, old);
++
++ return d;
++}
++
++static void __init ati_bugs_contd(int num, int slot, int func)
++{
++ u32 d, rev;
++
++ if (acpi_use_timer_override)
++ return;
++
++ rev = ati_sbx00_rev(num, slot, func);
++ if (rev > 0x13)
++ return;
++
++ /* check for IRQ0 interrupt swap */
++ d = read_pci_config(num, slot, func, 0x64);
++ if (!(d & (1<<14)))
++ acpi_skip_timer_override = 1;
++
++ if (acpi_skip_timer_override) {
++ printk(KERN_INFO "SB600 revision 0x%x\n", rev);
++ printk(KERN_INFO "Ignoring ACPI timer override.\n");
++ printk(KERN_INFO "If you got timer trouble "
++ "try acpi_use_timer_override\n");
++ }
++}
++#else
++static void __init ati_bugs(int num, int slot, int func)
++{
++}
++
++static void __init ati_bugs_contd(int num, int slot, int func)
++{
++}
++#endif
++
+ #define QFLAG_APPLY_ONCE 0x1
+ #define QFLAG_APPLIED 0x2
+ #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
+@@ -162,6 +209,8 @@ static struct chipset early_qrk[] __initdata = {
+ PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, fix_hypertransport_config },
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS,
+ PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
++ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
++ PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
+ {}
+ };
+
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 64b5c42..7667443 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -604,7 +604,7 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
+ .callback = dmi_low_memory_corruption,
+ .ident = "Phoenix BIOS",
+ .matches = {
+- DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
++ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"),
+ },
+ },
+ #endif
+diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c
+index 62fa440..62aec7e 100644
+--- a/arch/x86/mm/discontig_32.c
++++ b/arch/x86/mm/discontig_32.c
+@@ -222,6 +222,41 @@ static void __init remap_numa_kva(void)
+ }
+ }
+
++#ifdef CONFIG_HIBERNATION
++/**
++ * resume_map_numa_kva - add KVA mapping to the temporary page tables created
++ * during resume from hibernation
++ * @pgd_base - temporary resume page directory
++ */
++void resume_map_numa_kva(pgd_t *pgd_base)
++{
++ int node;
++
++ for_each_online_node(node) {
++ unsigned long start_va, start_pfn, size, pfn;
++
++ start_va = (unsigned long)node_remap_start_vaddr[node];
++ start_pfn = node_remap_start_pfn[node];
++ size = node_remap_size[node];
++
++ printk(KERN_DEBUG "%s: node %d\n", __FUNCTION__, node);
++
++ for (pfn = 0; pfn < size; pfn += PTRS_PER_PTE) {
++ unsigned long vaddr = start_va + (pfn << PAGE_SHIFT);
++ pgd_t *pgd = pgd_base + pgd_index(vaddr);
++ pud_t *pud = pud_offset(pgd, vaddr);
++ pmd_t *pmd = pmd_offset(pud, vaddr);
++
++ set_pmd(pmd, pfn_pmd(start_pfn + pfn,
++ PAGE_KERNEL_LARGE_EXEC));
++
++ printk(KERN_DEBUG "%s: %08lx -> pfn %08lx\n",
++ __FUNCTION__, vaddr, start_pfn + pfn);
++ }
++ }
++}
++#endif
++
+ static unsigned long calculate_numa_remap_pages(void)
+ {
+ int nid;
+diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c
+index f2b6e3f..81197c6 100644
+--- a/arch/x86/power/hibernate_32.c
++++ b/arch/x86/power/hibernate_32.c
+@@ -12,6 +12,7 @@
+ #include <asm/system.h>
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
++#include <asm/mmzone.h>
+
+ /* Defined in hibernate_asm_32.S */
+ extern int restore_image(void);
+@@ -127,6 +128,9 @@ static int resume_physical_mapping_init(pgd_t *pgd_base)
+ }
+ }
+ }
++
++ resume_map_numa_kva(pgd_base);
++
+ return 0;
+ }
+
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index a4e201b..6bbcf8a 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -1413,7 +1413,7 @@ static void __init xen_reserve_top(void)
+ if (HYPERVISOR_xen_version(XENVER_platform_parameters, &pp) == 0)
+ top = pp.virt_start;
+
+- reserve_top_address(-top + 2 * PAGE_SIZE);
++ reserve_top_address(-top);
+ #endif /* CONFIG_X86_32 */
+ }
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 41b8e7c..9ab3fb9 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -219,7 +219,8 @@ static void gpe_transaction(struct acpi_ec *ec, u8 status)
+ goto unlock;
+ err:
+ /* false interrupt, state didn't change */
+- ++ec->curr->irq_count;
++ if (in_interrupt())
++ ++ec->curr->irq_count;
+ unlock:
+ spin_unlock_irqrestore(&ec->curr_lock, flags);
+ }
+diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
+index d5b4ef8..8d4a568 100644
+--- a/drivers/acpi/pci_slot.c
++++ b/drivers/acpi/pci_slot.c
+@@ -150,7 +150,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
+ }
+
+ snprintf(name, sizeof(name), "%u", (u32)sun);
+- pci_slot = pci_create_slot(pci_bus, device, name);
++ pci_slot = pci_create_slot(pci_bus, device, name, NULL);
+ if (IS_ERR(pci_slot)) {
+ err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
+ kfree(slot);
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 8228ae3..b551cda 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -551,7 +551,7 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ block |= (u64)tf->hob_lbah << 40;
+ block |= (u64)tf->hob_lbam << 32;
+- block |= tf->hob_lbal << 24;
++ block |= (u64)tf->hob_lbal << 24;
+ } else
+ block |= (tf->device & 0xf) << 24;
+
+@@ -1207,7 +1207,7 @@ u64 ata_tf_to_lba48(const struct ata_taskfile *tf)
+
+ sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
+ sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
+- sectors |= (tf->hob_lbal & 0xff) << 24;
++ sectors |= ((u64)(tf->hob_lbal & 0xff)) << 24;
+ sectors |= (tf->lbah & 0xff) << 16;
+ sectors |= (tf->lbam & 0xff) << 8;
+ sectors |= (tf->lbal & 0xff);
+@@ -2428,6 +2428,13 @@ int ata_dev_configure(struct ata_device *dev)
+ }
+ }
+
++ if ((dev->horkage & ATA_HORKAGE_FIRMWARE_WARN) && print_info) {
++ ata_dev_printk(dev, KERN_WARNING, "WARNING: device requires "
++ "firmware update to be fully functional.\n");
++ ata_dev_printk(dev, KERN_WARNING, " contact the vendor "
++ "or visit http://ata.wiki.kernel.org.\n");
++ }
++
+ return 0;
+
+ err_out_nosup:
+@@ -3971,6 +3978,20 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
+ { "ST380817AS", "3.42", ATA_HORKAGE_NONCQ },
+ { "ST3160023AS", "3.42", ATA_HORKAGE_NONCQ },
+
++ /* Seagate NCQ + FLUSH CACHE firmware bug */
++ { "ST31500341AS", "9JU138", ATA_HORKAGE_NONCQ |
++ ATA_HORKAGE_FIRMWARE_WARN },
++ { "ST31000333AS", "9FZ136", ATA_HORKAGE_NONCQ |
++ ATA_HORKAGE_FIRMWARE_WARN },
++ { "ST3640623AS", "9FZ164", ATA_HORKAGE_NONCQ |
++ ATA_HORKAGE_FIRMWARE_WARN },
++ { "ST3640323AS", "9FZ134", ATA_HORKAGE_NONCQ |
++ ATA_HORKAGE_FIRMWARE_WARN },
++ { "ST3320813AS", "9FZ182", ATA_HORKAGE_NONCQ |
++ ATA_HORKAGE_FIRMWARE_WARN },
++ { "ST3320613AS", "9FZ162", ATA_HORKAGE_NONCQ |
++ ATA_HORKAGE_FIRMWARE_WARN },
++
+ /* Blacklist entries taken from Silicon Image 3124/3132
+ Windows driver .inf file - also several Linux problem reports */
+ { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
+diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
+index 2a4c516..bb26a26 100644
+--- a/drivers/ata/libata-sff.c
++++ b/drivers/ata/libata-sff.c
+@@ -1227,10 +1227,19 @@ fsm_start:
+ /* ATA PIO protocol */
+ if (unlikely((status & ATA_DRQ) == 0)) {
+ /* handle BSY=0, DRQ=0 as error */
+- if (likely(status & (ATA_ERR | ATA_DF)))
++ if (likely(status & (ATA_ERR | ATA_DF))) {
+ /* device stops HSM for abort/error */
+ qc->err_mask |= AC_ERR_DEV;
+- else {
++
++ /* If diagnostic failed and this is
++ * IDENTIFY, it's likely a phantom
++ * device. Mark hint.
++ */
++ if (qc->dev->horkage &
++ ATA_HORKAGE_DIAGNOSTIC)
++ qc->err_mask |=
++ AC_ERR_NODEV_HINT;
++ } else {
+ /* HSM violation. Let EH handle this.
+ * Phantom devices also trigger this
+ * condition. Mark hint.
+diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
+index 4f73537..64142c1 100644
+--- a/drivers/firewire/fw-sbp2.c
++++ b/drivers/firewire/fw-sbp2.c
+@@ -365,6 +365,11 @@ static const struct {
+ },
+ /* iPod mini */ {
+ .firmware_revision = 0x0a2700,
++ .model = 0x000022,
++ .workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
++ },
++ /* iPod mini */ {
++ .firmware_revision = 0x0a2700,
+ .model = 0x000023,
+ .workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
+ },
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 59f6ad8..9ed5947 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1049,7 +1049,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+ continue;
+
+ is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
+- seq_printf(s, " gpio-%-3d (%-12s) %s %s",
++ seq_printf(s, " gpio-%-3d (%-20.20s) %s %s",
+ gpio, gdesc->label,
+ is_out ? "out" : "in ",
+ chip->get
+diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
+index 1d6ad34..bad46ea 100644
+--- a/drivers/ieee1394/sbp2.c
++++ b/drivers/ieee1394/sbp2.c
+@@ -402,6 +402,11 @@ static const struct {
+ },
+ /* iPod mini */ {
+ .firmware_revision = 0x0a2700,
++ .model_id = 0x000022,
++ .workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
++ },
++ /* iPod mini */ {
++ .firmware_revision = 0x0a2700,
+ .model_id = 0x000023,
+ .workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
+ },
+diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
+index d0866a3..1830849 100644
+--- a/drivers/infiniband/hw/mlx4/cq.c
++++ b/drivers/infiniband/hw/mlx4/cq.c
+@@ -343,6 +343,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
+ {
+ struct mlx4_ib_dev *dev = to_mdev(ibcq->device);
+ struct mlx4_ib_cq *cq = to_mcq(ibcq);
++ struct mlx4_mtt mtt;
+ int outst_cqe;
+ int err;
+
+@@ -376,10 +377,13 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
+ goto out;
+ }
+
++ mtt = cq->buf.mtt;
++
+ err = mlx4_cq_resize(dev->dev, &cq->mcq, entries, &cq->resize_buf->buf.mtt);
+ if (err)
+ goto err_buf;
+
++ mlx4_mtt_cleanup(dev->dev, &mtt);
+ if (ibcq->uobject) {
+ cq->buf = cq->resize_buf->buf;
+ cq->ibcq.cqe = cq->resize_buf->cqe;
+@@ -406,6 +410,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
+ goto out;
+
+ err_buf:
++ mlx4_mtt_cleanup(dev->dev, &cq->resize_buf->buf.mtt);
+ if (!ibcq->uobject)
+ mlx4_ib_free_cq_buf(dev, &cq->resize_buf->buf,
+ cq->resize_buf->cqe);
+diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
+index e32c24d..c694eaa 100644
+--- a/drivers/input/keyboard/atkbd.c
++++ b/drivers/input/keyboard/atkbd.c
+@@ -868,6 +868,22 @@ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
+ }
+
+ /*
++ * Inventec system with broken key release on volume keys
++ */
++static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)
++{
++ const unsigned int forced_release_keys[] = {
++ 0xae, 0xb0,
++ };
++ int i;
++
++ if (atkbd->set == 2)
++ for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
++ __set_bit(forced_release_keys[i],
++ atkbd->force_release_mask);
++}
++
++/*
+ * atkbd_set_keycode_table() initializes keyboard's keycode table
+ * according to the selected scancode set
+ */
+@@ -1478,6 +1494,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
+ .callback = atkbd_setup_fixup,
+ .driver_data = atkbd_hp_keymap_fixup,
+ },
++ {
++ .ident = "Inventec Symphony",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
++ },
++ .callback = atkbd_setup_fixup,
++ .driver_data = atkbd_inventec_keymap_fixup,
++ },
+ { }
+ };
+
+diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
+index bd5d9de..e6ca401 100644
+--- a/drivers/media/video/compat_ioctl32.c
++++ b/drivers/media/video/compat_ioctl32.c
+@@ -867,6 +867,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
+ case VIDIOC_STREAMON32:
+ case VIDIOC_STREAMOFF32:
+ case VIDIOC_G_PARM:
++ case VIDIOC_S_PARM:
+ case VIDIOC_G_STD:
+ case VIDIOC_S_STD:
+ case VIDIOC_G_TUNER:
+@@ -885,6 +886,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
+ case VIDIOC_S_INPUT32:
+ case VIDIOC_TRY_FMT32:
+ case VIDIOC_S_HW_FREQ_SEEK:
++ case VIDIOC_ENUM_FRAMESIZES:
++ case VIDIOC_ENUM_FRAMEINTERVALS:
+ ret = do_video_ioctl(file, cmd, arg);
+ break;
+
+diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/atl1e/atl1e_hw.c
+index 949e753..c0d5f7c 100644
+--- a/drivers/net/atl1e/atl1e_hw.c
++++ b/drivers/net/atl1e/atl1e_hw.c
+@@ -163,9 +163,6 @@ int atl1e_read_mac_addr(struct atl1e_hw *hw)
+ * atl1e_hash_mc_addr
+ * purpose
+ * set hash value for a multicast address
+- * hash calcu processing :
+- * 1. calcu 32bit CRC for multicast address
+- * 2. reverse crc with MSB to LSB
+ */
+ u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
+ {
+@@ -174,7 +171,6 @@ u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
+ int i;
+
+ crc32 = ether_crc_le(6, mc_addr);
+- crc32 = ~crc32;
+ for (i = 0; i < 32; i++)
+ value |= (((crc32 >> i) & 1) << (31 - i));
+
+diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
+index 6a3893a..c854c96 100644
+--- a/drivers/net/e1000/e1000_ethtool.c
++++ b/drivers/net/e1000/e1000_ethtool.c
+@@ -1774,7 +1774,8 @@ static void e1000_get_wol(struct net_device *netdev,
+
+ /* this function will set ->supported = 0 and return 1 if wol is not
+ * supported by this hardware */
+- if (e1000_wol_exclusion(adapter, wol))
++ if (e1000_wol_exclusion(adapter, wol) ||
++ !device_can_wakeup(&adapter->pdev->dev))
+ return;
+
+ /* apply any specific unsupported masks here */
+@@ -1811,7 +1812,8 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+ if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+ return -EOPNOTSUPP;
+
+- if (e1000_wol_exclusion(adapter, wol))
++ if (e1000_wol_exclusion(adapter, wol) ||
++ !device_can_wakeup(&adapter->pdev->dev))
+ return wol->wolopts ? -EOPNOTSUPP : 0;
+
+ switch (hw->device_id) {
+@@ -1838,6 +1840,8 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= E1000_WUFC_MAG;
+
++ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
++
+ return 0;
+ }
+
+diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
+index ad6da7b..872ea58 100644
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -1180,6 +1180,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
+
+ /* initialize the wol settings based on the eeprom settings */
+ adapter->wol = adapter->eeprom_wol;
++ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ /* print bus type/speed/width info */
+ DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
+diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
+index 33a3ff1..e2a30dd 100644
+--- a/drivers/net/e1000e/ethtool.c
++++ b/drivers/net/e1000e/ethtool.c
+@@ -1681,7 +1681,8 @@ static void e1000_get_wol(struct net_device *netdev,
+ wol->supported = 0;
+ wol->wolopts = 0;
+
+- if (!(adapter->flags & FLAG_HAS_WOL))
++ if (!(adapter->flags & FLAG_HAS_WOL) ||
++ !device_can_wakeup(&adapter->pdev->dev))
+ return;
+
+ wol->supported = WAKE_UCAST | WAKE_MCAST |
+@@ -1719,7 +1720,8 @@ static int e1000_set_wol(struct net_device *netdev,
+ if (wol->wolopts & WAKE_MAGICSECURE)
+ return -EOPNOTSUPP;
+
+- if (!(adapter->flags & FLAG_HAS_WOL))
++ if (!(adapter->flags & FLAG_HAS_WOL) ||
++ !device_can_wakeup(&adapter->pdev->dev))
+ return wol->wolopts ? -EOPNOTSUPP : 0;
+
+ /* these settings will always override what we currently have */
+@@ -1738,6 +1740,8 @@ static int e1000_set_wol(struct net_device *netdev,
+ if (wol->wolopts & WAKE_ARP)
+ adapter->wol |= E1000_WUFC_ARP;
+
++ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
++
+ return 0;
+ }
+
+diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
+index b81c423..660c85a 100644
+--- a/drivers/net/e1000e/netdev.c
++++ b/drivers/net/e1000e/netdev.c
+@@ -4616,6 +4616,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
+
+ /* initialize the wol settings based on the eeprom settings */
+ adapter->wol = adapter->eeprom_wol;
++ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ /* reset the hardware with the new settings */
+ e1000e_reset(adapter);
+diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
+index 58906c9..89964fa 100644
+--- a/drivers/net/igb/igb_ethtool.c
++++ b/drivers/net/igb/igb_ethtool.c
+@@ -1776,7 +1776,8 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+
+ /* this function will set ->supported = 0 and return 1 if wol is not
+ * supported by this hardware */
+- if (igb_wol_exclusion(adapter, wol))
++ if (igb_wol_exclusion(adapter, wol) ||
++ !device_can_wakeup(&adapter->pdev->dev))
+ return;
+
+ /* apply any specific unsupported masks here */
+@@ -1805,7 +1806,8 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+ if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+ return -EOPNOTSUPP;
+
+- if (igb_wol_exclusion(adapter, wol))
++ if (igb_wol_exclusion(adapter, wol) ||
++ !device_can_wakeup(&adapter->pdev->dev))
+ return wol->wolopts ? -EOPNOTSUPP : 0;
+
+ switch (hw->device_id) {
+@@ -1825,6 +1827,8 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= E1000_WUFC_MAG;
+
++ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
++
+ return 0;
+ }
+
+diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
+index 634c4c9..11b5df3 100644
+--- a/drivers/net/igb/igb_main.c
++++ b/drivers/net/igb/igb_main.c
+@@ -1220,6 +1220,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
+
+ /* initialize the wol settings based on the eeprom settings */
+ adapter->wol = adapter->eeprom_wol;
++ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ /* reset the hardware with the new settings */
+ igb_reset(adapter);
+diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
+index 52bf11b..2f68295 100644
+--- a/drivers/net/pcmcia/axnet_cs.c
++++ b/drivers/net/pcmcia/axnet_cs.c
+@@ -787,6 +787,7 @@ static struct pcmcia_device_id axnet_ids[] = {
+ PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2),
+ PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8),
+ PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609),
++ PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875),
+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04),
+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116),
+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058),
+diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
+index ebc1ae6..7d6cf02 100644
+--- a/drivers/net/pcmcia/pcnet_cs.c
++++ b/drivers/net/pcmcia/pcnet_cs.c
+@@ -1697,7 +1697,6 @@ static struct pcmcia_device_id pcnet_ids[] = {
+ PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8),
+ PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76),
+ PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e),
+- PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875),
+ PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f),
+ PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1),
+ PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b),
+diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
+index 20ddb7a..0941589 100644
+--- a/drivers/net/wireless/ath9k/recv.c
++++ b/drivers/net/wireless/ath9k/recv.c
+@@ -52,7 +52,7 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
+ /* setup rx descriptors */
+ ath9k_hw_setuprxdesc(ah,
+ ds,
+- skb_tailroom(skb), /* buffer size */
++ sc->sc_rxbufsize,
+ 0);
+
+ if (sc->sc_rxlink == NULL)
+@@ -1011,7 +1011,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
+
+ pci_dma_sync_single_for_cpu(sc->pdev,
+ bf->bf_buf_addr,
+- skb_tailroom(skb),
++ sc->sc_rxbufsize,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(sc->pdev,
+ bf->bf_buf_addr,
+@@ -1303,8 +1303,7 @@ dma_addr_t ath_skb_map_single(struct ath_softc *sc,
+ * NB: do NOT use skb->len, which is 0 on initialization.
+ * Use skb's entire data area instead.
+ */
+- *pa = pci_map_single(sc->pdev, skb->data,
+- skb_end_pointer(skb) - skb->head, direction);
++ *pa = pci_map_single(sc->pdev, skb->data, sc->sc_rxbufsize, direction);
+ return *pa;
+ }
+
+@@ -1314,6 +1313,5 @@ void ath_skb_unmap_single(struct ath_softc *sc,
+ dma_addr_t *pa)
+ {
+ /* Unmap skb's entire data area */
+- pci_unmap_single(sc->pdev, *pa,
+- skb_end_pointer(skb) - skb->head, direction);
++ pci_unmap_single(sc->pdev, *pa, sc->sc_rxbufsize, direction);
+ }
+diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
+index 0cebbc4..1640096 100644
+--- a/drivers/net/wireless/rtl8187_dev.c
++++ b/drivers/net/wireless/rtl8187_dev.c
+@@ -33,10 +33,13 @@ MODULE_LICENSE("GPL");
+ static struct usb_device_id rtl8187_table[] __devinitdata = {
+ /* Asus */
+ {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
++ /* Belkin */
++ {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B},
+ /* Realtek */
+ {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
+ {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
+ {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
++ {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
+ /* Netgear */
+ {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
+ {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
+diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
+index e2e95b3..101ed49 100644
+--- a/drivers/parport/parport_serial.c
++++ b/drivers/parport/parport_serial.c
+@@ -70,6 +70,8 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc
+ * parallel ports and <S> is the number of serial ports.
+ */
+ card->numports = (dev->subsystem_device & 0xf0) >> 4;
++ if (card->numports > ARRAY_SIZE(card->addr))
++ card->numports = ARRAY_SIZE(card->addr);
+ return 0;
+ }
+
+diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
+index 5a58b07..f9e244d 100644
+--- a/drivers/pci/hotplug/acpiphp.h
++++ b/drivers/pci/hotplug/acpiphp.h
+@@ -50,9 +50,6 @@
+ #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+ #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+
+-/* name size which is used for entries in pcihpfs */
+-#define SLOT_NAME_SIZE 20 /* {_SUN} */
+-
+ struct acpiphp_bridge;
+ struct acpiphp_slot;
+
+@@ -63,9 +60,13 @@ struct slot {
+ struct hotplug_slot *hotplug_slot;
+ struct acpiphp_slot *acpi_slot;
+ struct hotplug_slot_info info;
+- char name[SLOT_NAME_SIZE];
+ };
+
++static inline const char *slot_name(struct slot *slot)
++{
++ return hotplug_slot_name(slot->hotplug_slot);
++}
++
+ /*
+ * struct acpiphp_bridge - PCI bridge information
+ *
+diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
+index 0e496e8..95b536a 100644
+--- a/drivers/pci/hotplug/acpiphp_core.c
++++ b/drivers/pci/hotplug/acpiphp_core.c
+@@ -44,6 +44,9 @@
+
+ #define MY_NAME "acpiphp"
+
++/* name size which is used for entries in pcihpfs */
++#define SLOT_NAME_SIZE 21 /* {_SUN} */
++
+ static int debug;
+ int acpiphp_debug;
+
+@@ -84,7 +87,6 @@ static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
+ .get_adapter_status = get_adapter_status,
+ };
+
+-
+ /**
+ * acpiphp_register_attention - set attention LED callback
+ * @info: must be completely filled with LED callbacks
+@@ -136,7 +138,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ /* enable the specified slot */
+ return acpiphp_enable_slot(slot->acpi_slot);
+@@ -154,7 +156,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
+ struct slot *slot = hotplug_slot->private;
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ /* disable the specified slot */
+ retval = acpiphp_disable_slot(slot->acpi_slot);
+@@ -177,7 +179,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
+ {
+ int retval = -ENODEV;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot));
+
+ if (attention_info && try_module_get(attention_info->owner)) {
+ retval = attention_info->set_attn(hotplug_slot, status);
+@@ -200,7 +202,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = acpiphp_get_power_status(slot->acpi_slot);
+
+@@ -222,7 +224,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ {
+ int retval = -EINVAL;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot));
+
+ if (attention_info && try_module_get(attention_info->owner)) {
+ retval = attention_info->get_attn(hotplug_slot, value);
+@@ -245,7 +247,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = acpiphp_get_latch_status(slot->acpi_slot);
+
+@@ -265,7 +267,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = acpiphp_get_adapter_status(slot->acpi_slot);
+
+@@ -299,7 +301,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ kfree(slot->hotplug_slot);
+ kfree(slot);
+@@ -310,6 +312,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
+ {
+ struct slot *slot;
+ int retval = -ENOMEM;
++ char name[SLOT_NAME_SIZE];
+
+ slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+ if (!slot)
+@@ -321,8 +324,6 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
+
+ slot->hotplug_slot->info = &slot->info;
+
+- slot->hotplug_slot->name = slot->name;
+-
+ slot->hotplug_slot->private = slot;
+ slot->hotplug_slot->release = &release_slot;
+ slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
+@@ -336,11 +337,12 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
+ slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
+
+ acpiphp_slot->slot = slot;
+- snprintf(slot->name, sizeof(slot->name), "%u", slot->acpi_slot->sun);
++ snprintf(name, SLOT_NAME_SIZE, "%u", slot->acpi_slot->sun);
+
+ retval = pci_hp_register(slot->hotplug_slot,
+ acpiphp_slot->bridge->pci_bus,
+- acpiphp_slot->device);
++ acpiphp_slot->device,
++ name);
+ if (retval == -EBUSY)
+ goto error_hpslot;
+ if (retval) {
+@@ -348,7 +350,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
+ goto error_hpslot;
+ }
+
+- info("Slot [%s] registered\n", slot->hotplug_slot->name);
++ info("Slot [%s] registered\n", slot_name(slot));
+
+ return 0;
+ error_hpslot:
+@@ -365,7 +367,7 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
+ struct slot *slot = acpiphp_slot->slot;
+ int retval = 0;
+
+- info ("Slot [%s] unregistered\n", slot->hotplug_slot->name);
++ info("Slot [%s] unregistered\n", slot_name(slot));
+
+ retval = pci_hp_deregister(slot->hotplug_slot);
+ if (retval)
+diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
+index d9769b3..9fff878 100644
+--- a/drivers/pci/hotplug/cpci_hotplug.h
++++ b/drivers/pci/hotplug/cpci_hotplug.h
+@@ -30,6 +30,7 @@
+
+ #include <linux/types.h>
+ #include <linux/pci.h>
++#include <linux/pci_hotplug.h>
+
+ /* PICMG 2.1 R2.0 HS CSR bits: */
+ #define HS_CSR_INS 0x0080
+@@ -69,6 +70,11 @@ struct cpci_hp_controller {
+ struct cpci_hp_controller_ops *ops;
+ };
+
++static inline const char *slot_name(struct slot *slot)
++{
++ return hotplug_slot_name(slot->hotplug_slot);
++}
++
+ extern int cpci_hp_register_controller(struct cpci_hp_controller *controller);
+ extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
+ extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
+diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
+index 9359479..de94f4f 100644
+--- a/drivers/pci/hotplug/cpci_hotplug_core.c
++++ b/drivers/pci/hotplug/cpci_hotplug_core.c
+@@ -108,7 +108,7 @@ enable_slot(struct hotplug_slot *hotplug_slot)
+ struct slot *slot = hotplug_slot->private;
+ int retval = 0;
+
+- dbg("%s - physical_slot = %s", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s", __func__, slot_name(slot));
+
+ if (controller->ops->set_power)
+ retval = controller->ops->set_power(slot, 1);
+@@ -121,25 +121,23 @@ disable_slot(struct hotplug_slot *hotplug_slot)
+ struct slot *slot = hotplug_slot->private;
+ int retval = 0;
+
+- dbg("%s - physical_slot = %s", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s", __func__, slot_name(slot));
+
+ down_write(&list_rwsem);
+
+ /* Unconfigure device */
+- dbg("%s - unconfiguring slot %s",
+- __func__, slot->hotplug_slot->name);
++ dbg("%s - unconfiguring slot %s", __func__, slot_name(slot));
+ if ((retval = cpci_unconfigure_slot(slot))) {
+ err("%s - could not unconfigure slot %s",
+- __func__, slot->hotplug_slot->name);
++ __func__, slot_name(slot));
+ goto disable_error;
+ }
+- dbg("%s - finished unconfiguring slot %s",
+- __func__, slot->hotplug_slot->name);
++ dbg("%s - finished unconfiguring slot %s", __func__, slot_name(slot));
+
+ /* Clear EXT (by setting it) */
+ if (cpci_clear_ext(slot)) {
+ err("%s - could not clear EXT for slot %s",
+- __func__, slot->hotplug_slot->name);
++ __func__, slot_name(slot));
+ retval = -ENODEV;
+ goto disable_error;
+ }
+@@ -214,7 +212,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
+ struct slot *slot = hotplug_slot->private;
+
+ kfree(slot->hotplug_slot->info);
+- kfree(slot->hotplug_slot->name);
+ kfree(slot->hotplug_slot);
+ if (slot->dev)
+ pci_dev_put(slot->dev);
+@@ -222,12 +219,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
+ }
+
+ #define SLOT_NAME_SIZE 6
+-static void
+-make_slot_name(struct slot *slot)
+-{
+- snprintf(slot->hotplug_slot->name,
+- SLOT_NAME_SIZE, "%02x:%02x", slot->bus->number, slot->number);
+-}
+
+ int
+ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
+@@ -235,7 +226,7 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
+ struct slot *slot;
+ struct hotplug_slot *hotplug_slot;
+ struct hotplug_slot_info *info;
+- char *name;
++ char name[SLOT_NAME_SIZE];
+ int status = -ENOMEM;
+ int i;
+
+@@ -262,34 +253,31 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
+ goto error_hpslot;
+ hotplug_slot->info = info;
+
+- name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+- if (!name)
+- goto error_info;
+- hotplug_slot->name = name;
+-
+ slot->bus = bus;
+ slot->number = i;
+ slot->devfn = PCI_DEVFN(i, 0);
+
++ snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i);
++
+ hotplug_slot->private = slot;
+ hotplug_slot->release = &release_slot;
+- make_slot_name(slot);
+ hotplug_slot->ops = &cpci_hotplug_slot_ops;
+
+ /*
+ * Initialize the slot info structure with some known
+ * good values.
+ */
+- dbg("initializing slot %s", slot->hotplug_slot->name);
++ dbg("initializing slot %s", name);
+ info->power_status = cpci_get_power_status(slot);
+ info->attention_status = cpci_get_attention_status(slot);
+
+- dbg("registering slot %s", slot->hotplug_slot->name);
+- status = pci_hp_register(slot->hotplug_slot, bus, i);
++ dbg("registering slot %s", name);
++ status = pci_hp_register(slot->hotplug_slot, bus, i, name);
+ if (status) {
+ err("pci_hp_register failed with error %d", status);
+- goto error_name;
++ goto error_info;
+ }
++ dbg("slot registered with name: %s", slot_name(slot));
+
+ /* Add slot to our internal list */
+ down_write(&list_rwsem);
+@@ -298,8 +286,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
+ up_write(&list_rwsem);
+ }
+ return 0;
+-error_name:
+- kfree(name);
+ error_info:
+ kfree(info);
+ error_hpslot:
+@@ -327,7 +313,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
+ list_del(&slot->slot_list);
+ slots--;
+
+- dbg("deregistering slot %s", slot->hotplug_slot->name);
++ dbg("deregistering slot %s", slot_name(slot));
+ status = pci_hp_deregister(slot->hotplug_slot);
+ if (status) {
+ err("pci_hp_deregister failed with error %d",
+@@ -379,11 +365,10 @@ init_slots(int clear_ins)
+ return -1;
+ }
+ list_for_each_entry(slot, &slot_list, slot_list) {
+- dbg("%s - looking at slot %s",
+- __func__, slot->hotplug_slot->name);
++ dbg("%s - looking at slot %s", __func__, slot_name(slot));
+ if (clear_ins && cpci_check_and_clear_ins(slot))
+ dbg("%s - cleared INS for slot %s",
+- __func__, slot->hotplug_slot->name);
++ __func__, slot_name(slot));
+ dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0));
+ if (dev) {
+ if (update_adapter_status(slot->hotplug_slot, 1))
+@@ -414,8 +399,7 @@ check_slots(void)
+ }
+ extracted = inserted = 0;
+ list_for_each_entry(slot, &slot_list, slot_list) {
+- dbg("%s - looking at slot %s",
+- __func__, slot->hotplug_slot->name);
++ dbg("%s - looking at slot %s", __func__, slot_name(slot));
+ if (cpci_check_and_clear_ins(slot)) {
+ /*
+ * Some broken hardware (e.g. PLX 9054AB) asserts
+@@ -423,35 +407,34 @@ check_slots(void)
+ */
+ if (slot->dev) {
+ warn("slot %s already inserted",
+- slot->hotplug_slot->name);
++ slot_name(slot));
+ inserted++;
+ continue;
+ }
+
+ /* Process insertion */
+- dbg("%s - slot %s inserted",
+- __func__, slot->hotplug_slot->name);
++ dbg("%s - slot %s inserted", __func__, slot_name(slot));
+
+ /* GSM, debug */
+ hs_csr = cpci_get_hs_csr(slot);
+ dbg("%s - slot %s HS_CSR (1) = %04x",
+- __func__, slot->hotplug_slot->name, hs_csr);
++ __func__, slot_name(slot), hs_csr);
+
+ /* Configure device */
+ dbg("%s - configuring slot %s",
+- __func__, slot->hotplug_slot->name);
++ __func__, slot_name(slot));
+ if (cpci_configure_slot(slot)) {
+ err("%s - could not configure slot %s",
+- __func__, slot->hotplug_slot->name);
++ __func__, slot_name(slot));
+ continue;
+ }
+ dbg("%s - finished configuring slot %s",
+- __func__, slot->hotplug_slot->name);
++ __func__, slot_name(slot));
+
+ /* GSM, debug */
+ hs_csr = cpci_get_hs_csr(slot);
+ dbg("%s - slot %s HS_CSR (2) = %04x",
+- __func__, slot->hotplug_slot->name, hs_csr);
++ __func__, slot_name(slot), hs_csr);
+
+ if (update_latch_status(slot->hotplug_slot, 1))
+ warn("failure to update latch file");
+@@ -464,18 +447,18 @@ check_slots(void)
+ /* GSM, debug */
+ hs_csr = cpci_get_hs_csr(slot);
+ dbg("%s - slot %s HS_CSR (3) = %04x",
+- __func__, slot->hotplug_slot->name, hs_csr);
++ __func__, slot_name(slot), hs_csr);
+
+ inserted++;
+ } else if (cpci_check_ext(slot)) {
+ /* Process extraction request */
+ dbg("%s - slot %s extracted",
+- __func__, slot->hotplug_slot->name);
++ __func__, slot_name(slot));
+
+ /* GSM, debug */
+ hs_csr = cpci_get_hs_csr(slot);
+ dbg("%s - slot %s HS_CSR = %04x",
+- __func__, slot->hotplug_slot->name, hs_csr);
++ __func__, slot_name(slot), hs_csr);
+
+ if (!slot->extracting) {
+ if (update_latch_status(slot->hotplug_slot, 0)) {
+@@ -493,7 +476,7 @@ check_slots(void)
+ * bother trying to tell the driver or not?
+ */
+ err("card in slot %s was improperly removed",
+- slot->hotplug_slot->name);
++ slot_name(slot));
+ if (update_adapter_status(slot->hotplug_slot, 0))
+ warn("failure to update adapter file");
+ slot->extracting = 0;
+diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
+index df82b95..829c327 100644
+--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
++++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
+@@ -209,7 +209,7 @@ int cpci_led_on(struct slot* slot)
+ hs_cap + 2,
+ hs_csr)) {
+ err("Could not set LOO for slot %s",
+- slot->hotplug_slot->name);
++ hotplug_slot_name(slot->hotplug_slot));
+ return -ENODEV;
+ }
+ }
+@@ -238,7 +238,7 @@ int cpci_led_off(struct slot* slot)
+ hs_cap + 2,
+ hs_csr)) {
+ err("Could not clear LOO for slot %s",
+- slot->hotplug_slot->name);
++ hotplug_slot_name(slot->hotplug_slot));
+ return -ENODEV;
+ }
+ }
+diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
+index b1decfa..afaf8f6 100644
+--- a/drivers/pci/hotplug/cpqphp.h
++++ b/drivers/pci/hotplug/cpqphp.h
+@@ -449,6 +449,11 @@ extern u8 cpqhp_disk_irq;
+
+ /* inline functions */
+
++static inline char *slot_name(struct slot *slot)
++{
++ return hotplug_slot_name(slot->hotplug_slot);
++}
++
+ /*
+ * return_resource
+ *
+@@ -696,14 +701,6 @@ static inline int get_presence_status(struct controller *ctrl, struct slot *slot
+ return presence_save;
+ }
+
+-#define SLOT_NAME_SIZE 10
+-
+-static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
+-{
+- snprintf(buffer, buffer_size, "%d", slot->number);
+-}
+-
+-
+ static inline int wait_for_ctrl_irq(struct controller *ctrl)
+ {
+ DECLARE_WAITQUEUE(wait, current);
+diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
+index 87a68d2..8514c3a 100644
+--- a/drivers/pci/hotplug/cpqphp_core.c
++++ b/drivers/pci/hotplug/cpqphp_core.c
+@@ -315,14 +315,15 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ kfree(slot->hotplug_slot->info);
+- kfree(slot->hotplug_slot->name);
+ kfree(slot->hotplug_slot);
+ kfree(slot);
+ }
+
++#define SLOT_NAME_SIZE 10
++
+ static int ctrl_slot_setup(struct controller *ctrl,
+ void __iomem *smbios_start,
+ void __iomem *smbios_table)
+@@ -335,6 +336,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
+ u8 slot_number;
+ u8 ctrl_slot;
+ u32 tempdword;
++ char name[SLOT_NAME_SIZE];
+ void __iomem *slot_entry= NULL;
+ int result = -ENOMEM;
+
+@@ -363,16 +365,12 @@ static int ctrl_slot_setup(struct controller *ctrl,
+ if (!hotplug_slot->info)
+ goto error_hpslot;
+ hotplug_slot_info = hotplug_slot->info;
+- hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+-
+- if (!hotplug_slot->name)
+- goto error_info;
+
+ slot->ctrl = ctrl;
+ slot->bus = ctrl->bus;
+ slot->device = slot_device;
+ slot->number = slot_number;
+- dbg("slot->number = %d\n", slot->number);
++ dbg("slot->number = %u\n", slot->number);
+
+ slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
+ slot_entry);
+@@ -418,9 +416,9 @@ static int ctrl_slot_setup(struct controller *ctrl,
+ /* register this slot with the hotplug pci core */
+ hotplug_slot->release = &release_slot;
+ hotplug_slot->private = slot;
+- make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot);
++ snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
+ hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
+-
++
+ hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
+ hotplug_slot_info->attention_status =
+ cpq_get_attention_status(ctrl, slot);
+@@ -436,10 +434,11 @@ static int ctrl_slot_setup(struct controller *ctrl,
+ slot_number);
+ result = pci_hp_register(hotplug_slot,
+ ctrl->pci_dev->bus,
+- slot->device);
++ slot->device,
++ name);
+ if (result) {
+ err("pci_hp_register failed with error %d\n", result);
+- goto error_name;
++ goto error_info;
+ }
+
+ slot->next = ctrl->slot;
+@@ -451,8 +450,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
+ }
+
+ return 0;
+-error_name:
+- kfree(hotplug_slot->name);
+ error_info:
+ kfree(hotplug_slot_info);
+ error_hpslot:
+@@ -638,7 +635,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+ u8 device;
+ u8 function;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
+ return -ENODEV;
+@@ -665,7 +662,7 @@ static int process_SI(struct hotplug_slot *hotplug_slot)
+ u8 device;
+ u8 function;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
+ return -ENODEV;
+@@ -697,7 +694,7 @@ static int process_SS(struct hotplug_slot *hotplug_slot)
+ u8 device;
+ u8 function;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
+ return -ENODEV;
+@@ -720,7 +717,7 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
+ struct slot *slot = hotplug_slot->private;
+ struct controller *ctrl = slot->ctrl;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ return cpqhp_hardware_test(ctrl, value);
+ }
+@@ -731,7 +728,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ struct controller *ctrl = slot->ctrl;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = get_slot_enabled(ctrl, slot);
+ return 0;
+@@ -742,7 +739,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ struct controller *ctrl = slot->ctrl;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = cpq_get_attention_status(ctrl, slot);
+ return 0;
+@@ -753,7 +750,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ struct controller *ctrl = slot->ctrl;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = cpq_get_latch_status(ctrl, slot);
+
+@@ -765,7 +762,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ struct controller *ctrl = slot->ctrl;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = get_presence_status(ctrl, slot);
+
+@@ -777,7 +774,7 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
+ struct slot *slot = hotplug_slot->private;
+ struct controller *ctrl = slot->ctrl;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = ctrl->speed_capability;
+
+@@ -789,7 +786,7 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
+ struct slot *slot = hotplug_slot->private;
+ struct controller *ctrl = slot->ctrl;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ *value = ctrl->speed;
+
+diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
+index 146ca9c..24dcbf1 100644
+--- a/drivers/pci/hotplug/fakephp.c
++++ b/drivers/pci/hotplug/fakephp.c
+@@ -66,7 +66,6 @@ struct dummy_slot {
+ struct pci_dev *dev;
+ struct work_struct remove_work;
+ unsigned long removed;
+- char name[8];
+ };
+
+ static int debug;
+@@ -96,10 +95,13 @@ static void dummy_release(struct hotplug_slot *slot)
+ kfree(dslot);
+ }
+
++#define SLOT_NAME_SIZE 8
++
+ static int add_slot(struct pci_dev *dev)
+ {
+ struct dummy_slot *dslot;
+ struct hotplug_slot *slot;
++ char name[SLOT_NAME_SIZE];
+ int retval = -ENOMEM;
+ static int count = 1;
+
+@@ -119,19 +121,18 @@ static int add_slot(struct pci_dev *dev)
+ if (!dslot)
+ goto error_info;
+
+- slot->name = dslot->name;
+- snprintf(slot->name, sizeof(dslot->name), "fake%d", count++);
+- dbg("slot->name = %s\n", slot->name);
++ snprintf(name, SLOT_NAME_SIZE, "fake%d", count++);
+ slot->ops = &dummy_hotplug_slot_ops;
+ slot->release = &dummy_release;
+ slot->private = dslot;
+
+- retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn));
++ retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn), name);
+ if (retval) {
+ err("pci_hp_register failed with error %d\n", retval);
+ goto error_dslot;
+ }
+
++ dbg("slot->name = %s\n", hotplug_slot_name(slot));
+ dslot->slot = slot;
+ dslot->dev = pci_dev_get(dev);
+ list_add (&dslot->node, &slot_list);
+@@ -167,10 +168,11 @@ static void remove_slot(struct dummy_slot *dslot)
+ {
+ int retval;
+
+- dbg("removing slot %s\n", dslot->slot->name);
++ dbg("removing slot %s\n", hotplug_slot_name(dslot->slot));
+ retval = pci_hp_deregister(dslot->slot);
+ if (retval)
+- err("Problem unregistering a slot %s\n", dslot->slot->name);
++ err("Problem unregistering a slot %s\n",
++ hotplug_slot_name(dslot->slot));
+ }
+
+ /* called from the single-threaded workqueue handler to remove a slot */
+@@ -308,7 +310,7 @@ static int disable_slot(struct hotplug_slot *slot)
+ return -ENODEV;
+ dslot = slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(slot));
+
+ for (func = 7; func >= 0; func--) {
+ dev = pci_get_slot(dslot->dev->bus, dslot->dev->devfn + func);
+diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
+index 612d963..a8d391a 100644
+--- a/drivers/pci/hotplug/ibmphp.h
++++ b/drivers/pci/hotplug/ibmphp.h
+@@ -707,17 +707,16 @@ struct slot {
+ u8 device;
+ u8 number;
+ u8 real_physical_slot_num;
+- char name[100];
+ u32 capabilities;
+ u8 supported_speed;
+ u8 supported_bus_mode;
++ u8 flag; /* this is for disable slot and polling */
++ u8 ctlr_index;
+ struct hotplug_slot *hotplug_slot;
+ struct controller *ctrl;
+ struct pci_func *func;
+ u8 irq[4];
+- u8 flag; /* this is for disable slot and polling */
+ int bit_mode; /* 0 = 32, 1 = 64 */
+- u8 ctlr_index;
+ struct bus_info *bus_on;
+ struct list_head ibm_slot_list;
+ u8 status;
+diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
+index 8467d02..8431246 100644
+--- a/drivers/pci/hotplug/ibmphp_ebda.c
++++ b/drivers/pci/hotplug/ibmphp_ebda.c
+@@ -620,11 +620,14 @@ static u8 calculate_first_slot (u8 slot_num)
+ return first_slot + 1;
+
+ }
++
++#define SLOT_NAME_SIZE 30
++
+ static char *create_file_name (struct slot * slot_cur)
+ {
+ struct opt_rio *opt_vg_ptr = NULL;
+ struct opt_rio_lo *opt_lo_ptr = NULL;
+- static char str[30];
++ static char str[SLOT_NAME_SIZE];
+ int which = 0; /* rxe = 1, chassis = 0 */
+ u8 number = 1; /* either chassis or rxe # */
+ u8 first_slot = 1;
+@@ -736,7 +739,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
+
+ slot = hotplug_slot->private;
+ kfree(slot->hotplug_slot->info);
+- kfree(slot->hotplug_slot->name);
+ kfree(slot->hotplug_slot);
+ slot->ctrl = NULL;
+ slot->bus_on = NULL;
+@@ -768,6 +770,7 @@ static int __init ebda_rsrc_controller (void)
+ int rc;
+ struct slot *tmp_slot;
+ struct list_head *list;
++ char name[SLOT_NAME_SIZE];
+
+ addr = hpc_list_ptr->phys_addr;
+ for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
+@@ -931,12 +934,6 @@ static int __init ebda_rsrc_controller (void)
+ goto error_no_hp_info;
+ }
+
+- hp_slot_ptr->name = kmalloc(30, GFP_KERNEL);
+- if (!hp_slot_ptr->name) {
+- rc = -ENOMEM;
+- goto error_no_hp_name;
+- }
+-
+ tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
+ if (!tmp_slot) {
+ rc = -ENOMEM;
+@@ -1000,9 +997,9 @@ static int __init ebda_rsrc_controller (void)
+ list_for_each (list, &ibmphp_slot_head) {
+ tmp_slot = list_entry (list, struct slot, ibm_slot_list);
+
+- snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
++ snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot));
+ pci_hp_register(tmp_slot->hotplug_slot,
+- pci_find_bus(0, tmp_slot->bus), tmp_slot->device);
++ pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name);
+ }
+
+ print_ebda_hpc ();
+@@ -1012,8 +1009,6 @@ static int __init ebda_rsrc_controller (void)
+ error:
+ kfree (hp_slot_ptr->private);
+ error_no_slot:
+- kfree (hp_slot_ptr->name);
+-error_no_hp_name:
+ kfree (hp_slot_ptr->info);
+ error_no_hp_info:
+ kfree (hp_slot_ptr);
+diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
+index 5f85b1b..4871b96 100644
+--- a/drivers/pci/hotplug/pci_hotplug_core.c
++++ b/drivers/pci/hotplug/pci_hotplug_core.c
+@@ -37,6 +37,7 @@
+ #include <linux/init.h>
+ #include <linux/mount.h>
+ #include <linux/namei.h>
++#include <linux/mutex.h>
+ #include <linux/pci.h>
+ #include <linux/pci_hotplug.h>
+ #include <asm/uaccess.h>
+@@ -61,7 +62,7 @@ static int debug;
+ //////////////////////////////////////////////////////////////////
+
+ static LIST_HEAD(pci_hotplug_slot_list);
+-static DEFINE_SPINLOCK(pci_hotplug_slot_list_lock);
++static DEFINE_MUTEX(pci_hp_mutex);
+
+ /* these strings match up with the values in pci_bus_speed */
+ static char *pci_bus_speed_strings[] = {
+@@ -530,16 +531,12 @@ static struct hotplug_slot *get_slot_from_name (const char *name)
+ struct hotplug_slot *slot;
+ struct list_head *tmp;
+
+- spin_lock(&pci_hotplug_slot_list_lock);
+ list_for_each (tmp, &pci_hotplug_slot_list) {
+ slot = list_entry (tmp, struct hotplug_slot, slot_list);
+- if (strcmp(slot->name, name) == 0)
+- goto out;
++ if (strcmp(hotplug_slot_name(slot), name) == 0)
++ return slot;
+ }
+- slot = NULL;
+-out:
+- spin_unlock(&pci_hotplug_slot_list_lock);
+- return slot;
++ return NULL;
+ }
+
+ /**
+@@ -547,13 +544,15 @@ out:
+ * @bus: bus this slot is on
+ * @slot: pointer to the &struct hotplug_slot to register
+ * @slot_nr: slot number
++ * @name: name registered with kobject core
+ *
+ * Registers a hotplug slot with the pci hotplug subsystem, which will allow
+ * userspace interaction to the slot.
+ *
+ * Returns 0 if successful, anything else for an error.
+ */
+-int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr)
++int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr,
++ const char *name)
+ {
+ int result;
+ struct pci_slot *pci_slot;
+@@ -568,48 +567,29 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr)
+ return -EINVAL;
+ }
+
+- /* Check if we have already registered a slot with the same name. */
+- if (get_slot_from_name(slot->name))
+- return -EEXIST;
++ mutex_lock(&pci_hp_mutex);
+
+ /*
+ * No problems if we call this interface from both ACPI_PCI_SLOT
+ * driver and call it here again. If we've already created the
+ * pci_slot, the interface will simply bump the refcount.
+ */
+- pci_slot = pci_create_slot(bus, slot_nr, slot->name);
+- if (IS_ERR(pci_slot))
+- return PTR_ERR(pci_slot);
+-
+- if (pci_slot->hotplug) {
+- dbg("%s: already claimed\n", __func__);
+- pci_destroy_slot(pci_slot);
+- return -EBUSY;
++ pci_slot = pci_create_slot(bus, slot_nr, name, slot);
++ if (IS_ERR(pci_slot)) {
++ result = PTR_ERR(pci_slot);
++ goto out;
+ }
+
+ slot->pci_slot = pci_slot;
+ pci_slot->hotplug = slot;
+
+- /*
+- * Allow pcihp drivers to override the ACPI_PCI_SLOT name.
+- */
+- if (strcmp(kobject_name(&pci_slot->kobj), slot->name)) {
+- result = kobject_rename(&pci_slot->kobj, slot->name);
+- if (result) {
+- pci_destroy_slot(pci_slot);
+- return result;
+- }
+- }
+-
+- spin_lock(&pci_hotplug_slot_list_lock);
+ list_add(&slot->slot_list, &pci_hotplug_slot_list);
+- spin_unlock(&pci_hotplug_slot_list_lock);
+
+ result = fs_add_slot(pci_slot);
+ kobject_uevent(&pci_slot->kobj, KOBJ_ADD);
+- dbg("Added slot %s to the list\n", slot->name);
+-
+-
++ dbg("Added slot %s to the list\n", name);
++out:
++ mutex_unlock(&pci_hp_mutex);
+ return result;
+ }
+
+@@ -630,21 +610,23 @@ int pci_hp_deregister(struct hotplug_slot *hotplug)
+ if (!hotplug)
+ return -ENODEV;
+
+- temp = get_slot_from_name(hotplug->name);
+- if (temp != hotplug)
++ mutex_lock(&pci_hp_mutex);
++ temp = get_slot_from_name(hotplug_slot_name(hotplug));
++ if (temp != hotplug) {
++ mutex_unlock(&pci_hp_mutex);
+ return -ENODEV;
++ }
+
+- spin_lock(&pci_hotplug_slot_list_lock);
+ list_del(&hotplug->slot_list);
+- spin_unlock(&pci_hotplug_slot_list_lock);
+
+ slot = hotplug->pci_slot;
+ fs_remove_slot(slot);
+- dbg("Removed slot %s from the list\n", hotplug->name);
++ dbg("Removed slot %s from the list\n", hotplug_slot_name(hotplug));
+
+ hotplug->release(hotplug);
+ slot->hotplug = NULL;
+ pci_destroy_slot(slot);
++ mutex_unlock(&pci_hp_mutex);
+
+ return 0;
+ }
+diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
+index 9e6cec6..0187af7 100644
+--- a/drivers/pci/hotplug/pciehp.h
++++ b/drivers/pci/hotplug/pciehp.h
+@@ -61,15 +61,13 @@ extern struct workqueue_struct *pciehp_wq;
+ struct slot {
+ u8 bus;
+ u8 device;
+- u32 number;
+ u8 state;
+- struct timer_list task_event;
+ u8 hp_slot;
++ u32 number;
+ struct controller *ctrl;
+ struct hpc_ops *hpc_ops;
+ struct hotplug_slot *hotplug_slot;
+ struct list_head slot_list;
+- char name[SLOT_NAME_SIZE];
+ unsigned long last_emi_toggle;
+ struct delayed_work work; /* work for button event */
+ struct mutex lock;
+@@ -161,6 +159,11 @@ int pciehp_enable_slot(struct slot *p_slot);
+ int pciehp_disable_slot(struct slot *p_slot);
+ int pcie_enable_notification(struct controller *ctrl);
+
++static inline const char *slot_name(struct slot *slot)
++{
++ return hotplug_slot_name(slot->hotplug_slot);
++}
++
+ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
+ {
+ struct slot *slot;
+diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
+index 4fd5355..6e18736 100644
+--- a/drivers/pci/hotplug/pciehp_core.c
++++ b/drivers/pci/hotplug/pciehp_core.c
+@@ -180,7 +180,8 @@ static struct hotplug_slot_attribute hotplug_slot_attr_lock = {
+ */
+ static void release_slot(struct hotplug_slot *hotplug_slot)
+ {
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__,
++ hotplug_slot_name(hotplug_slot));
+
+ kfree(hotplug_slot->info);
+ kfree(hotplug_slot);
+@@ -191,7 +192,7 @@ static int init_slots(struct controller *ctrl)
+ struct slot *slot;
+ struct hotplug_slot *hotplug_slot;
+ struct hotplug_slot_info *info;
+- int len, dup = 1;
++ char name[SLOT_NAME_SIZE];
+ int retval = -ENOMEM;
+
+ list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
+@@ -205,39 +206,27 @@ static int init_slots(struct controller *ctrl)
+
+ /* register this slot with the hotplug pci core */
+ hotplug_slot->info = info;
+- hotplug_slot->name = slot->name;
+ hotplug_slot->private = slot;
+ hotplug_slot->release = &release_slot;
+ hotplug_slot->ops = &pciehp_hotplug_slot_ops;
+- get_power_status(hotplug_slot, &info->power_status);
+- get_attention_status(hotplug_slot, &info->attention_status);
+- get_latch_status(hotplug_slot, &info->latch_status);
+- get_adapter_status(hotplug_slot, &info->adapter_status);
+ slot->hotplug_slot = hotplug_slot;
++ snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
+
+ dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
+ "slot_device_offset=%x\n", slot->bus, slot->device,
+ slot->hp_slot, slot->number, ctrl->slot_device_offset);
+-duplicate_name:
+ retval = pci_hp_register(hotplug_slot,
+ ctrl->pci_dev->subordinate,
+- slot->device);
++ slot->device,
++ name);
+ if (retval) {
+- /*
+- * If slot N already exists, we'll try to create
+- * slot N-1, N-2 ... N-M, until we overflow.
+- */
+- if (retval == -EEXIST) {
+- len = snprintf(slot->name, SLOT_NAME_SIZE,
+- "%d-%d", slot->number, dup++);
+- if (len < SLOT_NAME_SIZE)
+- goto duplicate_name;
+- else
+- err("duplicate slot name overflow\n");
+- }
+ err("pci_hp_register failed with error %d\n", retval);
+ goto error_info;
+ }
++ get_power_status(hotplug_slot, &info->power_status);
++ get_attention_status(hotplug_slot, &info->attention_status);
++ get_latch_status(hotplug_slot, &info->latch_status);
++ get_adapter_status(hotplug_slot, &info->adapter_status);
+ /* create additional sysfs entries */
+ if (EMI(ctrl)) {
+ retval = sysfs_create_file(&hotplug_slot->pci_slot->kobj,
+@@ -278,7 +267,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ hotplug_slot->info->attention_status = status;
+
+@@ -293,7 +282,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ return pciehp_sysfs_enable_slot(slot);
+ }
+@@ -303,7 +292,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ return pciehp_sysfs_disable_slot(slot);
+ }
+@@ -313,7 +302,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_power_status(slot, value);
+ if (retval < 0)
+@@ -327,7 +316,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_attention_status(slot, value);
+ if (retval < 0)
+@@ -341,7 +330,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_latch_status(slot, value);
+ if (retval < 0)
+@@ -355,7 +344,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = hotplug_slot->private;
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_adapter_status(slot, value);
+ if (retval < 0)
+@@ -370,7 +359,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
+ struct slot *slot = hotplug_slot->private;
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_max_bus_speed(slot, value);
+ if (retval < 0)
+@@ -384,7 +373,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
+ struct slot *slot = hotplug_slot->private;
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
+ if (retval < 0)
+diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
+index 96a5d55..7266fbd 100644
+--- a/drivers/pci/hotplug/pciehp_ctrl.c
++++ b/drivers/pci/hotplug/pciehp_ctrl.c
+@@ -65,7 +65,7 @@ u8 pciehp_handle_attention_button(struct slot *p_slot)
+ /*
+ * Button pressed - See if need to TAKE ACTION!!!
+ */
+- info("Button pressed on Slot(%s)\n", p_slot->name);
++ info("Button pressed on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_BUTTON_PRESS;
+
+ queue_interrupt_event(p_slot, event_type);
+@@ -86,13 +86,13 @@ u8 pciehp_handle_switch_change(struct slot *p_slot)
+ /*
+ * Switch opened
+ */
+- info("Latch open on Slot(%s)\n", p_slot->name);
++ info("Latch open on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_SWITCH_OPEN;
+ } else {
+ /*
+ * Switch closed
+ */
+- info("Latch close on Slot(%s)\n", p_slot->name);
++ info("Latch close on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_SWITCH_CLOSE;
+ }
+
+@@ -117,13 +117,13 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
+ /*
+ * Card Present
+ */
+- info("Card present on Slot(%s)\n", p_slot->name);
++ info("Card present on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_PRESENCE_ON;
+ } else {
+ /*
+ * Not Present
+ */
+- info("Card not present on Slot(%s)\n", p_slot->name);
++ info("Card not present on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_PRESENCE_OFF;
+ }
+
+@@ -143,13 +143,13 @@ u8 pciehp_handle_power_fault(struct slot *p_slot)
+ /*
+ * power fault Cleared
+ */
+- info("Power fault cleared on Slot(%s)\n", p_slot->name);
++ info("Power fault cleared on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_POWER_FAULT_CLEAR;
+ } else {
+ /*
+ * power fault
+ */
+- info("Power fault on Slot(%s)\n", p_slot->name);
++ info("Power fault on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_POWER_FAULT;
+ info("power fault bit %x set\n", 0);
+ }
+@@ -404,11 +404,11 @@ static void handle_button_press_event(struct slot *p_slot)
+ if (getstatus) {
+ p_slot->state = BLINKINGOFF_STATE;
+ info("PCI slot #%s - powering off due to button "
+- "press.\n", p_slot->name);
++ "press.\n", slot_name(p_slot));
+ } else {
+ p_slot->state = BLINKINGON_STATE;
+ info("PCI slot #%s - powering on due to button "
+- "press.\n", p_slot->name);
++ "press.\n", slot_name(p_slot));
+ }
+ /* blink green LED and turn off amber */
+ if (PWR_LED(ctrl))
+@@ -425,7 +425,7 @@ static void handle_button_press_event(struct slot *p_slot)
+ * press the attention again before the 5 sec. limit
+ * expires to cancel hot-add or hot-remove
+ */
+- info("Button cancel on Slot(%s)\n", p_slot->name);
++ info("Button cancel on Slot(%s)\n", slot_name(p_slot));
+ dbg("%s: button cancel\n", __func__);
+ cancel_delayed_work(&p_slot->work);
+ if (p_slot->state == BLINKINGOFF_STATE) {
+@@ -438,7 +438,7 @@ static void handle_button_press_event(struct slot *p_slot)
+ if (ATTN_LED(ctrl))
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+ info("PCI slot #%s - action canceled due to button press\n",
+- p_slot->name);
++ slot_name(p_slot));
+ p_slot->state = STATIC_STATE;
+ break;
+ case POWEROFF_STATE:
+@@ -448,7 +448,7 @@ static void handle_button_press_event(struct slot *p_slot)
+ * this means that the previous attention button action
+ * to hot-add or hot-remove is undergoing
+ */
+- info("Button ignore on Slot(%s)\n", p_slot->name);
++ info("Button ignore on Slot(%s)\n", slot_name(p_slot));
+ update_slot_info(p_slot);
+ break;
+ default:
+@@ -529,7 +529,7 @@ int pciehp_enable_slot(struct slot *p_slot)
+ rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+ if (rc || !getstatus) {
+ info("%s: no adapter on slot(%s)\n", __func__,
+- p_slot->name);
++ slot_name(p_slot));
+ mutex_unlock(&p_slot->ctrl->crit_sect);
+ return -ENODEV;
+ }
+@@ -537,7 +537,7 @@ int pciehp_enable_slot(struct slot *p_slot)
+ rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ if (rc || getstatus) {
+ info("%s: latch open on slot(%s)\n", __func__,
+- p_slot->name);
++ slot_name(p_slot));
+ mutex_unlock(&p_slot->ctrl->crit_sect);
+ return -ENODEV;
+ }
+@@ -547,7 +547,7 @@ int pciehp_enable_slot(struct slot *p_slot)
+ rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (rc || getstatus) {
+ info("%s: already enabled on slot(%s)\n", __func__,
+- p_slot->name);
++ slot_name(p_slot));
+ mutex_unlock(&p_slot->ctrl->crit_sect);
+ return -EINVAL;
+ }
+@@ -582,7 +582,7 @@ int pciehp_disable_slot(struct slot *p_slot)
+ ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+ if (ret || !getstatus) {
+ info("%s: no adapter on slot(%s)\n", __func__,
+- p_slot->name);
++ slot_name(p_slot));
+ mutex_unlock(&p_slot->ctrl->crit_sect);
+ return -ENODEV;
+ }
+@@ -592,7 +592,7 @@ int pciehp_disable_slot(struct slot *p_slot)
+ ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ if (ret || getstatus) {
+ info("%s: latch open on slot(%s)\n", __func__,
+- p_slot->name);
++ slot_name(p_slot));
+ mutex_unlock(&p_slot->ctrl->crit_sect);
+ return -ENODEV;
+ }
+@@ -602,7 +602,7 @@ int pciehp_disable_slot(struct slot *p_slot)
+ ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (ret || !getstatus) {
+ info("%s: already disabled slot(%s)\n", __func__,
+- p_slot->name);
++ slot_name(p_slot));
+ mutex_unlock(&p_slot->ctrl->crit_sect);
+ return -EINVAL;
+ }
+@@ -632,14 +632,14 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
+ break;
+ case POWERON_STATE:
+ info("Slot %s is already in powering on state\n",
+- p_slot->name);
++ slot_name(p_slot));
+ break;
+ case BLINKINGOFF_STATE:
+ case POWEROFF_STATE:
+- info("Already enabled on slot %s\n", p_slot->name);
++ info("Already enabled on slot %s\n", slot_name(p_slot));
+ break;
+ default:
+- err("Not a valid state on slot %s\n", p_slot->name);
++ err("Not a valid state on slot %s\n", slot_name(p_slot));
+ break;
+ }
+ mutex_unlock(&p_slot->lock);
+@@ -664,14 +664,14 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
+ break;
+ case POWEROFF_STATE:
+ info("Slot %s is already in powering off state\n",
+- p_slot->name);
++ slot_name(p_slot));
+ break;
+ case BLINKINGON_STATE:
+ case POWERON_STATE:
+- info("Already disabled on slot %s\n", p_slot->name);
++ info("Already disabled on slot %s\n", slot_name(p_slot));
+ break;
+ default:
+- err("Not a valid state on slot %s\n", p_slot->name);
++ err("Not a valid state on slot %s\n", slot_name(p_slot));
+ break;
+ }
+ mutex_unlock(&p_slot->lock);
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index 9d934dd..d3cf6f9 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -1044,7 +1044,6 @@ static int pcie_init_slot(struct controller *ctrl)
+ slot->device = ctrl->slot_device_offset + slot->hp_slot;
+ slot->hpc_ops = ctrl->hpc_ops;
+ slot->number = ctrl->first_slot;
+- snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
+ mutex_init(&slot->lock);
+ INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
+ list_add(&slot->slot_list, &ctrl->slot_list);
+diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
+index 9b714ea..23be8a2 100644
+--- a/drivers/pci/hotplug/rpaphp_slot.c
++++ b/drivers/pci/hotplug/rpaphp_slot.c
+@@ -43,7 +43,7 @@ static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
+ void dealloc_slot_struct(struct slot *slot)
+ {
+ kfree(slot->hotplug_slot->info);
+- kfree(slot->hotplug_slot->name);
++ kfree(slot->name);
+ kfree(slot->hotplug_slot);
+ kfree(slot);
+ }
+@@ -63,11 +63,9 @@ struct slot *alloc_slot_struct(struct device_node *dn,
+ GFP_KERNEL);
+ if (!slot->hotplug_slot->info)
+ goto error_hpslot;
+- slot->hotplug_slot->name = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
+- if (!slot->hotplug_slot->name)
++ slot->name = kstrdup(drc_name, GFP_KERNEL);
++ if (!slot->name)
+ goto error_info;
+- slot->name = slot->hotplug_slot->name;
+- strcpy(slot->name, drc_name);
+ slot->dn = dn;
+ slot->index = drc_index;
+ slot->power_domain = power_domain;
+@@ -137,7 +135,7 @@ int rpaphp_register_slot(struct slot *slot)
+ slotno = PCI_SLOT(PCI_DN(slot->dn->child)->devfn);
+ else
+ slotno = -1;
+- retval = pci_hp_register(php_slot, slot->bus, slotno);
++ retval = pci_hp_register(php_slot, slot->bus, slotno, slot->name);
+ if (retval) {
+ err("pci_hp_register failed with error %d\n", retval);
+ return retval;
+diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
+index 410fe03..d748698 100644
+--- a/drivers/pci/hotplug/sgi_hotplug.c
++++ b/drivers/pci/hotplug/sgi_hotplug.c
+@@ -161,7 +161,8 @@ static int sn_pci_bus_valid(struct pci_bus *pci_bus)
+ }
+
+ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
+- struct pci_bus *pci_bus, int device)
++ struct pci_bus *pci_bus, int device,
++ char *name)
+ {
+ struct pcibus_info *pcibus_info;
+ struct slot *slot;
+@@ -173,15 +174,9 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
+ return -ENOMEM;
+ bss_hotplug_slot->private = slot;
+
+- bss_hotplug_slot->name = kmalloc(SN_SLOT_NAME_SIZE, GFP_KERNEL);
+- if (!bss_hotplug_slot->name) {
+- kfree(bss_hotplug_slot->private);
+- return -ENOMEM;
+- }
+-
+ slot->device_num = device;
+ slot->pci_bus = pci_bus;
+- sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
++ sprintf(name, "%04x:%02x:%02x",
+ pci_domain_nr(pci_bus),
+ ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
+ device + 1);
+@@ -608,7 +603,6 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
+ static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
+ {
+ kfree(bss_hotplug_slot->info);
+- kfree(bss_hotplug_slot->name);
+ kfree(bss_hotplug_slot->private);
+ kfree(bss_hotplug_slot);
+ }
+@@ -618,6 +612,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
+ int device;
+ struct pci_slot *pci_slot;
+ struct hotplug_slot *bss_hotplug_slot;
++ char name[SN_SLOT_NAME_SIZE];
+ int rc = 0;
+
+ /*
+@@ -645,15 +640,14 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
+ }
+
+ if (sn_hp_slot_private_alloc(bss_hotplug_slot,
+- pci_bus, device)) {
++ pci_bus, device, name)) {
+ rc = -ENOMEM;
+ goto alloc_err;
+ }
+-
+ bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
+ bss_hotplug_slot->release = &sn_release_slot;
+
+- rc = pci_hp_register(bss_hotplug_slot, pci_bus, device);
++ rc = pci_hp_register(bss_hotplug_slot, pci_bus, device, name);
+ if (rc)
+ goto register_err;
+
+diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
+index 8a026f7..4d9fed0 100644
+--- a/drivers/pci/hotplug/shpchp.h
++++ b/drivers/pci/hotplug/shpchp.h
+@@ -69,15 +69,13 @@ struct slot {
+ u8 state;
+ u8 presence_save;
+ u8 pwr_save;
+- struct timer_list task_event;
+- u8 hp_slot;
+ struct controller *ctrl;
+ struct hpc_ops *hpc_ops;
+ struct hotplug_slot *hotplug_slot;
+ struct list_head slot_list;
+- char name[SLOT_NAME_SIZE];
+ struct delayed_work work; /* work for button event */
+ struct mutex lock;
++ u8 hp_slot;
+ };
+
+ struct event_info {
+@@ -169,6 +167,11 @@ extern void cleanup_slots(struct controller *ctrl);
+ extern void shpchp_queue_pushbutton_work(struct work_struct *work);
+ extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
+
++static inline const char *slot_name(struct slot *slot)
++{
++ return hotplug_slot_name(slot->hotplug_slot);
++}
++
+ #ifdef CONFIG_ACPI
+ #include <linux/pci-acpi.h>
+ static inline int get_hp_params_from_firmware(struct pci_dev *dev,
+diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
+index cc38615..7af9191 100644
+--- a/drivers/pci/hotplug/shpchp_core.c
++++ b/drivers/pci/hotplug/shpchp_core.c
+@@ -89,7 +89,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = hotplug_slot->private;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ kfree(slot->hotplug_slot->info);
+ kfree(slot->hotplug_slot);
+@@ -101,8 +101,9 @@ static int init_slots(struct controller *ctrl)
+ struct slot *slot;
+ struct hotplug_slot *hotplug_slot;
+ struct hotplug_slot_info *info;
++ char name[SLOT_NAME_SIZE];
+ int retval = -ENOMEM;
+- int i, len, dup = 1;
++ int i;
+
+ for (i = 0; i < ctrl->num_slots; i++) {
+ slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+@@ -119,8 +120,6 @@ static int init_slots(struct controller *ctrl)
+ goto error_hpslot;
+ hotplug_slot->info = info;
+
+- hotplug_slot->name = slot->name;
+-
+ slot->hp_slot = i;
+ slot->ctrl = ctrl;
+ slot->bus = ctrl->pci_dev->subordinate->number;
+@@ -133,37 +132,24 @@ static int init_slots(struct controller *ctrl)
+ /* register this slot with the hotplug pci core */
+ hotplug_slot->private = slot;
+ hotplug_slot->release = &release_slot;
+- snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
++ snprintf(name, SLOT_NAME_SIZE, "%d", slot->number);
+ hotplug_slot->ops = &shpchp_hotplug_slot_ops;
+
+- get_power_status(hotplug_slot, &info->power_status);
+- get_attention_status(hotplug_slot, &info->attention_status);
+- get_latch_status(hotplug_slot, &info->latch_status);
+- get_adapter_status(hotplug_slot, &info->adapter_status);
+-
+ dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
+ "slot_device_offset=%x\n", slot->bus, slot->device,
+ slot->hp_slot, slot->number, ctrl->slot_device_offset);
+-duplicate_name:
+ retval = pci_hp_register(slot->hotplug_slot,
+- ctrl->pci_dev->subordinate, slot->device);
++ ctrl->pci_dev->subordinate, slot->device, name);
+ if (retval) {
+- /*
+- * If slot N already exists, we'll try to create
+- * slot N-1, N-2 ... N-M, until we overflow.
+- */
+- if (retval == -EEXIST) {
+- len = snprintf(slot->name, SLOT_NAME_SIZE,
+- "%d-%d", slot->number, dup++);
+- if (len < SLOT_NAME_SIZE)
+- goto duplicate_name;
+- else
+- err("duplicate slot name overflow\n");
+- }
+ err("pci_hp_register failed with error %d\n", retval);
+ goto error_info;
+ }
+
++ get_power_status(hotplug_slot, &info->power_status);
++ get_attention_status(hotplug_slot, &info->attention_status);
++ get_latch_status(hotplug_slot, &info->latch_status);
++ get_adapter_status(hotplug_slot, &info->adapter_status);
++
+ list_add(&slot->slot_list, &ctrl->slot_list);
+ }
+
+@@ -201,7 +187,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+ {
+ struct slot *slot = get_slot(hotplug_slot);
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ hotplug_slot->info->attention_status = status;
+ slot->hpc_ops->set_attention_status(slot, status);
+@@ -213,7 +199,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = get_slot(hotplug_slot);
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ return shpchp_sysfs_enable_slot(slot);
+ }
+@@ -222,7 +208,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot)
+ {
+ struct slot *slot = get_slot(hotplug_slot);
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ return shpchp_sysfs_disable_slot(slot);
+ }
+@@ -232,7 +218,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = get_slot(hotplug_slot);
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_power_status(slot, value);
+ if (retval < 0)
+@@ -246,7 +232,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = get_slot(hotplug_slot);
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_attention_status(slot, value);
+ if (retval < 0)
+@@ -260,7 +246,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = get_slot(hotplug_slot);
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_latch_status(slot, value);
+ if (retval < 0)
+@@ -274,7 +260,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
+ struct slot *slot = get_slot(hotplug_slot);
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_adapter_status(slot, value);
+ if (retval < 0)
+@@ -289,7 +275,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
+ struct slot *slot = get_slot(hotplug_slot);
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_max_bus_speed(slot, value);
+ if (retval < 0)
+@@ -303,7 +289,7 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
+ struct slot *slot = get_slot(hotplug_slot);
+ int retval;
+
+- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
++ dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
+
+ retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
+ if (retval < 0)
+diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
+index dfb5393..919b1ee 100644
+--- a/drivers/pci/hotplug/shpchp_ctrl.c
++++ b/drivers/pci/hotplug/shpchp_ctrl.c
+@@ -70,7 +70,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
+ /*
+ * Button pressed - See if need to TAKE ACTION!!!
+ */
+- info("Button pressed on Slot(%s)\n", p_slot->name);
++ info("Button pressed on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_BUTTON_PRESS;
+
+ queue_interrupt_event(p_slot, event_type);
+@@ -98,7 +98,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
+ /*
+ * Switch opened
+ */
+- info("Latch open on Slot(%s)\n", p_slot->name);
++ info("Latch open on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_SWITCH_OPEN;
+ if (p_slot->pwr_save && p_slot->presence_save) {
+ event_type = INT_POWER_FAULT;
+@@ -108,7 +108,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
+ /*
+ * Switch closed
+ */
+- info("Latch close on Slot(%s)\n", p_slot->name);
++ info("Latch close on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_SWITCH_CLOSE;
+ }
+
+@@ -135,13 +135,13 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
+ /*
+ * Card Present
+ */
+- info("Card present on Slot(%s)\n", p_slot->name);
++ info("Card present on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_PRESENCE_ON;
+ } else {
+ /*
+ * Not Present
+ */
+- info("Card not present on Slot(%s)\n", p_slot->name);
++ info("Card not present on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_PRESENCE_OFF;
+ }
+
+@@ -164,14 +164,14 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
+ /*
+ * Power fault Cleared
+ */
+- info("Power fault cleared on Slot(%s)\n", p_slot->name);
++ info("Power fault cleared on Slot(%s)\n", slot_name(p_slot));
+ p_slot->status = 0x00;
+ event_type = INT_POWER_FAULT_CLEAR;
+ } else {
+ /*
+ * Power fault
+ */
+- info("Power fault on Slot(%s)\n", p_slot->name);
++ info("Power fault on Slot(%s)\n", slot_name(p_slot));
+ event_type = INT_POWER_FAULT;
+ /* set power fault status for this board */
+ p_slot->status = 0xFF;
+@@ -493,11 +493,11 @@ static void handle_button_press_event(struct slot *p_slot)
+ if (getstatus) {
+ p_slot->state = BLINKINGOFF_STATE;
+ info("PCI slot #%s - powering off due to button "
+- "press.\n", p_slot->name);
++ "press.\n", slot_name(p_slot));
+ } else {
+ p_slot->state = BLINKINGON_STATE;
+ info("PCI slot #%s - powering on due to button "
+- "press.\n", p_slot->name);
++ "press.\n", slot_name(p_slot));
+ }
+ /* blink green LED and turn off amber */
+ p_slot->hpc_ops->green_led_blink(p_slot);
+@@ -512,7 +512,7 @@ static void handle_button_press_event(struct slot *p_slot)
+ * press the attention again before the 5 sec. limit
+ * expires to cancel hot-add or hot-remove
+ */
+- info("Button cancel on Slot(%s)\n", p_slot->name);
++ info("Button cancel on Slot(%s)\n", slot_name(p_slot));
+ dbg("%s: button cancel\n", __func__);
+ cancel_delayed_work(&p_slot->work);
+ if (p_slot->state == BLINKINGOFF_STATE)
+@@ -521,7 +521,7 @@ static void handle_button_press_event(struct slot *p_slot)
+ p_slot->hpc_ops->green_led_off(p_slot);
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+ info("PCI slot #%s - action canceled due to button press\n",
+- p_slot->name);
++ slot_name(p_slot));
+ p_slot->state = STATIC_STATE;
+ break;
+ case POWEROFF_STATE:
+@@ -531,7 +531,7 @@ static void handle_button_press_event(struct slot *p_slot)
+ * this means that the previous attention button action
+ * to hot-add or hot-remove is undergoing
+ */
+- info("Button ignore on Slot(%s)\n", p_slot->name);
++ info("Button ignore on Slot(%s)\n", slot_name(p_slot));
+ update_slot_info(p_slot);
+ break;
+ default:
+@@ -574,17 +574,17 @@ static int shpchp_enable_slot (struct slot *p_slot)
+ mutex_lock(&p_slot->ctrl->crit_sect);
+ rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+ if (rc || !getstatus) {
+- info("No adapter on slot(%s)\n", p_slot->name);
++ info("No adapter on slot(%s)\n", slot_name(p_slot));
+ goto out;
+ }
+ rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ if (rc || getstatus) {
+- info("Latch open on slot(%s)\n", p_slot->name);
++ info("Latch open on slot(%s)\n", slot_name(p_slot));
+ goto out;
+ }
+ rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (rc || getstatus) {
+- info("Already enabled on slot(%s)\n", p_slot->name);
++ info("Already enabled on slot(%s)\n", slot_name(p_slot));
+ goto out;
+ }
+
+@@ -633,17 +633,17 @@ static int shpchp_disable_slot (struct slot *p_slot)
+
+ rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+ if (rc || !getstatus) {
+- info("No adapter on slot(%s)\n", p_slot->name);
++ info("No adapter on slot(%s)\n", slot_name(p_slot));
+ goto out;
+ }
+ rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ if (rc || getstatus) {
+- info("Latch open on slot(%s)\n", p_slot->name);
++ info("Latch open on slot(%s)\n", slot_name(p_slot));
+ goto out;
+ }
+ rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (rc || !getstatus) {
+- info("Already disabled slot(%s)\n", p_slot->name);
++ info("Already disabled slot(%s)\n", slot_name(p_slot));
+ goto out;
+ }
+
+@@ -671,14 +671,14 @@ int shpchp_sysfs_enable_slot(struct slot *p_slot)
+ break;
+ case POWERON_STATE:
+ info("Slot %s is already in powering on state\n",
+- p_slot->name);
++ slot_name(p_slot));
+ break;
+ case BLINKINGOFF_STATE:
+ case POWEROFF_STATE:
+- info("Already enabled on slot %s\n", p_slot->name);
++ info("Already enabled on slot %s\n", slot_name(p_slot));
+ break;
+ default:
+- err("Not a valid state on slot %s\n", p_slot->name);
++ err("Not a valid state on slot %s\n", slot_name(p_slot));
+ break;
+ }
+ mutex_unlock(&p_slot->lock);
+@@ -703,14 +703,14 @@ int shpchp_sysfs_disable_slot(struct slot *p_slot)
+ break;
+ case POWEROFF_STATE:
+ info("Slot %s is already in powering off state\n",
+- p_slot->name);
++ slot_name(p_slot));
+ break;
+ case BLINKINGON_STATE:
+ case POWERON_STATE:
+- info("Already disabled on slot %s\n", p_slot->name);
++ info("Already disabled on slot %s\n", slot_name(p_slot));
+ break;
+ default:
+- err("Not a valid state on slot %s\n", p_slot->name);
++ err("Not a valid state on slot %s\n", slot_name(p_slot));
+ break;
+ }
+ mutex_unlock(&p_slot->lock);
+diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
+index 7e5b85c..b703b09 100644
+--- a/drivers/pci/slot.c
++++ b/drivers/pci/slot.c
+@@ -73,18 +73,100 @@ static struct kobj_type pci_slot_ktype = {
+ .default_attrs = pci_slot_default_attrs,
+ };
+
++static char *make_slot_name(const char *name)
++{
++ char *new_name;
++ int len, max, dup;
++
++ new_name = kstrdup(name, GFP_KERNEL);
++ if (!new_name)
++ return NULL;
++
++ /*
++ * Make sure we hit the realloc case the first time through the
++ * loop. 'len' will be strlen(name) + 3 at that point which is
++ * enough space for "name-X" and the trailing NUL.
++ */
++ len = strlen(name) + 2;
++ max = 1;
++ dup = 1;
++
++ for (;;) {
++ struct kobject *dup_slot;
++ dup_slot = kset_find_obj(pci_slots_kset, new_name);
++ if (!dup_slot)
++ break;
++ kobject_put(dup_slot);
++ if (dup == max) {
++ len++;
++ max *= 10;
++ kfree(new_name);
++ new_name = kmalloc(len, GFP_KERNEL);
++ if (!new_name)
++ break;
++ }
++ sprintf(new_name, "%s-%d", name, dup++);
++ }
++
++ return new_name;
++}
++
++static int rename_slot(struct pci_slot *slot, const char *name)
++{
++ int result = 0;
++ char *slot_name;
++
++ if (strcmp(pci_slot_name(slot), name) == 0)
++ return result;
++
++ slot_name = make_slot_name(name);
++ if (!slot_name)
++ return -ENOMEM;
++
++ result = kobject_rename(&slot->kobj, slot_name);
++ kfree(slot_name);
++
++ return result;
++}
++
++static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)
++{
++ struct pci_slot *slot;
++ /*
++ * We already hold pci_bus_sem so don't worry
++ */
++ list_for_each_entry(slot, &parent->slots, list)
++ if (slot->number == slot_nr) {
++ kobject_get(&slot->kobj);
++ return slot;
++ }
++
++ return NULL;
++}
++
+ /**
+ * pci_create_slot - create or increment refcount for physical PCI slot
+ * @parent: struct pci_bus of parent bridge
+ * @slot_nr: PCI_SLOT(pci_dev->devfn) or -1 for placeholder
+ * @name: user visible string presented in /sys/bus/pci/slots/<name>
++ * @hotplug: set if caller is hotplug driver, NULL otherwise
+ *
+ * PCI slots have first class attributes such as address, speed, width,
+ * and a &struct pci_slot is used to manage them. This interface will
+ * either return a new &struct pci_slot to the caller, or if the pci_slot
+ * already exists, its refcount will be incremented.
+ *
+- * Slots are uniquely identified by a @pci_bus, @slot_nr, @name tuple.
++ * Slots are uniquely identified by a @pci_bus, @slot_nr tuple.
++ *
++ * There are known platforms with broken firmware that assign the same
++ * name to multiple slots. Workaround these broken platforms by renaming
++ * the slots on behalf of the caller. If firmware assigns name N to
++ * multiple slots:
++ *
++ * The first slot is assigned N
++ * The second slot is assigned N-1
++ * The third slot is assigned N-2
++ * etc.
+ *
+ * Placeholder slots:
+ * In most cases, @pci_bus, @slot_nr will be sufficient to uniquely identify
+@@ -93,12 +175,8 @@ static struct kobj_type pci_slot_ktype = {
+ * the slot. In this scenario, the caller may pass -1 for @slot_nr.
+ *
+ * The following semantics are imposed when the caller passes @slot_nr ==
+- * -1. First, the check for existing %struct pci_slot is skipped, as the
+- * caller may know about several unpopulated slots on a given %struct
+- * pci_bus, and each slot would have a @slot_nr of -1. Uniqueness for
+- * these slots is then determined by the @name parameter. We expect
+- * kobject_init_and_add() to warn us if the caller attempts to create
+- * multiple slots with the same name. The other change in semantics is
++ * -1. First, we no longer check for an existing %struct pci_slot, as there
++ * may be many slots with @slot_nr of -1. The other change in semantics is
+ * user-visible, which is the 'address' parameter presented in sysfs will
+ * consist solely of a dddd:bb tuple, where dddd is the PCI domain of the
+ * %struct pci_bus and bb is the bus number. In other words, the devfn of
+@@ -106,47 +184,57 @@ static struct kobj_type pci_slot_ktype = {
+ */
+
+ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
+- const char *name)
++ const char *name,
++ struct hotplug_slot *hotplug)
+ {
+ struct pci_slot *slot;
+- int err;
++ int err = 0;
++ char *slot_name = NULL;
+
+ down_write(&pci_bus_sem);
+
+ if (slot_nr == -1)
+ goto placeholder;
+
+- /* If we've already created this slot, bump refcount and return. */
+- list_for_each_entry(slot, &parent->slots, list) {
+- if (slot->number == slot_nr) {
+- kobject_get(&slot->kobj);
+- pr_debug("%s: inc refcount to %d on %04x:%02x:%02x\n",
+- __func__,
+- atomic_read(&slot->kobj.kref.refcount),
+- pci_domain_nr(parent), parent->number,
+- slot_nr);
+- goto out;
++ /*
++ * Hotplug drivers are allowed to rename an existing slot,
++ * but only if not already claimed.
++ */
++ slot = get_slot(parent, slot_nr);
++ if (slot) {
++ if (hotplug) {
++ if ((err = slot->hotplug ? -EBUSY : 0)
++ || (err = rename_slot(slot, name))) {
++ kobject_put(&slot->kobj);
++ slot = NULL;
++ goto err;
++ }
+ }
++ goto out;
+ }
+
+ placeholder:
+ slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+ if (!slot) {
+- slot = ERR_PTR(-ENOMEM);
+- goto out;
++ err = -ENOMEM;
++ goto err;
+ }
+
+ slot->bus = parent;
+ slot->number = slot_nr;
+
+ slot->kobj.kset = pci_slots_kset;
+- err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
+- "%s", name);
+- if (err) {
+- printk(KERN_ERR "Unable to register kobject %s\n", name);
++ slot_name = make_slot_name(name);
++ if (!slot_name) {
++ err = -ENOMEM;
+ goto err;
+ }
+
++ err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
++ "%s", slot_name);
++ if (err)
++ goto err;
++
+ INIT_LIST_HEAD(&slot->list);
+ list_add(&slot->list, &parent->slots);
+
+@@ -154,10 +242,10 @@ placeholder:
+ pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
+ __func__, pci_domain_nr(parent), parent->number, slot_nr);
+
+- out:
++out:
+ up_write(&pci_bus_sem);
+ return slot;
+- err:
++err:
+ kfree(slot);
+ slot = ERR_PTR(err);
+ goto out;
+@@ -203,7 +291,6 @@ EXPORT_SYMBOL_GPL(pci_update_slot_number);
+ * just call kobject_put on its kobj and let our release methods do the
+ * rest.
+ */
+-
+ void pci_destroy_slot(struct pci_slot *slot)
+ {
+ pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__,
+diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
+index d47d363..b5fc978 100644
+--- a/drivers/spi/pxa2xx_spi.c
++++ b/drivers/spi/pxa2xx_spi.c
+@@ -348,21 +348,21 @@ static int map_dma_buffers(struct driver_data *drv_data)
+ } else
+ drv_data->tx_map_len = drv_data->len;
+
+- /* Stream map the rx buffer */
+- drv_data->rx_dma = dma_map_single(dev, drv_data->rx,
+- drv_data->rx_map_len,
+- DMA_FROM_DEVICE);
+- if (dma_mapping_error(dev, drv_data->rx_dma))
+- return 0;
+-
+- /* Stream map the tx buffer */
++ /* Stream map the tx buffer. Always do DMA_TO_DEVICE first
++ * so we flush the cache *before* invalidating it, in case
++ * the tx and rx buffers overlap.
++ */
+ drv_data->tx_dma = dma_map_single(dev, drv_data->tx,
+- drv_data->tx_map_len,
+- DMA_TO_DEVICE);
++ drv_data->tx_map_len, DMA_TO_DEVICE);
++ if (dma_mapping_error(dev, drv_data->tx_dma))
++ return 0;
+
+- if (dma_mapping_error(dev, drv_data->tx_dma)) {
+- dma_unmap_single(dev, drv_data->rx_dma,
++ /* Stream map the rx buffer */
++ drv_data->rx_dma = dma_map_single(dev, drv_data->rx,
+ drv_data->rx_map_len, DMA_FROM_DEVICE);
++ if (dma_mapping_error(dev, drv_data->rx_dma)) {
++ dma_unmap_single(dev, drv_data->tx_dma,
++ drv_data->tx_map_len, DMA_TO_DEVICE);
+ return 0;
+ }
+
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 659b3d9..428b599 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -172,7 +172,6 @@ static struct usb_interface_descriptor rndis_data_intf __initdata = {
+ .bDescriptorType = USB_DT_INTERFACE,
+
+ /* .bInterfaceNumber = DYNAMIC */
+- .bAlternateSetting = 1,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = USB_CLASS_CDC_DATA,
+ .bInterfaceSubClass = 0,
+@@ -303,7 +302,7 @@ static void rndis_response_available(void *_rndis)
+ __le32 *data = req->buf;
+ int status;
+
+- if (atomic_inc_return(&rndis->notify_count))
++ if (atomic_inc_return(&rndis->notify_count) != 1)
+ return;
+
+ /* Send RNDIS RESPONSE_AVAILABLE notification; a
+diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
+index c46a58f..36864f9 100644
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -66,6 +66,8 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
+ {
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
++ struct pci_dev *p_smbus;
++ u8 rev;
+ u32 temp;
+ int retval;
+
+@@ -166,6 +168,28 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
+ pci_write_config_byte(pdev, 0x4b, tmp | 0x20);
+ }
+ break;
++ case PCI_VENDOR_ID_ATI:
++ /* SB600 and old version of SB700 have a bug in EHCI controller,
++ * which causes usb devices lose response in some cases.
++ */
++ if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) {
++ p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
++ PCI_DEVICE_ID_ATI_SBX00_SMBUS,
++ NULL);
++ if (!p_smbus)
++ break;
++ rev = p_smbus->revision;
++ if ((pdev->device == 0x4386) || (rev == 0x3a)
++ || (rev == 0x3b)) {
++ u8 tmp;
++ ehci_info(ehci, "applying AMD SB600/SB700 USB "
++ "freeze workaround\n");
++ pci_read_config_byte(pdev, 0x53, &tmp);
++ pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
++ }
++ pci_dev_put(p_smbus);
++ }
++ break;
+ }
+
+ ehci_reset(ehci);
+diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
+index 6566fc0..0ada0fc 100644
+--- a/drivers/usb/mon/mon_bin.c
++++ b/drivers/usb/mon/mon_bin.c
+@@ -687,7 +687,10 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
+ }
+
+ if (rp->b_read >= sizeof(struct mon_bin_hdr)) {
+- step_len = min(nbytes, (size_t)ep->len_cap);
++ step_len = ep->len_cap;
++ step_len -= rp->b_read - sizeof(struct mon_bin_hdr);
++ if (step_len > nbytes)
++ step_len = nbytes;
+ offset = rp->b_out + PKT_SIZE;
+ offset += rp->b_read - sizeof(struct mon_bin_hdr);
+ if (offset >= rp->b_size)
+diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
+index 98843c2..3f050e2 100644
+--- a/drivers/video/fbmem.c
++++ b/drivers/video/fbmem.c
+@@ -232,7 +232,7 @@ static void fb_set_logo_directpalette(struct fb_info *info,
+ greenshift = info->var.green.offset;
+ blueshift = info->var.blue.offset;
+
+- for (i = 32; i < logo->clutsize; i++)
++ for (i = 32; i < 32 + logo->clutsize; i++)
+ palette[i] = i << redshift | i << greenshift | i << blueshift;
+ }
+
+diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
+index a3765e0..763c1ea 100644
+--- a/drivers/watchdog/hpwdt.c
++++ b/drivers/watchdog/hpwdt.c
+@@ -40,6 +40,7 @@
+ #include <linux/bootmem.h>
+ #include <linux/slab.h>
+ #include <asm/desc.h>
++#include <asm/cacheflush.h>
+
+ #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */
+ #define CRU_BIOS_SIGNATURE_VALUE 0x55524324
+@@ -394,6 +395,8 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm)
+ smbios_cru64_ptr->double_offset;
+ cru_rom_addr = ioremap(cru_physical_address,
+ smbios_cru64_ptr->double_length);
++ set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
++ smbios_cru64_ptr->double_length >> PAGE_SHIFT);
+ }
+ }
+ }
+@@ -482,7 +485,7 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
+ "Management Log for details.\n");
+ }
+
+- return NOTIFY_STOP;
++ return NOTIFY_OK;
+ }
+
+ /*
+diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
+index 69a12aa..490e34b 100644
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -107,12 +107,13 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
+ #ifdef CONFIG_PROC_FS
+ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
+ {
+- struct list_head *tmp;
+- struct list_head *tmp1;
++ struct list_head *tmp1, *tmp2, *tmp3;
+ struct mid_q_entry *mid_entry;
++ struct TCP_Server_Info *server;
+ struct cifsSesInfo *ses;
+ struct cifsTconInfo *tcon;
+- int i;
++ int i, j;
++ __u32 dev_type;
+
+ seq_puts(m,
+ "Display Internal CIFS Data Structures for Debugging\n"
+@@ -122,46 +123,78 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
+ seq_printf(m, "Servers:");
+
+ i = 0;
+- read_lock(&GlobalSMBSeslock);
+- list_for_each(tmp, &GlobalSMBSessionList) {
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp1, &cifs_tcp_ses_list) {
++ server = list_entry(tmp1, struct TCP_Server_Info,
++ tcp_ses_list);
+ i++;
+- ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
+- if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
+- (ses->serverNOS == NULL)) {
+- seq_printf(m, "\nentry for %s not fully "
+- "displayed\n\t", ses->serverName);
+- } else {
+- seq_printf(m,
+- "\n%d) Name: %s Domain: %s Mounts: %d OS:"
+- " %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB"
++ list_for_each(tmp2, &server->smb_ses_list) {
++ ses = list_entry(tmp2, struct cifsSesInfo,
++ smb_ses_list);
++ if ((ses->serverDomain == NULL) ||
++ (ses->serverOS == NULL) ||
++ (ses->serverNOS == NULL)) {
++ seq_printf(m, "\n%d) entry for %s not fully "
++ "displayed\n\t", i, ses->serverName);
++ } else {
++ seq_printf(m,
++ "\n%d) Name: %s Domain: %s Uses: %d OS:"
++ " %s\n\tNOS: %s\tCapability: 0x%x\n\tSMB"
+ " session status: %d\t",
+ i, ses->serverName, ses->serverDomain,
+- atomic_read(&ses->inUse),
+- ses->serverOS, ses->serverNOS,
++ ses->ses_count, ses->serverOS, ses->serverNOS,
+ ses->capabilities, ses->status);
+- }
+- if (ses->server) {
++ }
+ seq_printf(m, "TCP status: %d\n\tLocal Users To "
+- "Server: %d SecMode: 0x%x Req On Wire: %d",
+- ses->server->tcpStatus,
+- atomic_read(&ses->server->socketUseCount),
+- ses->server->secMode,
+- atomic_read(&ses->server->inFlight));
++ "Server: %d SecMode: 0x%x Req On Wire: %d",
++ server->tcpStatus, server->srv_count,
++ server->secMode,
++ atomic_read(&server->inFlight));
+
+ #ifdef CONFIG_CIFS_STATS2
+ seq_printf(m, " In Send: %d In MaxReq Wait: %d",
+- atomic_read(&ses->server->inSend),
+- atomic_read(&ses->server->num_waiters));
++ atomic_read(&server->inSend),
++ atomic_read(&server->num_waiters));
+ #endif
+
+- seq_puts(m, "\nMIDs:\n");
++ seq_puts(m, "\n\tShares:");
++ j = 0;
++ list_for_each(tmp3, &ses->tcon_list) {
++ tcon = list_entry(tmp3, struct cifsTconInfo,
++ tcon_list);
++ ++j;
++ dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
++ seq_printf(m, "\n\t%d) %s Mounts: %d ", j,
++ tcon->treeName, tcon->tc_count);
++ if (tcon->nativeFileSystem) {
++ seq_printf(m, "Type: %s ",
++ tcon->nativeFileSystem);
++ }
++ seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x"
++ "\nPathComponentMax: %d Status: 0x%d",
++ le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
++ le32_to_cpu(tcon->fsAttrInfo.Attributes),
++ le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
++ tcon->tidStatus);
++ if (dev_type == FILE_DEVICE_DISK)
++ seq_puts(m, " type: DISK ");
++ else if (dev_type == FILE_DEVICE_CD_ROM)
++ seq_puts(m, " type: CDROM ");
++ else
++ seq_printf(m, " type: %d ", dev_type);
++
++ if (tcon->need_reconnect)
++ seq_puts(m, "\tDISCONNECTED ");
++ seq_putc(m, '\n');
++ }
++
++ seq_puts(m, "\n\tMIDs:\n");
+
+ spin_lock(&GlobalMid_Lock);
+- list_for_each(tmp1, &ses->server->pending_mid_q) {
+- mid_entry = list_entry(tmp1, struct
+- mid_q_entry,
++ list_for_each(tmp3, &server->pending_mid_q) {
++ mid_entry = list_entry(tmp3, struct mid_q_entry,
+ qhead);
+- seq_printf(m, "State: %d com: %d pid:"
++ seq_printf(m, "\tState: %d com: %d pid:"
+ " %d tsk: %p mid %d\n",
+ mid_entry->midState,
+ (int)mid_entry->command,
+@@ -171,44 +204,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
+ }
+ spin_unlock(&GlobalMid_Lock);
+ }
+-
+- }
+- read_unlock(&GlobalSMBSeslock);
+- seq_putc(m, '\n');
+-
+- seq_puts(m, "Shares:");
+-
+- i = 0;
+- read_lock(&GlobalSMBSeslock);
+- list_for_each(tmp, &GlobalTreeConnectionList) {
+- __u32 dev_type;
+- i++;
+- tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+- dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
+- seq_printf(m, "\n%d) %s Uses: %d ", i,
+- tcon->treeName, atomic_read(&tcon->useCount));
+- if (tcon->nativeFileSystem) {
+- seq_printf(m, "Type: %s ",
+- tcon->nativeFileSystem);
+- }
+- seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x"
+- "\nPathComponentMax: %d Status: %d",
+- le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
+- le32_to_cpu(tcon->fsAttrInfo.Attributes),
+- le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
+- tcon->tidStatus);
+- if (dev_type == FILE_DEVICE_DISK)
+- seq_puts(m, " type: DISK ");
+- else if (dev_type == FILE_DEVICE_CD_ROM)
+- seq_puts(m, " type: CDROM ");
+- else
+- seq_printf(m, " type: %d ", dev_type);
+-
+- if (tcon->tidStatus == CifsNeedReconnect)
+- seq_puts(m, "\tDISCONNECTED ");
+ }
+- read_unlock(&GlobalSMBSeslock);
+-
++ read_unlock(&cifs_tcp_ses_lock);
+ seq_putc(m, '\n');
+
+ /* BB add code to dump additional info such as TCP session info now */
+@@ -234,7 +231,9 @@ static ssize_t cifs_stats_proc_write(struct file *file,
+ {
+ char c;
+ int rc;
+- struct list_head *tmp;
++ struct list_head *tmp1, *tmp2, *tmp3;
++ struct TCP_Server_Info *server;
++ struct cifsSesInfo *ses;
+ struct cifsTconInfo *tcon;
+
+ rc = get_user(c, buffer);
+@@ -242,33 +241,42 @@ static ssize_t cifs_stats_proc_write(struct file *file,
+ return rc;
+
+ if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
+- read_lock(&GlobalSMBSeslock);
+ #ifdef CONFIG_CIFS_STATS2
+ atomic_set(&totBufAllocCount, 0);
+ atomic_set(&totSmBufAllocCount, 0);
+ #endif /* CONFIG_CIFS_STATS2 */
+- list_for_each(tmp, &GlobalTreeConnectionList) {
+- tcon = list_entry(tmp, struct cifsTconInfo,
+- cifsConnectionList);
+- atomic_set(&tcon->num_smbs_sent, 0);
+- atomic_set(&tcon->num_writes, 0);
+- atomic_set(&tcon->num_reads, 0);
+- atomic_set(&tcon->num_oplock_brks, 0);
+- atomic_set(&tcon->num_opens, 0);
+- atomic_set(&tcon->num_closes, 0);
+- atomic_set(&tcon->num_deletes, 0);
+- atomic_set(&tcon->num_mkdirs, 0);
+- atomic_set(&tcon->num_rmdirs, 0);
+- atomic_set(&tcon->num_renames, 0);
+- atomic_set(&tcon->num_t2renames, 0);
+- atomic_set(&tcon->num_ffirst, 0);
+- atomic_set(&tcon->num_fnext, 0);
+- atomic_set(&tcon->num_fclose, 0);
+- atomic_set(&tcon->num_hardlinks, 0);
+- atomic_set(&tcon->num_symlinks, 0);
+- atomic_set(&tcon->num_locks, 0);
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp1, &cifs_tcp_ses_list) {
++ server = list_entry(tmp1, struct TCP_Server_Info,
++ tcp_ses_list);
++ list_for_each(tmp2, &server->smb_ses_list) {
++ ses = list_entry(tmp2, struct cifsSesInfo,
++ smb_ses_list);
++ list_for_each(tmp3, &ses->tcon_list) {
++ tcon = list_entry(tmp3,
++ struct cifsTconInfo,
++ tcon_list);
++ atomic_set(&tcon->num_smbs_sent, 0);
++ atomic_set(&tcon->num_writes, 0);
++ atomic_set(&tcon->num_reads, 0);
++ atomic_set(&tcon->num_oplock_brks, 0);
++ atomic_set(&tcon->num_opens, 0);
++ atomic_set(&tcon->num_closes, 0);
++ atomic_set(&tcon->num_deletes, 0);
++ atomic_set(&tcon->num_mkdirs, 0);
++ atomic_set(&tcon->num_rmdirs, 0);
++ atomic_set(&tcon->num_renames, 0);
++ atomic_set(&tcon->num_t2renames, 0);
++ atomic_set(&tcon->num_ffirst, 0);
++ atomic_set(&tcon->num_fnext, 0);
++ atomic_set(&tcon->num_fclose, 0);
++ atomic_set(&tcon->num_hardlinks, 0);
++ atomic_set(&tcon->num_symlinks, 0);
++ atomic_set(&tcon->num_locks, 0);
++ }
++ }
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ }
+
+ return count;
+@@ -277,7 +285,9 @@ static ssize_t cifs_stats_proc_write(struct file *file,
+ static int cifs_stats_proc_show(struct seq_file *m, void *v)
+ {
+ int i;
+- struct list_head *tmp;
++ struct list_head *tmp1, *tmp2, *tmp3;
++ struct TCP_Server_Info *server;
++ struct cifsSesInfo *ses;
+ struct cifsTconInfo *tcon;
+
+ seq_printf(m,
+@@ -306,44 +316,55 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
+ GlobalCurrentXid, GlobalMaxActiveXid);
+
+ i = 0;
+- read_lock(&GlobalSMBSeslock);
+- list_for_each(tmp, &GlobalTreeConnectionList) {
+- i++;
+- tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+- seq_printf(m, "\n%d) %s", i, tcon->treeName);
+- if (tcon->tidStatus == CifsNeedReconnect)
+- seq_puts(m, "\tDISCONNECTED ");
+- seq_printf(m, "\nSMBs: %d Oplock Breaks: %d",
+- atomic_read(&tcon->num_smbs_sent),
+- atomic_read(&tcon->num_oplock_brks));
+- seq_printf(m, "\nReads: %d Bytes: %lld",
+- atomic_read(&tcon->num_reads),
+- (long long)(tcon->bytes_read));
+- seq_printf(m, "\nWrites: %d Bytes: %lld",
+- atomic_read(&tcon->num_writes),
+- (long long)(tcon->bytes_written));
+- seq_printf(m,
+- "\nLocks: %d HardLinks: %d Symlinks: %d",
+- atomic_read(&tcon->num_locks),
+- atomic_read(&tcon->num_hardlinks),
+- atomic_read(&tcon->num_symlinks));
+-
+- seq_printf(m, "\nOpens: %d Closes: %d Deletes: %d",
+- atomic_read(&tcon->num_opens),
+- atomic_read(&tcon->num_closes),
+- atomic_read(&tcon->num_deletes));
+- seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
+- atomic_read(&tcon->num_mkdirs),
+- atomic_read(&tcon->num_rmdirs));
+- seq_printf(m, "\nRenames: %d T2 Renames %d",
+- atomic_read(&tcon->num_renames),
+- atomic_read(&tcon->num_t2renames));
+- seq_printf(m, "\nFindFirst: %d FNext %d FClose %d",
+- atomic_read(&tcon->num_ffirst),
+- atomic_read(&tcon->num_fnext),
+- atomic_read(&tcon->num_fclose));
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp1, &cifs_tcp_ses_list) {
++ server = list_entry(tmp1, struct TCP_Server_Info,
++ tcp_ses_list);
++ list_for_each(tmp2, &server->smb_ses_list) {
++ ses = list_entry(tmp2, struct cifsSesInfo,
++ smb_ses_list);
++ list_for_each(tmp3, &ses->tcon_list) {
++ tcon = list_entry(tmp3,
++ struct cifsTconInfo,
++ tcon_list);
++ i++;
++ seq_printf(m, "\n%d) %s", i, tcon->treeName);
++ if (tcon->need_reconnect)
++ seq_puts(m, "\tDISCONNECTED ");
++ seq_printf(m, "\nSMBs: %d Oplock Breaks: %d",
++ atomic_read(&tcon->num_smbs_sent),
++ atomic_read(&tcon->num_oplock_brks));
++ seq_printf(m, "\nReads: %d Bytes: %lld",
++ atomic_read(&tcon->num_reads),
++ (long long)(tcon->bytes_read));
++ seq_printf(m, "\nWrites: %d Bytes: %lld",
++ atomic_read(&tcon->num_writes),
++ (long long)(tcon->bytes_written));
++ seq_printf(m, "\nLocks: %d HardLinks: %d "
++ "Symlinks: %d",
++ atomic_read(&tcon->num_locks),
++ atomic_read(&tcon->num_hardlinks),
++ atomic_read(&tcon->num_symlinks));
++ seq_printf(m, "\nOpens: %d Closes: %d"
++ "Deletes: %d",
++ atomic_read(&tcon->num_opens),
++ atomic_read(&tcon->num_closes),
++ atomic_read(&tcon->num_deletes));
++ seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
++ atomic_read(&tcon->num_mkdirs),
++ atomic_read(&tcon->num_rmdirs));
++ seq_printf(m, "\nRenames: %d T2 Renames %d",
++ atomic_read(&tcon->num_renames),
++ atomic_read(&tcon->num_t2renames));
++ seq_printf(m, "\nFindFirst: %d FNext %d "
++ "FClose %d",
++ atomic_read(&tcon->num_ffirst),
++ atomic_read(&tcon->num_fnext),
++ atomic_read(&tcon->num_fclose));
++ }
++ }
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+
+ seq_putc(m, '\n');
+ return 0;
+diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
+index 117ef4b..d0758b2 100644
+--- a/fs/cifs/cifs_spnego.c
++++ b/fs/cifs/cifs_spnego.c
+@@ -70,7 +70,8 @@ struct key_type cifs_spnego_key_type = {
+ strlen("ver=0xFF") */
+ #define MAX_MECH_STR_LEN 13 /* length of longest security mechanism name, eg
+ in future could have strlen(";sec=ntlmsspi") */
+-#define MAX_IPV6_ADDR_LEN 42 /* eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60 */
++/* max possible addr len eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/128 */
++#define MAX_IPV6_ADDR_LEN 43
+ /* get a key struct with a SPNEGO security blob, suitable for session setup */
+ struct key *
+ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 25ecbd5..2fcc66c 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -510,10 +510,11 @@ static void cifs_umount_begin(struct super_block *sb)
+ tcon = cifs_sb->tcon;
+ if (tcon == NULL)
+ return;
+- down(&tcon->tconSem);
+- if (atomic_read(&tcon->useCount) == 1)
++
++ read_lock(&cifs_tcp_ses_lock);
++ if (tcon->tc_count == 1)
+ tcon->tidStatus = CifsExiting;
+- up(&tcon->tconSem);
++ read_unlock(&cifs_tcp_ses_lock);
+
+ /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
+ /* cancel_notify_requests(tcon); */
+@@ -967,7 +968,7 @@ static int cifs_oplock_thread(void *dummyarg)
+ not bother sending an oplock release if session
+ to server still is disconnected since oplock
+ already released by the server in that case */
+- if (pTcon->tidStatus != CifsNeedReconnect) {
++ if (!pTcon->need_reconnect) {
+ rc = CIFSSMBLock(0, pTcon, netfid,
+ 0 /* len */ , 0 /* offset */, 0,
+ 0, LOCKING_ANDX_OPLOCK_RELEASE,
+@@ -985,24 +986,24 @@ static int cifs_oplock_thread(void *dummyarg)
+ static int cifs_dnotify_thread(void *dummyarg)
+ {
+ struct list_head *tmp;
+- struct cifsSesInfo *ses;
++ struct TCP_Server_Info *server;
+
+ do {
+ if (try_to_freeze())
+ continue;
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(15*HZ);
+- read_lock(&GlobalSMBSeslock);
+ /* check if any stuck requests that need
+ to be woken up and wakeq so the
+ thread can wake up and error out */
+- list_for_each(tmp, &GlobalSMBSessionList) {
+- ses = list_entry(tmp, struct cifsSesInfo,
+- cifsSessionList);
+- if (ses->server && atomic_read(&ses->server->inFlight))
+- wake_up_all(&ses->server->response_q);
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp, &cifs_tcp_ses_list) {
++ server = list_entry(tmp, struct TCP_Server_Info,
++ tcp_ses_list);
++ if (atomic_read(&server->inFlight))
++ wake_up_all(&server->response_q);
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ } while (!kthread_should_stop());
+
+ return 0;
+@@ -1013,9 +1014,7 @@ init_cifs(void)
+ {
+ int rc = 0;
+ cifs_proc_init();
+-/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */
+- INIT_LIST_HEAD(&GlobalSMBSessionList);
+- INIT_LIST_HEAD(&GlobalTreeConnectionList);
++ INIT_LIST_HEAD(&cifs_tcp_ses_list);
+ INIT_LIST_HEAD(&GlobalOplock_Q);
+ #ifdef CONFIG_CIFS_EXPERIMENTAL
+ INIT_LIST_HEAD(&GlobalDnotifyReqList);
+@@ -1043,6 +1042,7 @@ init_cifs(void)
+ GlobalMaxActiveXid = 0;
+ memset(Local_System_Name, 0, 15);
+ rwlock_init(&GlobalSMBSeslock);
++ rwlock_init(&cifs_tcp_ses_lock);
+ spin_lock_init(&GlobalMid_Lock);
+
+ if (cifs_max_pending < 2) {
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 0d22479..1ae6314 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -85,8 +85,7 @@ enum securityEnum {
+ };
+
+ enum protocolEnum {
+- IPV4 = 0,
+- IPV6,
++ TCP = 0,
+ SCTP
+ /* Netbios frames protocol not supported at this time */
+ };
+@@ -122,6 +121,9 @@ struct cifs_cred {
+ */
+
+ struct TCP_Server_Info {
++ struct list_head tcp_ses_list;
++ struct list_head smb_ses_list;
++ int srv_count; /* reference counter */
+ /* 15 character server name + 0x20 16th byte indicating type = srv */
+ char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
+ char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
+@@ -141,7 +143,8 @@ struct TCP_Server_Info {
+ char versionMajor;
+ char versionMinor;
+ bool svlocal:1; /* local server or remote */
+- atomic_t socketUseCount; /* number of open cifs sessions on socket */
++ bool noblocksnd; /* use blocking sendmsg */
++ bool noautotune; /* do not autotune send buf sizes */
+ atomic_t inFlight; /* number of requests on the wire to server */
+ #ifdef CONFIG_CIFS_STATS2
+ atomic_t inSend; /* requests trying to send */
+@@ -192,13 +195,14 @@ struct cifsUidInfo {
+ * Session structure. One of these for each uid session with a particular host
+ */
+ struct cifsSesInfo {
+- struct list_head cifsSessionList;
++ struct list_head smb_ses_list;
++ struct list_head tcon_list;
+ struct semaphore sesSem;
+ #if 0
+ struct cifsUidInfo *uidInfo; /* pointer to user info */
+ #endif
+ struct TCP_Server_Info *server; /* pointer to server info */
+- atomic_t inUse; /* # of mounts (tree connections) on this ses */
++ int ses_count; /* reference counter */
+ enum statusEnum status;
+ unsigned overrideSecFlg; /* if non-zero override global sec flags */
+ __u16 ipc_tid; /* special tid for connection to IPC share */
+@@ -214,6 +218,7 @@ struct cifsSesInfo {
+ char userName[MAX_USERNAME_SIZE + 1];
+ char *domainName;
+ char *password;
++ bool need_reconnect:1; /* connection reset, uid now invalid */
+ };
+ /* no more than one of the following three session flags may be set */
+ #define CIFS_SES_NT4 1
+@@ -228,16 +233,15 @@ struct cifsSesInfo {
+ * session
+ */
+ struct cifsTconInfo {
+- struct list_head cifsConnectionList;
++ struct list_head tcon_list;
++ int tc_count;
+ struct list_head openFileList;
+- struct semaphore tconSem;
+ struct cifsSesInfo *ses; /* pointer to session associated with */
+ char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
+ char *nativeFileSystem;
+ __u16 tid; /* The 2 byte tree id */
+ __u16 Flags; /* optional support bits */
+ enum statusEnum tidStatus;
+- atomic_t useCount; /* how many explicit/implicit mounts to share */
+ #ifdef CONFIG_CIFS_STATS
+ atomic_t num_smbs_sent;
+ atomic_t num_writes;
+@@ -285,6 +289,7 @@ struct cifsTconInfo {
+ bool seal:1; /* transport encryption for this mounted share */
+ bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
+ for this mount even if server would support */
++ bool need_reconnect:1; /* connection reset, tid now invalid */
+ /* BB add field for back pointer to sb struct(s)? */
+ };
+
+@@ -584,21 +589,21 @@ require use of the stronger protocol */
+ #endif
+
+ /*
+- * The list of servers that did not respond with NT LM 0.12.
+- * This list helps improve performance and eliminate the messages indicating
+- * that we had a communications error talking to the server in this list.
++ * the list of TCP_Server_Info structures, ie each of the sockets
++ * connecting our client to a distinct server (ip address), is
++ * chained together by cifs_tcp_ses_list. The list of all our SMB
++ * sessions (and from that the tree connections) can be found
++ * by iterating over cifs_tcp_ses_list
+ */
+-/* Feature not supported */
+-/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */
++GLOBAL_EXTERN struct list_head cifs_tcp_ses_list;
+
+ /*
+- * The following is a hash table of all the users we know about.
++ * This lock protects the cifs_tcp_ses_list, the list of smb sessions per
++ * tcp session, and the list of tcon's per smb session. It also protects
++ * the reference counters for the server, smb session, and tcon. Finally,
++ * changes to the tcon->tidStatus should be done while holding this lock.
+ */
+-GLOBAL_EXTERN struct smbUidInfo *GlobalUidList[UID_HASH];
+-
+-/* GLOBAL_EXTERN struct list_head GlobalServerList; BB not implemented yet */
+-GLOBAL_EXTERN struct list_head GlobalSMBSessionList;
+-GLOBAL_EXTERN struct list_head GlobalTreeConnectionList;
++GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock;
+ GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */
+
+ GLOBAL_EXTERN struct list_head GlobalOplock_Q;
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index a729d08..ca91f16 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -36,7 +36,7 @@ extern void cifs_buf_release(void *);
+ extern struct smb_hdr *cifs_small_buf_get(void);
+ extern void cifs_small_buf_release(void *);
+ extern int smb_send(struct socket *, struct smb_hdr *,
+- unsigned int /* length */ , struct sockaddr *);
++ unsigned int /* length */ , struct sockaddr *, bool);
+ extern unsigned int _GetXid(void);
+ extern void _FreeXid(unsigned int);
+ #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current->fsuid));
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
+index 77a0d1f..8f0f86d 100644
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -190,10 +190,10 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+ /* need to prevent multiple threads trying to
+ simultaneously reconnect the same SMB session */
+ down(&tcon->ses->sesSem);
+- if (tcon->ses->status == CifsNeedReconnect)
++ if (tcon->ses->need_reconnect)
+ rc = cifs_setup_session(0, tcon->ses,
+ nls_codepage);
+- if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
++ if (!rc && (tcon->need_reconnect)) {
+ mark_open_files_invalid(tcon);
+ rc = CIFSTCon(0, tcon->ses, tcon->treeName,
+ tcon, nls_codepage);
+@@ -337,10 +337,10 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+ /* need to prevent multiple threads trying to
+ simultaneously reconnect the same SMB session */
+ down(&tcon->ses->sesSem);
+- if (tcon->ses->status == CifsNeedReconnect)
++ if (tcon->ses->need_reconnect)
+ rc = cifs_setup_session(0, tcon->ses,
+ nls_codepage);
+- if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
++ if (!rc && (tcon->need_reconnect)) {
+ mark_open_files_invalid(tcon);
+ rc = CIFSTCon(0, tcon->ses, tcon->treeName,
+ tcon, nls_codepage);
+@@ -664,8 +664,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
+ rc = -EIO;
+ goto neg_err_exit;
+ }
+-
+- if (server->socketUseCount.counter > 1) {
++ read_lock(&cifs_tcp_ses_lock);
++ if (server->srv_count > 1) {
++ read_unlock(&cifs_tcp_ses_lock);
+ if (memcmp(server->server_GUID,
+ pSMBr->u.extended_response.
+ GUID, 16) != 0) {
+@@ -674,9 +675,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
+ pSMBr->u.extended_response.GUID,
+ 16);
+ }
+- } else
++ } else {
++ read_unlock(&cifs_tcp_ses_lock);
+ memcpy(server->server_GUID,
+ pSMBr->u.extended_response.GUID, 16);
++ }
+
+ if (count == 16) {
+ server->secType = RawNTLMSSP;
+@@ -739,50 +742,31 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
+ int rc = 0;
+
+ cFYI(1, ("In tree disconnect"));
+- /*
+- * If last user of the connection and
+- * connection alive - disconnect it
+- * If this is the last connection on the server session disconnect it
+- * (and inside session disconnect we should check if tcp socket needs
+- * to be freed and kernel thread woken up).
+- */
+- if (tcon)
+- down(&tcon->tconSem);
+- else
+- return -EIO;
+
+- atomic_dec(&tcon->useCount);
+- if (atomic_read(&tcon->useCount) > 0) {
+- up(&tcon->tconSem);
+- return -EBUSY;
+- }
++ /* BB: do we need to check this? These should never be NULL. */
++ if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
++ return -EIO;
+
+- /* No need to return error on this operation if tid invalidated and
+- closed on server already e.g. due to tcp session crashing */
+- if (tcon->tidStatus == CifsNeedReconnect) {
+- up(&tcon->tconSem);
++ /*
++ * No need to return error on this operation if tid invalidated and
++ * closed on server already e.g. due to tcp session crashing. Also,
++ * the tcon is no longer on the list, so no need to take lock before
++ * checking this.
++ */
++ if (tcon->need_reconnect)
+ return 0;
+- }
+
+- if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) {
+- up(&tcon->tconSem);
+- return -EIO;
+- }
+ rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
+ (void **)&smb_buffer);
+- if (rc) {
+- up(&tcon->tconSem);
++ if (rc)
+ return rc;
+- }
+
+ rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
+ if (rc)
+ cFYI(1, ("Tree disconnect failed %d", rc));
+
+- up(&tcon->tconSem);
+-
+ /* No need to return error on this operation if tid invalidated and
+- closed on server already e.g. due to tcp session crashing */
++ closed on server already e.g. due to tcp session crashing */
+ if (rc == -EAGAIN)
+ rc = 0;
+
+@@ -796,43 +780,36 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
+ int rc = 0;
+
+ cFYI(1, ("In SMBLogoff for session disconnect"));
+- if (ses)
+- down(&ses->sesSem);
+- else
++
++ /*
++ * BB: do we need to check validity of ses and server? They should
++ * always be valid since we have an active reference. If not, that
++ * should probably be a BUG()
++ */
++ if (!ses || !ses->server)
+ return -EIO;
+
+- atomic_dec(&ses->inUse);
+- if (atomic_read(&ses->inUse) > 0) {
+- up(&ses->sesSem);
+- return -EBUSY;
+- }
++ down(&ses->sesSem);
++ if (ses->need_reconnect)
++ goto session_already_dead; /* no need to send SMBlogoff if uid
++ already closed due to reconnect */
+ rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
+ if (rc) {
+ up(&ses->sesSem);
+ return rc;
+ }
+
+- if (ses->server) {
+- pSMB->hdr.Mid = GetNextMid(ses->server);
++ pSMB->hdr.Mid = GetNextMid(ses->server);
+
+- if (ses->server->secMode &
++ if (ses->server->secMode &
+ (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+- }
+
+ pSMB->hdr.Uid = ses->Suid;
+
+ pSMB->AndXCommand = 0xFF;
+ rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
+- if (ses->server) {
+- atomic_dec(&ses->server->socketUseCount);
+- if (atomic_read(&ses->server->socketUseCount) == 0) {
+- spin_lock(&GlobalMid_Lock);
+- ses->server->tcpStatus = CifsExiting;
+- spin_unlock(&GlobalMid_Lock);
+- rc = -ESHUTDOWN;
+- }
+- }
++session_already_dead:
+ up(&ses->sesSem);
+
+ /* if session dead then we do not need to do ulogoff,
+@@ -1534,7 +1511,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
+ __u32 bytes_sent;
+ __u16 byte_count;
+
+- /* cFYI(1,("write at %lld %d bytes",offset,count));*/
++ /* cFYI(1, ("write at %lld %d bytes",offset,count));*/
+ if (tcon->ses == NULL)
+ return -ECONNABORTED;
+
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 4c13bcd..6e2be4a 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -90,6 +90,8 @@ struct smb_vol {
+ bool nocase:1; /* request case insensitive filenames */
+ bool nobrl:1; /* disable sending byte range locks to srv */
+ bool seal:1; /* request transport encryption on share */
++ bool noblocksnd:1;
++ bool noautotune:1;
+ unsigned int rsize;
+ unsigned int wsize;
+ unsigned int sockopt;
+@@ -100,9 +102,11 @@ struct smb_vol {
+ static int ipv4_connect(struct sockaddr_in *psin_server,
+ struct socket **csocket,
+ char *netb_name,
+- char *server_netb_name);
++ char *server_netb_name,
++ bool noblocksnd,
++ bool nosndbuf); /* ipv6 never set sndbuf size */
+ static int ipv6_connect(struct sockaddr_in6 *psin_server,
+- struct socket **csocket);
++ struct socket **csocket, bool noblocksnd);
+
+
+ /*
+@@ -118,7 +122,7 @@ static int
+ cifs_reconnect(struct TCP_Server_Info *server)
+ {
+ int rc = 0;
+- struct list_head *tmp;
++ struct list_head *tmp, *tmp2;
+ struct cifsSesInfo *ses;
+ struct cifsTconInfo *tcon;
+ struct mid_q_entry *mid_entry;
+@@ -138,23 +142,17 @@ cifs_reconnect(struct TCP_Server_Info *server)
+
+ /* before reconnecting the tcp session, mark the smb session (uid)
+ and the tid bad so they are not used until reconnected */
+- read_lock(&GlobalSMBSeslock);
+- list_for_each(tmp, &GlobalSMBSessionList) {
+- ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
+- if (ses->server) {
+- if (ses->server == server) {
+- ses->status = CifsNeedReconnect;
+- ses->ipc_tid = 0;
+- }
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp, &server->smb_ses_list) {
++ ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
++ ses->need_reconnect = true;
++ ses->ipc_tid = 0;
++ list_for_each(tmp2, &ses->tcon_list) {
++ tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
++ tcon->need_reconnect = true;
+ }
+- /* else tcp and smb sessions need reconnection */
+- }
+- list_for_each(tmp, &GlobalTreeConnectionList) {
+- tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+- if ((tcon->ses) && (tcon->ses->server == server))
+- tcon->tidStatus = CifsNeedReconnect;
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ /* do not want to be sending data on a socket we are freeing */
+ down(&server->tcpSem);
+ if (server->ssocket) {
+@@ -186,14 +184,15 @@ cifs_reconnect(struct TCP_Server_Info *server)
+
+ while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
+ try_to_freeze();
+- if (server->protocolType == IPV6) {
++ if (server->addr.sockAddr6.sin6_family == AF_INET6) {
+ rc = ipv6_connect(&server->addr.sockAddr6,
+- &server->ssocket);
++ &server->ssocket, server->noautotune);
+ } else {
+ rc = ipv4_connect(&server->addr.sockAddr,
+ &server->ssocket,
+ server->workstation_RFC1001_name,
+- server->server_RFC1001_name);
++ server->server_RFC1001_name,
++ server->noblocksnd, server->noautotune);
+ }
+ if (rc) {
+ cFYI(1, ("reconnect error %d", rc));
+@@ -409,8 +408,14 @@ incomplete_rcv:
+ msleep(1); /* minimum sleep to prevent looping
+ allowing socket to clear and app threads to set
+ tcpStatus CifsNeedReconnect if server hung */
+- if (pdu_length < 4)
++ if (pdu_length < 4) {
++ iov.iov_base = (4 - pdu_length) +
++ (char *)smb_buffer;
++ iov.iov_len = pdu_length;
++ smb_msg.msg_control = NULL;
++ smb_msg.msg_controllen = 0;
+ goto incomplete_rcv;
++ }
+ else
+ continue;
+ } else if (length <= 0) {
+@@ -646,6 +651,11 @@ multi_t2_fnd:
+ }
+ } /* end while !EXITING */
+
++ /* take it off the list, if it's not already */
++ write_lock(&cifs_tcp_ses_lock);
++ list_del_init(&server->tcp_ses_list);
++ write_unlock(&cifs_tcp_ses_lock);
++
+ spin_lock(&GlobalMid_Lock);
+ server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
+@@ -686,29 +696,29 @@ multi_t2_fnd:
+ if (smallbuf) /* no sense logging a debug message if NULL */
+ cifs_small_buf_release(smallbuf);
+
+- read_lock(&GlobalSMBSeslock);
++ /*
++ * BB: we shouldn't have to do any of this. It shouldn't be
++ * possible to exit from the thread with active SMB sessions
++ */
++ read_lock(&cifs_tcp_ses_lock);
+ if (list_empty(&server->pending_mid_q)) {
+ /* loop through server session structures attached to this and
+ mark them dead */
+- list_for_each(tmp, &GlobalSMBSessionList) {
+- ses =
+- list_entry(tmp, struct cifsSesInfo,
+- cifsSessionList);
+- if (ses->server == server) {
+- ses->status = CifsExiting;
+- ses->server = NULL;
+- }
++ list_for_each(tmp, &server->smb_ses_list) {
++ ses = list_entry(tmp, struct cifsSesInfo,
++ smb_ses_list);
++ ses->status = CifsExiting;
++ ses->server = NULL;
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ } else {
+ /* although we can not zero the server struct pointer yet,
+ since there are active requests which may depnd on them,
+ mark the corresponding SMB sessions as exiting too */
+- list_for_each(tmp, &GlobalSMBSessionList) {
++ list_for_each(tmp, &server->smb_ses_list) {
+ ses = list_entry(tmp, struct cifsSesInfo,
+- cifsSessionList);
+- if (ses->server == server)
+- ses->status = CifsExiting;
++ smb_ses_list);
++ ses->status = CifsExiting;
+ }
+
+ spin_lock(&GlobalMid_Lock);
+@@ -723,7 +733,7 @@ multi_t2_fnd:
+ }
+ }
+ spin_unlock(&GlobalMid_Lock);
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ /* 1/8th of sec is more than enough time for them to exit */
+ msleep(125);
+ }
+@@ -745,14 +755,13 @@ multi_t2_fnd:
+ if there are any pointing to this (e.g
+ if a crazy root user tried to kill cifsd
+ kernel thread explicitly this might happen) */
+- write_lock(&GlobalSMBSeslock);
+- list_for_each(tmp, &GlobalSMBSessionList) {
+- ses = list_entry(tmp, struct cifsSesInfo,
+- cifsSessionList);
+- if (ses->server == server)
+- ses->server = NULL;
++ /* BB: This shouldn't be necessary, see above */
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp, &server->smb_ses_list) {
++ ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
++ ses->server = NULL;
+ }
+- write_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+
+ kfree(server->hostname);
+ kfree(server);
+@@ -1186,6 +1195,10 @@ cifs_parse_mount_options(char *options, const char *devname,
+ /* ignore */
+ } else if (strnicmp(data, "rw", 2) == 0) {
+ vol->rw = true;
++ } else if (strnicmp(data, "noblocksnd", 11) == 0) {
++ vol->noblocksnd = true;
++ } else if (strnicmp(data, "noautotune", 10) == 0) {
++ vol->noautotune = true;
+ } else if ((strnicmp(data, "suid", 4) == 0) ||
+ (strnicmp(data, "nosuid", 6) == 0) ||
+ (strnicmp(data, "exec", 4) == 0) ||
+@@ -1331,94 +1344,158 @@ cifs_parse_mount_options(char *options, const char *devname,
+ return 0;
+ }
+
+-static struct cifsSesInfo *
+-cifs_find_tcp_session(struct in_addr *target_ip_addr,
+- struct in6_addr *target_ip6_addr,
+- char *userName, struct TCP_Server_Info **psrvTcp)
++static struct TCP_Server_Info *
++cifs_find_tcp_session(struct sockaddr *addr)
+ {
+ struct list_head *tmp;
+- struct cifsSesInfo *ses;
+-
+- *psrvTcp = NULL;
++ struct TCP_Server_Info *server;
++ struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
++ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
++
++ write_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp, &cifs_tcp_ses_list) {
++ server = list_entry(tmp, struct TCP_Server_Info,
++ tcp_ses_list);
++ /*
++ * the demux thread can exit on its own while still in CifsNew
++ * so don't accept any sockets in that state. Since the
++ * tcpStatus never changes back to CifsNew it's safe to check
++ * for this without a lock.
++ */
++ if (server->tcpStatus == CifsNew)
++ continue;
+
+- read_lock(&GlobalSMBSeslock);
+- list_for_each(tmp, &GlobalSMBSessionList) {
+- ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
+- if (!ses->server)
++ if (addr->sa_family == AF_INET &&
++ (addr4->sin_addr.s_addr !=
++ server->addr.sockAddr.sin_addr.s_addr))
++ continue;
++ else if (addr->sa_family == AF_INET6 &&
++ memcmp(&server->addr.sockAddr6.sin6_addr,
++ &addr6->sin6_addr, sizeof(addr6->sin6_addr)))
+ continue;
+
+- if (target_ip_addr &&
+- ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
+- continue;
+- else if (target_ip6_addr &&
+- memcmp(&ses->server->addr.sockAddr6.sin6_addr,
+- target_ip6_addr, sizeof(*target_ip6_addr)))
+- continue;
+- /* BB lock server and tcp session; increment use count here?? */
++ ++server->srv_count;
++ write_unlock(&cifs_tcp_ses_lock);
++ cFYI(1, ("Existing tcp session with server found"));
++ return server;
++ }
++ write_unlock(&cifs_tcp_ses_lock);
++ return NULL;
++}
+
+- /* found a match on the TCP session */
+- *psrvTcp = ses->server;
++static void
++cifs_put_tcp_session(struct TCP_Server_Info *server)
++{
++ struct task_struct *task;
+
+- /* BB check if reconnection needed */
+- if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
+- read_unlock(&GlobalSMBSeslock);
+- /* Found exact match on both TCP and
+- SMB sessions */
+- return ses;
+- }
+- /* else tcp and smb sessions need reconnection */
++ write_lock(&cifs_tcp_ses_lock);
++ if (--server->srv_count > 0) {
++ write_unlock(&cifs_tcp_ses_lock);
++ return;
+ }
+- read_unlock(&GlobalSMBSeslock);
+
+- return NULL;
++ list_del_init(&server->tcp_ses_list);
++ write_unlock(&cifs_tcp_ses_lock);
++
++ spin_lock(&GlobalMid_Lock);
++ server->tcpStatus = CifsExiting;
++ spin_unlock(&GlobalMid_Lock);
++
++ task = xchg(&server->tsk, NULL);
++ if (task)
++ force_sig(SIGKILL, task);
+ }
+
+-static struct cifsTconInfo *
+-find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
++static struct cifsSesInfo *
++cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
+ {
+ struct list_head *tmp;
+- struct cifsTconInfo *tcon;
+- __be32 old_ip;
+-
+- read_lock(&GlobalSMBSeslock);
++ struct cifsSesInfo *ses;
+
+- list_for_each(tmp, &GlobalTreeConnectionList) {
+- cFYI(1, ("Next tcon"));
+- tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+- if (!tcon->ses || !tcon->ses->server)
++ write_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp, &server->smb_ses_list) {
++ ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
++ if (strncmp(ses->userName, username, MAX_USERNAME_SIZE))
+ continue;
+
+- old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr;
+- cFYI(1, ("old ip addr: %x == new ip %x ?",
+- old_ip, new_target_ip_addr));
++ ++ses->ses_count;
++ write_unlock(&cifs_tcp_ses_lock);
++ return ses;
++ }
++ write_unlock(&cifs_tcp_ses_lock);
++ return NULL;
++}
+
+- if (old_ip != new_target_ip_addr)
+- continue;
++static void
++cifs_put_smb_ses(struct cifsSesInfo *ses)
++{
++ int xid;
++ struct TCP_Server_Info *server = ses->server;
+
+- /* BB lock tcon, server, tcp session and increment use count? */
+- /* found a match on the TCP session */
+- /* BB check if reconnection needed */
+- cFYI(1, ("IP match, old UNC: %s new: %s",
+- tcon->treeName, uncName));
++ write_lock(&cifs_tcp_ses_lock);
++ if (--ses->ses_count > 0) {
++ write_unlock(&cifs_tcp_ses_lock);
++ return;
++ }
+
+- if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE))
+- continue;
++ list_del_init(&ses->smb_ses_list);
++ write_unlock(&cifs_tcp_ses_lock);
++
++ if (ses->status == CifsGood) {
++ xid = GetXid();
++ CIFSSMBLogoff(xid, ses);
++ _FreeXid(xid);
++ }
++ sesInfoFree(ses);
++ cifs_put_tcp_session(server);
++}
+
+- cFYI(1, ("and old usr: %s new: %s",
+- tcon->treeName, uncName));
++static struct cifsTconInfo *
++cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
++{
++ struct list_head *tmp;
++ struct cifsTconInfo *tcon;
+
+- if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE))
++ write_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp, &ses->tcon_list) {
++ tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
++ if (tcon->tidStatus == CifsExiting)
++ continue;
++ if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
+ continue;
+
+- /* matched smb session (user name) */
+- read_unlock(&GlobalSMBSeslock);
++ ++tcon->tc_count;
++ write_unlock(&cifs_tcp_ses_lock);
+ return tcon;
+ }
+-
+- read_unlock(&GlobalSMBSeslock);
++ write_unlock(&cifs_tcp_ses_lock);
+ return NULL;
+ }
+
++static void
++cifs_put_tcon(struct cifsTconInfo *tcon)
++{
++ int xid;
++ struct cifsSesInfo *ses = tcon->ses;
++
++ write_lock(&cifs_tcp_ses_lock);
++ if (--tcon->tc_count > 0) {
++ write_unlock(&cifs_tcp_ses_lock);
++ return;
++ }
++
++ list_del_init(&tcon->tcon_list);
++ write_unlock(&cifs_tcp_ses_lock);
++
++ xid = GetXid();
++ CIFSSMBTDis(xid, tcon);
++ _FreeXid(xid);
++
++ DeleteTconOplockQEntries(tcon);
++ tconInfoFree(tcon);
++ cifs_put_smb_ses(ses);
++}
++
+ int
+ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
+ const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
+@@ -1506,7 +1583,8 @@ static void rfc1002mangle(char *target, char *source, unsigned int length)
+
+ static int
+ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
+- char *netbios_name, char *target_name)
++ char *netbios_name, char *target_name,
++ bool noblocksnd, bool noautotune)
+ {
+ int rc = 0;
+ int connected = 0;
+@@ -1578,11 +1656,15 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
+ (*csocket)->sk->sk_sndbuf,
+ (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
+ (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
++ if (!noblocksnd)
++ (*csocket)->sk->sk_sndtimeo = 3 * HZ;
+ /* make the bufsizes depend on wsize/rsize and max requests */
+- if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
+- (*csocket)->sk->sk_sndbuf = 200 * 1024;
+- if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
+- (*csocket)->sk->sk_rcvbuf = 140 * 1024;
++ if (noautotune) {
++ if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
++ (*csocket)->sk->sk_sndbuf = 200 * 1024;
++ if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
++ (*csocket)->sk->sk_rcvbuf = 140 * 1024;
++ }
+
+ /* send RFC1001 sessinit */
+ if (psin_server->sin_port == htons(RFC1001_PORT)) {
+@@ -1619,7 +1701,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
+ /* sizeof RFC1002_SESSION_REQUEST with no scope */
+ smb_buf->smb_buf_length = 0x81000044;
+ rc = smb_send(*csocket, smb_buf, 0x44,
+- (struct sockaddr *)psin_server);
++ (struct sockaddr *)psin_server, noblocksnd);
+ kfree(ses_init_buf);
+ msleep(1); /* RFC1001 layer in at least one server
+ requires very short break before negprot
+@@ -1639,7 +1721,8 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
+ }
+
+ static int
+-ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
++ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket,
++ bool noblocksnd)
+ {
+ int rc = 0;
+ int connected = 0;
+@@ -1708,6 +1791,8 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
+ the default. sock_setsockopt not used because it expects
+ user space buffer */
+ (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
++ if (!noblocksnd)
++ (*csocket)->sk->sk_sndtimeo = 3 * HZ;
+
+ return rc;
+ }
+@@ -1845,19 +1930,104 @@ convert_delimiter(char *path, char delim)
+ }
+ }
+
++static void setup_cifs_sb(struct smb_vol *pvolume_info,
++ struct cifs_sb_info *cifs_sb)
++{
++ if (pvolume_info->rsize > CIFSMaxBufSize) {
++ cERROR(1, ("rsize %d too large, using MaxBufSize",
++ pvolume_info->rsize));
++ cifs_sb->rsize = CIFSMaxBufSize;
++ } else if ((pvolume_info->rsize) &&
++ (pvolume_info->rsize <= CIFSMaxBufSize))
++ cifs_sb->rsize = pvolume_info->rsize;
++ else /* default */
++ cifs_sb->rsize = CIFSMaxBufSize;
++
++ if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
++ cERROR(1, ("wsize %d too large, using 4096 instead",
++ pvolume_info->wsize));
++ cifs_sb->wsize = 4096;
++ } else if (pvolume_info->wsize)
++ cifs_sb->wsize = pvolume_info->wsize;
++ else
++ cifs_sb->wsize = min_t(const int,
++ PAGEVEC_SIZE * PAGE_CACHE_SIZE,
++ 127*1024);
++ /* old default of CIFSMaxBufSize was too small now
++ that SMB Write2 can send multiple pages in kvec.
++ RFC1001 does not describe what happens when frame
++ bigger than 128K is sent so use that as max in
++ conjunction with 52K kvec constraint on arch with 4K
++ page size */
++
++ if (cifs_sb->rsize < 2048) {
++ cifs_sb->rsize = 2048;
++ /* Windows ME may prefer this */
++ cFYI(1, ("readsize set to minimum: 2048"));
++ }
++ /* calculate prepath */
++ cifs_sb->prepath = pvolume_info->prepath;
++ if (cifs_sb->prepath) {
++ cifs_sb->prepathlen = strlen(cifs_sb->prepath);
++ /* we can not convert the / to \ in the path
++ separators in the prefixpath yet because we do not
++ know (until reset_cifs_unix_caps is called later)
++ whether POSIX PATH CAP is available. We normalize
++ the / to \ after reset_cifs_unix_caps is called */
++ pvolume_info->prepath = NULL;
++ } else
++ cifs_sb->prepathlen = 0;
++ cifs_sb->mnt_uid = pvolume_info->linux_uid;
++ cifs_sb->mnt_gid = pvolume_info->linux_gid;
++ cifs_sb->mnt_file_mode = pvolume_info->file_mode;
++ cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
++ cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
++ cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
++
++ if (pvolume_info->noperm)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
++ if (pvolume_info->setuids)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
++ if (pvolume_info->server_ino)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
++ if (pvolume_info->remap)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
++ if (pvolume_info->no_xattr)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
++ if (pvolume_info->sfu_emul)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
++ if (pvolume_info->nobrl)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
++ if (pvolume_info->cifs_acl)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
++ if (pvolume_info->override_uid)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
++ if (pvolume_info->override_gid)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
++ if (pvolume_info->dynperm)
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
++ if (pvolume_info->direct_io) {
++ cFYI(1, ("mounting share using direct i/o"));
++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
++ }
++
++ if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
++ cERROR(1, ("mount option dynperm ignored if cifsacl "
++ "mount option supported"));
++}
++
+ int
+ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ char *mount_data, const char *devname)
+ {
+ int rc = 0;
+ int xid;
+- int address_type = AF_INET;
+ struct socket *csocket = NULL;
+- struct sockaddr_in sin_server;
+- struct sockaddr_in6 sin_server6;
++ struct sockaddr addr;
++ struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
++ struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
+ struct smb_vol volume_info;
+ struct cifsSesInfo *pSesInfo = NULL;
+- struct cifsSesInfo *existingCifsSes = NULL;
+ struct cifsTconInfo *tcon = NULL;
+ struct TCP_Server_Info *srvTcp = NULL;
+
+@@ -1865,6 +2035,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+
+ /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
+
++ memset(&addr, 0, sizeof(struct sockaddr));
+ memset(&volume_info, 0, sizeof(struct smb_vol));
+ if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
+ rc = -EINVAL;
+@@ -1887,16 +2058,16 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+
+ if (volume_info.UNCip && volume_info.UNC) {
+ rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
+- &sin_server.sin_addr.s_addr);
++ &sin_server->sin_addr.s_addr);
+
+ if (rc <= 0) {
+ /* not ipv4 address, try ipv6 */
+ rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
+- &sin_server6.sin6_addr.in6_u);
++ &sin_server6->sin6_addr.in6_u);
+ if (rc > 0)
+- address_type = AF_INET6;
++ addr.sa_family = AF_INET6;
+ } else {
+- address_type = AF_INET;
++ addr.sa_family = AF_INET;
+ }
+
+ if (rc <= 0) {
+@@ -1936,38 +2107,25 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ }
+ }
+
+- if (address_type == AF_INET)
+- existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
+- NULL /* no ipv6 addr */,
+- volume_info.username, &srvTcp);
+- else if (address_type == AF_INET6) {
+- cFYI(1, ("looking for ipv6 address"));
+- existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
+- &sin_server6.sin6_addr,
+- volume_info.username, &srvTcp);
+- } else {
+- rc = -EINVAL;
+- goto out;
+- }
+-
+- if (srvTcp) {
+- cFYI(1, ("Existing tcp session with server found"));
+- } else { /* create socket */
+- if (volume_info.port)
+- sin_server.sin_port = htons(volume_info.port);
+- else
+- sin_server.sin_port = 0;
+- if (address_type == AF_INET6) {
++ srvTcp = cifs_find_tcp_session(&addr);
++ if (!srvTcp) { /* create socket */
++ if (addr.sa_family == AF_INET6) {
+ cFYI(1, ("attempting ipv6 connect"));
+ /* BB should we allow ipv6 on port 139? */
+ /* other OS never observed in Wild doing 139 with v6 */
+- rc = ipv6_connect(&sin_server6, &csocket);
+- } else
+- rc = ipv4_connect(&sin_server, &csocket,
+- volume_info.source_rfc1001_name,
+- volume_info.target_rfc1001_name);
++ sin_server6->sin6_port = htons(volume_info.port);
++ rc = ipv6_connect(sin_server6, &csocket,
++ volume_info.noblocksnd);
++ } else {
++ sin_server->sin_port = htons(volume_info.port);
++ rc = ipv4_connect(sin_server, &csocket,
++ volume_info.source_rfc1001_name,
++ volume_info.target_rfc1001_name,
++ volume_info.noblocksnd,
++ volume_info.noautotune);
++ }
+ if (rc < 0) {
+- cERROR(1, ("Error connecting to IPv4 socket. "
++ cERROR(1, ("Error connecting to socket. "
+ "Aborting operation"));
+ if (csocket != NULL)
+ sock_release(csocket);
+@@ -1980,12 +2138,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ sock_release(csocket);
+ goto out;
+ } else {
+- memcpy(&srvTcp->addr.sockAddr, &sin_server,
+- sizeof(struct sockaddr_in));
++ srvTcp->noblocksnd = volume_info.noblocksnd;
++ srvTcp->noautotune = volume_info.noautotune;
++ if (addr.sa_family == AF_INET6)
++ memcpy(&srvTcp->addr.sockAddr6, sin_server6,
++ sizeof(struct sockaddr_in6));
++ else
++ memcpy(&srvTcp->addr.sockAddr, sin_server,
++ sizeof(struct sockaddr_in));
+ atomic_set(&srvTcp->inFlight, 0);
+ /* BB Add code for ipv6 case too */
+ srvTcp->ssocket = csocket;
+- srvTcp->protocolType = IPV4;
+ srvTcp->hostname = extract_hostname(volume_info.UNC);
+ if (IS_ERR(srvTcp->hostname)) {
+ rc = PTR_ERR(srvTcp->hostname);
+@@ -2015,15 +2178,28 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ memcpy(srvTcp->server_RFC1001_name,
+ volume_info.target_rfc1001_name, 16);
+ srvTcp->sequence_number = 0;
++ INIT_LIST_HEAD(&srvTcp->tcp_ses_list);
++ INIT_LIST_HEAD(&srvTcp->smb_ses_list);
++ ++srvTcp->srv_count;
++ write_lock(&cifs_tcp_ses_lock);
++ list_add(&srvTcp->tcp_ses_list,
++ &cifs_tcp_ses_list);
++ write_unlock(&cifs_tcp_ses_lock);
+ }
+ }
+
+- if (existingCifsSes) {
+- pSesInfo = existingCifsSes;
++ pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username);
++ if (pSesInfo) {
+ cFYI(1, ("Existing smb sess found (status=%d)",
+ pSesInfo->status));
++ /*
++ * The existing SMB session already has a reference to srvTcp,
++ * so we can put back the extra one we got before
++ */
++ cifs_put_tcp_session(srvTcp);
++
+ down(&pSesInfo->sesSem);
+- if (pSesInfo->status == CifsNeedReconnect) {
++ if (pSesInfo->need_reconnect) {
+ cFYI(1, ("Session needs reconnect"));
+ rc = cifs_setup_session(xid, pSesInfo,
+ cifs_sb->local_nls);
+@@ -2032,180 +2208,94 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ } else if (!rc) {
+ cFYI(1, ("Existing smb sess not found"));
+ pSesInfo = sesInfoAlloc();
+- if (pSesInfo == NULL)
++ if (pSesInfo == NULL) {
+ rc = -ENOMEM;
+- else {
+- pSesInfo->server = srvTcp;
+- sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
+- NIPQUAD(sin_server.sin_addr.s_addr));
+- }
++ goto mount_fail_check;
++ }
++
++ /* new SMB session uses our srvTcp ref */
++ pSesInfo->server = srvTcp;
++ sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
++ NIPQUAD(sin_server->sin_addr.s_addr));
++
++ write_lock(&cifs_tcp_ses_lock);
++ list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
++ write_unlock(&cifs_tcp_ses_lock);
++
++ /* volume_info.password freed at unmount */
++ if (volume_info.password) {
++ pSesInfo->password = volume_info.password;
++ /* set to NULL to prevent freeing on exit */
++ volume_info.password = NULL;
++ }
++ if (volume_info.username)
++ strncpy(pSesInfo->userName, volume_info.username,
++ MAX_USERNAME_SIZE);
++ if (volume_info.domainname) {
++ int len = strlen(volume_info.domainname);
++ pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
++ if (pSesInfo->domainName)
++ strcpy(pSesInfo->domainName,
++ volume_info.domainname);
++ }
++ pSesInfo->linux_uid = volume_info.linux_uid;
++ pSesInfo->overrideSecFlg = volume_info.secFlg;
++ down(&pSesInfo->sesSem);
+
+- if (!rc) {
+- /* volume_info.password freed at unmount */
+- if (volume_info.password) {
+- pSesInfo->password = volume_info.password;
+- /* set to NULL to prevent freeing on exit */
+- volume_info.password = NULL;
+- }
+- if (volume_info.username)
+- strncpy(pSesInfo->userName,
+- volume_info.username,
+- MAX_USERNAME_SIZE);
+- if (volume_info.domainname) {
+- int len = strlen(volume_info.domainname);
+- pSesInfo->domainName =
+- kmalloc(len + 1, GFP_KERNEL);
+- if (pSesInfo->domainName)
+- strcpy(pSesInfo->domainName,
+- volume_info.domainname);
+- }
+- pSesInfo->linux_uid = volume_info.linux_uid;
+- pSesInfo->overrideSecFlg = volume_info.secFlg;
+- down(&pSesInfo->sesSem);
+- /* BB FIXME need to pass vol->secFlgs BB */
+- rc = cifs_setup_session(xid, pSesInfo,
+- cifs_sb->local_nls);
+- up(&pSesInfo->sesSem);
+- if (!rc)
+- atomic_inc(&srvTcp->socketUseCount);
+- }
++ /* BB FIXME need to pass vol->secFlgs BB */
++ rc = cifs_setup_session(xid, pSesInfo,
++ cifs_sb->local_nls);
++ up(&pSesInfo->sesSem);
+ }
+
+ /* search for existing tcon to this server share */
+ if (!rc) {
+- if (volume_info.rsize > CIFSMaxBufSize) {
+- cERROR(1, ("rsize %d too large, using MaxBufSize",
+- volume_info.rsize));
+- cifs_sb->rsize = CIFSMaxBufSize;
+- } else if ((volume_info.rsize) &&
+- (volume_info.rsize <= CIFSMaxBufSize))
+- cifs_sb->rsize = volume_info.rsize;
+- else /* default */
+- cifs_sb->rsize = CIFSMaxBufSize;
+-
+- if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
+- cERROR(1, ("wsize %d too large, using 4096 instead",
+- volume_info.wsize));
+- cifs_sb->wsize = 4096;
+- } else if (volume_info.wsize)
+- cifs_sb->wsize = volume_info.wsize;
+- else
+- cifs_sb->wsize =
+- min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
+- 127*1024);
+- /* old default of CIFSMaxBufSize was too small now
+- that SMB Write2 can send multiple pages in kvec.
+- RFC1001 does not describe what happens when frame
+- bigger than 128K is sent so use that as max in
+- conjunction with 52K kvec constraint on arch with 4K
+- page size */
+-
+- if (cifs_sb->rsize < 2048) {
+- cifs_sb->rsize = 2048;
+- /* Windows ME may prefer this */
+- cFYI(1, ("readsize set to minimum: 2048"));
+- }
+- /* calculate prepath */
+- cifs_sb->prepath = volume_info.prepath;
+- if (cifs_sb->prepath) {
+- cifs_sb->prepathlen = strlen(cifs_sb->prepath);
+- /* we can not convert the / to \ in the path
+- separators in the prefixpath yet because we do not
+- know (until reset_cifs_unix_caps is called later)
+- whether POSIX PATH CAP is available. We normalize
+- the / to \ after reset_cifs_unix_caps is called */
+- volume_info.prepath = NULL;
+- } else
+- cifs_sb->prepathlen = 0;
+- cifs_sb->mnt_uid = volume_info.linux_uid;
+- cifs_sb->mnt_gid = volume_info.linux_gid;
+- cifs_sb->mnt_file_mode = volume_info.file_mode;
+- cifs_sb->mnt_dir_mode = volume_info.dir_mode;
+- cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
+- cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
+-
+- if (volume_info.noperm)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
+- if (volume_info.setuids)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
+- if (volume_info.server_ino)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
+- if (volume_info.remap)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
+- if (volume_info.no_xattr)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
+- if (volume_info.sfu_emul)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
+- if (volume_info.nobrl)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
+- if (volume_info.cifs_acl)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
+- if (volume_info.override_uid)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
+- if (volume_info.override_gid)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
+- if (volume_info.dynperm)
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
+- if (volume_info.direct_io) {
+- cFYI(1, ("mounting share using direct i/o"));
+- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
+- }
+-
+- if ((volume_info.cifs_acl) && (volume_info.dynperm))
+- cERROR(1, ("mount option dynperm ignored if cifsacl "
+- "mount option supported"));
+-
+- tcon =
+- find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
+- volume_info.username);
++ setup_cifs_sb(&volume_info, cifs_sb);
++ tcon = cifs_find_tcon(pSesInfo, volume_info.UNC);
+ if (tcon) {
+ cFYI(1, ("Found match on UNC path"));
+- /* we can have only one retry value for a connection
+- to a share so for resources mounted more than once
+- to the same server share the last value passed in
+- for the retry flag is used */
+- tcon->retry = volume_info.retry;
+- tcon->nocase = volume_info.nocase;
++ /* existing tcon already has a reference */
++ cifs_put_smb_ses(pSesInfo);
+ if (tcon->seal != volume_info.seal)
+ cERROR(1, ("transport encryption setting "
+ "conflicts with existing tid"));
+ } else {
+ tcon = tconInfoAlloc();
+- if (tcon == NULL)
++ if (tcon == NULL) {
+ rc = -ENOMEM;
+- else {
+- /* check for null share name ie connecting to
+- * dfs root */
+-
+- /* BB check if this works for exactly length
+- * three strings */
+- if ((strchr(volume_info.UNC + 3, '\\') == NULL)
+- && (strchr(volume_info.UNC + 3, '/') ==
+- NULL)) {
+-/* rc = connect_to_dfs_path(xid, pSesInfo,
+- "", cifs_sb->local_nls,
+- cifs_sb->mnt_cifs_flags &
+- CIFS_MOUNT_MAP_SPECIAL_CHR);*/
+- cFYI(1, ("DFS root not supported"));
+- rc = -ENODEV;
+- goto out;
+- } else {
+- /* BB Do we need to wrap sesSem around
+- * this TCon call and Unix SetFS as
+- * we do on SessSetup and reconnect? */
+- rc = CIFSTCon(xid, pSesInfo,
+- volume_info.UNC,
+- tcon, cifs_sb->local_nls);
+- cFYI(1, ("CIFS Tcon rc = %d", rc));
+- }
+- if (!rc) {
+- atomic_inc(&pSesInfo->inUse);
+- tcon->retry = volume_info.retry;
+- tcon->nocase = volume_info.nocase;
+- tcon->seal = volume_info.seal;
+- }
++ goto mount_fail_check;
++ }
++ tcon->ses = pSesInfo;
++
++ /* check for null share name ie connect to dfs root */
++ if ((strchr(volume_info.UNC + 3, '\\') == NULL)
++ && (strchr(volume_info.UNC + 3, '/') == NULL)) {
++ /* rc = connect_to_dfs_path(...) */
++ cFYI(1, ("DFS root not supported"));
++ rc = -ENODEV;
++ goto mount_fail_check;
++ } else {
++ /* BB Do we need to wrap sesSem around
++ * this TCon call and Unix SetFS as
++ * we do on SessSetup and reconnect? */
++ rc = CIFSTCon(xid, pSesInfo, volume_info.UNC,
++ tcon, cifs_sb->local_nls);
++ cFYI(1, ("CIFS Tcon rc = %d", rc));
+ }
++ if (rc)
++ goto mount_fail_check;
++ tcon->seal = volume_info.seal;
++ write_lock(&cifs_tcp_ses_lock);
++ list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
++ write_unlock(&cifs_tcp_ses_lock);
+ }
++
++ /* we can have only one retry value for a connection
++ to a share so for resources mounted more than once
++ to the same server share the last value passed in
++ for the retry flag is used */
++ tcon->retry = volume_info.retry;
++ tcon->nocase = volume_info.nocase;
+ }
+ if (pSesInfo) {
+ if (pSesInfo->capabilities & CAP_LARGE_FILES) {
+@@ -2217,91 +2307,49 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ /* BB FIXME fix time_gran to be larger for LANMAN sessions */
+ sb->s_time_gran = 100;
+
+-/* on error free sesinfo and tcon struct if needed */
++ /* on error free sesinfo and tcon struct if needed */
++mount_fail_check:
+ if (rc) {
+- /* if session setup failed, use count is zero but
+- we still need to free cifsd thread */
+- if (atomic_read(&srvTcp->socketUseCount) == 0) {
+- spin_lock(&GlobalMid_Lock);
+- srvTcp->tcpStatus = CifsExiting;
+- spin_unlock(&GlobalMid_Lock);
+- if (srvTcp->tsk) {
+- /* If we could verify that kthread_stop would
+- always wake up processes blocked in
+- tcp in recv_mesg then we could remove the
+- send_sig call */
+- force_sig(SIGKILL, srvTcp->tsk);
+- kthread_stop(srvTcp->tsk);
+- }
+- }
+ /* If find_unc succeeded then rc == 0 so we can not end */
+- if (tcon) /* up accidently freeing someone elses tcon struct */
+- tconInfoFree(tcon);
+- if (existingCifsSes == NULL) {
+- if (pSesInfo) {
+- if ((pSesInfo->server) &&
+- (pSesInfo->status == CifsGood)) {
+- int temp_rc;
+- temp_rc = CIFSSMBLogoff(xid, pSesInfo);
+- /* if the socketUseCount is now zero */
+- if ((temp_rc == -ESHUTDOWN) &&
+- (pSesInfo->server) &&
+- (pSesInfo->server->tsk)) {
+- force_sig(SIGKILL,
+- pSesInfo->server->tsk);
+- kthread_stop(pSesInfo->server->tsk);
+- }
+- } else {
+- cFYI(1, ("No session or bad tcon"));
+- if ((pSesInfo->server) &&
+- (pSesInfo->server->tsk)) {
+- force_sig(SIGKILL,
+- pSesInfo->server->tsk);
+- kthread_stop(pSesInfo->server->tsk);
+- }
+- }
+- sesInfoFree(pSesInfo);
+- /* pSesInfo = NULL; */
+- }
+- }
+- } else {
+- atomic_inc(&tcon->useCount);
+- cifs_sb->tcon = tcon;
+- tcon->ses = pSesInfo;
+-
+- /* do not care if following two calls succeed - informational */
+- if (!tcon->ipc) {
+- CIFSSMBQFSDeviceInfo(xid, tcon);
+- CIFSSMBQFSAttributeInfo(xid, tcon);
+- }
+-
+- /* tell server which Unix caps we support */
+- if (tcon->ses->capabilities & CAP_UNIX)
+- /* reset of caps checks mount to see if unix extensions
+- disabled for just this mount */
+- reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
++ /* up accidently freeing someone elses tcon struct */
++ if (tcon)
++ cifs_put_tcon(tcon);
++ else if (pSesInfo)
++ cifs_put_smb_ses(pSesInfo);
+ else
+- tcon->unix_ext = 0; /* server does not support them */
++ cifs_put_tcp_session(srvTcp);
++ goto out;
++ }
++ cifs_sb->tcon = tcon;
+
+- /* convert forward to back slashes in prepath here if needed */
+- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
+- convert_delimiter(cifs_sb->prepath,
+- CIFS_DIR_SEP(cifs_sb));
++ /* do not care if following two calls succeed - informational */
++ if (!tcon->ipc) {
++ CIFSSMBQFSDeviceInfo(xid, tcon);
++ CIFSSMBQFSAttributeInfo(xid, tcon);
++ }
+
+- if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
+- cifs_sb->rsize = 1024 * 127;
+- cFYI(DBG2,
+- ("no very large read support, rsize now 127K"));
+- }
+- if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
+- cifs_sb->wsize = min(cifs_sb->wsize,
+- (tcon->ses->server->maxBuf -
+- MAX_CIFS_HDR_SIZE));
+- if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
+- cifs_sb->rsize = min(cifs_sb->rsize,
+- (tcon->ses->server->maxBuf -
+- MAX_CIFS_HDR_SIZE));
++ /* tell server which Unix caps we support */
++ if (tcon->ses->capabilities & CAP_UNIX)
++ /* reset of caps checks mount to see if unix extensions
++ disabled for just this mount */
++ reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
++ else
++ tcon->unix_ext = 0; /* server does not support them */
++
++ /* convert forward to back slashes in prepath here if needed */
++ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
++ convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
++
++ if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
++ cifs_sb->rsize = 1024 * 127;
++ cFYI(DBG2, ("no very large read support, rsize now 127K"));
+ }
++ if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
++ cifs_sb->wsize = min(cifs_sb->wsize,
++ (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
++ if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
++ cifs_sb->rsize = min(cifs_sb->rsize,
++ (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
+
+ /* volume_info.password is freed above when existing session found
+ (in which case it is not needed anymore) but when new sesion is created
+@@ -3471,6 +3519,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
+ /* above now done in SendReceive */
+ if ((rc == 0) && (tcon != NULL)) {
+ tcon->tidStatus = CifsGood;
++ tcon->need_reconnect = false;
+ tcon->tid = smb_buffer_response->Tid;
+ bcc_ptr = pByteArea(smb_buffer_response);
+ length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
+@@ -3542,52 +3591,17 @@ int
+ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
+ {
+ int rc = 0;
+- int xid;
+- struct cifsSesInfo *ses = NULL;
+- struct task_struct *cifsd_task;
+ char *tmp;
+
+- xid = GetXid();
+-
+- if (cifs_sb->tcon) {
+- ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
+- rc = CIFSSMBTDis(xid, cifs_sb->tcon);
+- if (rc == -EBUSY) {
+- FreeXid(xid);
+- return 0;
+- }
+- DeleteTconOplockQEntries(cifs_sb->tcon);
+- tconInfoFree(cifs_sb->tcon);
+- if ((ses) && (ses->server)) {
+- /* save off task so we do not refer to ses later */
+- cifsd_task = ses->server->tsk;
+- cFYI(1, ("About to do SMBLogoff "));
+- rc = CIFSSMBLogoff(xid, ses);
+- if (rc == -EBUSY) {
+- FreeXid(xid);
+- return 0;
+- } else if (rc == -ESHUTDOWN) {
+- cFYI(1, ("Waking up socket by sending signal"));
+- if (cifsd_task) {
+- force_sig(SIGKILL, cifsd_task);
+- kthread_stop(cifsd_task);
+- }
+- rc = 0;
+- } /* else - we have an smb session
+- left on this socket do not kill cifsd */
+- } else
+- cFYI(1, ("No session or bad tcon"));
+- }
++ if (cifs_sb->tcon)
++ cifs_put_tcon(cifs_sb->tcon);
+
+ cifs_sb->tcon = NULL;
+ tmp = cifs_sb->prepath;
+ cifs_sb->prepathlen = 0;
+ cifs_sb->prepath = NULL;
+ kfree(tmp);
+- if (ses)
+- sesInfoFree(ses);
+
+- FreeXid(xid);
+ return rc;
+ }
+
+@@ -3702,6 +3716,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
+ } else {
+ cFYI(1, ("CIFS Session Established successfully"));
+ pSesInfo->status = CifsGood;
++ pSesInfo->need_reconnect = false;
+ }
+
+ ss_err_exit:
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index cbefe1f..042b122 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -493,7 +493,7 @@ int cifs_close(struct inode *inode, struct file *file)
+ if (pTcon) {
+ /* no sense reconnecting to close a file that is
+ already closed */
+- if (pTcon->tidStatus != CifsNeedReconnect) {
++ if (!pTcon->need_reconnect) {
+ timeout = 2;
+ while ((atomic_read(&pSMBFile->wrtPending) != 0)
+ && (timeout <= 2048)) {
+@@ -1396,7 +1396,10 @@ retry:
+ if ((wbc->nr_to_write -= n_iov) <= 0)
+ done = 1;
+ index = next;
+- }
++ } else
++ /* Need to re-find the pages we skipped */
++ index = pvec.pages[0]->index + 1;
++
+ pagevec_release(&pvec);
+ }
+ if (!scanned && !done) {
+@@ -1813,7 +1816,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
+ pTcon = cifs_sb->tcon;
+
+ pagevec_init(&lru_pvec, 0);
+- cFYI(DBG2, ("rpages: num pages %d", num_pages));
++ cFYI(DBG2, ("rpages: num pages %d", num_pages));
+ for (i = 0; i < num_pages; ) {
+ unsigned contig_pages;
+ struct page *tmp_page;
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 4b17f8f..b891553 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -75,12 +75,12 @@ sesInfoAlloc(void)
+
+ ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
+ if (ret_buf) {
+- write_lock(&GlobalSMBSeslock);
+ atomic_inc(&sesInfoAllocCount);
+ ret_buf->status = CifsNew;
+- list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList);
++ ++ret_buf->ses_count;
++ INIT_LIST_HEAD(&ret_buf->smb_ses_list);
++ INIT_LIST_HEAD(&ret_buf->tcon_list);
+ init_MUTEX(&ret_buf->sesSem);
+- write_unlock(&GlobalSMBSeslock);
+ }
+ return ret_buf;
+ }
+@@ -93,10 +93,7 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
+ return;
+ }
+
+- write_lock(&GlobalSMBSeslock);
+ atomic_dec(&sesInfoAllocCount);
+- list_del(&buf_to_free->cifsSessionList);
+- write_unlock(&GlobalSMBSeslock);
+ kfree(buf_to_free->serverOS);
+ kfree(buf_to_free->serverDomain);
+ kfree(buf_to_free->serverNOS);
+@@ -111,17 +108,14 @@ tconInfoAlloc(void)
+ struct cifsTconInfo *ret_buf;
+ ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
+ if (ret_buf) {
+- write_lock(&GlobalSMBSeslock);
+ atomic_inc(&tconInfoAllocCount);
+- list_add(&ret_buf->cifsConnectionList,
+- &GlobalTreeConnectionList);
+ ret_buf->tidStatus = CifsNew;
++ ++ret_buf->tc_count;
+ INIT_LIST_HEAD(&ret_buf->openFileList);
+- init_MUTEX(&ret_buf->tconSem);
++ INIT_LIST_HEAD(&ret_buf->tcon_list);
+ #ifdef CONFIG_CIFS_STATS
+ spin_lock_init(&ret_buf->stat_lock);
+ #endif
+- write_unlock(&GlobalSMBSeslock);
+ }
+ return ret_buf;
+ }
+@@ -133,10 +127,7 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
+ cFYI(1, ("Null buffer passed to tconInfoFree"));
+ return;
+ }
+- write_lock(&GlobalSMBSeslock);
+ atomic_dec(&tconInfoAllocCount);
+- list_del(&buf_to_free->cifsConnectionList);
+- write_unlock(&GlobalSMBSeslock);
+ kfree(buf_to_free->nativeFileSystem);
+ kfree(buf_to_free);
+ }
+@@ -354,9 +345,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
+ if (current->fsuid != treeCon->ses->linux_uid) {
+ cFYI(1, ("Multiuser mode and UID "
+ "did not match tcon uid"));
+- read_lock(&GlobalSMBSeslock);
+- list_for_each(temp_item, &GlobalSMBSessionList) {
+- ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
++ ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
+ if (ses->linux_uid == current->fsuid) {
+ if (ses->server == treeCon->ses->server) {
+ cFYI(1, ("found matching uid substitute right smb_uid"));
+@@ -368,7 +359,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
+ }
+ }
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ }
+ }
+ }
+@@ -501,9 +492,10 @@ bool
+ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
+ {
+ struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
+- struct list_head *tmp;
+- struct list_head *tmp1;
++ struct list_head *tmp, *tmp1, *tmp2;
++ struct cifsSesInfo *ses;
+ struct cifsTconInfo *tcon;
++ struct cifsInodeInfo *pCifsInode;
+ struct cifsFileInfo *netfile;
+
+ cFYI(1, ("Checking for oplock break or dnotify response"));
+@@ -558,42 +550,42 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
+ return false;
+
+ /* look up tcon based on tid & uid */
+- read_lock(&GlobalSMBSeslock);
+- list_for_each(tmp, &GlobalTreeConnectionList) {
+- tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+- if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) {
++ read_lock(&cifs_tcp_ses_lock);
++ list_for_each(tmp, &srv->smb_ses_list) {
++ ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
++ list_for_each(tmp1, &ses->tcon_list) {
++ tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);
++ if (tcon->tid != buf->Tid)
++ continue;
++
+ cifs_stats_inc(&tcon->num_oplock_brks);
+- list_for_each(tmp1, &tcon->openFileList) {
+- netfile = list_entry(tmp1, struct cifsFileInfo,
++ list_for_each(tmp2, &tcon->openFileList) {
++ netfile = list_entry(tmp2, struct cifsFileInfo,
+ tlist);
+- if (pSMB->Fid == netfile->netfid) {
+- struct cifsInodeInfo *pCifsInode;
+- read_unlock(&GlobalSMBSeslock);
+- cFYI(1,
+- ("file id match, oplock break"));
+- pCifsInode =
+- CIFS_I(netfile->pInode);
+- pCifsInode->clientCanCacheAll = false;
+- if (pSMB->OplockLevel == 0)
+- pCifsInode->clientCanCacheRead
+- = false;
+- pCifsInode->oplockPending = true;
+- AllocOplockQEntry(netfile->pInode,
+- netfile->netfid,
+- tcon);
+- cFYI(1,
+- ("about to wake up oplock thread"));
+- if (oplockThread)
+- wake_up_process(oplockThread);
+- return true;
+- }
++ if (pSMB->Fid != netfile->netfid)
++ continue;
++
++ read_unlock(&cifs_tcp_ses_lock);
++ cFYI(1, ("file id match, oplock break"));
++ pCifsInode = CIFS_I(netfile->pInode);
++ pCifsInode->clientCanCacheAll = false;
++ if (pSMB->OplockLevel == 0)
++ pCifsInode->clientCanCacheRead = false;
++ pCifsInode->oplockPending = true;
++ AllocOplockQEntry(netfile->pInode,
++ netfile->netfid, tcon);
++ cFYI(1, ("about to wake up oplock thread"));
++ if (oplockThread)
++ wake_up_process(oplockThread);
++
++ return true;
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ cFYI(1, ("No matching file for oplock break"));
+ return true;
+ }
+ }
+- read_unlock(&GlobalSMBSeslock);
++ read_unlock(&cifs_tcp_ses_lock);
+ cFYI(1, ("Can not process oplock break for non-existent connection"));
+ return true;
+ }
+diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
+index e286db9..bb0f329 100644
+--- a/fs/cifs/transport.c
++++ b/fs/cifs/transport.c
+@@ -162,7 +162,7 @@ void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
+
+ int
+ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
+- unsigned int smb_buf_length, struct sockaddr *sin)
++ unsigned int smb_buf_length, struct sockaddr *sin, bool noblocksnd)
+ {
+ int rc = 0;
+ int i = 0;
+@@ -179,7 +179,10 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
+ smb_msg.msg_namelen = sizeof(struct sockaddr);
+ smb_msg.msg_control = NULL;
+ smb_msg.msg_controllen = 0;
+- smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
++ if (noblocksnd)
++ smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
++ else
++ smb_msg.msg_flags = MSG_NOSIGNAL;
+
+ /* smb header is converted in header_assemble. bcc and rest of SMB word
+ area, and byte area if necessary, is converted to littleendian in
+@@ -230,8 +233,8 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
+ }
+
+ static int
+-smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
+- struct sockaddr *sin)
++smb_send2(struct TCP_Server_Info *server, struct kvec *iov, int n_vec,
++ struct sockaddr *sin, bool noblocksnd)
+ {
+ int rc = 0;
+ int i = 0;
+@@ -241,6 +244,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
+ unsigned int total_len;
+ int first_vec = 0;
+ unsigned int smb_buf_length = smb_buffer->smb_buf_length;
++ struct socket *ssocket = server->ssocket;
+
+ if (ssocket == NULL)
+ return -ENOTSOCK; /* BB eventually add reconnect code here */
+@@ -249,7 +253,10 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
+ smb_msg.msg_namelen = sizeof(struct sockaddr);
+ smb_msg.msg_control = NULL;
+ smb_msg.msg_controllen = 0;
+- smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
++ if (noblocksnd)
++ smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
++ else
++ smb_msg.msg_flags = MSG_NOSIGNAL;
+
+ /* smb header is converted in header_assemble. bcc and rest of SMB word
+ area, and byte area if necessary, is converted to littleendian in
+@@ -284,8 +291,11 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
+ if (rc < 0)
+ break;
+
+- if (rc >= total_len) {
+- WARN_ON(rc > total_len);
++ if (rc == total_len) {
++ total_len = 0;
++ break;
++ } else if (rc > total_len) {
++ cERROR(1, ("sent %d requested %d", rc, total_len));
+ break;
+ }
+ if (rc == 0) {
+@@ -313,6 +323,16 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
+ i = 0; /* in case we get ENOSPC on the next send */
+ }
+
++ if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
++ cFYI(1, ("partial send (%d remaining), terminating session",
++ total_len));
++ /* If we have only sent part of an SMB then the next SMB
++ could be taken as the remainder of this one. We need
++ to kill the socket so the server throws away the partial
++ SMB */
++ server->tcpStatus = CifsNeedReconnect;
++ }
++
+ if (rc < 0) {
+ cERROR(1, ("Error %d sending data on socket to server", rc));
+ } else
+@@ -519,8 +539,9 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+ #ifdef CONFIG_CIFS_STATS2
+ atomic_inc(&ses->server->inSend);
+ #endif
+- rc = smb_send2(ses->server->ssocket, iov, n_vec,
+- (struct sockaddr *) &(ses->server->addr.sockAddr));
++ rc = smb_send2(ses->server, iov, n_vec,
++ (struct sockaddr *) &(ses->server->addr.sockAddr),
++ ses->server->noblocksnd);
+ #ifdef CONFIG_CIFS_STATS2
+ atomic_dec(&ses->server->inSend);
+ midQ->when_sent = jiffies;
+@@ -712,7 +733,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
+ atomic_inc(&ses->server->inSend);
+ #endif
+ rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
+- (struct sockaddr *) &(ses->server->addr.sockAddr));
++ (struct sockaddr *) &(ses->server->addr.sockAddr),
++ ses->server->noblocksnd);
+ #ifdef CONFIG_CIFS_STATS2
+ atomic_dec(&ses->server->inSend);
+ midQ->when_sent = jiffies;
+@@ -852,7 +874,8 @@ send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
+ return rc;
+ }
+ rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
+- (struct sockaddr *) &(ses->server->addr.sockAddr));
++ (struct sockaddr *) &(ses->server->addr.sockAddr),
++ ses->server->noblocksnd);
+ up(&ses->server->tcpSem);
+ return rc;
+ }
+@@ -942,7 +965,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
+ atomic_inc(&ses->server->inSend);
+ #endif
+ rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
+- (struct sockaddr *) &(ses->server->addr.sockAddr));
++ (struct sockaddr *) &(ses->server->addr.sockAddr),
++ ses->server->noblocksnd);
+ #ifdef CONFIG_CIFS_STATS2
+ atomic_dec(&ses->server->inSend);
+ midQ->when_sent = jiffies;
+diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
+index f5b76a3..59b9833 100644
+--- a/fs/ecryptfs/keystore.c
++++ b/fs/ecryptfs/keystore.c
+@@ -1037,17 +1037,14 @@ static int
+ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ struct ecryptfs_crypt_stat *crypt_stat)
+ {
+- struct scatterlist dst_sg;
+- struct scatterlist src_sg;
++ struct scatterlist dst_sg[2];
++ struct scatterlist src_sg[2];
+ struct mutex *tfm_mutex;
+ struct blkcipher_desc desc = {
+ .flags = CRYPTO_TFM_REQ_MAY_SLEEP
+ };
+ int rc = 0;
+
+- sg_init_table(&dst_sg, 1);
+- sg_init_table(&src_sg, 1);
+-
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(
+ KERN_DEBUG, "Session key encryption key (size [%d]):\n",
+@@ -1066,8 +1063,8 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ }
+ rc = virt_to_scatterlist(auth_tok->session_key.encrypted_key,
+ auth_tok->session_key.encrypted_key_size,
+- &src_sg, 1);
+- if (rc != 1) {
++ src_sg, 2);
++ if (rc < 1 || rc > 2) {
+ printk(KERN_ERR "Internal error whilst attempting to convert "
+ "auth_tok->session_key.encrypted_key to scatterlist; "
+ "expected rc = 1; got rc = [%d]. "
+@@ -1079,8 +1076,8 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ auth_tok->session_key.encrypted_key_size;
+ rc = virt_to_scatterlist(auth_tok->session_key.decrypted_key,
+ auth_tok->session_key.decrypted_key_size,
+- &dst_sg, 1);
+- if (rc != 1) {
++ dst_sg, 2);
++ if (rc < 1 || rc > 2) {
+ printk(KERN_ERR "Internal error whilst attempting to convert "
+ "auth_tok->session_key.decrypted_key to scatterlist; "
+ "expected rc = 1; got rc = [%d]\n", rc);
+@@ -1096,7 +1093,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ rc = -EINVAL;
+ goto out;
+ }
+- rc = crypto_blkcipher_decrypt(&desc, &dst_sg, &src_sg,
++ rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg,
+ auth_tok->session_key.encrypted_key_size);
+ mutex_unlock(tfm_mutex);
+ if (unlikely(rc)) {
+@@ -1541,8 +1538,8 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
+ size_t i;
+ size_t encrypted_session_key_valid = 0;
+ char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+- struct scatterlist dst_sg;
+- struct scatterlist src_sg;
++ struct scatterlist dst_sg[2];
++ struct scatterlist src_sg[2];
+ struct mutex *tfm_mutex = NULL;
+ u8 cipher_code;
+ size_t packet_size_length;
+@@ -1621,8 +1618,8 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
+ ecryptfs_dump_hex(session_key_encryption_key, 16);
+ }
+ rc = virt_to_scatterlist(crypt_stat->key, key_rec->enc_key_size,
+- &src_sg, 1);
+- if (rc != 1) {
++ src_sg, 2);
++ if (rc < 1 || rc > 2) {
+ ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
+ "for crypt_stat session key; expected rc = 1; "
+ "got rc = [%d]. key_rec->enc_key_size = [%d]\n",
+@@ -1631,8 +1628,8 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
+ goto out;
+ }
+ rc = virt_to_scatterlist(key_rec->enc_key, key_rec->enc_key_size,
+- &dst_sg, 1);
+- if (rc != 1) {
++ dst_sg, 2);
++ if (rc < 1 || rc > 2) {
+ ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
+ "for crypt_stat encrypted session key; "
+ "expected rc = 1; got rc = [%d]. "
+@@ -1653,7 +1650,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
+ rc = 0;
+ ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
+ crypt_stat->key_size);
+- rc = crypto_blkcipher_encrypt(&desc, &dst_sg, &src_sg,
++ rc = crypto_blkcipher_encrypt(&desc, dst_sg, src_sg,
+ (*key_rec).enc_key_size);
+ mutex_unlock(tfm_mutex);
+ if (rc) {
+diff --git a/fs/eventpoll.c b/fs/eventpoll.c
+index 7cc0eb7..c8cec49 100644
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -102,6 +102,8 @@
+
+ #define EP_UNACTIVE_PTR ((void *) -1L)
+
++#define EP_ITEM_COST (sizeof(struct epitem) + sizeof(struct eppoll_entry))
++
+ struct epoll_filefd {
+ struct file *file;
+ int fd;
+@@ -200,6 +202,9 @@ struct eventpoll {
+ * holding ->lock.
+ */
+ struct epitem *ovflist;
++
++ /* The user that created the eventpoll descriptor */
++ struct user_struct *user;
+ };
+
+ /* Wait structure used by the poll hooks */
+@@ -227,9 +232,17 @@ struct ep_pqueue {
+ };
+
+ /*
++ * Configuration options available inside /proc/sys/fs/epoll/
++ */
++/* Maximum number of epoll devices, per user */
++static int max_user_instances __read_mostly;
++/* Maximum number of epoll watched descriptors, per user */
++static int max_user_watches __read_mostly;
++
++/*
+ * This mutex is used to serialize ep_free() and eventpoll_release_file().
+ */
+-static struct mutex epmutex;
++static DEFINE_MUTEX(epmutex);
+
+ /* Safe wake up implementation */
+ static struct poll_safewake psw;
+@@ -240,6 +253,33 @@ static struct kmem_cache *epi_cache __read_mostly;
+ /* Slab cache used to allocate "struct eppoll_entry" */
+ static struct kmem_cache *pwq_cache __read_mostly;
+
++#ifdef CONFIG_SYSCTL
++
++#include <linux/sysctl.h>
++
++static int zero;
++
++ctl_table epoll_table[] = {
++ {
++ .procname = "max_user_instances",
++ .data = &max_user_instances,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_minmax,
++ .extra1 = &zero,
++ },
++ {
++ .procname = "max_user_watches",
++ .data = &max_user_watches,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_minmax,
++ .extra1 = &zero,
++ },
++ { .ctl_name = 0 }
++};
++#endif /* CONFIG_SYSCTL */
++
+
+ /* Setup the structure that is used as key for the RB tree */
+ static inline void ep_set_ffd(struct epoll_filefd *ffd,
+@@ -402,6 +442,8 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
+ /* At this point it is safe to free the eventpoll item */
+ kmem_cache_free(epi_cache, epi);
+
++ atomic_dec(&ep->user->epoll_watches);
++
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p)\n",
+ current, ep, file));
+
+@@ -449,6 +491,8 @@ static void ep_free(struct eventpoll *ep)
+
+ mutex_unlock(&epmutex);
+ mutex_destroy(&ep->mtx);
++ atomic_dec(&ep->user->epoll_devs);
++ free_uid(ep->user);
+ kfree(ep);
+ }
+
+@@ -532,10 +576,19 @@ void eventpoll_release_file(struct file *file)
+
+ static int ep_alloc(struct eventpoll **pep)
+ {
+- struct eventpoll *ep = kzalloc(sizeof(*ep), GFP_KERNEL);
++ int error;
++ struct user_struct *user;
++ struct eventpoll *ep;
+
+- if (!ep)
+- return -ENOMEM;
++ user = get_current_user();
++ error = -EMFILE;
++ if (unlikely(atomic_read(&user->epoll_devs) >=
++ max_user_instances))
++ goto free_uid;
++ error = -ENOMEM;
++ ep = kzalloc(sizeof(*ep), GFP_KERNEL);
++ if (unlikely(!ep))
++ goto free_uid;
+
+ spin_lock_init(&ep->lock);
+ mutex_init(&ep->mtx);
+@@ -544,12 +597,17 @@ static int ep_alloc(struct eventpoll **pep)
+ INIT_LIST_HEAD(&ep->rdllist);
+ ep->rbr = RB_ROOT;
+ ep->ovflist = EP_UNACTIVE_PTR;
++ ep->user = user;
+
+ *pep = ep;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_alloc() ep=%p\n",
+ current, ep));
+ return 0;
++
++free_uid:
++ free_uid(user);
++ return error;
+ }
+
+ /*
+@@ -703,9 +761,11 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
+ struct epitem *epi;
+ struct ep_pqueue epq;
+
+- error = -ENOMEM;
++ if (unlikely(atomic_read(&ep->user->epoll_watches) >=
++ max_user_watches))
++ return -ENOSPC;
+ if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL)))
+- goto error_return;
++ return -ENOMEM;
+
+ /* Item initialization follow here ... */
+ INIT_LIST_HEAD(&epi->rdllink);
+@@ -735,6 +795,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
+ * install process. Namely an allocation for a wait queue failed due
+ * high memory pressure.
+ */
++ error = -ENOMEM;
+ if (epi->nwait < 0)
+ goto error_unregister;
+
+@@ -765,6 +826,8 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
+
+ spin_unlock_irqrestore(&ep->lock, flags);
+
++ atomic_inc(&ep->user->epoll_watches);
++
+ /* We have to call this outside the lock */
+ if (pwake)
+ ep_poll_safewake(&psw, &ep->poll_wait);
+@@ -789,7 +852,7 @@ error_unregister:
+ spin_unlock_irqrestore(&ep->lock, flags);
+
+ kmem_cache_free(epi_cache, epi);
+-error_return:
++
+ return error;
+ }
+
+@@ -1074,6 +1137,7 @@ asmlinkage long sys_epoll_create1(int flags)
+ flags & O_CLOEXEC);
+ if (fd < 0)
+ ep_free(ep);
++ atomic_inc(&ep->user->epoll_devs);
+
+ error_return:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+@@ -1295,7 +1359,12 @@ asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
+
+ static int __init eventpoll_init(void)
+ {
+- mutex_init(&epmutex);
++ struct sysinfo si;
++
++ si_meminfo(&si);
++ max_user_instances = 128;
++ max_user_watches = (((si.totalram - si.totalhigh) / 32) << PAGE_SHIFT) /
++ EP_ITEM_COST;
+
+ /* Initialize the structure used to perform safe poll wait head wake ups */
+ ep_poll_safewake_init(&psw);
+diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
+index 10bb02c..6dac7ba 100644
+--- a/fs/ext2/balloc.c
++++ b/fs/ext2/balloc.c
+@@ -1295,6 +1295,7 @@ retry_alloc:
+ * turn off reservation for this allocation
+ */
+ if (my_rsv && (free_blocks < windowsz)
++ && (free_blocks > 0)
+ && (rsv_is_empty(&my_rsv->rsv_window)))
+ my_rsv = NULL;
+
+@@ -1332,7 +1333,7 @@ retry_alloc:
+ * free blocks is less than half of the reservation
+ * window size.
+ */
+- if (free_blocks <= (windowsz/2))
++ if (my_rsv && (free_blocks <= (windowsz/2)))
+ continue;
+
+ brelse(bitmap_bh);
+diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
+index 92fd033..f5b57a2 100644
+--- a/fs/ext3/balloc.c
++++ b/fs/ext3/balloc.c
+@@ -1547,6 +1547,7 @@ retry_alloc:
+ * turn off reservation for this allocation
+ */
+ if (my_rsv && (free_blocks < windowsz)
++ && (free_blocks > 0)
+ && (rsv_is_empty(&my_rsv->rsv_window)))
+ my_rsv = NULL;
+
+@@ -1585,7 +1586,7 @@ retry_alloc:
+ * free blocks is less than half of the reservation
+ * window size.
+ */
+- if (free_blocks <= (windowsz/2))
++ if (my_rsv && (free_blocks <= (windowsz/2)))
+ continue;
+
+ brelse(bitmap_bh);
+diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
+index 1b80f1c..5853f44 100644
+--- a/fs/ext3/dir.c
++++ b/fs/ext3/dir.c
+@@ -414,7 +414,7 @@ static int call_filldir(struct file * filp, void * dirent,
+ get_dtype(sb, fname->file_type));
+ if (error) {
+ filp->f_pos = curr_pos;
+- info->extra_fname = fname->next;
++ info->extra_fname = fname;
+ return error;
+ }
+ fname = fname->next;
+@@ -453,11 +453,12 @@ static int ext3_dx_readdir(struct file * filp,
+ * If there are any leftover names on the hash collision
+ * chain, return them first.
+ */
+- if (info->extra_fname &&
+- call_filldir(filp, dirent, filldir, info->extra_fname))
+- goto finished;
+-
+- if (!info->curr_node)
++ if (info->extra_fname) {
++ if (call_filldir(filp, dirent, filldir, info->extra_fname))
++ goto finished;
++ info->extra_fname = NULL;
++ goto next_node;
++ } else if (!info->curr_node)
+ info->curr_node = rb_first(&info->root);
+
+ while (1) {
+@@ -488,9 +489,14 @@ static int ext3_dx_readdir(struct file * filp,
+ info->curr_minor_hash = fname->minor_hash;
+ if (call_filldir(filp, dirent, filldir, fname))
+ break;
+-
++ next_node:
+ info->curr_node = rb_next(info->curr_node);
+- if (!info->curr_node) {
++ if (info->curr_node) {
++ fname = rb_entry(info->curr_node, struct fname,
++ rb_hash);
++ info->curr_hash = fname->hash;
++ info->curr_minor_hash = fname->minor_hash;
++ } else {
+ if (info->next_hash == ~0) {
+ filp->f_pos = EXT3_HTREE_EOF;
+ break;
+diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
+index 77278e9..78fdf38 100644
+--- a/fs/ext3/resize.c
++++ b/fs/ext3/resize.c
+@@ -790,7 +790,8 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
+
+ if (reserved_gdb || gdb_off == 0) {
+ if (!EXT3_HAS_COMPAT_FEATURE(sb,
+- EXT3_FEATURE_COMPAT_RESIZE_INODE)){
++ EXT3_FEATURE_COMPAT_RESIZE_INODE)
++ || !le16_to_cpu(es->s_reserved_gdt_blocks)) {
+ ext3_warning(sb, __func__,
+ "No reserved GDT blocks, can't resize");
+ return -EPERM;
+diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
+index e9fa960..c2e4b89 100644
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -318,9 +318,11 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
+ block_group, bitmap_blk);
+ return NULL;
+ }
+- if (bh_uptodate_or_lock(bh))
++ if (buffer_uptodate(bh) &&
++ !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))
+ return bh;
+
++ lock_buffer(bh);
+ spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+ ext4_init_block_bitmap(sb, bh, block_group, desc);
+diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
+index d1d6487..e45d086 100644
+--- a/fs/ext4/dir.c
++++ b/fs/ext4/dir.c
+@@ -458,17 +458,8 @@ static int ext4_dx_readdir(struct file * filp,
+ if (info->extra_fname) {
+ if (call_filldir(filp, dirent, filldir, info->extra_fname))
+ goto finished;
+-
+ info->extra_fname = NULL;
+- info->curr_node = rb_next(info->curr_node);
+- if (!info->curr_node) {
+- if (info->next_hash == ~0) {
+- filp->f_pos = EXT4_HTREE_EOF;
+- goto finished;
+- }
+- info->curr_hash = info->next_hash;
+- info->curr_minor_hash = 0;
+- }
++ goto next_node;
+ } else if (!info->curr_node)
+ info->curr_node = rb_first(&info->root);
+
+@@ -500,9 +491,14 @@ static int ext4_dx_readdir(struct file * filp,
+ info->curr_minor_hash = fname->minor_hash;
+ if (call_filldir(filp, dirent, filldir, fname))
+ break;
+-
++ next_node:
+ info->curr_node = rb_next(info->curr_node);
+- if (!info->curr_node) {
++ if (info->curr_node) {
++ fname = rb_entry(info->curr_node, struct fname,
++ rb_hash);
++ info->curr_hash = fname->hash;
++ info->curr_minor_hash = fname->minor_hash;
++ } else {
+ if (info->next_hash == ~0) {
+ filp->f_pos = EXT4_HTREE_EOF;
+ break;
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 2950032..4829dac 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -291,8 +291,6 @@ struct ext4_new_group_data {
+ #define EXT4_IOC_SETFLAGS FS_IOC_SETFLAGS
+ #define EXT4_IOC_GETVERSION _IOR('f', 3, long)
+ #define EXT4_IOC_SETVERSION _IOW('f', 4, long)
+-#define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
+-#define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input)
+ #define EXT4_IOC_GETVERSION_OLD FS_IOC_GETVERSION
+ #define EXT4_IOC_SETVERSION_OLD FS_IOC_SETVERSION
+ #ifdef CONFIG_JBD2_DEBUG
+@@ -300,7 +298,10 @@ struct ext4_new_group_data {
+ #endif
+ #define EXT4_IOC_GETRSVSZ _IOR('f', 5, long)
+ #define EXT4_IOC_SETRSVSZ _IOW('f', 6, long)
+-#define EXT4_IOC_MIGRATE _IO('f', 7)
++#define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
++#define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input)
++#define EXT4_IOC_MIGRATE _IO('f', 9)
++ /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
+
+ /*
+ * ioctl commands in 32 bit emulation
+@@ -1083,8 +1084,7 @@ extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
+ extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long);
+
+ /* migrate.c */
+-extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
+- unsigned long);
++extern int ext4_ext_migrate(struct inode *);
+ /* namei.c */
+ extern int ext4_orphan_add(handle_t *, struct inode *);
+ extern int ext4_orphan_del(handle_t *, struct inode *);
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index f344834..13efb5f 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -115,9 +115,11 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
+ block_group, bitmap_blk);
+ return NULL;
+ }
+- if (bh_uptodate_or_lock(bh))
++ if (buffer_uptodate(bh) &&
++ !(desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)))
+ return bh;
+
++ lock_buffer(bh);
+ spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+ ext4_init_inode_bitmap(sb, bh, block_group, desc);
+@@ -715,6 +717,8 @@ got:
+ gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+ free = ext4_free_blocks_after_init(sb, group, gdp);
+ gdp->bg_free_blocks_count = cpu_to_le16(free);
++ gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
++ gdp);
+ }
+ spin_unlock(sb_bgl_lock(sbi, group));
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 7e91913..846a790 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -2242,6 +2242,8 @@ static int ext4_da_writepage(struct page *page,
+ unlock_page(page);
+ return 0;
+ }
++ /* now mark the buffer_heads as dirty and uptodate */
++ block_commit_write(page, 0, PAGE_CACHE_SIZE);
+ }
+
+ if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
+@@ -4444,9 +4446,10 @@ static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks,
+ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
+ {
+ if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
+- return ext4_indirect_trans_blocks(inode, nrblocks, 0);
+- return ext4_ext_index_trans_blocks(inode, nrblocks, 0);
++ return ext4_indirect_trans_blocks(inode, nrblocks, chunk);
++ return ext4_ext_index_trans_blocks(inode, nrblocks, chunk);
+ }
++
+ /*
+ * Account for index blocks, block groups bitmaps and block group
+ * descriptor blocks if modify datablocks and index blocks
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index 7a6c2f1..306bfd4 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -267,7 +267,26 @@ setversion_out:
+ }
+
+ case EXT4_IOC_MIGRATE:
+- return ext4_ext_migrate(inode, filp, cmd, arg);
++ {
++ int err;
++ if (!is_owner_or_cap(inode))
++ return -EACCES;
++
++ err = mnt_want_write(filp->f_path.mnt);
++ if (err)
++ return err;
++ /*
++ * inode_mutex prevent write and truncate on the file.
++ * Read still goes through. We take i_data_sem in
++ * ext4_ext_swap_inode_data before we switch the
++ * inode format to prevent read.
++ */
++ mutex_lock(&(inode->i_mutex));
++ err = ext4_ext_migrate(inode);
++ mutex_unlock(&(inode->i_mutex));
++ mnt_drop_write(filp->f_path.mnt);
++ return err;
++ }
+
+ default:
+ return -ENOTTY;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index e0e3a5e..c666b8d 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -784,9 +784,11 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
+ if (bh[i] == NULL)
+ goto out;
+
+- if (bh_uptodate_or_lock(bh[i]))
++ if (buffer_uptodate(bh[i]) &&
++ !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))
+ continue;
+
++ lock_buffer(bh[i]);
+ spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+ if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+ ext4_init_block_bitmap(sb, bh[i],
+@@ -2575,7 +2577,7 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp)
+ pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list);
+ list_del(&pa->pa_group_list);
+ count++;
+- kfree(pa);
++ kmem_cache_free(ext4_pspace_cachep, pa);
+ }
+ if (count)
+ mb_debug("mballoc: %u PAs left\n", count);
+@@ -2785,14 +2787,20 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb)
+ mode_t mode = S_IFREG | S_IRUGO | S_IWUSR;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct proc_dir_entry *proc;
+- char devname[64];
++ char devname[BDEVNAME_SIZE], *p;
+
+ if (proc_root_ext4 == NULL) {
+ sbi->s_mb_proc = NULL;
+ return -EINVAL;
+ }
+ bdevname(sb->s_bdev, devname);
++ p = devname;
++ while ((p = strchr(p, '/')))
++ *p = '!';
++
+ sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4);
++ if (!sbi->s_mb_proc)
++ goto err_create_dir;
+
+ MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats);
+ MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan);
+@@ -2804,7 +2812,6 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb)
+ return 0;
+
+ err_out:
+- printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname);
+ remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
+ remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
+ remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
+@@ -2813,6 +2820,8 @@ err_out:
+ remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
+ remove_proc_entry(devname, proc_root_ext4);
+ sbi->s_mb_proc = NULL;
++err_create_dir:
++ printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname);
+
+ return -ENOMEM;
+ }
+@@ -2820,12 +2829,15 @@ err_out:
+ static int ext4_mb_destroy_per_dev_proc(struct super_block *sb)
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+- char devname[64];
++ char devname[BDEVNAME_SIZE], *p;
+
+ if (sbi->s_mb_proc == NULL)
+ return -EINVAL;
+
+ bdevname(sb->s_bdev, devname);
++ p = devname;
++ while ((p = strchr(p, '/')))
++ *p = '!';
+ remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
+ remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
+ remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
+index 46fc0b5..f2a9cf4 100644
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -447,8 +447,7 @@ static int free_ext_block(handle_t *handle, struct inode *inode)
+
+ }
+
+-int ext4_ext_migrate(struct inode *inode, struct file *filp,
+- unsigned int cmd, unsigned long arg)
++int ext4_ext_migrate(struct inode *inode)
+ {
+ handle_t *handle;
+ int retval = 0, i;
+@@ -516,12 +515,6 @@ int ext4_ext_migrate(struct inode *inode, struct file *filp,
+ * when we add extents we extent the journal
+ */
+ /*
+- * inode_mutex prevent write and truncate on the file. Read still goes
+- * through. We take i_data_sem in ext4_ext_swap_inode_data before we
+- * switch the inode format to prevent read.
+- */
+- mutex_lock(&(inode->i_mutex));
+- /*
+ * Even though we take i_mutex we can still cause block allocation
+ * via mmap write to holes. If we have allocated new blocks we fail
+ * migrate. New block allocation will clear EXT4_EXT_MIGRATE flag.
+@@ -623,7 +616,6 @@ err_out:
+ tmp_inode->i_nlink = 0;
+
+ ext4_journal_stop(handle);
+- mutex_unlock(&(inode->i_mutex));
+
+ if (tmp_inode)
+ iput(tmp_inode);
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index b3d3560..3922a8b 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -929,6 +929,15 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
+ percpu_counter_add(&sbi->s_freeinodes_counter,
+ EXT4_INODES_PER_GROUP(sb));
+
++ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
++ ext4_group_t flex_group;
++ flex_group = ext4_flex_group(sbi, input->group);
++ sbi->s_flex_groups[flex_group].free_blocks +=
++ input->free_blocks_count;
++ sbi->s_flex_groups[flex_group].free_inodes +=
++ EXT4_INODES_PER_GROUP(sb);
++ }
++
+ ext4_journal_dirty_metadata(handle, sbi->s_sbh);
+ sb->s_dirt = 1;
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 566344b..7726e8e 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1504,8 +1504,10 @@ static int ext4_fill_flex_info(struct super_block *sb)
+ sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
+ groups_per_flex = 1 << sbi->s_log_groups_per_flex;
+
+- flex_group_count = (sbi->s_groups_count + groups_per_flex - 1) /
+- groups_per_flex;
++ /* We allocate both existing and potentially added groups */
++ flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
++ ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
++ EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex;
+ sbi->s_flex_groups = kzalloc(flex_group_count *
+ sizeof(struct flex_groups), GFP_KERNEL);
+ if (sbi->s_flex_groups == NULL) {
+@@ -1623,8 +1625,10 @@ static int ext4_check_descriptors(struct super_block *sb)
+ "Checksum for group %lu failed (%u!=%u)\n",
+ i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
+ gdp)), le16_to_cpu(gdp->bg_checksum));
+- if (!(sb->s_flags & MS_RDONLY))
++ if (!(sb->s_flags & MS_RDONLY)) {
++ spin_unlock(sb_bgl_lock(sbi, i));
+ return 0;
++ }
+ }
+ spin_unlock(sb_bgl_lock(sbi, i));
+ if (!flexbg_flag)
+@@ -2444,6 +2448,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ "available.\n");
+ }
+
++ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
++ printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - "
++ "requested data journaling mode\n");
++ clear_opt(sbi->s_mount_opt, DELALLOC);
++ } else if (test_opt(sb, DELALLOC))
++ printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n");
++
++ ext4_ext_init(sb);
++ err = ext4_mb_init(sb, needs_recovery);
++ if (err) {
++ printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n",
++ err);
++ goto failed_mount4;
++ }
++
+ /*
+ * akpm: core read_super() calls in here with the superblock locked.
+ * That deadlocks, because orphan cleanup needs to lock the superblock
+@@ -2463,16 +2482,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered":
+ "writeback");
+
+- if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
+- printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - "
+- "requested data journaling mode\n");
+- clear_opt(sbi->s_mount_opt, DELALLOC);
+- } else if (test_opt(sb, DELALLOC))
+- printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n");
+-
+- ext4_ext_init(sb);
+- ext4_mb_init(sb, needs_recovery);
+-
+ lock_kernel();
+ return 0;
+
+@@ -2799,13 +2808,34 @@ static void ext4_commit_super(struct super_block *sb,
+
+ if (!sbh)
+ return;
++ if (buffer_write_io_error(sbh)) {
++ /*
++ * Oh, dear. A previous attempt to write the
++ * superblock failed. This could happen because the
++ * USB device was yanked out. Or it could happen to
++ * be a transient write error and maybe the block will
++ * be remapped. Nothing we can do but to retry the
++ * write and hope for the best.
++ */
++ printk(KERN_ERR "ext4: previous I/O error to "
++ "superblock detected for %s.\n", sb->s_id);
++ clear_buffer_write_io_error(sbh);
++ set_buffer_uptodate(sbh);
++ }
+ es->s_wtime = cpu_to_le32(get_seconds());
+ ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb));
+ es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb));
+ BUFFER_TRACE(sbh, "marking dirty");
+ mark_buffer_dirty(sbh);
+- if (sync)
++ if (sync) {
+ sync_dirty_buffer(sbh);
++ if (buffer_write_io_error(sbh)) {
++ printk(KERN_ERR "ext4: I/O error while writing "
++ "superblock for %s.\n", sb->s_id);
++ clear_buffer_write_io_error(sbh);
++ set_buffer_uptodate(sbh);
++ }
++ }
+ }
+
+
+@@ -2890,12 +2920,9 @@ int ext4_force_commit(struct super_block *sb)
+ /*
+ * Ext4 always journals updates to the superblock itself, so we don't
+ * have to propagate any other updates to the superblock on disk at this
+- * point. Just start an async writeback to get the buffers on their way
+- * to the disk.
+- *
+- * This implicitly triggers the writebehind on sync().
++ * point. (We can probably nuke this function altogether, and remove
++ * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...)
+ */
+-
+ static void ext4_write_super(struct super_block *sb)
+ {
+ if (mutex_trylock(&sb->s_lock) != 0)
+@@ -2905,14 +2932,14 @@ static void ext4_write_super(struct super_block *sb)
+
+ static int ext4_sync_fs(struct super_block *sb, int wait)
+ {
+- tid_t target;
++ int ret = 0;
+
+ sb->s_dirt = 0;
+- if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) {
+- if (wait)
+- jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target);
+- }
+- return 0;
++ if (wait)
++ ret = ext4_force_commit(sb);
++ else
++ jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL);
++ return ret;
+ }
+
+ /*
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 8954208..362b0ed 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -959,6 +959,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ struct ext4_xattr_block_find bs = {
+ .s = { .not_found = -ENODATA, },
+ };
++ unsigned long no_expand;
+ int error;
+
+ if (!name)
+@@ -966,6 +967,9 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ if (strlen(name) > 255)
+ return -ERANGE;
+ down_write(&EXT4_I(inode)->xattr_sem);
++ no_expand = EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND;
++ EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
++
+ error = ext4_get_inode_loc(inode, &is.iloc);
+ if (error)
+ goto cleanup;
+@@ -1042,6 +1046,8 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
++ if (no_expand == 0)
++ EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND;
+ up_write(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
+diff --git a/fs/inotify.c b/fs/inotify.c
+index 690e725..7bbed1b 100644
+--- a/fs/inotify.c
++++ b/fs/inotify.c
+@@ -106,6 +106,20 @@ void get_inotify_watch(struct inotify_watch *watch)
+ }
+ EXPORT_SYMBOL_GPL(get_inotify_watch);
+
++int pin_inotify_watch(struct inotify_watch *watch)
++{
++ struct super_block *sb = watch->inode->i_sb;
++ spin_lock(&sb_lock);
++ if (sb->s_count >= S_BIAS) {
++ atomic_inc(&sb->s_active);
++ spin_unlock(&sb_lock);
++ atomic_inc(&watch->count);
++ return 1;
++ }
++ spin_unlock(&sb_lock);
++ return 0;
++}
++
+ /**
+ * put_inotify_watch - decrements the ref count on a given watch. cleans up
+ * watch references if the count reaches zero. inotify_watch is freed by
+@@ -124,6 +138,13 @@ void put_inotify_watch(struct inotify_watch *watch)
+ }
+ EXPORT_SYMBOL_GPL(put_inotify_watch);
+
++void unpin_inotify_watch(struct inotify_watch *watch)
++{
++ struct super_block *sb = watch->inode->i_sb;
++ put_inotify_watch(watch);
++ deactivate_super(sb);
++}
++
+ /*
+ * inotify_handle_get_wd - returns the next WD for use by the given handle
+ *
+@@ -479,6 +500,112 @@ void inotify_init_watch(struct inotify_watch *watch)
+ }
+ EXPORT_SYMBOL_GPL(inotify_init_watch);
+
++/*
++ * Watch removals suck violently. To kick the watch out we need (in this
++ * order) inode->inotify_mutex and ih->mutex. That's fine if we have
++ * a hold on inode; however, for all other cases we need to make damn sure
++ * we don't race with umount. We can *NOT* just grab a reference to a
++ * watch - inotify_unmount_inodes() will happily sail past it and we'll end
++ * with reference to inode potentially outliving its superblock. Ideally
++ * we just want to grab an active reference to superblock if we can; that
++ * will make sure we won't go into inotify_umount_inodes() until we are
++ * done. Cleanup is just deactivate_super(). However, that leaves a messy
++ * case - what if we *are* racing with umount() and active references to
++ * superblock can't be acquired anymore? We can bump ->s_count, grab
++ * ->s_umount, which will almost certainly wait until the superblock is shut
++ * down and the watch in question is pining for fjords. That's fine, but
++ * there is a problem - we might have hit the window between ->s_active
++ * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock
++ * is past the point of no return and is heading for shutdown) and the
++ * moment when deactivate_super() acquires ->s_umount. We could just do
++ * drop_super() yield() and retry, but that's rather antisocial and this
++ * stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having
++ * found that we'd got there first (i.e. that ->s_root is non-NULL) we know
++ * that we won't race with inotify_umount_inodes(). So we could grab a
++ * reference to watch and do the rest as above, just with drop_super() instead
++ * of deactivate_super(), right? Wrong. We had to drop ih->mutex before we
++ * could grab ->s_umount. So the watch could've been gone already.
++ *
++ * That still can be dealt with - we need to save watch->wd, do idr_find()
++ * and compare its result with our pointer. If they match, we either have
++ * the damn thing still alive or we'd lost not one but two races at once,
++ * the watch had been killed and a new one got created with the same ->wd
++ * at the same address. That couldn't have happened in inotify_destroy(),
++ * but inotify_rm_wd() could run into that. Still, "new one got created"
++ * is not a problem - we have every right to kill it or leave it alone,
++ * whatever's more convenient.
++ *
++ * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as
++ * "grab it and kill it" check. If it's been our original watch, we are
++ * fine, if it's a newcomer - nevermind, just pretend that we'd won the
++ * race and kill the fscker anyway; we are safe since we know that its
++ * superblock won't be going away.
++ *
++ * And yes, this is far beyond mere "not very pretty"; so's the entire
++ * concept of inotify to start with.
++ */
++
++/**
++ * pin_to_kill - pin the watch down for removal
++ * @ih: inotify handle
++ * @watch: watch to kill
++ *
++ * Called with ih->mutex held, drops it. Possible return values:
++ * 0 - nothing to do, it has died
++ * 1 - remove it, drop the reference and deactivate_super()
++ * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid
++ * that variant, since it involved a lot of PITA, but that's the best that
++ * could've been done.
++ */
++static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch)
++{
++ struct super_block *sb = watch->inode->i_sb;
++ s32 wd = watch->wd;
++
++ spin_lock(&sb_lock);
++ if (sb->s_count >= S_BIAS) {
++ atomic_inc(&sb->s_active);
++ spin_unlock(&sb_lock);
++ get_inotify_watch(watch);
++ mutex_unlock(&ih->mutex);
++ return 1; /* the best outcome */
++ }
++ sb->s_count++;
++ spin_unlock(&sb_lock);
++ mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */
++ down_read(&sb->s_umount);
++ if (likely(!sb->s_root)) {
++ /* fs is already shut down; the watch is dead */
++ drop_super(sb);
++ return 0;
++ }
++ /* raced with the final deactivate_super() */
++ mutex_lock(&ih->mutex);
++ if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) {
++ /* the watch is dead */
++ mutex_unlock(&ih->mutex);
++ drop_super(sb);
++ return 0;
++ }
++ /* still alive or freed and reused with the same sb and wd; kill */
++ get_inotify_watch(watch);
++ mutex_unlock(&ih->mutex);
++ return 2;
++}
++
++static void unpin_and_kill(struct inotify_watch *watch, int how)
++{
++ struct super_block *sb = watch->inode->i_sb;
++ put_inotify_watch(watch);
++ switch (how) {
++ case 1:
++ deactivate_super(sb);
++ break;
++ case 2:
++ drop_super(sb);
++ }
++}
++
+ /**
+ * inotify_destroy - clean up and destroy an inotify instance
+ * @ih: inotify handle
+@@ -490,11 +617,15 @@ void inotify_destroy(struct inotify_handle *ih)
+ * pretty. We cannot do a simple iteration over the list, because we
+ * do not know the inode until we iterate to the watch. But we need to
+ * hold inode->inotify_mutex before ih->mutex. The following works.
++ *
++ * AV: it had to become even uglier to start working ;-/
+ */
+ while (1) {
+ struct inotify_watch *watch;
+ struct list_head *watches;
++ struct super_block *sb;
+ struct inode *inode;
++ int how;
+
+ mutex_lock(&ih->mutex);
+ watches = &ih->watches;
+@@ -503,8 +634,10 @@ void inotify_destroy(struct inotify_handle *ih)
+ break;
+ }
+ watch = list_first_entry(watches, struct inotify_watch, h_list);
+- get_inotify_watch(watch);
+- mutex_unlock(&ih->mutex);
++ sb = watch->inode->i_sb;
++ how = pin_to_kill(ih, watch);
++ if (!how)
++ continue;
+
+ inode = watch->inode;
+ mutex_lock(&inode->inotify_mutex);
+@@ -518,7 +651,7 @@ void inotify_destroy(struct inotify_handle *ih)
+
+ mutex_unlock(&ih->mutex);
+ mutex_unlock(&inode->inotify_mutex);
+- put_inotify_watch(watch);
++ unpin_and_kill(watch, how);
+ }
+
+ /* free this handle: the put matching the get in inotify_init() */
+@@ -719,7 +852,9 @@ void inotify_evict_watch(struct inotify_watch *watch)
+ int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
+ {
+ struct inotify_watch *watch;
++ struct super_block *sb;
+ struct inode *inode;
++ int how;
+
+ mutex_lock(&ih->mutex);
+ watch = idr_find(&ih->idr, wd);
+@@ -727,9 +862,12 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
+ mutex_unlock(&ih->mutex);
+ return -EINVAL;
+ }
+- get_inotify_watch(watch);
++ sb = watch->inode->i_sb;
++ how = pin_to_kill(ih, watch);
++ if (!how)
++ return 0;
++
+ inode = watch->inode;
+- mutex_unlock(&ih->mutex);
+
+ mutex_lock(&inode->inotify_mutex);
+ mutex_lock(&ih->mutex);
+@@ -740,7 +878,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
+
+ mutex_unlock(&ih->mutex);
+ mutex_unlock(&inode->inotify_mutex);
+- put_inotify_watch(watch);
++ unpin_and_kill(watch, how);
+
+ return 0;
+ }
+diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
+index 0540ca2..d15cd6e 100644
+--- a/fs/jbd/transaction.c
++++ b/fs/jbd/transaction.c
+@@ -954,9 +954,10 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
+ journal_t *journal = handle->h_transaction->t_journal;
+ int need_brelse = 0;
+ struct journal_head *jh;
++ int ret = 0;
+
+ if (is_handle_aborted(handle))
+- return 0;
++ return ret;
+
+ jh = journal_add_journal_head(bh);
+ JBUFFER_TRACE(jh, "entry");
+@@ -1067,7 +1068,16 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
+ time if it is redirtied */
+ }
+
+- /* journal_clean_data_list() may have got there first */
++ /*
++ * We cannot remove the buffer with io error from the
++ * committing transaction, because otherwise it would
++ * miss the error and the commit would not abort.
++ */
++ if (unlikely(!buffer_uptodate(bh))) {
++ ret = -EIO;
++ goto no_journal;
++ }
++
+ if (jh->b_transaction != NULL) {
+ JBUFFER_TRACE(jh, "unfile from commit");
+ __journal_temp_unlink_buffer(jh);
+@@ -1108,7 +1118,7 @@ no_journal:
+ }
+ JBUFFER_TRACE(jh, "exit");
+ journal_put_journal_head(jh);
+- return 0;
++ return ret;
+ }
+
+ /**
+diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
+index 91389c8..77255a3 100644
+--- a/fs/jbd2/checkpoint.c
++++ b/fs/jbd2/checkpoint.c
+@@ -114,7 +114,7 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
+ */
+ void __jbd2_log_wait_for_space(journal_t *journal)
+ {
+- int nblocks;
++ int nblocks, space_left;
+ assert_spin_locked(&journal->j_state_lock);
+
+ nblocks = jbd_space_needed(journal);
+@@ -126,14 +126,47 @@ void __jbd2_log_wait_for_space(journal_t *journal)
+
+ /*
+ * Test again, another process may have checkpointed while we
+- * were waiting for the checkpoint lock
++ * were waiting for the checkpoint lock. If there are no
++ * transactions ready to be checkpointed, try to recover
++ * journal space by calling cleanup_journal_tail(), and if
++ * that doesn't work, by waiting for the currently committing
++ * transaction to complete. If there is absolutely no way
++ * to make progress, this is either a BUG or corrupted
++ * filesystem, so abort the journal and leave a stack
++ * trace for forensic evidence.
+ */
+ spin_lock(&journal->j_state_lock);
++ spin_lock(&journal->j_list_lock);
+ nblocks = jbd_space_needed(journal);
+- if (__jbd2_log_space_left(journal) < nblocks) {
++ space_left = __jbd2_log_space_left(journal);
++ if (space_left < nblocks) {
++ int chkpt = journal->j_checkpoint_transactions != NULL;
++ tid_t tid = 0;
++
++ if (journal->j_committing_transaction)
++ tid = journal->j_committing_transaction->t_tid;
++ spin_unlock(&journal->j_list_lock);
+ spin_unlock(&journal->j_state_lock);
+- jbd2_log_do_checkpoint(journal);
++ if (chkpt) {
++ jbd2_log_do_checkpoint(journal);
++ } else if (jbd2_cleanup_journal_tail(journal) == 0) {
++ /* We were able to recover space; yay! */
++ ;
++ } else if (tid) {
++ jbd2_log_wait_commit(journal, tid);
++ } else {
++ printk(KERN_ERR "%s: needed %d blocks and "
++ "only had %d space available\n",
++ __func__, nblocks, space_left);
++ printk(KERN_ERR "%s: no way to get more "
++ "journal space in %s\n", __func__,
++ journal->j_devname);
++ WARN_ON(1);
++ jbd2_journal_abort(journal, 0);
++ }
+ spin_lock(&journal->j_state_lock);
++ } else {
++ spin_unlock(&journal->j_list_lock);
+ }
+ mutex_unlock(&journal->j_checkpoint_mutex);
+ }
+diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
+index f2ad061..6caf22d 100644
+--- a/fs/jbd2/commit.c
++++ b/fs/jbd2/commit.c
+@@ -126,8 +126,7 @@ static int journal_submit_commit_record(journal_t *journal,
+
+ JBUFFER_TRACE(descriptor, "submit commit block");
+ lock_buffer(bh);
+- get_bh(bh);
+- set_buffer_dirty(bh);
++ clear_buffer_dirty(bh);
+ set_buffer_uptodate(bh);
+ bh->b_end_io = journal_end_buffer_io_sync;
+
+@@ -160,7 +159,7 @@ static int journal_submit_commit_record(journal_t *journal,
+ /* And try again, without the barrier */
+ lock_buffer(bh);
+ set_buffer_uptodate(bh);
+- set_buffer_dirty(bh);
++ clear_buffer_dirty(bh);
+ ret = submit_bh(WRITE, bh);
+ }
+ *cbh = bh;
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index 8207a01..52d2bee 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -901,10 +901,7 @@ static struct proc_dir_entry *proc_jbd2_stats;
+
+ static void jbd2_stats_proc_init(journal_t *journal)
+ {
+- char name[BDEVNAME_SIZE];
+-
+- bdevname(journal->j_dev, name);
+- journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats);
++ journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats);
+ if (journal->j_proc_entry) {
+ proc_create_data("history", S_IRUGO, journal->j_proc_entry,
+ &jbd2_seq_history_fops, journal);
+@@ -915,12 +912,9 @@ static void jbd2_stats_proc_init(journal_t *journal)
+
+ static void jbd2_stats_proc_exit(journal_t *journal)
+ {
+- char name[BDEVNAME_SIZE];
+-
+- bdevname(journal->j_dev, name);
+ remove_proc_entry("info", journal->j_proc_entry);
+ remove_proc_entry("history", journal->j_proc_entry);
+- remove_proc_entry(name, proc_jbd2_stats);
++ remove_proc_entry(journal->j_devname, proc_jbd2_stats);
+ }
+
+ static void journal_init_stats(journal_t *journal)
+@@ -1018,6 +1012,7 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
+ {
+ journal_t *journal = journal_init_common();
+ struct buffer_head *bh;
++ char *p;
+ int n;
+
+ if (!journal)
+@@ -1039,6 +1034,10 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
+ journal->j_fs_dev = fs_dev;
+ journal->j_blk_offset = start;
+ journal->j_maxlen = len;
++ bdevname(journal->j_dev, journal->j_devname);
++ p = journal->j_devname;
++ while ((p = strchr(p, '/')))
++ *p = '!';
+ jbd2_stats_proc_init(journal);
+
+ bh = __getblk(journal->j_dev, start, journal->j_blocksize);
+@@ -1061,6 +1060,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode)
+ {
+ struct buffer_head *bh;
+ journal_t *journal = journal_init_common();
++ char *p;
+ int err;
+ int n;
+ unsigned long long blocknr;
+@@ -1070,6 +1070,12 @@ journal_t * jbd2_journal_init_inode (struct inode *inode)
+
+ journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev;
+ journal->j_inode = inode;
++ bdevname(journal->j_dev, journal->j_devname);
++ p = journal->j_devname;
++ while ((p = strchr(p, '/')))
++ *p = '!';
++ p = journal->j_devname + strlen(journal->j_devname);
++ sprintf(p, ":%lu", journal->j_inode->i_ino);
+ jbd_debug(1,
+ "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n",
+ journal, inode->i_sb->s_id, inode->i_ino,
+@@ -1253,6 +1259,22 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait)
+ goto out;
+ }
+
++ if (buffer_write_io_error(bh)) {
++ /*
++ * Oh, dear. A previous attempt to write the journal
++ * superblock failed. This could happen because the
++ * USB device was yanked out. Or it could happen to
++ * be a transient write error and maybe the block will
++ * be remapped. Nothing we can do but to retry the
++ * write and hope for the best.
++ */
++ printk(KERN_ERR "JBD2: previous I/O error detected "
++ "for journal superblock update for %s.\n",
++ journal->j_devname);
++ clear_buffer_write_io_error(bh);
++ set_buffer_uptodate(bh);
++ }
++
+ spin_lock(&journal->j_state_lock);
+ jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n",
+ journal->j_tail, journal->j_tail_sequence, journal->j_errno);
+@@ -1264,9 +1286,16 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait)
+
+ BUFFER_TRACE(bh, "marking dirty");
+ mark_buffer_dirty(bh);
+- if (wait)
++ if (wait) {
+ sync_dirty_buffer(bh);
+- else
++ if (buffer_write_io_error(bh)) {
++ printk(KERN_ERR "JBD2: I/O error detected "
++ "when updating journal superblock for %s.\n",
++ journal->j_devname);
++ clear_buffer_write_io_error(bh);
++ set_buffer_uptodate(bh);
++ }
++ } else
+ ll_rw_block(SWRITE, 1, &bh);
+
+ out:
+diff --git a/include/asm-x86/mmzone_32.h b/include/asm-x86/mmzone_32.h
+index 5862e64..eb77583 100644
+--- a/include/asm-x86/mmzone_32.h
++++ b/include/asm-x86/mmzone_32.h
+@@ -34,10 +34,14 @@ static inline void get_memcfg_numa(void)
+
+ extern int early_pfn_to_nid(unsigned long pfn);
+
++extern void resume_map_numa_kva(pgd_t *pgd);
++
+ #else /* !CONFIG_NUMA */
+
+ #define get_memcfg_numa get_memcfg_numa_flat
+
++static inline void resume_map_numa_kva(pgd_t *pgd) {}
++
+ #endif /* CONFIG_NUMA */
+
+ #ifdef CONFIG_DISCONTIGMEM
+diff --git a/include/asm-x86/pci_64.h b/include/asm-x86/pci_64.h
+index f330234..50d3df5 100644
+--- a/include/asm-x86/pci_64.h
++++ b/include/asm-x86/pci_64.h
+@@ -34,8 +34,6 @@ extern void pci_iommu_alloc(void);
+ */
+ #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
+
+-#if defined(CONFIG_GART_IOMMU) || defined(CONFIG_CALGARY_IOMMU)
+-
+ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
+ dma_addr_t ADDR_NAME;
+ #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
+@@ -49,18 +47,6 @@ extern void pci_iommu_alloc(void);
+ #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+ (((PTR)->LEN_NAME) = (VAL))
+
+-#else
+-/* No IOMMU */
+-
+-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
+-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
+-#define pci_unmap_len(PTR, LEN_NAME) (0)
+-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
+-
+-#endif
+-
+ #endif /* __KERNEL__ */
+
+ #endif /* __x8664_PCI_H */
+diff --git a/include/linux/idr.h b/include/linux/idr.h
+index fa035f9..dd846df 100644
+--- a/include/linux/idr.h
++++ b/include/linux/idr.h
+@@ -52,13 +52,14 @@ struct idr_layer {
+ unsigned long bitmap; /* A zero bit means "space here" */
+ struct idr_layer *ary[1<<IDR_BITS];
+ int count; /* When zero, we can release it */
++ int layer; /* distance from leaf */
+ struct rcu_head rcu_head;
+ };
+
+ struct idr {
+ struct idr_layer *top;
+ struct idr_layer *id_free;
+- int layers;
++ int layers; /* only valid without concurrent changes */
+ int id_free_cnt;
+ spinlock_t lock;
+ };
+diff --git a/include/linux/inotify.h b/include/linux/inotify.h
+index bd57857..37ea289 100644
+--- a/include/linux/inotify.h
++++ b/include/linux/inotify.h
+@@ -134,6 +134,8 @@ extern void inotify_remove_watch_locked(struct inotify_handle *,
+ struct inotify_watch *);
+ extern void get_inotify_watch(struct inotify_watch *);
+ extern void put_inotify_watch(struct inotify_watch *);
++extern int pin_inotify_watch(struct inotify_watch *);
++extern void unpin_inotify_watch(struct inotify_watch *);
+
+ #else
+
+@@ -228,6 +230,15 @@ static inline void put_inotify_watch(struct inotify_watch *watch)
+ {
+ }
+
++extern inline int pin_inotify_watch(struct inotify_watch *watch)
++{
++ return 0;
++}
++
++extern inline void unpin_inotify_watch(struct inotify_watch *watch)
++{
++}
++
+ #endif /* CONFIG_INOTIFY */
+
+ #endif /* __KERNEL __ */
+diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
+index 3dd2090..66c3499 100644
+--- a/include/linux/jbd2.h
++++ b/include/linux/jbd2.h
+@@ -850,7 +850,8 @@ struct journal_s
+ */
+ struct block_device *j_dev;
+ int j_blocksize;
+- unsigned long long j_blk_offset;
++ unsigned long long j_blk_offset;
++ char j_devname[BDEVNAME_SIZE+24];
+
+ /*
+ * Device which holds the client fs. For internal journal this will be
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index 225bfc5..25062ac 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -364,6 +364,7 @@ enum {
+ ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */
+ ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */
+ ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */
++ ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firwmare update warning */
+
+ /* DMA mask for user DMA control: User visible values; DO NOT
+ renumber */
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 98dc624..426e029 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -64,6 +64,11 @@ struct pci_slot {
+ struct kobject kobj;
+ };
+
++static inline const char *pci_slot_name(const struct pci_slot *slot)
++{
++ return kobject_name(&slot->kobj);
++}
++
+ /* File state for mmap()s on /proc/bus/pci/X/Y */
+ enum pci_mmap_state {
+ pci_mmap_io,
+@@ -509,7 +514,8 @@ struct pci_bus *pci_create_bus(struct device *parent, int bus,
+ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
+ int busnr);
+ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
+- const char *name);
++ const char *name,
++ struct hotplug_slot *hotplug);
+ void pci_destroy_slot(struct pci_slot *slot);
+ void pci_update_slot_number(struct pci_slot *slot, int slot_nr);
+ int pci_scan_slot(struct pci_bus *bus, int devfn);
+diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
+index a08cd06..a00bd1a 100644
+--- a/include/linux/pci_hotplug.h
++++ b/include/linux/pci_hotplug.h
+@@ -142,8 +142,6 @@ struct hotplug_slot_info {
+
+ /**
+ * struct hotplug_slot - used to register a physical slot with the hotplug pci core
+- * @name: the name of the slot being registered. This string must
+- * be unique amoung slots registered on this system.
+ * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
+ * @info: pointer to the &struct hotplug_slot_info for the initial values for
+ * this slot.
+@@ -153,7 +151,6 @@ struct hotplug_slot_info {
+ * needs.
+ */
+ struct hotplug_slot {
+- char *name;
+ struct hotplug_slot_ops *ops;
+ struct hotplug_slot_info *info;
+ void (*release) (struct hotplug_slot *slot);
+@@ -165,7 +162,13 @@ struct hotplug_slot {
+ };
+ #define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)
+
+-extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr);
++static inline const char *hotplug_slot_name(const struct hotplug_slot *slot)
++{
++ return pci_slot_name(slot->pci_slot);
++}
++
++extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr,
++ const char *name);
+ extern int pci_hp_deregister(struct hotplug_slot *slot);
+ extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot,
+ struct hotplug_slot_info *info);
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 6bfb849..086f5e1 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -587,6 +587,10 @@ struct user_struct {
+ atomic_t inotify_watches; /* How many inotify watches does this user have? */
+ atomic_t inotify_devs; /* How many inotify devs does this user have opened? */
+ #endif
++#ifdef CONFIG_EPOLL
++ atomic_t epoll_devs; /* The number of epoll descriptors currently open */
++ atomic_t epoll_watches; /* The number of file descriptors currently watched */
++#endif
+ #ifdef CONFIG_POSIX_MQUEUE
+ /* protected by mq_lock */
+ unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index c29ff1d..1614d78 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -9,6 +9,7 @@
+ extern void unix_inflight(struct file *fp);
+ extern void unix_notinflight(struct file *fp);
+ extern void unix_gc(void);
++extern void wait_for_unix_gc(void);
+
+ #define UNIX_HASH_SIZE 256
+
+diff --git a/ipc/util.c b/ipc/util.c
+index 49b3ea6..361fd1c 100644
+--- a/ipc/util.c
++++ b/ipc/util.c
+@@ -266,9 +266,17 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
+ if (ids->in_use >= size)
+ return -ENOSPC;
+
++ spin_lock_init(&new->lock);
++ new->deleted = 0;
++ rcu_read_lock();
++ spin_lock(&new->lock);
++
+ err = idr_get_new(&ids->ipcs_idr, new, &id);
+- if (err)
++ if (err) {
++ spin_unlock(&new->lock);
++ rcu_read_unlock();
+ return err;
++ }
+
+ ids->in_use++;
+
+@@ -280,10 +288,6 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
+ ids->seq = 0;
+
+ new->id = ipc_buildid(id, new->seq);
+- spin_lock_init(&new->lock);
+- new->deleted = 0;
+- rcu_read_lock();
+- spin_lock(&new->lock);
+ return id;
+ }
+
+diff --git a/kernel/Makefile b/kernel/Makefile
+index 4e1d7df..143e8b6 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -11,8 +11,6 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
+ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
+ notifier.o ksysfs.o pm_qos_params.o sched_clock.o
+
+-CFLAGS_REMOVE_sched.o = -mno-spe
+-
+ ifdef CONFIG_FTRACE
+ # Do not trace debug files and internal ftrace files
+ CFLAGS_REMOVE_lockdep.o = -pg
+@@ -21,7 +19,7 @@ CFLAGS_REMOVE_mutex-debug.o = -pg
+ CFLAGS_REMOVE_rtmutex-debug.o = -pg
+ CFLAGS_REMOVE_cgroup-debug.o = -pg
+ CFLAGS_REMOVE_sched_clock.o = -pg
+-CFLAGS_REMOVE_sched.o = -mno-spe -pg
++CFLAGS_REMOVE_sched.o = -pg
+ endif
+
+ obj-$(CONFIG_PROFILING) += profile.o
+diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
+index f7921a2..894b599 100644
+--- a/kernel/audit_tree.c
++++ b/kernel/audit_tree.c
+@@ -24,6 +24,7 @@ struct audit_chunk {
+ struct list_head trees; /* with root here */
+ int dead;
+ int count;
++ atomic_long_t refs;
+ struct rcu_head head;
+ struct node {
+ struct list_head list;
+@@ -56,7 +57,8 @@ static LIST_HEAD(prune_list);
+ * tree is refcounted; one reference for "some rules on rules_list refer to
+ * it", one for each chunk with pointer to it.
+ *
+- * chunk is refcounted by embedded inotify_watch.
++ * chunk is refcounted by embedded inotify_watch + .refs (non-zero refcount
++ * of watch contributes 1 to .refs).
+ *
+ * node.index allows to get from node.list to containing chunk.
+ * MSB of that sucker is stolen to mark taggings that we might have to
+@@ -121,6 +123,7 @@ static struct audit_chunk *alloc_chunk(int count)
+ INIT_LIST_HEAD(&chunk->hash);
+ INIT_LIST_HEAD(&chunk->trees);
+ chunk->count = count;
++ atomic_long_set(&chunk->refs, 1);
+ for (i = 0; i < count; i++) {
+ INIT_LIST_HEAD(&chunk->owners[i].list);
+ chunk->owners[i].index = i;
+@@ -129,9 +132,8 @@ static struct audit_chunk *alloc_chunk(int count)
+ return chunk;
+ }
+
+-static void __free_chunk(struct rcu_head *rcu)
++static void free_chunk(struct audit_chunk *chunk)
+ {
+- struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
+ int i;
+
+ for (i = 0; i < chunk->count; i++) {
+@@ -141,14 +143,16 @@ static void __free_chunk(struct rcu_head *rcu)
+ kfree(chunk);
+ }
+
+-static inline void free_chunk(struct audit_chunk *chunk)
++void audit_put_chunk(struct audit_chunk *chunk)
+ {
+- call_rcu(&chunk->head, __free_chunk);
++ if (atomic_long_dec_and_test(&chunk->refs))
++ free_chunk(chunk);
+ }
+
+-void audit_put_chunk(struct audit_chunk *chunk)
++static void __put_chunk(struct rcu_head *rcu)
+ {
+- put_inotify_watch(&chunk->watch);
++ struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
++ audit_put_chunk(chunk);
+ }
+
+ enum {HASH_SIZE = 128};
+@@ -176,7 +180,7 @@ struct audit_chunk *audit_tree_lookup(const struct inode *inode)
+
+ list_for_each_entry_rcu(p, list, hash) {
+ if (p->watch.inode == inode) {
+- get_inotify_watch(&p->watch);
++ atomic_long_inc(&p->refs);
+ return p;
+ }
+ }
+@@ -194,17 +198,49 @@ int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
+
+ /* tagging and untagging inodes with trees */
+
+-static void untag_chunk(struct audit_chunk *chunk, struct node *p)
++static struct audit_chunk *find_chunk(struct node *p)
++{
++ int index = p->index & ~(1U<<31);
++ p -= index;
++ return container_of(p, struct audit_chunk, owners[0]);
++}
++
++static void untag_chunk(struct node *p)
+ {
++ struct audit_chunk *chunk = find_chunk(p);
+ struct audit_chunk *new;
+ struct audit_tree *owner;
+ int size = chunk->count - 1;
+ int i, j;
+
++ if (!pin_inotify_watch(&chunk->watch)) {
++ /*
++ * Filesystem is shutting down; all watches are getting
++ * evicted, just take it off the node list for this
++ * tree and let the eviction logics take care of the
++ * rest.
++ */
++ owner = p->owner;
++ if (owner->root == chunk) {
++ list_del_init(&owner->same_root);
++ owner->root = NULL;
++ }
++ list_del_init(&p->list);
++ p->owner = NULL;
++ put_tree(owner);
++ return;
++ }
++
++ spin_unlock(&hash_lock);
++
++ /*
++ * pin_inotify_watch() succeeded, so the watch won't go away
++ * from under us.
++ */
+ mutex_lock(&chunk->watch.inode->inotify_mutex);
+ if (chunk->dead) {
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
+- return;
++ goto out;
+ }
+
+ owner = p->owner;
+@@ -221,7 +257,7 @@ static void untag_chunk(struct audit_chunk *chunk, struct node *p)
+ inotify_evict_watch(&chunk->watch);
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
+ put_inotify_watch(&chunk->watch);
+- return;
++ goto out;
+ }
+
+ new = alloc_chunk(size);
+@@ -263,7 +299,7 @@ static void untag_chunk(struct audit_chunk *chunk, struct node *p)
+ inotify_evict_watch(&chunk->watch);
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
+ put_inotify_watch(&chunk->watch);
+- return;
++ goto out;
+
+ Fallback:
+ // do the best we can
+@@ -277,6 +313,9 @@ Fallback:
+ put_tree(owner);
+ spin_unlock(&hash_lock);
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
++out:
++ unpin_inotify_watch(&chunk->watch);
++ spin_lock(&hash_lock);
+ }
+
+ static int create_chunk(struct inode *inode, struct audit_tree *tree)
+@@ -387,13 +426,6 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+ return 0;
+ }
+
+-static struct audit_chunk *find_chunk(struct node *p)
+-{
+- int index = p->index & ~(1U<<31);
+- p -= index;
+- return container_of(p, struct audit_chunk, owners[0]);
+-}
+-
+ static void kill_rules(struct audit_tree *tree)
+ {
+ struct audit_krule *rule, *next;
+@@ -431,17 +463,10 @@ static void prune_one(struct audit_tree *victim)
+ spin_lock(&hash_lock);
+ while (!list_empty(&victim->chunks)) {
+ struct node *p;
+- struct audit_chunk *chunk;
+
+ p = list_entry(victim->chunks.next, struct node, list);
+- chunk = find_chunk(p);
+- get_inotify_watch(&chunk->watch);
+- spin_unlock(&hash_lock);
+-
+- untag_chunk(chunk, p);
+
+- put_inotify_watch(&chunk->watch);
+- spin_lock(&hash_lock);
++ untag_chunk(p);
+ }
+ spin_unlock(&hash_lock);
+ put_tree(victim);
+@@ -469,7 +494,6 @@ static void trim_marked(struct audit_tree *tree)
+
+ while (!list_empty(&tree->chunks)) {
+ struct node *node;
+- struct audit_chunk *chunk;
+
+ node = list_entry(tree->chunks.next, struct node, list);
+
+@@ -477,14 +501,7 @@ static void trim_marked(struct audit_tree *tree)
+ if (!(node->index & (1U<<31)))
+ break;
+
+- chunk = find_chunk(node);
+- get_inotify_watch(&chunk->watch);
+- spin_unlock(&hash_lock);
+-
+- untag_chunk(chunk, node);
+-
+- put_inotify_watch(&chunk->watch);
+- spin_lock(&hash_lock);
++ untag_chunk(node);
+ }
+ if (!tree->root && !tree->goner) {
+ tree->goner = 1;
+@@ -878,7 +895,7 @@ static void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
+ static void destroy_watch(struct inotify_watch *watch)
+ {
+ struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
+- free_chunk(chunk);
++ call_rcu(&chunk->head, __put_chunk);
+ }
+
+ static const struct inotify_operations rtree_inotify_ops = {
+diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
+index b7d354e..9fd85a4 100644
+--- a/kernel/auditfilter.c
++++ b/kernel/auditfilter.c
+@@ -1094,8 +1094,8 @@ static void audit_inotify_unregister(struct list_head *in_list)
+ list_for_each_entry_safe(p, n, in_list, ilist) {
+ list_del(&p->ilist);
+ inotify_rm_watch(audit_ih, &p->wdata);
+- /* the put matching the get in audit_do_del_rule() */
+- put_inotify_watch(&p->wdata);
++ /* the unpin matching the pin in audit_do_del_rule() */
++ unpin_inotify_watch(&p->wdata);
+ }
+ }
+
+@@ -1389,9 +1389,13 @@ static inline int audit_del_rule(struct audit_entry *entry,
+ /* Put parent on the inotify un-registration
+ * list. Grab a reference before releasing
+ * audit_filter_mutex, to be released in
+- * audit_inotify_unregister(). */
+- list_add(&parent->ilist, &inotify_list);
+- get_inotify_watch(&parent->wdata);
++ * audit_inotify_unregister().
++ * If filesystem is going away, just leave
++ * the sucker alone, eviction will take
++ * care of it.
++ */
++ if (pin_inotify_watch(&parent->wdata))
++ list_add(&parent->ilist, &inotify_list);
+ }
+ }
+ }
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index d68bf2b..0ba3a5a 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -2045,10 +2045,13 @@ int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)
+ struct cgroup *cgrp;
+ struct cgroup_iter it;
+ struct task_struct *tsk;
++
+ /*
+- * Validate dentry by checking the superblock operations
++ * Validate dentry by checking the superblock operations,
++ * and make sure it's a directory.
+ */
+- if (dentry->d_sb->s_op != &cgroup_ops)
++ if (dentry->d_sb->s_op != &cgroup_ops ||
++ !S_ISDIR(dentry->d_inode->i_mode))
+ goto err;
+
+ ret = 0;
+diff --git a/kernel/cpuset.c b/kernel/cpuset.c
+index 827cd9a..fbda85d 100644
+--- a/kernel/cpuset.c
++++ b/kernel/cpuset.c
+@@ -587,7 +587,6 @@ static int generate_sched_domains(cpumask_t **domains,
+ int ndoms; /* number of sched domains in result */
+ int nslot; /* next empty doms[] cpumask_t slot */
+
+- ndoms = 0;
+ doms = NULL;
+ dattr = NULL;
+ csa = NULL;
+@@ -674,10 +673,8 @@ restart:
+ * Convert <csn, csa> to <ndoms, doms> and populate cpu masks.
+ */
+ doms = kmalloc(ndoms * sizeof(cpumask_t), GFP_KERNEL);
+- if (!doms) {
+- ndoms = 0;
++ if (!doms)
+ goto done;
+- }
+
+ /*
+ * The rest of the code, including the scheduler, can deal with
+@@ -732,6 +729,13 @@ restart:
+ done:
+ kfree(csa);
+
++ /*
++ * Fallback to the default domain if kmalloc() failed.
++ * See comments in partition_sched_domains().
++ */
++ if (doms == NULL)
++ ndoms = 1;
++
+ *domains = doms;
+ *attributes = dattr;
+ return ndoms;
+diff --git a/kernel/sched.c b/kernel/sched.c
+index ad1962d..a992cbe 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -7692,13 +7692,14 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur,
+ *
+ * The passed in 'doms_new' should be kmalloc'd. This routine takes
+ * ownership of it and will kfree it when done with it. If the caller
+- * failed the kmalloc call, then it can pass in doms_new == NULL,
+- * and partition_sched_domains() will fallback to the single partition
+- * 'fallback_doms', it also forces the domains to be rebuilt.
++ * failed the kmalloc call, then it can pass in doms_new == NULL &&
++ * ndoms_new == 1, and partition_sched_domains() will fallback to
++ * the single partition 'fallback_doms', it also forces the domains
++ * to be rebuilt.
+ *
+- * If doms_new==NULL it will be replaced with cpu_online_map.
+- * ndoms_new==0 is a special case for destroying existing domains.
+- * It will not create the default domain.
++ * If doms_new == NULL it will be replaced with cpu_online_map.
++ * ndoms_new == 0 is a special case for destroying existing domains,
++ * and it will not create the default domain.
+ *
+ * Call with hotplug lock held
+ */
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 50ec088..6ffbed2 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -179,6 +179,9 @@ extern struct ctl_table random_table[];
+ #ifdef CONFIG_INOTIFY_USER
+ extern struct ctl_table inotify_table[];
+ #endif
++#ifdef CONFIG_EPOLL
++extern struct ctl_table epoll_table[];
++#endif
+
+ #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
+ int sysctl_legacy_va_layout;
+@@ -1313,6 +1316,13 @@ static struct ctl_table fs_table[] = {
+ .child = inotify_table,
+ },
+ #endif
++#ifdef CONFIG_EPOLL
++ {
++ .procname = "epoll",
++ .mode = 0555,
++ .child = epoll_table,
++ },
++#endif
+ #endif
+ {
+ .ctl_name = KERN_SETUID_DUMPABLE,
+diff --git a/lib/idr.c b/lib/idr.c
+index e728c7f..7a785a0 100644
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -185,6 +185,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
+ new = get_from_free_list(idp);
+ if (!new)
+ return -1;
++ new->layer = l-1;
+ rcu_assign_pointer(p->ary[m], new);
+ p->count++;
+ }
+@@ -210,6 +211,7 @@ build_up:
+ if (unlikely(!p)) {
+ if (!(p = get_from_free_list(idp)))
+ return -1;
++ p->layer = 0;
+ layers = 1;
+ }
+ /*
+@@ -237,6 +239,7 @@ build_up:
+ }
+ new->ary[0] = p;
+ new->count = 1;
++ new->layer = layers-1;
+ if (p->bitmap == IDR_FULL)
+ __set_bit(0, &new->bitmap);
+ p = new;
+@@ -493,17 +496,21 @@ void *idr_find(struct idr *idp, int id)
+ int n;
+ struct idr_layer *p;
+
+- n = idp->layers * IDR_BITS;
+ p = rcu_dereference(idp->top);
++ if (!p)
++ return NULL;
++ n = (p->layer+1) * IDR_BITS;
+
+ /* Mask off upper bits we don't use for the search. */
+ id &= MAX_ID_MASK;
+
+ if (id >= (1 << n))
+ return NULL;
++ BUG_ON(n == 0);
+
+ while (n > 0 && p) {
+ n -= IDR_BITS;
++ BUG_ON(n != p->layer*IDR_BITS);
+ p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
+ }
+ return((void *)p);
+@@ -582,8 +589,11 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
+ int n;
+ struct idr_layer *p, *old_p;
+
+- n = idp->layers * IDR_BITS;
+ p = idp->top;
++ if (!p)
++ return ERR_PTR(-EINVAL);
++
++ n = (p->layer+1) * IDR_BITS;
+
+ id &= MAX_ID_MASK;
+
+diff --git a/lib/scatterlist.c b/lib/scatterlist.c
+index 8d2688f..b7b449d 100644
+--- a/lib/scatterlist.c
++++ b/lib/scatterlist.c
+@@ -395,7 +395,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
+ WARN_ON(!irqs_disabled());
+ kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ);
+ } else
+- kunmap(miter->addr);
++ kunmap(miter->page);
+
+ miter->page = NULL;
+ miter->addr = NULL;
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 8bde9bf..b0785ef 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1341,6 +1341,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
+
+ if (NULL == siocb->scm)
+ siocb->scm = &tmp_scm;
++ wait_for_unix_gc();
+ err = scm_send(sock, msg, siocb->scm);
+ if (err < 0)
+ return err;
+@@ -1491,6 +1492,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
+
+ if (NULL == siocb->scm)
+ siocb->scm = &tmp_scm;
++ wait_for_unix_gc();
+ err = scm_send(sock, msg, siocb->scm);
+ if (err < 0)
+ return err;
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 6d4a9a8..abb3ab3 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -80,6 +80,7 @@
+ #include <linux/file.h>
+ #include <linux/proc_fs.h>
+ #include <linux/mutex.h>
++#include <linux/wait.h>
+
+ #include <net/sock.h>
+ #include <net/af_unix.h>
+@@ -91,6 +92,7 @@
+ static LIST_HEAD(gc_inflight_list);
+ static LIST_HEAD(gc_candidates);
+ static DEFINE_SPINLOCK(unix_gc_lock);
++static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
+
+ unsigned int unix_tot_inflight;
+
+@@ -266,12 +268,16 @@ static void inc_inflight_move_tail(struct unix_sock *u)
+ list_move_tail(&u->link, &gc_candidates);
+ }
+
+-/* The external entry point: unix_gc() */
++static bool gc_in_progress = false;
+
+-void unix_gc(void)
++void wait_for_unix_gc(void)
+ {
+- static bool gc_in_progress = false;
++ wait_event(unix_gc_wait, gc_in_progress == false);
++}
+
++/* The external entry point: unix_gc() */
++void unix_gc(void)
++{
+ struct unix_sock *u;
+ struct unix_sock *next;
+ struct sk_buff_head hitlist;
+@@ -376,6 +382,7 @@ void unix_gc(void)
+ /* All candidates should have been detached by now. */
+ BUG_ON(!list_empty(&gc_candidates));
+ gc_in_progress = false;
++ wake_up(&unix_gc_wait);
+
+ out:
+ spin_unlock(&unix_gc_lock);
|
[-]
[+]
|
Added |
patches.kernel.org.tar.bz2/revert-scsi-qla2xxx-correct-atmel-flash-part-handling.patch
^
|
@@ -0,0 +1,110 @@
+From 821b3996001508e872582dcafc7575021f122728 Mon Sep 17 00:00:00 2001
+From: Lalit Chandivade <lalit.chandivade@qlogic.com>
+Date: Fri, 24 Oct 2008 15:13:44 -0700
+Subject: revert - SCSI: qla2xxx: Correct Atmel flash-part handling.
+
+-------------------
+This is a revert of this patch that is included in 2.6.27.7
+as a further qla2xxx driver update in the series conflicts with this
+ - gregkh
+-------------------
+
+From: Lalit Chandivade <lalit.chandivade@qlogic.com>
+
+commit 821b3996001508e872582dcafc7575021f122728 upstream.
+
+Use correct block size (4K) for erase command 0x20 for Atmel
+Flash. Use dword addresses for determining sector boundary.
+
+Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
+Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+
+---
+ drivers/scsi/qla2xxx/qla_def.h | 1 +
+ drivers/scsi/qla2xxx/qla_sup.c | 23 ++++++++++++++---------
+ 2 files changed, 15 insertions(+), 9 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2546,6 +2546,7 @@ typedef struct scsi_qla_host {
+ uint8_t fcode_revision[16];
+ uint32_t fw_revision[4];
+
++ uint16_t fdt_odd_index;
+ uint32_t fdt_wrt_disable;
+ uint32_t fdt_erase_cmd;
+ uint32_t fdt_block_size;
+--- a/drivers/scsi/qla2xxx/qla_sup.c
++++ b/drivers/scsi/qla2xxx/qla_sup.c
+@@ -546,7 +546,6 @@ qla24xx_get_flash_manufacturer(scsi_qla_
+ void
+ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+ {
+-#define FLASH_BLK_SIZE_4K 0x1000
+ #define FLASH_BLK_SIZE_32K 0x8000
+ #define FLASH_BLK_SIZE_64K 0x10000
+ uint16_t cnt, chksum;
+@@ -578,6 +577,7 @@ qla2xxx_get_flash_info(scsi_qla_host_t *
+ goto no_flash_data;
+ }
+
++ ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f;
+ ha->fdt_wrt_disable = fdt->wrt_disable_bits;
+ ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
+ ha->fdt_block_size = le32_to_cpu(fdt->block_size);
+@@ -590,10 +590,10 @@ qla2xxx_get_flash_info(scsi_qla_host_t *
+ }
+
+ DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x "
+- "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n",
++ "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n",
+ le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd,
+ ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd,
+- ha->fdt_wrt_disable, ha->fdt_block_size));
++ ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size));
+ return;
+
+ no_flash_data:
+@@ -614,7 +614,8 @@ no_flash_data:
+ ha->fdt_block_size = FLASH_BLK_SIZE_64K;
+ break;
+ case 0x1f: /* Atmel 26DF081A. */
+- ha->fdt_block_size = FLASH_BLK_SIZE_4K;
++ ha->fdt_odd_index = 1;
++ ha->fdt_block_size = FLASH_BLK_SIZE_64K;
+ ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320);
+ ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339);
+ ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336);
+@@ -626,9 +627,9 @@ no_flash_data:
+ }
+
+ DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x "
+- "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
++ "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
+ ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
+- ha->fdt_unprotect_sec_cmd, ha->fdt_wrt_disable,
++ ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
+ ha->fdt_block_size));
+ }
+
+@@ -709,9 +710,13 @@ qla24xx_write_flash_data(scsi_qla_host_t
+ qla24xx_unprotect_flash(ha);
+
+ for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
+-
+- findex = faddr;
+- fdata = (findex & sec_mask) << 2;
++ if (ha->fdt_odd_index) {
++ findex = faddr << 2;
++ fdata = findex & sec_mask;
++ } else {
++ findex = faddr;
++ fdata = (findex & sec_mask) << 2;
++ }
+
+ /* Are we at the beginning of a sector? */
+ if ((findex & rest_addr) == 0) {
|
[-]
[+]
|
Added |
patches.kernel.org.tar.bz2/revert-scsi-qla2xxx-do-not-honour-max_vports-from-firmware-for-2g-isps-and-below.patch
^
|
@@ -0,0 +1,58 @@
+From 680d7db88ace53c673e1c437c9b6abcc053e8d6f Mon Sep 17 00:00:00 2001
+From: Shyam Sundar <shyam.sundar@qlogic.com>
+Date: Fri, 24 Oct 2008 15:13:46 -0700
+Subject: revert - SCSI: qla2xxx: Do not honour max_vports from firmware for 2G ISPs and below.
+
+-------------------
+This is a revert of this patch that is included in 2.6.27.7
+as a further qla2xxx driver update in the series conflicts with this
+ - gregkh
+-------------------
+
+From: Shyam Sundar <shyam.sundar@qlogic.com>
+
+commit 680d7db88ace53c673e1c437c9b6abcc053e8d6f upstream.
+
+For 23XX ISPs, max_vports may return an invalid value.
+Do not honour it.
+
+Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+
+---
+ drivers/scsi/qla2xxx/qla_init.c | 2 +-
+ drivers/scsi/qla2xxx/qla_mbx.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -974,6 +974,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
+ &ha->fw_minor_version,
+ &ha->fw_subminor_version,
+ &ha->fw_attributes, &ha->fw_memory_size);
++ qla2x00_resize_request_q(ha);
+ ha->flags.npiv_supported = 0;
+ if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) ||
+ IS_QLA84XX(ha)) &&
+@@ -985,7 +986,6 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
+ ha->max_npiv_vports =
+ MIN_MULTI_ID_FABRIC - 1;
+ }
+- qla2x00_resize_request_q(ha);
+
+ if (ql2xallocfwdump)
+ qla2x00_alloc_fw_dump(ha);
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -1964,7 +1964,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_
+ *cur_iocb_cnt = mcp->mb[7];
+ if (orig_iocb_cnt)
+ *orig_iocb_cnt = mcp->mb[10];
+- if (ha->flags.npiv_supported && max_npiv_vports)
++ if (max_npiv_vports)
+ *max_npiv_vports = mcp->mb[11];
+ }
+
|
[-]
[+]
|
Added |
patches.kernel.org.tar.bz2/revert-scsi-qla2xxx-return-a-failed-status-when-abort-mailbox-command-fails.patch
^
|
@@ -0,0 +1,46 @@
+From 5bff55db3dc4d659f46b4d2fce2f61c1964c2762 Mon Sep 17 00:00:00 2001
+From: Michael Reed <mdr@sgi.com>
+Date: Fri, 24 Oct 2008 15:13:47 -0700
+Subject: revert - SCSI: qla2xxx: Return a FAILED status when abort mailbox-command fails.
+
+-------------------
+This is a revert of this patch that is included in 2.6.27.7
+as a further qla2xxx driver update in the series conflicts with this
+ - gregkh
+-------------------
+
+From: Michael Reed <mdr@sgi.com>
+
+commit 5bff55db3dc4d659f46b4d2fce2f61c1964c2762 upstream.
+
+Mike Reed noted
+(https://bugzilla.novell.com/show_bug.cgi?id=421330) that the
+driver was incorrectly returning a SUCCESS status if the driver's
+request to the firmware to abort a command failed. By doing so,
+the mid-layer believed, incorrectly, that the command has
+completed and has been returned (ultimately clearing
+scsi_cmnd.request_buffer) yet the driver still has the command.
+What should correctly happen is a mid-layer escalation
+(device-reset, etc.) of recovery during which the driver will
+eventually return the outstanding commands to the mid-layer.
+
+Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+
+---
+ drivers/scsi/qla2xxx/qla_os.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -730,7 +730,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ if (ha->isp_ops->abort_command(ha, sp)) {
+ DEBUG2(printk("%s(%ld): abort_command "
+ "mbx failed.\n", __func__, ha->host_no));
+- ret = FAILED;
+ } else {
+ DEBUG3(printk("%s(%ld): abort_command "
+ "mbx success.\n", __func__, ha->host_no));
|
[-]
[+]
|
Deleted |
patches.kernel.org.tar.bz2/touch_mnt_namespace-when-the-mount-flags-change.patch
^
|
@@ -1,45 +0,0 @@
-From: Dan Williams <dan.j.williams@intel.com>
-Date: Sat, 27 Sep 2008 02:01:20 +0000 (-0700)
-Subject: [RFC PATCH] touch_mnt_namespace when the mount flags change
-X-git-tag: v2.6.28-rc1~24^2~6
-X-git-url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=0e55a7cca4b66f625d67b292f80b6a976e77c51b
-Patch-mainline: 2.6.28-rc1
-References: FATE#304218
-
-[RFC PATCH] touch_mnt_namespace when the mount flags change
-
-Daemons that need to be launched while the rootfs is read-only can now
-poll /proc/mounts to be notified when their O_RDWR requests may no
-longer end in EROFS.
-
-[[SLES: This is needed for mdadm-3.0 to be able to handle DDF and IMSM
- arrays early in the boot process ]]
-
-Cc: Kay Sievers <kay.sievers@vrfy.org>
-Cc: Neil Brown <neilb@suse.de>
-Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-Acked-by: Neil Brown <neilb@suse.de>
-
----
-
----
- fs/namespace.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- linux-2.6.27-neilb.orig/fs/namespace.c
-+++ linux-2.6.27-neilb/fs/namespace.c
-@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct na
- if (!err)
- nd->path.mnt->mnt_flags = mnt_flags;
- up_write(&sb->s_umount);
-- if (!err)
-+ if (!err) {
- security_sb_post_remount(nd->path.mnt, flags, data);
-+
-+ spin_lock(&vfsmount_lock);
-+ touch_mnt_namespace(nd->path.mnt->mnt_ns);
-+ spin_unlock(&vfsmount_lock);
-+ }
- return err;
- }
-
|
|
Changed |
patches.rt.tar.bz2
^
|
|
Changed |
patches.suse.tar.bz2
^
|
[-]
[+]
|
Changed |
patches.trace.tar.bz2/lttng-instrumentation-hugetlb.patch
^
|
@@ -35,10 +35,8 @@
mm/hugetlb.c | 55 +++++++++++++++++++++++++++++++++---------------
2 files changed, 66 insertions(+), 17 deletions(-)
-Index: linux-2.6.27/include/trace/hugetlb.h
-===================================================================
--- /dev/null
-+++ linux-2.6.27/include/trace/hugetlb.h
++++ b/include/trace/hugetlb.h
@@ -0,0 +1,28 @@
+#ifndef _TRACE_HUGETLB_H
+#define _TRACE_HUGETLB_H
@@ -68,10 +66,8 @@
+ TPARGS(inode, offset, freed));
+
+#endif
-Index: linux-2.6.27/mm/hugetlb.c
-===================================================================
---- linux-2.6.27.orig/mm/hugetlb.c
-+++ linux-2.6.27/mm/hugetlb.c
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
@@ -17,6 +17,7 @@
#include <linux/mutex.h>
#include <linux/bootmem.h>
@@ -80,15 +76,15 @@
#include <asm/page.h>
#include <asm/pgtable.h>
-@@ -462,6 +463,7 @@ static void update_and_free_page(struct
+@@ -492,6 +493,7 @@ static void update_and_free_page(struct
- BUG_ON(h->order >= MAX_ORDER);
+ VM_BUG_ON(h->order >= MAX_ORDER);
+ trace_hugetlb_page_release(page);
h->nr_huge_pages--;
h->nr_huge_pages_node[page_to_nid(page)]--;
for (i = 0; i < pages_per_huge_page(h); i++) {
-@@ -496,6 +498,7 @@ static void free_huge_page(struct page *
+@@ -526,6 +528,7 @@ static void free_huge_page(struct page *
int nid = page_to_nid(page);
struct address_space *mapping;
@@ -96,7 +92,7 @@
mapping = (struct address_space *) page_private(page);
set_page_private(page, 0);
BUG_ON(page_count(page));
-@@ -563,8 +566,10 @@ static struct page *alloc_fresh_huge_pag
+@@ -593,8 +596,10 @@ static struct page *alloc_fresh_huge_pag
{
struct page *page;
@@ -109,7 +105,7 @@
page = alloc_pages_node(nid,
htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE|
-@@ -573,11 +578,13 @@ static struct page *alloc_fresh_huge_pag
+@@ -603,11 +608,13 @@ static struct page *alloc_fresh_huge_pag
if (page) {
if (arch_prepare_hugepage(page)) {
__free_pages(page, huge_page_order(h));
@@ -125,7 +121,7 @@
return page;
}
-@@ -661,7 +668,8 @@ static struct page *alloc_buddy_huge_pag
+@@ -691,7 +698,8 @@ static struct page *alloc_buddy_huge_pag
spin_lock(&hugetlb_lock);
if (h->surplus_huge_pages >= h->nr_overcommit_huge_pages) {
spin_unlock(&hugetlb_lock);
@@ -135,7 +131,7 @@
} else {
h->nr_huge_pages++;
h->surplus_huge_pages++;
-@@ -699,7 +707,8 @@ static struct page *alloc_buddy_huge_pag
+@@ -729,7 +737,8 @@ static struct page *alloc_buddy_huge_pag
__count_vm_event(HTLB_BUDDY_PGALLOC_FAIL);
}
spin_unlock(&hugetlb_lock);
@@ -145,7 +141,7 @@
return page;
}
-@@ -938,6 +947,7 @@ static struct page *alloc_huge_page(stru
+@@ -968,6 +977,7 @@ static struct page *alloc_huge_page(stru
vma_commit_reservation(h, vma, addr);
@@ -153,7 +149,7 @@
return page;
}
-@@ -2194,11 +2204,12 @@ int hugetlb_reserve_pages(struct inode *
+@@ -2233,11 +2243,12 @@ int hugetlb_reserve_pages(struct inode *
long from, long to,
struct vm_area_struct *vma)
{
@@ -168,7 +164,7 @@
/*
* Shared mappings base their reservation on the number of pages that
-@@ -2210,8 +2221,10 @@ int hugetlb_reserve_pages(struct inode *
+@@ -2249,8 +2260,10 @@ int hugetlb_reserve_pages(struct inode *
chg = region_chg(&inode->i_mapping->private_list, from, to);
else {
struct resv_map *resv_map = resv_map_alloc();
@@ -181,7 +177,7 @@
chg = to - from;
-@@ -2219,26 +2232,34 @@ int hugetlb_reserve_pages(struct inode *
+@@ -2258,26 +2271,34 @@ int hugetlb_reserve_pages(struct inode *
set_vma_resv_flags(vma, HPAGE_RESV_OWNER);
}
|
[-]
[+]
|
Changed |
patches.trace.tar.bz2/lttng-instrumentation-kernel.patch
^
|
@@ -60,7 +60,7 @@
#if 0
#define DEBUGP printk
-@@ -1457,6 +1458,8 @@ static int __unlink_module(void *_mod)
+@@ -1473,6 +1474,8 @@ static int __unlink_module(void *_mod)
/* Free a module, remove from lists, etc (must hold module_mutex). */
static void free_module(struct module *mod)
{
@@ -69,7 +69,7 @@
/* Delete from various lists */
stop_machine(__unlink_module, mod, NULL);
remove_notes_attrs(mod);
-@@ -2336,6 +2339,8 @@ static noinline struct module *load_modu
+@@ -2354,6 +2357,8 @@ static noinline struct module *load_modu
/* Get rid of temporary copy */
vfree(hdr);
|
[-]
[+]
|
Changed |
patches.trace.tar.bz2/lttng-instrumentation-page_alloc.patch
^
|
@@ -64,7 +64,7 @@
/*
* Array of node states.
*/
-@@ -526,6 +528,8 @@ static void __free_pages_ok(struct page
+@@ -528,6 +530,8 @@ static void __free_pages_ok(struct page
int i;
int reserved = 0;
@@ -73,7 +73,7 @@
for (i = 0 ; i < (1 << order) ; ++i)
reserved += free_pages_check(page + i);
if (reserved)
-@@ -986,6 +990,8 @@ static void free_hot_cold_page(struct pa
+@@ -988,6 +992,8 @@ static void free_hot_cold_page(struct pa
struct per_cpu_pages *pcp;
unsigned long flags;
@@ -82,7 +82,7 @@
if (PageAnon(page))
page->mapping = NULL;
if (free_pages_check(page))
-@@ -1656,6 +1662,7 @@ nopage:
+@@ -1658,6 +1664,7 @@ nopage:
show_mem();
}
got_pg:
|
[-]
[+]
|
Changed |
patches.trace.tar.bz2/lttng-instrumentation-scheduler.patch
^
|
@@ -124,7 +124,7 @@
exit_sem(tsk);
exit_files(tsk);
exit_fs(tsk);
-@@ -1678,6 +1684,8 @@ static long do_wait(enum pid_type type,
+@@ -1678,6 +1684,8 @@ static long do_wait(enum pid_type type,
struct task_struct *tsk;
int retval;
@@ -190,7 +190,7 @@
#include <asm/tlb.h>
#include <asm/irq_regs.h>
-@@ -1918,6 +1919,7 @@ unsigned long wait_task_inactive(struct
+@@ -1918,6 +1919,7 @@ unsigned long wait_task_inactive(struct
* just go back and repeat.
*/
rq = task_rq_lock(p, &flags);
|
[-]
[+]
|
Added |
patches.trace.tar.bz2/s390-syscall-get-nr.diff
^
|
@@ -0,0 +1,281 @@
+Subject: [PATCH] fix syscall_get_nr.
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+syscall_get_nr() currently returns a valid result only if the call
+chain of the traced process includes do_syscall_trace_enter(). But
+collect_syscall() can be called for any sleeping task, the result of
+syscall_get_nr() in general is completely bogus.
+
+To make syscall_get_nr() work for any sleeping task the traps field
+in pt_regs is replace with svcnr - the system call number the process
+is executing. If svcnr == 0 the process is not on a system call path.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Acked-by: John Jolly <jjolly@novell.com>
+---
+
+ arch/s390/include/asm/ptrace.h | 2 +-
+ arch/s390/include/asm/syscall.h | 4 +---
+ arch/s390/kernel/asm-offsets.c | 2 +-
+ arch/s390/kernel/compat_signal.c | 2 +-
+ arch/s390/kernel/entry.S | 21 +++++++++++----------
+ arch/s390/kernel/entry64.S | 23 ++++++++++-------------
+ arch/s390/kernel/ptrace.c | 2 +-
+ arch/s390/kernel/signal.c | 6 +++---
+ 8 files changed, 29 insertions(+), 33 deletions(-)
+
+--- a/arch/s390/include/asm/ptrace.h
++++ b/arch/s390/include/asm/ptrace.h
+@@ -321,8 +321,8 @@ struct pt_regs
+ psw_t psw;
+ unsigned long gprs[NUM_GPRS];
+ unsigned long orig_gpr2;
++ unsigned short svcnr;
+ unsigned short ilc;
+- unsigned short trap;
+ };
+ #endif
+
+--- a/arch/s390/include/asm/syscall.h
++++ b/arch/s390/include/asm/syscall.h
+@@ -17,9 +17,7 @@
+ static inline long syscall_get_nr(struct task_struct *task,
+ struct pt_regs *regs)
+ {
+- if (regs->trap != __LC_SVC_OLD_PSW)
+- return -1;
+- return regs->gprs[2];
++ return regs->svcnr ? regs->svcnr : -1;
+ }
+
+ static inline void syscall_rollback(struct task_struct *task,
+--- a/arch/s390/kernel/asm-offsets.c
++++ b/arch/s390/kernel/asm-offsets.c
+@@ -32,7 +32,7 @@ int main(void)
+ DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
+ DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
+ DEFINE(__PT_ILC, offsetof(struct pt_regs, ilc));
+- DEFINE(__PT_TRAP, offsetof(struct pt_regs, trap));
++ DEFINE(__PT_SVCNR, offsetof(struct pt_regs, svcnr));
+ DEFINE(__PT_SIZE, sizeof(struct pt_regs));
+ BLANK();
+ DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
+--- a/arch/s390/kernel/compat_signal.c
++++ b/arch/s390/kernel/compat_signal.c
+@@ -340,7 +340,7 @@ static int restore_sigregs32(struct pt_r
+ return err;
+
+ restore_fp_regs(¤t->thread.fp_regs);
+- regs->trap = -1; /* disable syscall checks */
++ regs->svcnr = 0; /* disable syscall checks */
+ return 0;
+ }
+
+--- a/arch/s390/kernel/entry64.S
++++ b/arch/s390/kernel/entry64.S
+@@ -46,7 +46,7 @@ SP_R14 = STACK_FRAME_OVERHEAD + __P
+ SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120
+ SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
+ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
+-SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
++SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR
+ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
+
+ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
+@@ -168,11 +168,10 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_
+ .macro CREATE_STACK_FRAME psworg,savearea
+ aghi %r15,-SP_SIZE # make room for registers & psw
+ mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
+- la %r12,\psworg
+ stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
+- icm %r12,12,__LC_SVC_ILC
++ icm %r12,3,__LC_SVC_ILC
+ stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
+- st %r12,SP_ILC(%r15)
++ st %r12,SP_SVCNR(%r15)
+ mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack
+ la %r12,0
+ stg %r12,__SF_BACKCHAIN(%r15)
+@@ -247,16 +246,17 @@ sysc_update:
+ #endif
+ sysc_do_svc:
+ lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+- slag %r7,%r7,2 # *4 and test for svc 0
++ ltgr %r7,%r7 # test for svc 0
+ jnz sysc_nr_ok
+ # svc 0: system call number in %r1
+ cl %r1,BASED(.Lnr_syscalls)
+ jnl sysc_nr_ok
+ lgfr %r7,%r1 # clear high word in r1
+- slag %r7,%r7,2 # svc 0: system call number in %r1
+ sysc_nr_ok:
+ mvc SP_ARGS(8,%r15),SP_R7(%r15)
+ sysc_do_restart:
++ sth %r7,SP_SVCNR(%r15)
++ sllg %r7,%r7,2 # svc number * 4
+ larl %r10,sys_call_table
+ #ifdef CONFIG_COMPAT
+ tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ?
+@@ -360,7 +360,6 @@ sysc_notify_resume:
+ sysc_restart:
+ ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
+ lg %r7,SP_R2(%r15) # load new svc number
+- slag %r7,%r7,2 # *4
+ mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument
+ lmg %r2,%r6,SP_R2(%r15) # load svc arguments
+ j sysc_do_restart # restart svc
+@@ -369,9 +368,8 @@ sysc_restart:
+ # _TIF_SINGLE_STEP is set, call do_single_step
+ #
+ sysc_singlestep:
+- ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+- lhi %r0,__LC_PGM_OLD_PSW
+- sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
++ ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
++ xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ larl %r14,sysc_return # load adr. of system return
+ jg do_single_step # branch to do_sigtrap
+@@ -389,7 +387,7 @@ sysc_tracesys:
+ lghi %r0,NR_syscalls
+ clgr %r0,%r2
+ jnh sysc_tracenogo
+- slag %r7,%r2,2 # *4
++ sllg %r7,%r2,2 # svc number *4
+ lgf %r8,0(%r7,%r10)
+ sysc_tracego:
+ lmg %r3,%r6,SP_R3(%r15)
+@@ -564,8 +562,7 @@ pgm_svcper:
+ # per was called from kernel, must be kprobes
+ #
+ kernel_per:
+- lhi %r0,__LC_PGM_OLD_PSW
+- sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
++ xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ larl %r14,sysc_restore # load adr. of system ret, no work
+ jg do_single_step # branch to do_single_step
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -46,7 +46,7 @@ SP_R14 = STACK_FRAME_OVERHEAD + __P
+ SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60
+ SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
+ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
+-SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
++SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR
+ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
+
+ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
+@@ -180,11 +180,10 @@ STACK_SIZE = 1 << STACK_SHIFT
+ .macro CREATE_STACK_FRAME psworg,savearea
+ s %r15,BASED(.Lc_spsize) # make room for registers & psw
+ mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
+- la %r12,\psworg
+ st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
+- icm %r12,12,__LC_SVC_ILC
++ icm %r12,3,__LC_SVC_ILC
+ stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
+- st %r12,SP_ILC(%r15)
++ st %r12,SP_SVCNR(%r15)
+ mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
+ la %r12,0
+ st %r12,__SF_BACKCHAIN(%r15) # clear back chain
+@@ -261,16 +260,17 @@ sysc_update:
+ #endif
+ sysc_do_svc:
+ l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
+- sla %r7,2 # *4 and test for svc 0
++ ltr %r7,%r7 # test for svc 0
+ bnz BASED(sysc_nr_ok) # svc number > 0
+ # svc 0: system call number in %r1
+ cl %r1,BASED(.Lnr_syscalls)
+ bnl BASED(sysc_nr_ok)
+ lr %r7,%r1 # copy svc number to %r7
+- sla %r7,2 # *4
+ sysc_nr_ok:
+ mvc SP_ARGS(4,%r15),SP_R7(%r15)
+ sysc_do_restart:
++ sth %r7,SP_SVCNR(%r15)
++ sll %r7,2 # svc number *4
+ l %r8,BASED(.Lsysc_table)
+ tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ l %r8,0(%r7,%r8) # get system call addr.
+@@ -373,7 +373,6 @@ sysc_notify_resume:
+ sysc_restart:
+ ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
+ l %r7,SP_R2(%r15) # load new svc number
+- sla %r7,2
+ mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
+ lm %r2,%r6,SP_R2(%r15) # load svc arguments
+ b BASED(sysc_do_restart) # restart svc
+@@ -383,7 +382,8 @@ sysc_restart:
+ #
+ sysc_singlestep:
+ ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+- mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
++ mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
++ mvi SP_SVCNR+1(%r15),0xff
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ l %r1,BASED(.Lhandle_per) # load adr. of per handler
+ la %r14,BASED(sysc_return) # load adr. of system return
+@@ -404,7 +404,7 @@ sysc_tracesys:
+ bnl BASED(sysc_tracenogo)
+ l %r8,BASED(.Lsysc_table)
+ lr %r7,%r2
+- sll %r7,2 # *4
++ sll %r7,2 # svc number *4
+ l %r8,0(%r7,%r8)
+ sysc_tracego:
+ lm %r3,%r6,SP_R3(%r15)
+@@ -583,7 +583,8 @@ pgm_svcper:
+ # per was called from kernel, must be kprobes
+ #
+ kernel_per:
+- mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
++ mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
++ mvi SP_SVCNR+1(%r15),0xff
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ l %r1,BASED(.Lhandle_per) # load adr. of per handler
+ la %r14,BASED(sysc_restore)# load adr. of system return
+--- a/arch/s390/kernel/ptrace.c
++++ b/arch/s390/kernel/ptrace.c
+@@ -671,7 +671,7 @@ asmlinkage long do_syscall_trace_enter(s
+ * debugger stored an invalid system call number. Skip
+ * the system call and the system call restart handling.
+ */
+- regs->trap = -1;
++ regs->svcnr = 0;
+ ret = -1;
+ }
+
+--- a/arch/s390/kernel/signal.c
++++ b/arch/s390/kernel/signal.c
+@@ -160,7 +160,7 @@ static int restore_sigregs(struct pt_reg
+ current->thread.fp_regs.fpc &= FPC_VALID_MASK;
+
+ restore_fp_regs(¤t->thread.fp_regs);
+- regs->trap = -1; /* disable syscall checks */
++ regs->svcnr = 0; /* disable syscall checks */
+ return 0;
+ }
+
+@@ -445,7 +445,7 @@ void do_signal(struct pt_regs *regs)
+ oldset = ¤t->blocked;
+
+ /* Are we from a system call? */
+- if (regs->trap == __LC_SVC_OLD_PSW) {
++ if (regs->svcnr) {
+ continue_addr = regs->psw.addr;
+ restart_addr = continue_addr - regs->ilc;
+ retval = regs->gprs[2];
+@@ -462,7 +462,7 @@ void do_signal(struct pt_regs *regs)
+ case -ERESTART_RESTARTBLOCK:
+ regs->gprs[2] = -EINTR;
+ }
+- regs->trap = -1; /* Don't deal with this again. */
++ regs->svcnr = 0; /* Don't deal with this again. */
+ }
+
+ /* Get signal to deliver. When running under ptrace, at this point
|
[-]
[+]
|
Added |
patches.trace.tar.bz2/s390-utrace-enablement.patch
^
|
@@ -0,0 +1,498 @@
+Subject: Backport s390 kernel components required for utrace enablement
+
+From: Ananth N. Mavinakayanahalli <ananth@in.ibm.com>
+
+References: bnc#442709
+
+Acked-by: John Jolly <jjolly@novell.com>
+---
+ arch/s390/Kconfig | 1
+ arch/s390/include/asm/ptrace.h | 1
+ arch/s390/include/asm/syscall.h | 80 ++++++++++++++++++++++++++++++++++++
+ arch/s390/include/asm/thread_info.h | 2
+ arch/s390/kernel/entry.S | 50 ++++++++++++++++++----
+ arch/s390/kernel/entry64.S | 42 ++++++++++++++----
+ arch/s390/kernel/ptrace.c | 75 +++++++++++++++++++++------------
+ arch/s390/kernel/signal.c | 13 +++++
+ 8 files changed, 216 insertions(+), 48 deletions(-)
+
+--- a/arch/s390/include/asm/ptrace.h
++++ b/arch/s390/include/asm/ptrace.h
+@@ -490,6 +490,7 @@ extern void user_disable_single_step(str
+
+ #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
+ #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
++#define user_stack_pointer(regs)((regs)->gprs[15])
+ #define regs_return_value(regs)((regs)->gprs[2])
+ #define profile_pc(regs) instruction_pointer(regs)
+ extern void show_regs(struct pt_regs * regs);
+--- /dev/null
++++ b/arch/s390/include/asm/syscall.h
+@@ -0,0 +1,80 @@
++/*
++ * Access to user system call parameters and results
++ *
++ * Copyright IBM Corp. 2008
++ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License (version 2 only)
++ * as published by the Free Software Foundation.
++ */
++
++#ifndef _ASM_SYSCALL_H
++#define _ASM_SYSCALL_H 1
++
++#include <asm/ptrace.h>
++
++static inline long syscall_get_nr(struct task_struct *task,
++ struct pt_regs *regs)
++{
++ if (regs->trap != __LC_SVC_OLD_PSW)
++ return -1;
++ return regs->gprs[2];
++}
++
++static inline void syscall_rollback(struct task_struct *task,
++ struct pt_regs *regs)
++{
++ regs->gprs[2] = regs->orig_gpr2;
++}
++
++static inline long syscall_get_error(struct task_struct *task,
++ struct pt_regs *regs)
++{
++ return (regs->gprs[2] >= -4096UL) ? -regs->gprs[2] : 0;
++}
++
++static inline long syscall_get_return_value(struct task_struct *task,
++ struct pt_regs *regs)
++{
++ return regs->gprs[2];
++}
++
++static inline void syscall_set_return_value(struct task_struct *task,
++ struct pt_regs *regs,
++ int error, long val)
++{
++ regs->gprs[2] = error ? -error : val;
++}
++
++static inline void syscall_get_arguments(struct task_struct *task,
++ struct pt_regs *regs,
++ unsigned int i, unsigned int n,
++ unsigned long *args)
++{
++ BUG_ON(i + n > 6);
++#ifdef CONFIG_COMPAT
++ if (test_tsk_thread_flag(task, TIF_31BIT)) {
++ if (i + n == 6)
++ args[--n] = (u32) regs->args[0];
++ while (n-- > 0)
++ args[n] = (u32) regs->gprs[2 + i + n];
++ }
++#endif
++ if (i + n == 6)
++ args[--n] = regs->args[0];
++ memcpy(args, ®s->gprs[2 + i], n * sizeof(args[0]));
++}
++
++static inline void syscall_set_arguments(struct task_struct *task,
++ struct pt_regs *regs,
++ unsigned int i, unsigned int n,
++ const unsigned long *args)
++{
++ BUG_ON(i + n > 6);
++ if (i + n == 6)
++ regs->args[0] = args[--n];
++ memcpy(®s->gprs[2 + i], args, n * sizeof(args[0]));
++}
++
++#endif /* _ASM_SYSCALL_H */
+--- a/arch/s390/include/asm/thread_info.h
++++ b/arch/s390/include/asm/thread_info.h
+@@ -86,6 +86,7 @@ static inline struct thread_info *curren
+ * thread information flags bit numbers
+ */
+ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
++#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
+ #define TIF_SIGPENDING 2 /* signal pending */
+ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+ #define TIF_RESTART_SVC 4 /* restart svc with new svc number */
+@@ -101,6 +102,7 @@ static inline struct thread_info *curren
+ #define TIF_FREEZE 21
+
+ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
++#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+ #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+ #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -74,6 +74,7 @@ config S390
+ select HAVE_KPROBES
+ select HAVE_KRETPROBES
+ select HAVE_KVM if 64BIT
++ select HAVE_ARCH_TRACEHOOK
+
+ source "init/Kconfig"
+
+--- a/arch/s390/kernel/entry64.S
++++ b/arch/s390/kernel/entry64.S
+@@ -52,9 +52,9 @@ SP_SIZE = STACK_FRAME_OVERHEAD + __
+ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
+ STACK_SIZE = 1 << STACK_SHIFT
+
+-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
++_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
+ _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
+-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
++_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
+ _TIF_MCCK_PENDING)
+
+ #define BASED(name) name-system_call(%r13)
+@@ -310,6 +310,8 @@ sysc_work:
+ jo sysc_reschedule
+ tm __TI_flags+7(%r9),_TIF_SIGPENDING
+ jnz sysc_sigpending
++ tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
++ jnz sysc_notify_resume
+ tm __TI_flags+7(%r9),_TIF_RESTART_SVC
+ jo sysc_restart
+ tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
+@@ -345,6 +347,14 @@ sysc_sigpending:
+ j sysc_work_loop
+
+ #
++# _TIF_NOTIFY_RESUME is set, call do_notify_resume
++#
++sysc_notify_resume:
++ la %r2,SP_PTREGS(%r15) # load pt_regs
++ larl %r14,sysc_work_loop
++ jg do_notify_resume # call do_notify_resume
++
++#
+ # _TIF_RESTART_SVC is set, set up registers and restart svc
+ #
+ sysc_restart:
+@@ -367,20 +377,19 @@ sysc_singlestep:
+ jg do_single_step # branch to do_sigtrap
+
+ #
+-# call syscall_trace before and after system call
+-# special linkage: %r12 contains the return address for trace_svc
++# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
++# and after the system call
+ #
+ sysc_tracesys:
+ la %r2,SP_PTREGS(%r15) # load pt_regs
+ la %r3,0
+ srl %r7,2
+ stg %r7,SP_R2(%r15)
+- brasl %r14,syscall_trace
++ brasl %r14,do_syscall_trace_enter
+ lghi %r0,NR_syscalls
+- clg %r0,SP_R2(%r15)
++ clgr %r0,%r2
+ jnh sysc_tracenogo
+- lg %r7,SP_R2(%r15) # strace might have changed the
+- sll %r7,2 # system call
++ slag %r7,%r2,2 # *4
+ lgf %r8,0(%r7,%r10)
+ sysc_tracego:
+ lmg %r3,%r6,SP_R3(%r15)
+@@ -391,9 +400,8 @@ sysc_tracenogo:
+ tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ jz sysc_return
+ la %r2,SP_PTREGS(%r15) # load pt_regs
+- la %r3,1
+ larl %r14,sysc_return # return point is sysc_return
+- jg syscall_trace
++ jg do_syscall_trace_exit
+
+ #
+ # a new process exits the kernel with ret_from_fork
+@@ -672,6 +680,8 @@ io_work_loop:
+ jo io_reschedule
+ tm __TI_flags+7(%r9),_TIF_SIGPENDING
+ jnz io_sigpending
++ tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
++ jnz io_notify_resume
+ j io_restore
+ io_work_done:
+
+@@ -712,6 +722,18 @@ io_sigpending:
+ TRACE_IRQS_OFF
+ j io_work_loop
+
++#
++# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
++#
++io_notify_resume:
++ TRACE_IRQS_ON
++ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
++ la %r2,SP_PTREGS(%r15) # load pt_regs
++ brasl %r14,do_notify_resume # call do_notify_resume
++ stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
++ TRACE_IRQS_OFF
++ j io_work_loop
++
+ /*
+ * External interrupt handler routine
+ */
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -49,9 +49,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __P
+ SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
+ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
+
+-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
++_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
+ _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
+-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
++_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
+ _TIF_MCCK_PENDING)
+
+ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
+@@ -318,6 +318,8 @@ sysc_work:
+ bo BASED(sysc_reschedule)
+ tm __TI_flags+3(%r9),_TIF_SIGPENDING
+ bnz BASED(sysc_sigpending)
++ tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
++ bnz BASED(sysc_notify_resume)
+ tm __TI_flags+3(%r9),_TIF_RESTART_SVC
+ bo BASED(sysc_restart)
+ tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
+@@ -356,6 +358,16 @@ sysc_sigpending:
+ b BASED(sysc_work_loop)
+
+ #
++# _TIF_NOTIFY_RESUME is set, call do_notify_resume
++#
++sysc_notify_resume:
++ la %r2,SP_PTREGS(%r15) # load pt_regs
++ l %r1,BASED(.Ldo_notify_resume)
++ la %r14,BASED(sysc_work_loop)
++ br %r1 # call do_notify_resume
++
++
++#
+ # _TIF_RESTART_SVC is set, set up registers and restart svc
+ #
+ sysc_restart:
+@@ -378,20 +390,21 @@ sysc_singlestep:
+ br %r1 # branch to do_single_step
+
+ #
+-# call trace before and after sys_call
++# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
++# and after the system call
+ #
+ sysc_tracesys:
+- l %r1,BASED(.Ltrace)
++ l %r1,BASED(.Ltrace_entry)
+ la %r2,SP_PTREGS(%r15) # load pt_regs
+ la %r3,0
+ srl %r7,2
+ st %r7,SP_R2(%r15)
+ basr %r14,%r1
+- clc SP_R2(4,%r15),BASED(.Lnr_syscalls)
++ cl %r2,BASED(.Lnr_syscalls)
+ bnl BASED(sysc_tracenogo)
+ l %r8,BASED(.Lsysc_table)
+- l %r7,SP_R2(%r15) # strace might have changed the
+- sll %r7,2 # system call
++ lr %r7,%r2
++ sll %r7,2 # *4
+ l %r8,0(%r7,%r8)
+ sysc_tracego:
+ lm %r3,%r6,SP_R3(%r15)
+@@ -401,9 +414,8 @@ sysc_tracego:
+ sysc_tracenogo:
+ tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+ bz BASED(sysc_return)
+- l %r1,BASED(.Ltrace)
++ l %r1,BASED(.Ltrace_exit)
+ la %r2,SP_PTREGS(%r15) # load pt_regs
+- la %r3,1
+ la %r14,BASED(sysc_return)
+ br %r1
+
+@@ -666,6 +678,8 @@ io_work_loop:
+ bo BASED(io_reschedule)
+ tm __TI_flags+3(%r9),_TIF_SIGPENDING
+ bnz BASED(io_sigpending)
++ tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
++ bnz BASED(io_notify_resume)
+ b BASED(io_restore)
+ io_work_done:
+
+@@ -704,6 +718,19 @@ io_sigpending:
+ TRACE_IRQS_OFF
+ b BASED(io_work_loop)
+
++#
++# _TIF_SIGPENDING is set, call do_signal
++#
++io_notify_resume:
++ TRACE_IRQS_ON
++ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
++ la %r2,SP_PTREGS(%r15) # load pt_regs
++ l %r1,BASED(.Ldo_notify_resume)
++ basr %r14,%r1 # call do_signal
++ stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
++ TRACE_IRQS_OFF
++ b BASED(io_work_loop)
++
+ /*
+ * External interrupt handler routine
+ */
+@@ -1070,6 +1097,8 @@ cleanup_io_leave_insn:
+ .Ldo_IRQ: .long do_IRQ
+ .Ldo_extint: .long do_extint
+ .Ldo_signal: .long do_signal
++.Ldo_notify_resume:
++ .long do_notify_resume
+ .Lhandle_per: .long do_single_step
+ .Ldo_execve: .long do_execve
+ .Lexecve_tail: .long execve_tail
+@@ -1079,7 +1108,8 @@ cleanup_io_leave_insn:
+ .Lpreempt_schedule_irq:
+ .long preempt_schedule_irq
+ #endif
+-.Ltrace: .long syscall_trace
++.Ltrace_entry: .long do_syscall_trace_enter
++.Ltrace_exit: .long do_syscall_trace_exit
+ .Lschedtail: .long schedule_tail
+ .Lsysc_table: .long sys_call_table
+ #ifdef CONFIG_TRACE_IRQFLAGS
+--- a/arch/s390/kernel/ptrace.c
++++ b/arch/s390/kernel/ptrace.c
+@@ -35,6 +35,7 @@
+ #include <linux/signal.h>
+ #include <linux/elf.h>
+ #include <linux/regset.h>
++#include <linux/tracehook.h>
+
+ #include <asm/segment.h>
+ #include <asm/page.h>
+@@ -639,40 +640,58 @@ long compat_arch_ptrace(struct task_stru
+ }
+ #endif
+
+-asmlinkage void
+-syscall_trace(struct pt_regs *regs, int entryexit)
++asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
+ {
+- if (unlikely(current->audit_context) && entryexit)
+- audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
+-
+- if (!test_thread_flag(TIF_SYSCALL_TRACE))
+- goto out;
+- if (!(current->ptrace & PT_PTRACED))
+- goto out;
+- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+- ? 0x80 : 0));
++ long ret;
+
+ /*
+- * If the debuffer has set an invalid system call number,
+- * we prepare to skip the system call restart handling.
++ * The sysc_tracesys code in entry.S stored the system
++ * call number to gprs[2].
+ */
+- if (!entryexit && regs->gprs[2] >= NR_syscalls)
++
++ if (is_self_ptracing(regs->gprs[2])) {
++ struct siginfo info;
++
++ memset(&info, 0, sizeof(struct siginfo));
++ info.si_signo = SIGSYS;
++ info.si_code = SYS_SYSCALL;
++ info.si_errno = regs->gprs[2];
++ info.si_addr = (void *)regs->orig_gpr2;
++ send_sig_info(SIGSYS, &info, current);
++ regs->gprs[2] = -1;
++ return -1L;
++ }
++
++ ret = regs->gprs[2];
++ if (test_thread_flag(TIF_SYSCALL_TRACE) &&
++ (tracehook_report_syscall_entry(regs) ||
++ regs->gprs[2] >= NR_syscalls)) {
++ /*
++ * Tracing decided this syscall should not happen or the
++ * debugger stored an invalid system call number. Skip
++ * the system call and the system call restart handling.
++ */
+ regs->trap = -1;
++ ret = -1;
++ }
+
+- /*
+- * this isn't the same as continuing with a signal, but it will do
+- * for normal use. strace only continues with a signal if the
+- * stopping signal is not SIGTRAP. -brl
+- */
+- if (current->exit_code) {
+- send_sig(current->exit_code, current, 1);
+- current->exit_code = 0;
+- }
+- out:
+- if (unlikely(current->audit_context) && !entryexit)
+- audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
+- regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
+- regs->gprs[4], regs->gprs[5]);
++ if (unlikely(current->audit_context))
++ audit_syscall_entry(test_thread_flag(TIF_31BIT) ?
++ AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
++ regs->gprs[2], regs->orig_gpr2,
++ regs->gprs[3], regs->gprs[4],
++ regs->gprs[5]);
++ return ret;
++}
++
++asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
++{
++ if (unlikely(current->audit_context))
++ audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
++ regs->gprs[2]);
++
++ if (test_thread_flag(TIF_SYSCALL_TRACE))
++ tracehook_report_syscall_exit(regs, 0);
+ }
+
+ /*
+--- a/arch/s390/kernel/signal.c
++++ b/arch/s390/kernel/signal.c
+@@ -24,6 +24,7 @@
+ #include <linux/tty.h>
+ #include <linux/personality.h>
+ #include <linux/binfmts.h>
++#include <linux/tracehook.h>
+ #include <asm/ucontext.h>
+ #include <asm/uaccess.h>
+ #include <asm/lowcore.h>
+@@ -507,6 +508,12 @@ void do_signal(struct pt_regs *regs)
+ */
+ if (current->thread.per_info.single_step)
+ set_thread_flag(TIF_SINGLE_STEP);
++
++ /*
++ * Let tracing know that we've done the handler setup.
++ */
++ tracehook_signal_handler(signr, &info, &ka, regs,
++ test_thread_flag(TIF_SINGLE_STEP));
+ }
+ return;
+ }
+@@ -526,3 +533,9 @@ void do_signal(struct pt_regs *regs)
+ set_thread_flag(TIF_RESTART_SVC);
+ }
+ }
++
++void do_notify_resume(struct pt_regs *regs)
++{
++ clear_thread_flag(TIF_NOTIFY_RESUME);
++ tracehook_notify_resume(regs);
++}
|
[-]
[+]
|
Changed |
patches.trace.tar.bz2/tracepoints.patch
^
|
@@ -437,7 +437,7 @@
#if 0
#define DEBUGP printk
-@@ -1899,6 +1900,8 @@ static noinline struct module *load_modu
+@@ -1915,6 +1916,8 @@ static noinline struct module *load_modu
#endif
unsigned int markersindex;
unsigned int markersstringsindex;
@@ -446,7 +446,7 @@
unsigned int verboseindex;
struct module *mod;
long err = 0;
-@@ -2188,6 +2191,10 @@ static noinline struct module *load_modu
+@@ -2206,6 +2209,10 @@ static noinline struct module *load_modu
"__markers_strings");
verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
@@ -457,7 +457,7 @@
/* Now do relocations. */
for (i = 1; i < hdr->e_shnum; i++) {
const char *strtab = (char *)sechdrs[strindex].sh_addr;
-@@ -2214,6 +2221,12 @@ static noinline struct module *load_modu
+@@ -2232,6 +2239,12 @@ static noinline struct module *load_modu
mod->num_markers =
sechdrs[markersindex].sh_size / sizeof(*mod->markers);
#endif
@@ -470,7 +470,7 @@
/* Find duplicate symbols */
err = verify_export_symbols(mod);
-@@ -2232,11 +2245,16 @@ static noinline struct module *load_modu
+@@ -2250,11 +2263,16 @@ static noinline struct module *load_modu
add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
@@ -488,7 +488,7 @@
dynamic_printk_setup(sechdrs, verboseindex);
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
-@@ -2826,3 +2844,50 @@ void module_update_markers(void)
+@@ -2844,3 +2862,50 @@ void module_update_markers(void)
mutex_unlock(&module_mutex);
}
#endif
|
[-]
[+]
|
Changed |
patches.trace.tar.bz2/utrace-core
^
|
@@ -641,7 +641,7 @@
fdt = files_fdtable(p->files);
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
-@@ -1196,6 +1196,11 @@ struct task_struct {
+@@ -1198,6 +1198,11 @@ struct task_struct {
#endif
seccomp_t seccomp;
|
|
Deleted |
patches.uml.tar.bz2
^
|
|
Changed |
patches.xen.tar.bz2
^
|
[-]
[+]
|
Changed |
post.sh
^
|
@@ -11,8 +11,8 @@
case "@FLAVOR@" in
ppc64|kdump)
if [ -d /proc/device-tree ]; then
- if [ ! -d /proc/ppc64 ]; then
- wrong_boardtype "OpenFirmware based 64bit machines or legacy iSeries"
+ if [ -d /proc/iSeries -o ! -d /proc/ppc64 ]; then
+ wrong_boardtype "OpenFirmware based 64bit machines"
fi
fi
;;
@@ -28,7 +28,7 @@
suffix=
case @FLAVOR@ in
- kdump|ps3|um|xen*)
+ kdump|ps3|xen*|vanilla)
suffix=-@FLAVOR@
;;
esac
@@ -113,7 +113,7 @@
# handle 10.1 and SLES10 GA
elif [ -x /sbin/update-bootloader ]; then
case @FLAVOR@ in
- kdump|um|ps3)
+ kdump|ps3)
;;
*)
opt_xen_kernel=
|
[-]
[+]
|
Changed |
postun.sh
^
|
@@ -21,7 +21,7 @@
remove_previos_entry=no
suffix=
case @FLAVOR@ in
- kdump|ps3|um|xen*)
+ kdump|ps3|xen*|vanilla)
suffix=-@FLAVOR@
;;
esac
|
|
Added |
ready
^
|
[-]
[+]
|
Changed |
series.conf
^
|
@@ -31,6 +31,13 @@
patches.kernel.org/patch-2.6.27.1-2
patches.kernel.org/patch-2.6.27.2-3
patches.kernel.org/patch-2.6.27.3-4
+ patches.kernel.org/patch-2.6.27.4-5
+ patches.kernel.org/patch-2.6.27.5-6
+ patches.kernel.org/patch-2.6.27.6-7
+ patches.kernel.org/revert-scsi-qla2xxx-correct-atmel-flash-part-handling.patch
+ patches.kernel.org/revert-scsi-qla2xxx-do-not-honour-max_vports-from-firmware-for-2g-isps-and-below.patch
+ patches.kernel.org/revert-scsi-qla2xxx-return-a-failed-status-when-abort-mailbox-command-fails.patch
+ patches.kernel.org/patch-2.6.27.8-rc1
########################################################
# Build fixes that apply to the vanilla kernel too.
@@ -93,6 +100,8 @@
patches.fixes/seccomp-disable-tsc-option
patches.suse/self-ptrace.patch
-RT patches.suse/rwlocks-enable-interrupts
+ patches.suse/coredump_filter-add-elfhdr-default.patch
+ patches.fixes/sched-fix-bug-in-sched-domain-degenerate.patch
########################################################
# Architecture-specific patches. These used to be all
@@ -108,11 +117,14 @@
patches.fixes/ia64-sparse-fixes.diff
-RT patches.arch/ia64-rwlocks-enable-interrupts
patches.fixes/nr-irqs-file
+ patches.arch/mm-avoid-bad-page-on-lru
+ patches.arch/ia64-page-migration
########################################################
# i386
########################################################
+
# amd64 | x86-64 | x86_64
# 'Intel(r) Extended Memory 64 Technology' | 'Intel(r) EM64T'
# x64
@@ -134,6 +146,8 @@
patches.arch/x86-introduce-config-option-for-pci-reroute-quirks.patch
patches.arch/x86-self-ptrace.patch
patches.arch/x86-tracehook
+ patches.arch/x86-hpet-use-WARN_ON_ONCE
+ patches.arch/x86-hpet-pre-read
########################################################
# x86_64/i386 biarch - x2APIC next generation x86 CPU support
@@ -200,15 +214,46 @@
patches.arch/x86_sgi_cpus4096-06-optimize-cpumask-in-sched_c.patch
patches.arch/x86_sgi_cpus4096-07_pae_compile_fixups.patch
+ # UV
+ patches.arch/x86_sgi-uv-scir.patch
+ patches.fixes/uv-efi_bios.diff
+ patches.fixes/uv-bios_common.diff
+ patches.fixes/uv-bios_call_partition.diff
+ patches.fixes/uv-sysfs.diff
+ patches.fixes/uv-sn_region_size.diff
+ patches.fixes/uv-bios_call_watchlist.diff
+ patches.fixes/uv-bios_call_memprotect.diff
+ patches.fixes/uv-bios_call_reserve_page.diff
+ patches.fixes/ia64_uv_partition_id.diff
+ patches.fixes/ia64_uv_watchlist.diff
+
+ patches.fixes/null_irq_desc_name.diff
+ patches.fixes/uv_setup_irq.diff
+ patches.fixes/uv-xp-change_memprotect.diff
+ patches.fixes/uv-xpc_create_gru_mq_uv.diff
+ patches.fixes/uv-xpc-get_sn_info.diff
+ patches.fixes/uv-xpc_get_part_rsvd_page.diff
+
+ # VMware TSC workaround patches (bnc#441338)
+ patches.arch/x86-vmware-tsc-01-add-TSC_RELIABLE
+ patches.arch/x86-vmware-tsc-02-add-X86_FEATURE_HYPERVISOR
+ patches.arch/x86-vmware-tsc-03-detect-from-hypervisor
+ patches.arch/x86-vmware-tsc-04-use-TSC_RELIABLE
+ patches.arch/x86-vmware-tsc-05-skip-tsc-clocksource
+ patches.arch/x86-vmware-tsc-06-fix-vmware_get_tsc
+ patches.arch/x86-vmware-tsc-07-DMI-product-serial-key
+
########################################################
# powerpc/generic
########################################################
+ patches.suse/8250-sysrq-ctrl_o.patch
patches.arch/ppc-pseries_remove_lmb-PAGE_SHIFTT.patch
patches.arch/ppc-pseries_pfn-mem-rm.patch
patches.suse/ppc-no-LDFLAGS_MODULE.patch
patches.arch/ppc-vio-modalias.patch
patches.arch/ppc-efika-mpc52xx-ac97.patch
patches.arch/ppc-efika-psc-console-autodetection.patch
+- patches.arch/ppc-efika-bestcomm-ata-dma.patch
patches.arch/ppc-pegasos-console-autodetection.patch
patches.suse/ppc-powerbook-usb-fn-key-default.patch
patches.suse/suse-ppc32-mol.patch
@@ -225,19 +270,33 @@
patches.arch/ppc-prom-nodisplay.patch
patches.fixes/ptrace-getsiginfo
patches.arch/ppc-ipic-suspend-without-83xx-fix
- patches.arch/ppc64-rpanote-relocate-firmware.patch
patches.arch/ppc-dynamic-reconfiguration.diff
patches.arch/ppc-vmcoreinfo.diff
- patches.arch/ppc-pseries_16g-numa.patch
- patches.arch/ppc-pseries_hugepage_pagetable_allocation.patch
- patches.arch/ppc-pseries_mem-limit-16g.patch
- patches.arch/ppc-gigantic-page-fix2.patch
- patches.arch/ppc-gigantic-page-fix3.patch
patches.arch/ppc-powerpc-fix-pci-unmap-io.patch
patches.arch/ppc-pcibios_allocate_bus_resources.patch
patches.arch/ppc-powerpc-debug-pci-hotplug.patch
patches.arch/ppc-oprofile-spu.patch
patches.arch/ppc-oprofile-spu-mutex-locking.patch
+ patches.arch/ppc-clock_gettime-nanoseconds.patch
+ patches.arch/compat-sys-swapcontext
+ patches.arch/ppc-select
+
+ patches.arch/ppc-axon-missing-msi-workaround-5.diff
+ patches.arch/ppc-pseries-bsr-4k.patch
+ patches.arch/ppc-pseries-bsr-multinode.patch
+ patches.arch/ppc-pseries-cmm-pagecounter.patch
+ patches.arch/ppc-of-irq-map.patch
+ patches.arch/ppc-memoryless-nodes.patch
+
+ patches.arch/ppc-spufs-01-use-inc_nlink.patch
+ patches.arch/ppc-spufs-03-sputrace-Only-enable-logging-on-open.patch
+ patches.arch/ppc-spufs-04-sputrace-Don-t-block-until-the-read.patch
+ patches.arch/ppc-spufs-05-Use-state_mutex-for-switch_log-lockin.patch
+ patches.arch/ppc-spufs-06-Don-t-require-full-buffer-in-switch_l.patch
+ patches.arch/ppc-spufs-07-Don-t-spu_acquire_saved-unnecessarily.patch
+ patches.arch/ppc-spufs-08-Use-kmalloc-rather-than-kzalloc-for-s.patch
+ patches.arch/ppc-spufs-09-Improve-search-of-node-for-contexts-w.patch
+ patches.arch/ppc-spufs-10-Explain-conditional-decrement-of-aff_.patch
########################################################
# PS3
@@ -246,6 +305,7 @@
patches.arch/ppc-ps3-add-ps3av-audio-mute-analog.patch
patches.arch/ppc-ps3-add-passthrough-support-for-non-audio-streams.patch
patches.arch/ppc-ps3-add-support-for-SPDIF-HDMI-passthrough.patch
+ patches.arch/ppc-ps3-introduce-ps3_gpu_mutex.patch
patches.arch/ppc-ps3-ps3vram-mtd.patch
########################################################
@@ -253,17 +313,15 @@
########################################################
patches.arch/s390-add-FREE_PTE_NR
- patches.arch/s390-01-01-self-ptrace-v3.patch
patches.arch/s390-01-02-dcss-64-v2.patch
patches.arch/s390-01-04-fcpperf-1.patch
patches.arch/s390-01-04-fcpperf-2.patch
- patches.arch/s390-01-04-fcpperf-3.patch
+ patches.arch/s390-01-04-fcpperf-3-v2.patch
patches.arch/s390-01-04-fcpperf-4-v2.patch
- patches.arch/s390-01-05-kmsg-v2.patch
+ patches.arch/s390-01-05-kmsg-v3.patch
patches.arch/s390-01-06-zfcp-cleanup-v2.patch
patches.arch/s390-02-01-xpram.patch
- patches.arch/s390-02-02-smp-sysdev.patch
patches.arch/s390-02-03-zfcp.patch
patches.arch/s390-02-04-qeth-mac.patch
patches.arch/s390-02-05-qeth-recovery.patch
@@ -271,31 +329,62 @@
patches.arch/s390-02-07-qeth-ipv6check.patch
patches.arch/s390-02-08-qeth-panic.patch
patches.arch/s390-02-09-tape-lock.patch
+ patches.arch/s390-02-10-zfcp-scan-online.patch
+
+ patches.arch/s390-03-01-stp-init.patch
+ patches.arch/s390-03-02-setup_memory.patch
+ patches.arch/s390-03-03-dasd_unsolicited_interrupt.patch
+ patches.arch/s390-03-04-qdio_multicast_performance.patch
+ patches.arch/s390-03-05-dasd-block-uevent.patch
+ patches.arch/s390-03-06-zfcp-hexdump.patch
+ patches.arch/s390-03-07-qeth_hsi_mcl_string.patch
+ patches.arch/s390-03-08-zfcp-abort-race.patch
+ patches.arch/s390-03-09-zfcp-oops-during-target-scan.patch
+
+ patches.arch/s390-04-01-qdio_prevent_double_shutdown.patch
+ patches.arch/s390-04-02-qdio-osa-port-count.patch
+ patches.arch/s390-04-03-kmsg.patch
+ patches.arch/s390-04-04-dasd_fatal_error_log_sense.patch
+ patches.arch/s390-04-06-cio-sac-update.diff
+ patches.arch/s390-04-07-als.patch
+ patches.arch/s390-04-08-cio-ungroup-race-fix.patch
+ patches.arch/s390-04-09-zfcp-host-busy-count-fix.patch
+
+ patches.arch/s390-05-01-zfcp-message-linebreak.patch
+ patches.arch/s390-05-02-zfcp-invalid-non-null-return.patch
+ patches.arch/s390-05-03-zfcp-wka-port.patch
patches.arch/s390-symmetrix-ioctl.patch
+ patches.arch/s390-personality-mask.patch
########################################################
# VM/FS patches
########################################################
-RT patches.suse/unmap_vmas-lat
+andrea patches.suse/silent-stack-overflow
-+npiggin patches.suse/silent-stack-overflow-2.patch
|
[-]
[+]
|
Deleted |
split-into-symsets
^
|
@@ -1,40 +0,0 @@
-#! /bin/bash
-
-usage() {
- echo "Usage: ${0##*/} {dir} < Module.symvers"
- exit $1
-}
-
-[ $# -eq 1 ] || usage 1
-dir=$1
-
-tmpdir=$(mktemp -dt ${0##*/}.XXXXXXXXXX)
-trap "rm -rf $tmpdir" EXIT
-
-split_into_sets() {
- local dir=$1
-
- awk '
- { set = gensub(/\/[^\/]+$/, "", "", $3)
- sets[set] = sets[set] $0 "\n"
- }
- END {
- for (set in sets) {
- filename = gensub(/\//, "_", "g", set)
- printf "%s", sets[set] > dir "/" filename
- }
- }
- ' dir="$dir"
-}
-
-sort -k2 \
-| split_into_sets "$tmpdir"
-
-shopt -s nullglob
-set -- $tmpdir/*
-if [ $# -ne 0 ]; then
- md5sum "$@" \
- | while read md5sum set; do
- cp $set $dir/${set##*/}.${md5sum:0:16}
- done
-fi
|
[-]
[+]
|
Changed |
supported.conf
^
|
@@ -19,9 +19,9 @@
+external kernel/arch/powerpc/platforms/pseries/hvcserver
+external kernel/arch/powerpc/platforms/pseries/scanlog
+external kernel/arch/powerpc/sysdev/axonram
-- kernel/arch/powerpc/sysdev/bestcomm/bestcomm-ata # for Efika mpc52xx
-- kernel/arch/powerpc/sysdev/bestcomm/bestcomm-fec # for Efika mpc52xx
-- kernel/arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd # for Efika mpc52xx
+ kernel/arch/powerpc/sysdev/bestcomm/bestcomm-ata # for Efika mpc52xx
+ kernel/arch/powerpc/sysdev/bestcomm/bestcomm-fec # for Efika mpc52xx
+ kernel/arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd # for Efika mpc52xx
+external kernel/arch/powerpc/sysdev/pmi
kernel/arch/s390/appldata/appldata_mem
kernel/arch/s390/appldata/appldata_net_sum
@@ -35,6 +35,7 @@
kernel/arch/s390/crypto/sha512_s390
kernel/arch/s390/crypto/sha_common
kernel/arch/s390/mm/cmm
+ kernel/arch/s390/kvm/kvm
kernel/arch/x86/crypto/aes-i586 # Rijndael (AES) Cipher Algorithm (optimized for i586)
kernel/arch/x86/crypto/aes-x86_64
kernel/arch/x86/crypto/salsa20-i586
@@ -727,12 +728,14 @@
kernel/drivers/md/dm-crypt # device-mapper target for transparent encryption / decryption
kernel/drivers/md/dm-delay
kernel/drivers/md/dm-log
- kernel/drivers/md/dm-mem-cache
+ kernel/drivers/md/dm-memcache
kernel/drivers/md/dm-message
kernel/drivers/md/dm-mirror # device-mapper mirror target
+base kernel/drivers/md/dm-mod # device-mapper driver
kernel/drivers/md/dm-multipath # device-mapper multipath target
- kernel/drivers/md/dm-raid4-5
+ kernel/drivers/md/dm-raid45
+ kernel/drivers/md/dm-regions
+ kernel/drivers/md/dm-log
kernel/drivers/md/dm-region_hash
kernel/drivers/md/dm-round-robin # Round-robin path selector
kernel/drivers/md/dm-snapshot # device-mapper snapshot target
@@ -1080,7 +1083,7 @@
- kernel/drivers/mtd/devices/mtdram # Simulated MTD driver for testing
- kernel/drivers/mtd/devices/phram # MTD driver for physical RAM
- kernel/drivers/mtd/devices/pmc551
-- kernel/drivers/mtd/devices/ps3vram # Sony PS3 use video card RAM
+ kernel/drivers/mtd/devices/ps3vram # Sony PS3 use video card RAM ; supported to get it out of kernel-extra
- kernel/drivers/mtd/devices/slram # MTD driver for uncached system RAM
- kernel/drivers/mtd/maps/amd76xrom # MTD map driver for BIOS chips on the AMD76X southbridge
- kernel/drivers/mtd/maps/ck804xrom
@@ -1099,9 +1102,11 @@
- kernel/drivers/mtd/maps/scb2_flash # MTD map driver for Intel SCB2 BIOS Flash
- kernel/drivers/mtd/maps/scx200_docflash # NatSemi SCx200 DOCCS Flash Driver
- kernel/drivers/mtd/maps/ts5500_flash
-- kernel/drivers/mtd/mtd
-- kernel/drivers/mtd/mtd_blkdevs # Common interface to block layer for MTD 'translation layers'
-- kernel/drivers/mtd/mtdblock # Caching read/erase/writeback block device emulation access to MTD devices
+ # supported to get them out of kernel-extra, for ps3vram
+ kernel/drivers/mtd/mtd
+ kernel/drivers/mtd/mtd_blkdevs # Common interface to block layer for MTD 'translation layers'
+ kernel/drivers/mtd/mtdblock # Caching read/erase/writeback block device emulation access to MTD devices
+ #
- kernel/drivers/mtd/mtdblock_ro
- kernel/drivers/mtd/mtdchar # Direct character-device access to MTD devices
- kernel/drivers/mtd/mtdconcat # Generic support for concatenating of MTD devices
@@ -1158,7 +1163,7 @@
kernel/drivers/net/atlx/atl2
+isa kernel/drivers/net/atp
kernel/drivers/net/b44 # Broadcom 4400 10/100 PCI ethernet driver
-- kernel/drivers/net/bmac # PowerMac onboard ethernet, for older PCI macs
+ kernel/drivers/net/bmac # PowerMac onboard ethernet, for older PCI macs
kernel/drivers/net/bnx2 # Broadcom NX2 network driver
kernel/drivers/net/bnx2x
kernel/drivers/net/bonding/bonding # Ethernet Channel Bonding Driver, v2.6.0
@@ -1187,8 +1192,8 @@
+isa kernel/drivers/net/eth16i
+isa kernel/drivers/net/ewrk3
kernel/drivers/net/fealnx # Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver
-- kernel/drivers/net/fec_mpc52xx # for Efika mpc52xx
-- kernel/drivers/net/fec_mpc52xx_phy # for Efika mpc52xx
+ kernel/drivers/net/fec_mpc52xx # for Efika mpc52xx
+ kernel/drivers/net/fec_mpc52xx_phy # for Efika mpc52xx
kernel/drivers/net/forcedeth # Reverse Engineered nForce ethernet driver
kernel/drivers/net/hamachi # Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver
- kernel/drivers/net/hamradio/6pack # 6pack driver for AX.25
@@ -1238,11 +1243,11 @@
kernel/drivers/net/ixgb/ixgb # Intel(R) PRO/10GbE Network Driver
+isa kernel/drivers/net/lance
+isa kernel/drivers/net/lp486e
-- kernel/drivers/net/mace # PowerMac onboard ethernet, first PCI Macs
+ kernel/drivers/net/mace # PowerMac onboard ethernet, first PCI Macs
kernel/drivers/net/macvlan
kernel/drivers/net/mii # MII hardware support library
kernel/drivers/net/mlx4/mlx4_core
-- kernel/drivers/net/mv643xx_eth # gigabit Pegasos2, all chips share the same MAC
+ kernel/drivers/net/mv643xx_eth # gigabit Pegasos2, all chips share the same MAC
kernel/drivers/net/myri10ge/myri10ge
kernel/drivers/net/natsemi # National Semiconductor DP8381x series PCI Ethernet driver
+isa kernel/drivers/net/ne
@@ -1579,12 +1584,12 @@
kernel/drivers/scsi/libsas/libsas # Library module for SAS devices
kernel/drivers/scsi/libsrp # Library module for SRP devices
kernel/drivers/scsi/lpfc/lpfc
-- kernel/drivers/scsi/mac53c94 # PowerMac onboard scsi, early PCI Macs
+ kernel/drivers/scsi/mac53c94 # PowerMac onboard scsi, early PCI Macs
kernel/drivers/scsi/megaraid # LSI Logic MegaRAID driver
kernel/drivers/scsi/megaraid/megaraid_mbox # LSI Logic MegaRAID Mailbox Driver
kernel/drivers/scsi/megaraid/megaraid_mm
kernel/drivers/scsi/megaraid/megaraid_sas
-- kernel/drivers/scsi/mesh # PowerMac onboard scsi, early PCI Macs
+ kernel/drivers/scsi/mesh # PowerMac onboard scsi, early PCI Macs
kernel/drivers/scsi/mvsas
+isa kernel/drivers/scsi/NCR53c406a
kernel/drivers/scsi/nsp32
@@ -1857,7 +1862,7 @@
kernel/drivers/watchdog/w83877f_wdt # Driver for watchdog timer in w83877f chip
+review kernel/drivers/watchdog/w83977f_wdt # W83977F Watchdog Timer Driver for Winbond W83977F I/O Chip
kernel/drivers/watchdog/wafer5823wdt # ICP Wafer 5823 Single Board Computer WDT driver
-- kernel/drivers/watchdog/wdrtas
+- kernel/drivers/watchdog/wdrtas # watchdog for RTAS on pSeries JS20
+isa kernel/drivers/watchdog/wdt
kernel/drivers/watchdog/wdt_pci # Driver for the ICS PCI-WDT500/501 watchdog cards
kernel/drivers/xen/blkback/blkbk # Xen block device backend
@@ -1957,13 +1962,14 @@
kernel/fs/nls/nls_utf8
kernel/fs/novfs/novfs
kernel/fs/ntfs/ntfs # NTFS 1.2/3.x driver - Copyright (c) 2001-2003 Anton Altaparmakov
- kernel/fs/ocfs2/cluster/ocfs2_nodemanager
- kernel/fs/ocfs2/dlm/ocfs2_dlm
- kernel/fs/ocfs2/dlm/ocfs2_dlmfs
- kernel/fs/ocfs2/ocfs2
- kernel/fs/ocfs2/ocfs2_stack_o2cb
- kernel/fs/ocfs2/ocfs2_stack_user
- kernel/fs/ocfs2/ocfs2_stackglue
+# ocfs2 is provided separately in the ocfs2 KMP package
+- kernel/fs/ocfs2/cluster/ocfs2_nodemanager
+- kernel/fs/ocfs2/dlm/ocfs2_dlm
+- kernel/fs/ocfs2/dlm/ocfs2_dlmfs
+- kernel/fs/ocfs2/ocfs2
+- kernel/fs/ocfs2/ocfs2_stack_o2cb
+- kernel/fs/ocfs2/ocfs2_stack_user
+- kernel/fs/ocfs2/ocfs2_stackglue
kernel/fs/omfs/omfs
- kernel/fs/qnx4/qnx4
kernel/fs/quota_v1 # Old quota format support
@@ -2072,18 +2078,19 @@
kernel/net/ipv4/ipcomp # IP Payload Compression Protocol (IPComp) - RFC3173
kernel/net/ipv4/ip_gre
kernel/net/ipv4/ipip
- kernel/net/ipv4/ipvs/ip_vs
- kernel/net/ipv4/ipvs/ip_vs_dh
- kernel/net/ipv4/ipvs/ip_vs_ftp
- kernel/net/ipv4/ipvs/ip_vs_lblc
- kernel/net/ipv4/ipvs/ip_vs_lblcr
- kernel/net/ipv4/ipvs/ip_vs_lc
- kernel/net/ipv4/ipvs/ip_vs_nq
- kernel/net/ipv4/ipvs/ip_vs_rr
- kernel/net/ipv4/ipvs/ip_vs_sed
- kernel/net/ipv4/ipvs/ip_vs_sh
- kernel/net/ipv4/ipvs/ip_vs_wlc
- kernel/net/ipv4/ipvs/ip_vs_wrr
+# provided separately in the cluster-network KMP
+- kernel/net/ipv4/ipvs/ip_vs
+- kernel/net/ipv4/ipvs/ip_vs_dh
+- kernel/net/ipv4/ipvs/ip_vs_ftp
+- kernel/net/ipv4/ipvs/ip_vs_lblc
+- kernel/net/ipv4/ipvs/ip_vs_lblcr
+- kernel/net/ipv4/ipvs/ip_vs_lc
+- kernel/net/ipv4/ipvs/ip_vs_nq
+- kernel/net/ipv4/ipvs/ip_vs_rr
+- kernel/net/ipv4/ipvs/ip_vs_sed
+- kernel/net/ipv4/ipvs/ip_vs_sh
+- kernel/net/ipv4/ipvs/ip_vs_wlc
+- kernel/net/ipv4/ipvs/ip_vs_wrr
kernel/net/ipv4/netfilter/arptable_filter # arptables filter table
kernel/net/ipv4/netfilter/arp_tables # arptables core
kernel/net/ipv4/netfilter/arpt_mangle # arptables arp payload mangle target
@@ -2096,7 +2103,8 @@
kernel/net/ipv4/netfilter/ip_tables # IPv4 packet filter
kernel/net/ipv4/netfilter/ipt_addrtype # iptables addrtype match
kernel/net/ipv4/netfilter/ipt_ah # iptables AH SPI match module
- kernel/net/ipv4/netfilter/ipt_CLUSTERIP
+# provided separately in the cluster-network KMP
+- kernel/net/ipv4/netfilter/ipt_CLUSTERIP
kernel/net/ipv4/netfilter/ipt_ecn # iptables ECN matching module
kernel/net/ipv4/netfilter/ipt_ECN # iptables ECN modification module
net/ipv4/netfilter/ipt_ipv4options # iptables ipv4 options module
|
[-]
[+]
|
Added |
symsets.pl
^
|
@@ -0,0 +1,392 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use diagnostics;
+
+use Digest::MD5 qw(md5_hex);
+use Getopt::Long;
+use Data::Dumper;
+
+
+our $usage =
+"Usage:
+ $0 --list-exported-symbols ...
+ $0 --generate-symsets [--reference=DIR] --output-dir=DIR ...
+ $0 --list-symsets [--reference=DIR] ...
+ $0 --check-kabi --reference=DIR ...
+";
+our ($opt_verbose);
+our $kabi_badness = 0;
+our (%commonsyms, %usedsyms, @severities);
+our ($opt_list_exp, $opt_gen_sets, $opt_list_sets, $opt_check_kabi) = (0,0,0,0);
+our ($opt_max_badness, $opt_commonsyms, $opt_usedsyms, $opt_severities);
+our ($opt_output_dir, $opt_reference, $opt_modules, $opt_symvers_file);
+
+sub main {
+ my $res = GetOptions(
+ 'list-exported-symbols' => \$opt_list_exp,
+ 'generate-symsets' => \$opt_gen_sets,
+ 'list-symsets' => \$opt_list_sets,
+ 'check-kabi' => \$opt_check_kabi,
+
+ 'max-badness=i' => \$opt_max_badness,
+ 'commonsyms|common-syms=s' => \$opt_commonsyms,
+ 'usedsyms|used-syms=s' => \$opt_usedsyms,
+ 'severities=s' => \$opt_severities,
+
+ 'symvers-file=s' => \$opt_symvers_file,
+ 'modules=s' => \$opt_modules,
+ 'reference=s' => \$opt_reference,
+
+ 'output-dir=s' => \$opt_output_dir,
+ 'verbose|v' => \$opt_verbose,
+ );
+ # boring option checking
+ my $opt_err = sub {
+ print STDERR "ERROR: @_\n";
+ $res = 0;
+ };
+ &$opt_err("Please choose one of --list-exported-symbols, --generate-symsets, --list-symsets or --check-kabi")
+ if ($opt_list_exp + $opt_gen_sets + $opt_list_sets > 1 ||
+ !($opt_list_exp + $opt_gen_sets + $opt_list_sets + $opt_check_kabi));
+ &$opt_err("--check-kabi doesn't work with --list-exported-symbols")
+ if ($opt_list_exp && $opt_check_kabi);
+ &$opt_err("--check-kabi requires --reference")
+ if ($opt_check_kabi && !$opt_reference);
+ &$opt_err("--output-dir only makes sense with --generate-symsets")
+ if ($opt_output_dir && !$opt_gen_sets);
+ &$opt_err("--generate-symsets requires --output-dir")
+ if ($opt_gen_sets && !$opt_output_dir);
+ if (!$opt_check_kabi) {
+ for my $opt qw(max-badness commonsyms usedsyms severities) {
+ no strict 'refs';
+ my $var = "opt_$opt";
+ $var =~ s/-/_/g;
+ if (defined(${$var})) {
+ &$opt_err("--$opt only makes sense with --check-kabi");
+ }
+ }
+ }
+ # get list of modules
+ my @modules;
+ if (defined($opt_modules)) {
+ my $fh;
+ if ($opt_modules eq '-') {
+ open($fh, '<&STDIN');
+ } else {
+ open($fh, '<', $opt_modules) or die "Can't open module list $opt_modules: $!\n";
+ }
+ @modules = <$fh>;
+ chomp(@modules);
+ close($fh);
+ } else {
+ @modules = @ARGV;
+ }
+ if (@modules == 0) {
+ &$opt_err("No modules supplied");
+ }
+ if (!$res) {
+ print STDERR $usage;
+ exit 1;
+ }
+
+ # get list of exports
+ my @exports;
+ for my $file (@modules) {
+ push(@exports, module_exports($file));
+ }
+ if (defined($opt_symvers_file)) {
+ push(@exports, builtin_exports(parse_symset($opt_symvers_file)));
+ }
+ if ($opt_list_exp) {
+ print format_exports(@exports);
+ exit 0;
+ }
+
+ # generate symsets and optionally check kabi
+ my (@ref, @sets);
+ @sets = split_into_symsets(@exports);
+ if (defined($opt_reference)) {
+ @ref = load_symsets($opt_reference);
+ if ($opt_check_kabi) {
+ load_kabi_files($opt_commonsyms, $opt_usedsyms, $opt_severities);
+ }
+ # records kabi breakage if $opt_check_kabi is set
+ preserve_symsets(\@ref, \@sets);
+ }
+ if ($opt_gen_sets) {
+ write_symsets($opt_output_dir, @sets);
+ } elsif ($opt_list_sets) {
+ write_symsets(undef, @sets);
+ }
+ if ($kabi_badness) {
+ print STDERR "KABI: badness is $kabi_badness";
+ if (!defined($opt_max_badness) || $kabi_badness <= $opt_max_badness) {
+ print STDERR " (tolerated)\n";
+ } else {
+ print STDERR " (exceeds threshold $opt_max_badness), aborting\n";
+ exit 1;
+ }
+ }
+ exit 0;
+}
+
+# structures used:
+# %export:
+# (crc => $crc, sym => $sym, mod => $module, type => $type)
+# @exportlist
+# ({crc => $crc, sym => $sym, mod => $module, type => $type}, ...)
+# @symset:
+# ($name, [{crc => $crc, sym => $sym, mod => $module, type => $type}, ...])
+# @symsetlist:
+# (
+# [$name, [{crc => $crc, sym => $sym, mod => $module, type => $type}, ...],
+# ...
+# )
+#
+
+# parse a Modules.symvers-style file
+# returns an exportlist
+sub parse_symset {
+ my ($file) = @_;
+ my @res;
+
+ open(my $fh, '<', $file) or die "Error opening $file: $!\n";
+ while (<$fh>) {
+ my @l = split(/\s+/);
+ if (@l < 4) {
+ print STDERR "$file:$.: unknown line\n";
+ next;
+ }
+ $l[0] =~ s/^0x//;
+ push(@res, {crc => $l[0], sym => $l[1], mod => $l[2], type => $l[3]});
+ }
+ close($fh);
+ return @res;
+}
+
+# greps an exportlist for built-in symbols
+sub builtin_exports {
+ return grep { $_->{mod} =~ /(^vmlinux$)|(\/built-in$)/ } @_;
+}
+
+my %export_types = (
+ __ksymtab => "EXPORT_SYMBOL",
+ __ksymtab_unused => "EXPORT_UNUSED_SYMBOL",
+ __ksymtab_gpl => "EXPORT_SYMBOL_GPL",
+ __ksymtab_unused_gpl => "EXPORT_UNUSED_SYMBOL_GPL",
+ __ksymtab_gpl_future => "EXPORT_SYMBOL_GPL_FUTURE"
+);
+# returns an exportlist for a given module
+sub module_exports {
+ my ($file) = @_;
+ my (%crcs, %types, @res);
+ my $mod = $file;
+ $mod =~ s/.*\/lib\/modules\/[^\/]*\/kernel\///;
+ $mod =~ s/\.(k?o|a)$//;
+
+ open(my $pipe, '-|', 'objdump', '-t', $file) or die "objdump -t $file: $!\n";
+ while (<$pipe>) {
+ my $l = $_;
+ my @l = split(/\s+/);
+ next if (@l < 3);
+ next if ($l =~ /^[^ ]* .....d/); # debug symbol
+ my $sym = $l[$#l];
+ my $sec = $l[$#l - 2];
+ if ($sym =~ /^__crc_(.*)/) {
+ $crcs{$1} = $l[0];
+ $crcs{$1} =~ s/^0{8}//;
|